From b7776785a18d3f4e6229cd625f92c11b55894b75 Mon Sep 17 00:00:00 2001 From: Nick Date: Fri, 13 Sep 2019 05:39:49 -0400 Subject: add /src/gpuwattch formatting --- src/gpuwattch/processor.cc | 2033 ++++++++++++++++++++++++-------------------- 1 file changed, 1092 insertions(+), 941 deletions(-) (limited to 'src/gpuwattch/processor.cc') diff --git a/src/gpuwattch/processor.cc b/src/gpuwattch/processor.cc index 5dda9fc..96c3351 100644 --- a/src/gpuwattch/processor.cc +++ b/src/gpuwattch/processor.cc @@ -29,1034 +29,1185 @@ * ***************************************************************************/ /******************************************************************** -* Modified by: * +* 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 -#include +#include "processor.h" +#include #include -#include #include +#include +#include #include -#include #include -#include "parameter.h" +#include +#include "XML_Parse.h" #include "array.h" -#include "const.h" #include "cacti/basic_circuit.h" -#include "XML_Parse.h" -#include "processor.h" +#include "const.h" +#include "parameter.h" #include "version.h" - Processor::Processor(ParseXML *XML_interface) -:XML(XML_interface),//TODO: using one global copy may have problems. - mc(0), - niu(0), - pcie(0), - flashcontroller(0) -{ + : XML(XML_interface), // TODO: using one global copy may have problems. + mc(0), + niu(0), + pcie(0), + flashcontroller(0) { /* - * placement and routing overhead is 10%, core scales worse than cache 40% is accumulated from 90 to 22nm + * placement and routing overhead is 10%, core scales worse than cache 40% is + * accumulated from 90 to 22nm * There is no point to have heterogeneous memory controller on chip, * thus McPAT only support homogeneous memory controllers. */ rt_power.reset(); int i; - double pppm_t[4] = {1,1,1,1}; - l2_power=0; - idle_core_power=0; + double pppm_t[4] = {1, 1, 1, 1}; + l2_power = 0; + idle_core_power = 0; set_proc_param(); if (procdynp.homoCore) - numCore = procdynp.numCore==0? 0:1; + numCore = procdynp.numCore == 0 ? 0 : 1; else - numCore = procdynp.numCore; + numCore = procdynp.numCore; if (procdynp.homoL2) - numL2 = procdynp.numL2==0? 0:1; + numL2 = procdynp.numL2 == 0 ? 0 : 1; else - numL2 = procdynp.numL2; + numL2 = procdynp.numL2; - if (XML->sys.Private_L2 && numCore != numL2) - { - cout<<"Number of private L2 does not match number of cores"<sys.Private_L2 && numCore != numL2) { + cout << "Number of private L2 does not match number of cores" << endl; + exit(0); } if (procdynp.homoL3) - numL3 = procdynp.numL3==0? 0:1; + numL3 = procdynp.numL3 == 0 ? 0 : 1; else - numL3 = procdynp.numL3; + numL3 = procdynp.numL3; if (procdynp.homoNOC) - numNOC = procdynp.numNOC==0? 0:1; + numNOC = procdynp.numNOC == 0 ? 0 : 1; else - numNOC = procdynp.numNOC; + numNOC = procdynp.numNOC; -// if (!procdynp.homoNOC) -// { -// cout<<"Current McPAT does not support heterogeneous NOC"<computeEnergy(); - cores[i]->computeEnergy(false); - if (procdynp.homoCore){ - core.area.set_area(core.area.get_area() + cores[i]->area.get_area()*procdynp.numCore); - set_pppm(pppm_t,cores[i]->clockRate*procdynp.numCore, procdynp.numCore,procdynp.numCore,procdynp.numCore); - //set the exClockRate - exClockRate=cores[0]->clockRate*2;//TODO; get from XML file - //cout<<"****EX clock rate:"<power*pppm_t; - set_pppm(pppm_t,1/cores[i]->executionTime, procdynp.numCore,procdynp.numCore,procdynp.numCore); - core.rt_power = core.rt_power + cores[i]->rt_power*pppm_t; - area.set_area(area.get_area() + core.area.get_area());//placement and routing overhead is 10%, core scales worse than cache 40% is accumulated from 90 to 22nm - power = power + core.power; - rt_power = rt_power + core.rt_power; - } - else{ - core.area.set_area(core.area.get_area() + cores[i]->area.get_area()); - area.set_area(area.get_area() + cores[i]->area.get_area());//placement and routing overhead is 10%, core scales worse than cache 40% is accumulated from 90 to 22nm - - set_pppm(pppm_t,cores[i]->clockRate, 1, 1, 1); - //set the exClockRate - exClockRate=cores[0]->clockRate;//TODO; get from XML file - //cout<<"****EX clock rate:"<power*pppm_t; - power = power + cores[i]->power*pppm_t; - - set_pppm(pppm_t,1/cores[i]->executionTime, 1, 1, 1); - core.rt_power = core.rt_power + cores[i]->rt_power*pppm_t; - rt_power = rt_power + cores[i]->rt_power*pppm_t; - } + numL2Dir = procdynp.numL2Dir; + + for (i = 0; i < numCore; i++) { + cores.push_back(new Core(XML, i, &interface_ip)); + cores[i]->computeEnergy(); + cores[i]->computeEnergy(false); + if (procdynp.homoCore) { + core.area.set_area(core.area.get_area() + + cores[i]->area.get_area() * procdynp.numCore); + set_pppm(pppm_t, cores[i]->clockRate * procdynp.numCore, procdynp.numCore, + procdynp.numCore, procdynp.numCore); + // set the exClockRate + exClockRate = cores[0]->clockRate * 2; // TODO; get from XML file + // cout<<"****EX clock rate:"<power * pppm_t; + set_pppm(pppm_t, 1 / cores[i]->executionTime, procdynp.numCore, + procdynp.numCore, procdynp.numCore); + core.rt_power = core.rt_power + cores[i]->rt_power * pppm_t; + area.set_area(area.get_area() + + core.area.get_area()); // placement and routing overhead is + // 10%, core scales worse than cache + // 40% is accumulated from 90 to + // 22nm + power = power + core.power; + rt_power = rt_power + core.rt_power; + } else { + core.area.set_area(core.area.get_area() + cores[i]->area.get_area()); + area.set_area(area.get_area() + + cores[i]->area.get_area()); // placement and routing + // overhead is 10%, core scales + // worse than cache 40% is + // accumulated from 90 to 22nm + + set_pppm(pppm_t, cores[i]->clockRate, 1, 1, 1); + // set the exClockRate + exClockRate = cores[0]->clockRate; // TODO; get from XML file + // cout<<"****EX clock rate:"<power * pppm_t; + power = power + cores[i]->power * pppm_t; + + set_pppm(pppm_t, 1 / cores[i]->executionTime, 1, 1, 1); + core.rt_power = core.rt_power + cores[i]->rt_power * pppm_t; + rt_power = rt_power + cores[i]->rt_power * pppm_t; + } } - if (!XML->sys.Private_L2) - { - - if (numL2 >0) - for (i = 0;i < numL2; i++) - { - l2array.push_back(new SharedCache(XML,i, &interface_ip)); - - l2array[i]->computeEnergy(); - l2array[i]->computeEnergy(false); - if (procdynp.homoL2){ - l2.area.set_area(l2.area.get_area() + l2array[i]->area.get_area()*procdynp.numL2); - set_pppm(pppm_t,l2array[i]->cachep.clockRate*procdynp.numL2, procdynp.numL2,procdynp.numL2,procdynp.numL2); - l2.power = l2.power + l2array[i]->power*pppm_t; - set_pppm(pppm_t,1/l2array[i]->cachep.executionTime, procdynp.numL2,procdynp.numL2,procdynp.numL2); - l2.rt_power = l2.rt_power + l2array[i]->rt_power*pppm_t; - area.set_area(area.get_area() + l2.area.get_area());//placement and routing overhead is 10%, l2 scales worse than cache 40% is accumulated from 90 to 22nm - power = power + l2.power; - rt_power = rt_power + l2.rt_power; - } - else{ - l2.area.set_area(l2.area.get_area() + l2array[i]->area.get_area()); - area.set_area(area.get_area() + l2array[i]->area.get_area());//placement and routing overhead is 10%, l2 scales worse than cache 40% is accumulated from 90 to 22nm - - set_pppm(pppm_t,l2array[i]->cachep.clockRate, 1, 1, 1); - l2.power = l2.power + l2array[i]->power*pppm_t; - power = power + l2array[i]->power*pppm_t;; - set_pppm(pppm_t,1/l2array[i]->cachep.executionTime, 1, 1, 1); - l2.rt_power = l2.rt_power + l2array[i]->rt_power*pppm_t; - rt_power = rt_power + l2array[i]->rt_power*pppm_t; - } - } + if (!XML->sys.Private_L2) { + if (numL2 > 0) + for (i = 0; i < numL2; i++) { + l2array.push_back(new SharedCache(XML, i, &interface_ip)); + + l2array[i]->computeEnergy(); + l2array[i]->computeEnergy(false); + if (procdynp.homoL2) { + l2.area.set_area(l2.area.get_area() + + l2array[i]->area.get_area() * procdynp.numL2); + set_pppm(pppm_t, l2array[i]->cachep.clockRate * procdynp.numL2, + procdynp.numL2, procdynp.numL2, procdynp.numL2); + l2.power = l2.power + l2array[i]->power * pppm_t; + set_pppm(pppm_t, 1 / l2array[i]->cachep.executionTime, procdynp.numL2, + procdynp.numL2, procdynp.numL2); + l2.rt_power = l2.rt_power + l2array[i]->rt_power * pppm_t; + area.set_area(area.get_area() + + l2.area.get_area()); // placement and routing overhead + // is 10%, l2 scales worse than + // cache 40% is accumulated from + // 90 to 22nm + power = power + l2.power; + rt_power = rt_power + l2.rt_power; + } else { + l2.area.set_area(l2.area.get_area() + l2array[i]->area.get_area()); + area.set_area(area.get_area() + + l2array[i]->area.get_area()); // placement and routing + // overhead is 10%, l2 + // scales worse than + // cache 40% is + // accumulated from 90 to + // 22nm + + set_pppm(pppm_t, l2array[i]->cachep.clockRate, 1, 1, 1); + l2.power = l2.power + l2array[i]->power * pppm_t; + power = power + l2array[i]->power * pppm_t; + ; + set_pppm(pppm_t, 1 / l2array[i]->cachep.executionTime, 1, 1, 1); + l2.rt_power = l2.rt_power + l2array[i]->rt_power * pppm_t; + rt_power = rt_power + l2array[i]->rt_power * pppm_t; + } + } } - if (numL3 >0) - for (i = 0;i < numL3; i++) - { - l3array.push_back(new SharedCache(XML,i, &interface_ip, L3)); - l3array[i]->computeEnergy(); - l3array[i]->computeEnergy(false); - if (procdynp.homoL3){ - l3.area.set_area(l3.area.get_area() + l3array[i]->area.get_area()*procdynp.numL3); - set_pppm(pppm_t,l3array[i]->cachep.clockRate*procdynp.numL3, procdynp.numL3,procdynp.numL3,procdynp.numL3); - l3.power = l3.power + l3array[i]->power*pppm_t; - set_pppm(pppm_t,1/l3array[i]->cachep.executionTime, procdynp.numL3,procdynp.numL3,procdynp.numL3); - l3.rt_power = l3.rt_power + l3array[i]->rt_power*pppm_t; - area.set_area(area.get_area() + l3.area.get_area());//placement and routing overhead is 10%, l3 scales worse than cache 40% is accumulated from 90 to 22nm - power = power + l3.power; - rt_power = rt_power + l3.rt_power; - - } - else{ - l3.area.set_area(l3.area.get_area() + l3array[i]->area.get_area()); - area.set_area(area.get_area() + l3array[i]->area.get_area());//placement and routing overhead is 10%, l3 scales worse than cache 40% is accumulated from 90 to 22nm - set_pppm(pppm_t,l3array[i]->cachep.clockRate, 1, 1, 1); - l3.power = l3.power + l3array[i]->power*pppm_t; - power = power + l3array[i]->power*pppm_t; - set_pppm(pppm_t,1/l3array[i]->cachep.executionTime, 1, 1, 1); - l3.rt_power = l3.rt_power + l3array[i]->rt_power*pppm_t; - rt_power = rt_power + l3array[i]->rt_power*pppm_t; - - } - } - if (numL1Dir >0) - for (i = 0;i < numL1Dir; i++) - { - l1dirarray.push_back(new SharedCache(XML,i, &interface_ip, L1Directory)); - l1dirarray[i]->computeEnergy(); - l1dirarray[i]->computeEnergy(false); - if (procdynp.homoL1Dir){ - l1dir.area.set_area(l1dir.area.get_area() + l1dirarray[i]->area.get_area()*procdynp.numL1Dir); - set_pppm(pppm_t,l1dirarray[i]->cachep.clockRate*procdynp.numL1Dir, procdynp.numL1Dir,procdynp.numL1Dir,procdynp.numL1Dir); - l1dir.power = l1dir.power + l1dirarray[i]->power*pppm_t; - set_pppm(pppm_t,1/l1dirarray[i]->cachep.executionTime, procdynp.numL1Dir,procdynp.numL1Dir,procdynp.numL1Dir); - l1dir.rt_power = l1dir.rt_power + l1dirarray[i]->rt_power*pppm_t; - area.set_area(area.get_area() + l1dir.area.get_area());//placement and routing overhead is 10%, l1dir scales worse than cache 40% is accumulated from 90 to 22nm - power = power + l1dir.power; - rt_power = rt_power + l1dir.rt_power; - - } - else{ - l1dir.area.set_area(l1dir.area.get_area() + l1dirarray[i]->area.get_area()); - area.set_area(area.get_area() + l1dirarray[i]->area.get_area()); - set_pppm(pppm_t,l1dirarray[i]->cachep.clockRate, 1, 1, 1); - l1dir.power = l1dir.power + l1dirarray[i]->power*pppm_t; - power = power + l1dirarray[i]->power; - set_pppm(pppm_t,1/l1dirarray[i]->cachep.executionTime, 1, 1, 1); - l1dir.rt_power = l1dir.rt_power + l1dirarray[i]->rt_power*pppm_t; - rt_power = rt_power + l1dirarray[i]->rt_power; - } - } - - if (numL2Dir >0) - for (i = 0;i < numL2Dir; i++) - { - l2dirarray.push_back(new SharedCache(XML,i, &interface_ip, L2Directory)); - l2dirarray[i]->computeEnergy(); - l2dirarray[i]->computeEnergy(false); - if (procdynp.homoL2Dir){ - l2dir.area.set_area(l2dir.area.get_area() + l2dirarray[i]->area.get_area()*procdynp.numL2Dir); - set_pppm(pppm_t,l2dirarray[i]->cachep.clockRate*procdynp.numL2Dir, procdynp.numL2Dir,procdynp.numL2Dir,procdynp.numL2Dir); - l2dir.power = l2dir.power + l2dirarray[i]->power*pppm_t; - set_pppm(pppm_t,1/l2dirarray[i]->cachep.executionTime, procdynp.numL2Dir,procdynp.numL2Dir,procdynp.numL2Dir); - l2dir.rt_power = l2dir.rt_power + l2dirarray[i]->rt_power*pppm_t; - area.set_area(area.get_area() + l2dir.area.get_area());//placement and routing overhead is 10%, l2dir scales worse than cache 40% is accumulated from 90 to 22nm - power = power + l2dir.power; - rt_power = rt_power + l2dir.rt_power; - - } - else{ - l2dir.area.set_area(l2dir.area.get_area() + l2dirarray[i]->area.get_area()); - area.set_area(area.get_area() + l2dirarray[i]->area.get_area()); - set_pppm(pppm_t,l2dirarray[i]->cachep.clockRate, 1, 1, 1); - l2dir.power = l2dir.power + l2dirarray[i]->power*pppm_t; - power = power + l2dirarray[i]->power*pppm_t; - set_pppm(pppm_t,1/l2dirarray[i]->cachep.executionTime, 1, 1, 1); - l2dir.rt_power = l2dir.rt_power + l2dirarray[i]->rt_power*pppm_t; - rt_power = rt_power + l2dirarray[i]->rt_power*pppm_t; - } - } - - if (XML->sys.mc.number_mcs >0 && XML->sys.mc.memory_channels_per_mc>0) - { - if(XML->sys.architecture==1) // 1 for fermi - mc = new MemoryController(XML, &interface_ip, MC,GDDR5); - else if (XML->sys.architecture==2) // 2 for quadro - mc = new MemoryController(XML, &interface_ip, MC,GDDR3); - else { - printf("Architecture %d not defined!\n", XML->sys.architecture); - printf("use 1 for fermi and 2 for quadro!\n"); - exit(1); - } - mc->computeEnergy(); - mc->computeEnergy(false); - mcs.area.set_area(mcs.area.get_area()+mc->area.get_area()*XML->sys.mc.number_mcs); - area.set_area(area.get_area()+mc->area.get_area()*XML->sys.mc.number_mcs); - set_pppm(pppm_t,XML->sys.mc.number_mcs*mc->mcp.clockRate, XML->sys.mc.number_mcs,XML->sys.mc.number_mcs,XML->sys.mc.number_mcs); - mcs.power = mc->power*pppm_t; - power = power + mcs.power; - set_pppm(pppm_t,1/mc->mcp.executionTime, XML->sys.mc.number_mcs,XML->sys.mc.number_mcs,XML->sys.mc.number_mcs); - mcs.rt_power = mc->rt_power*pppm_t; - rt_power = rt_power + mcs.rt_power; - + if (numL3 > 0) + for (i = 0; i < numL3; i++) { + l3array.push_back(new SharedCache(XML, i, &interface_ip, L3)); + l3array[i]->computeEnergy(); + l3array[i]->computeEnergy(false); + if (procdynp.homoL3) { + l3.area.set_area(l3.area.get_area() + + l3array[i]->area.get_area() * procdynp.numL3); + set_pppm(pppm_t, l3array[i]->cachep.clockRate * procdynp.numL3, + procdynp.numL3, procdynp.numL3, procdynp.numL3); + l3.power = l3.power + l3array[i]->power * pppm_t; + set_pppm(pppm_t, 1 / l3array[i]->cachep.executionTime, procdynp.numL3, + procdynp.numL3, procdynp.numL3); + l3.rt_power = l3.rt_power + l3array[i]->rt_power * pppm_t; + area.set_area(area.get_area() + + l3.area.get_area()); // placement and routing overhead is + // 10%, l3 scales worse than cache + // 40% is accumulated from 90 to + // 22nm + power = power + l3.power; + rt_power = rt_power + l3.rt_power; + + } else { + l3.area.set_area(l3.area.get_area() + l3array[i]->area.get_area()); + area.set_area(area.get_area() + + l3array[i]->area.get_area()); // placement and routing + // overhead is 10%, l3 + // scales worse than cache + // 40% is accumulated from + // 90 to 22nm + set_pppm(pppm_t, l3array[i]->cachep.clockRate, 1, 1, 1); + l3.power = l3.power + l3array[i]->power * pppm_t; + power = power + l3array[i]->power * pppm_t; + set_pppm(pppm_t, 1 / l3array[i]->cachep.executionTime, 1, 1, 1); + l3.rt_power = l3.rt_power + l3array[i]->rt_power * pppm_t; + rt_power = rt_power + l3array[i]->rt_power * pppm_t; + } + } + if (numL1Dir > 0) + for (i = 0; i < numL1Dir; i++) { + l1dirarray.push_back(new SharedCache(XML, i, &interface_ip, L1Directory)); + l1dirarray[i]->computeEnergy(); + l1dirarray[i]->computeEnergy(false); + if (procdynp.homoL1Dir) { + l1dir.area.set_area(l1dir.area.get_area() + + l1dirarray[i]->area.get_area() * procdynp.numL1Dir); + set_pppm(pppm_t, l1dirarray[i]->cachep.clockRate * procdynp.numL1Dir, + procdynp.numL1Dir, procdynp.numL1Dir, procdynp.numL1Dir); + l1dir.power = l1dir.power + l1dirarray[i]->power * pppm_t; + set_pppm(pppm_t, 1 / l1dirarray[i]->cachep.executionTime, + procdynp.numL1Dir, procdynp.numL1Dir, procdynp.numL1Dir); + l1dir.rt_power = l1dir.rt_power + l1dirarray[i]->rt_power * pppm_t; + area.set_area(area.get_area() + + l1dir.area.get_area()); // placement and routing overhead + // is 10%, l1dir scales worse + // than cache 40% is accumulated + // from 90 to 22nm + power = power + l1dir.power; + rt_power = rt_power + l1dir.rt_power; + + } else { + l1dir.area.set_area(l1dir.area.get_area() + + l1dirarray[i]->area.get_area()); + area.set_area(area.get_area() + l1dirarray[i]->area.get_area()); + set_pppm(pppm_t, l1dirarray[i]->cachep.clockRate, 1, 1, 1); + l1dir.power = l1dir.power + l1dirarray[i]->power * pppm_t; + power = power + l1dirarray[i]->power; + set_pppm(pppm_t, 1 / l1dirarray[i]->cachep.executionTime, 1, 1, 1); + l1dir.rt_power = l1dir.rt_power + l1dirarray[i]->rt_power * pppm_t; + rt_power = rt_power + l1dirarray[i]->rt_power; + } + } + + if (numL2Dir > 0) + for (i = 0; i < numL2Dir; i++) { + l2dirarray.push_back(new SharedCache(XML, i, &interface_ip, L2Directory)); + l2dirarray[i]->computeEnergy(); + l2dirarray[i]->computeEnergy(false); + if (procdynp.homoL2Dir) { + l2dir.area.set_area(l2dir.area.get_area() + + l2dirarray[i]->area.get_area() * procdynp.numL2Dir); + set_pppm(pppm_t, l2dirarray[i]->cachep.clockRate * procdynp.numL2Dir, + procdynp.numL2Dir, procdynp.numL2Dir, procdynp.numL2Dir); + l2dir.power = l2dir.power + l2dirarray[i]->power * pppm_t; + set_pppm(pppm_t, 1 / l2dirarray[i]->cachep.executionTime, + procdynp.numL2Dir, procdynp.numL2Dir, procdynp.numL2Dir); + l2dir.rt_power = l2dir.rt_power + l2dirarray[i]->rt_power * pppm_t; + area.set_area(area.get_area() + + l2dir.area.get_area()); // placement and routing overhead + // is 10%, l2dir scales worse + // than cache 40% is accumulated + // from 90 to 22nm + power = power + l2dir.power; + rt_power = rt_power + l2dir.rt_power; + + } else { + l2dir.area.set_area(l2dir.area.get_area() + + l2dirarray[i]->area.get_area()); + area.set_area(area.get_area() + l2dirarray[i]->area.get_area()); + set_pppm(pppm_t, l2dirarray[i]->cachep.clockRate, 1, 1, 1); + l2dir.power = l2dir.power + l2dirarray[i]->power * pppm_t; + power = power + l2dirarray[i]->power * pppm_t; + set_pppm(pppm_t, 1 / l2dirarray[i]->cachep.executionTime, 1, 1, 1); + l2dir.rt_power = l2dir.rt_power + l2dirarray[i]->rt_power * pppm_t; + rt_power = rt_power + l2dirarray[i]->rt_power * pppm_t; + } + } + + if (XML->sys.mc.number_mcs > 0 && XML->sys.mc.memory_channels_per_mc > 0) { + if (XML->sys.architecture == 1) // 1 for fermi + mc = new MemoryController(XML, &interface_ip, MC, GDDR5); + else if (XML->sys.architecture == 2) // 2 for quadro + mc = new MemoryController(XML, &interface_ip, MC, GDDR3); + else { + printf("Architecture %d not defined!\n", XML->sys.architecture); + printf("use 1 for fermi and 2 for quadro!\n"); + exit(1); + } + mc->computeEnergy(); + mc->computeEnergy(false); + mcs.area.set_area(mcs.area.get_area() + + mc->area.get_area() * XML->sys.mc.number_mcs); + area.set_area(area.get_area() + + mc->area.get_area() * XML->sys.mc.number_mcs); + set_pppm(pppm_t, XML->sys.mc.number_mcs * mc->mcp.clockRate, + XML->sys.mc.number_mcs, XML->sys.mc.number_mcs, + XML->sys.mc.number_mcs); + mcs.power = mc->power * pppm_t; + power = power + mcs.power; + set_pppm(pppm_t, 1 / mc->mcp.executionTime, XML->sys.mc.number_mcs, + XML->sys.mc.number_mcs, XML->sys.mc.number_mcs); + mcs.rt_power = mc->rt_power * pppm_t; + rt_power = rt_power + mcs.rt_power; } - if (XML->sys.flashc.number_mcs >0 )//flash controller + if (XML->sys.flashc.number_mcs > 0) // flash controller { - flashcontroller = new FlashController(XML, &interface_ip); - flashcontroller->computeEnergy(); - flashcontroller->computeEnergy(false); - double number_fcs = flashcontroller->fcp.num_mcs; - flashcontrollers.area.set_area(flashcontrollers.area.get_area()+flashcontroller->area.get_area()*number_fcs); - area.set_area(area.get_area()+flashcontrollers.area.get_area()); - set_pppm(pppm_t,number_fcs, number_fcs ,number_fcs, number_fcs ); - flashcontrollers.power = flashcontroller->power*pppm_t; - power = power + flashcontrollers.power; - set_pppm(pppm_t,number_fcs , number_fcs ,number_fcs ,number_fcs ); - flashcontrollers.rt_power = flashcontroller->rt_power*pppm_t; - rt_power = rt_power + flashcontrollers.rt_power; - + flashcontroller = new FlashController(XML, &interface_ip); + flashcontroller->computeEnergy(); + flashcontroller->computeEnergy(false); + double number_fcs = flashcontroller->fcp.num_mcs; + flashcontrollers.area.set_area(flashcontrollers.area.get_area() + + flashcontroller->area.get_area() * + number_fcs); + area.set_area(area.get_area() + flashcontrollers.area.get_area()); + set_pppm(pppm_t, number_fcs, number_fcs, number_fcs, number_fcs); + flashcontrollers.power = flashcontroller->power * pppm_t; + power = power + flashcontrollers.power; + set_pppm(pppm_t, number_fcs, number_fcs, number_fcs, number_fcs); + flashcontrollers.rt_power = flashcontroller->rt_power * pppm_t; + rt_power = rt_power + flashcontrollers.rt_power; } - if (XML->sys.niu.number_units >0) - { - niu = new NIUController(XML, &interface_ip); - niu->computeEnergy(); - niu->computeEnergy(false); - nius.area.set_area(nius.area.get_area()+niu->area.get_area()*XML->sys.niu.number_units); - area.set_area(area.get_area()+niu->area.get_area()*XML->sys.niu.number_units); - set_pppm(pppm_t,XML->sys.niu.number_units*niu->niup.clockRate, XML->sys.niu.number_units,XML->sys.niu.number_units,XML->sys.niu.number_units); - nius.power = niu->power*pppm_t; - power = power + nius.power; - set_pppm(pppm_t,XML->sys.niu.number_units*niu->niup.clockRate, XML->sys.niu.number_units,XML->sys.niu.number_units,XML->sys.niu.number_units); - nius.rt_power = niu->rt_power*pppm_t; - rt_power = rt_power + nius.rt_power; - + if (XML->sys.niu.number_units > 0) { + niu = new NIUController(XML, &interface_ip); + niu->computeEnergy(); + niu->computeEnergy(false); + nius.area.set_area(nius.area.get_area() + + niu->area.get_area() * XML->sys.niu.number_units); + area.set_area(area.get_area() + + niu->area.get_area() * XML->sys.niu.number_units); + set_pppm(pppm_t, XML->sys.niu.number_units * niu->niup.clockRate, + XML->sys.niu.number_units, XML->sys.niu.number_units, + XML->sys.niu.number_units); + nius.power = niu->power * pppm_t; + power = power + nius.power; + set_pppm(pppm_t, XML->sys.niu.number_units * niu->niup.clockRate, + XML->sys.niu.number_units, XML->sys.niu.number_units, + XML->sys.niu.number_units); + nius.rt_power = niu->rt_power * pppm_t; + rt_power = rt_power + nius.rt_power; } - if (XML->sys.pcie.number_units >0 && XML->sys.pcie.num_channels >0) - { - pcie = new PCIeController(XML, &interface_ip); - pcie->computeEnergy(); - pcie->computeEnergy(false); - pcies.area.set_area(pcies.area.get_area()+pcie->area.get_area()*XML->sys.pcie.number_units); - area.set_area(area.get_area()+pcie->area.get_area()*XML->sys.pcie.number_units); - set_pppm(pppm_t,XML->sys.pcie.number_units*pcie->pciep.clockRate, XML->sys.pcie.number_units,XML->sys.pcie.number_units,XML->sys.pcie.number_units); - pcies.power = pcie->power*pppm_t; - power = power + pcies.power; - set_pppm(pppm_t,XML->sys.pcie.number_units*pcie->pciep.clockRate, XML->sys.pcie.number_units,XML->sys.pcie.number_units,XML->sys.pcie.number_units); - pcies.rt_power = pcie->rt_power*pppm_t; - rt_power = rt_power + pcies.rt_power; - + if (XML->sys.pcie.number_units > 0 && XML->sys.pcie.num_channels > 0) { + pcie = new PCIeController(XML, &interface_ip); + pcie->computeEnergy(); + pcie->computeEnergy(false); + pcies.area.set_area(pcies.area.get_area() + + pcie->area.get_area() * XML->sys.pcie.number_units); + area.set_area(area.get_area() + + pcie->area.get_area() * XML->sys.pcie.number_units); + set_pppm(pppm_t, XML->sys.pcie.number_units * pcie->pciep.clockRate, + XML->sys.pcie.number_units, XML->sys.pcie.number_units, + XML->sys.pcie.number_units); + pcies.power = pcie->power * pppm_t; + power = power + pcies.power; + set_pppm(pppm_t, XML->sys.pcie.number_units * pcie->pciep.clockRate, + XML->sys.pcie.number_units, XML->sys.pcie.number_units, + XML->sys.pcie.number_units); + pcies.rt_power = pcie->rt_power * pppm_t; + rt_power = rt_power + pcies.rt_power; } - if (numNOC >0) - { - for (i = 0;i < numNOC; i++) - { - if (XML->sys.NoC[i].type) - {//First add up area of routers if NoC is used - nocs.push_back(new NoC(XML,i, &interface_ip, 1)); - - if (procdynp.homoNOC) - { - noc.area.set_area(noc.area.get_area() + nocs[i]->area.get_area()*procdynp.numNOC); - area.set_area(area.get_area() + noc.area.get_area()); - } - else - { - noc.area.set_area(noc.area.get_area() + nocs[i]->area.get_area()); - area.set_area(area.get_area() + nocs[i]->area.get_area()); - } - } - else - {//Bus based interconnect - nocs.push_back(new NoC(XML,i, &interface_ip, 1, sqrt(area.get_area()*XML->sys.NoC[i].chip_coverage))); - if (procdynp.homoNOC){ - noc.area.set_area(noc.area.get_area() + nocs[i]->area.get_area()*procdynp.numNOC); - area.set_area(area.get_area() + noc.area.get_area()); - } - else - { - noc.area.set_area(noc.area.get_area() + nocs[i]->area.get_area()); - area.set_area(area.get_area() + nocs[i]->area.get_area()); - } - } - } - - /* - * Compute global links associated with each NOC, if any. This must be done at the end (even after the NOC router part) since the total chip - * area must be obtain to decide the link routing - */ - for (i = 0;i < numNOC; i++) - { - if (nocs[i]->nocdynp.has_global_link && XML->sys.NoC[i].type) - { - nocs[i]->init_link_bus(sqrt(area.get_area()*XML->sys.NoC[i].chip_coverage));//compute global links - if (procdynp.homoNOC) - { - noc.area.set_area(noc.area.get_area() + nocs[i]->link_bus_tot_per_Router.area.get_area() - * nocs[i]->nocdynp.total_nodes - * procdynp.numNOC); - area.set_area(area.get_area() + nocs[i]->link_bus_tot_per_Router.area.get_area() - * nocs[i]->nocdynp.total_nodes - * procdynp.numNOC); - } - else - { - noc.area.set_area(noc.area.get_area() + nocs[i]->link_bus_tot_per_Router.area.get_area() - * nocs[i]->nocdynp.total_nodes); - area.set_area(area.get_area() + nocs[i]->link_bus_tot_per_Router.area.get_area() - * nocs[i]->nocdynp.total_nodes); - } - } - } - //Compute energy of NoC (w or w/o links) or buses - for (i = 0;i < numNOC; i++) - { - //cout<<"******************COMPUTE NOC ENERGY********************"<computeEnergy(); - nocs[i]->computeEnergy(false); - if (procdynp.homoNOC){ - - set_pppm(pppm_t,procdynp.numNOC*nocs[i]->nocdynp.clockRate, procdynp.numNOC,procdynp.numNOC,procdynp.numNOC); - noc.power = noc.power + nocs[i]->power*pppm_t; - set_pppm(pppm_t,1/nocs[i]->nocdynp.executionTime, procdynp.numNOC,procdynp.numNOC,procdynp.numNOC); - noc.rt_power = noc.rt_power + nocs[i]->rt_power*pppm_t; - power = power + noc.power; - rt_power = rt_power + noc.rt_power; - } - else - { - set_pppm(pppm_t,nocs[i]->nocdynp.clockRate, 1, 1, 1); - noc.power = noc.power + nocs[i]->power*pppm_t; - power = power + nocs[i]->power*pppm_t; - set_pppm(pppm_t,1/nocs[i]->nocdynp.executionTime, 1, 1, 1); - noc.rt_power = noc.rt_power + nocs[i]->rt_power*pppm_t; - rt_power = rt_power + nocs[i]->rt_power*pppm_t; - - - } - } + if (numNOC > 0) { + for (i = 0; i < numNOC; i++) { + if (XML->sys.NoC[i].type) { // First add up area of routers if NoC is + // used + nocs.push_back(new NoC(XML, i, &interface_ip, 1)); + + if (procdynp.homoNOC) { + noc.area.set_area(noc.area.get_area() + + nocs[i]->area.get_area() * procdynp.numNOC); + area.set_area(area.get_area() + noc.area.get_area()); + } else { + noc.area.set_area(noc.area.get_area() + nocs[i]->area.get_area()); + area.set_area(area.get_area() + nocs[i]->area.get_area()); + } + } else { // Bus based interconnect + nocs.push_back( + new NoC(XML, i, &interface_ip, 1, + sqrt(area.get_area() * XML->sys.NoC[i].chip_coverage))); + if (procdynp.homoNOC) { + noc.area.set_area(noc.area.get_area() + + nocs[i]->area.get_area() * procdynp.numNOC); + area.set_area(area.get_area() + noc.area.get_area()); + } else { + noc.area.set_area(noc.area.get_area() + nocs[i]->area.get_area()); + area.set_area(area.get_area() + nocs[i]->area.get_area()); + } + } + } + + /* + * Compute global links associated with each NOC, if any. This must be done + * at the end (even after the NOC router part) since the total chip + * area must be obtain to decide the link routing + */ + for (i = 0; i < numNOC; i++) { + if (nocs[i]->nocdynp.has_global_link && XML->sys.NoC[i].type) { + nocs[i]->init_link_bus( + sqrt(area.get_area() * + XML->sys.NoC[i].chip_coverage)); // compute global links + if (procdynp.homoNOC) { + noc.area.set_area(noc.area.get_area() + + nocs[i]->link_bus_tot_per_Router.area.get_area() * + nocs[i]->nocdynp.total_nodes * procdynp.numNOC); + area.set_area(area.get_area() + + nocs[i]->link_bus_tot_per_Router.area.get_area() * + nocs[i]->nocdynp.total_nodes * procdynp.numNOC); + } else { + noc.area.set_area(noc.area.get_area() + + nocs[i]->link_bus_tot_per_Router.area.get_area() * + nocs[i]->nocdynp.total_nodes); + area.set_area(area.get_area() + + nocs[i]->link_bus_tot_per_Router.area.get_area() * + nocs[i]->nocdynp.total_nodes); + } + } + } + // Compute energy of NoC (w or w/o links) or buses + for (i = 0; i < numNOC; i++) { + // cout<<"******************COMPUTE NOC ENERGY********************"<computeEnergy(); + nocs[i]->computeEnergy(false); + if (procdynp.homoNOC) { + set_pppm(pppm_t, procdynp.numNOC * nocs[i]->nocdynp.clockRate, + procdynp.numNOC, procdynp.numNOC, procdynp.numNOC); + noc.power = noc.power + nocs[i]->power * pppm_t; + set_pppm(pppm_t, 1 / nocs[i]->nocdynp.executionTime, procdynp.numNOC, + procdynp.numNOC, procdynp.numNOC); + noc.rt_power = noc.rt_power + nocs[i]->rt_power * pppm_t; + power = power + noc.power; + rt_power = rt_power + noc.rt_power; + } else { + set_pppm(pppm_t, nocs[i]->nocdynp.clockRate, 1, 1, 1); + noc.power = noc.power + nocs[i]->power * pppm_t; + power = power + nocs[i]->power * pppm_t; + set_pppm(pppm_t, 1 / nocs[i]->nocdynp.executionTime, 1, 1, 1); + noc.rt_power = noc.rt_power + nocs[i]->rt_power * pppm_t; + rt_power = rt_power + nocs[i]->rt_power * pppm_t; + } + } } -// //clock power -// globalClock.init_wire_external(is_default, &interface_ip); -// globalClock.clk_area =area*1e6; //change it from mm^2 to um^2 -// globalClock.end_wiring_level =5;//toplevel metal -// globalClock.start_wiring_level =5;//toplevel metal -// globalClock.l_ip.with_clock_grid=false;//global clock does not drive local final nodes -// globalClock.optimize_wire(); + // //clock power + // globalClock.init_wire_external(is_default, &interface_ip); + // globalClock.clk_area =area*1e6; //change it from mm^2 to um^2 + // globalClock.end_wiring_level =5;//toplevel metal + // globalClock.start_wiring_level =5;//toplevel metal + // globalClock.l_ip.with_clock_grid=false;//global clock does not drive local + // final nodes + // globalClock.optimize_wire(); } -void Processor::compute () -{ +void Processor::compute() { int i; - double pppm_t[4] = {1,1,1,1}; + double pppm_t[4] = {1, 1, 1, 1}; rt_power.reset(); - //power.reset(); - //core.power.reset(); + // power.reset(); + // core.power.reset(); core.rt_power.reset(); - for (i = 0;i < numCore; i++) - { - cores[i]->executionTime = XML->sys.total_cycles /(XML->sys.core[i].clock_rate*1e6); - cores[i]->rt_power.reset(); - cores[i]->compute(); - //cores[i]->computeEnergy(false); - if (procdynp.homoCore){ - set_pppm(pppm_t,1/cores[i]->executionTime, procdynp.numCore,procdynp.numCore,procdynp.numCore); - core.rt_power = core.rt_power + cores[i]->rt_power*pppm_t; - rt_power = rt_power + core.rt_power; - } - else{ - set_pppm(pppm_t,1/cores[i]->executionTime, 1, 1, 1); - core.rt_power = core.rt_power + cores[i]->rt_power*pppm_t; - rt_power = rt_power + cores[i]->rt_power*pppm_t; - } + for (i = 0; i < numCore; i++) { + cores[i]->executionTime = + XML->sys.total_cycles / (XML->sys.core[i].clock_rate * 1e6); + cores[i]->rt_power.reset(); + cores[i]->compute(); + // cores[i]->computeEnergy(false); + if (procdynp.homoCore) { + set_pppm(pppm_t, 1 / cores[i]->executionTime, procdynp.numCore, + procdynp.numCore, procdynp.numCore); + core.rt_power = core.rt_power + cores[i]->rt_power * pppm_t; + rt_power = rt_power + core.rt_power; + } else { + set_pppm(pppm_t, 1 / cores[i]->executionTime, 1, 1, 1); + core.rt_power = core.rt_power + cores[i]->rt_power * pppm_t; + rt_power = rt_power + cores[i]->rt_power * pppm_t; + } } - if (!XML->sys.Private_L2) - { - if (numL2 >0) - l2.rt_power.reset(); - for (i = 0;i < numL2; i++) - { + if (!XML->sys.Private_L2) { + if (numL2 > 0) l2.rt_power.reset(); + for (i = 0; i < numL2; i++) { l2array[i]->rt_power.reset(); - l2array[i]->cachep.executionTime=XML->sys.total_cycles /(XML->sys.core[0].clock_rate*1e6); - l2array[i]->computeEnergy(false); - if (procdynp.homoL2){ - set_pppm(pppm_t,1/l2array[i]->cachep.executionTime, procdynp.numL2,procdynp.numL2,procdynp.numL2); - l2.rt_power = l2.rt_power + l2array[i]->rt_power*pppm_t; - rt_power = rt_power + l2.rt_power; - } - else{ - set_pppm(pppm_t,1/l2array[i]->cachep.executionTime, 1, 1, 1); - l2.rt_power = l2.rt_power + l2array[i]->rt_power*pppm_t; - rt_power = rt_power + l2array[i]->rt_power*pppm_t; - } - } + l2array[i]->cachep.executionTime = + XML->sys.total_cycles / (XML->sys.core[0].clock_rate * 1e6); + l2array[i]->computeEnergy(false); + if (procdynp.homoL2) { + set_pppm(pppm_t, 1 / l2array[i]->cachep.executionTime, procdynp.numL2, + procdynp.numL2, procdynp.numL2); + l2.rt_power = l2.rt_power + l2array[i]->rt_power * pppm_t; + rt_power = rt_power + l2.rt_power; + } else { + set_pppm(pppm_t, 1 / l2array[i]->cachep.executionTime, 1, 1, 1); + l2.rt_power = l2.rt_power + l2array[i]->rt_power * pppm_t; + rt_power = rt_power + l2array[i]->rt_power * pppm_t; + } + } } l3.rt_power.reset(); - if (numL3 >0) - for (i = 0;i < numL3; i++) - { - l3array[i]->rt_power.reset(); - l3array[i]->computeEnergy(false); - if (procdynp.homoL3){ - set_pppm(pppm_t,1/l3array[i]->cachep.executionTime, procdynp.numL3,procdynp.numL3,procdynp.numL3); - l3.rt_power = l3.rt_power + l3array[i]->rt_power*pppm_t; - rt_power = rt_power + l3.rt_power; - - } - else{ - set_pppm(pppm_t,1/l3array[i]->cachep.executionTime, 1, 1, 1); - l3.rt_power = l3.rt_power + l3array[i]->rt_power*pppm_t; - rt_power = rt_power + l3array[i]->rt_power*pppm_t; - - } - } + if (numL3 > 0) + for (i = 0; i < numL3; i++) { + l3array[i]->rt_power.reset(); + l3array[i]->computeEnergy(false); + if (procdynp.homoL3) { + set_pppm(pppm_t, 1 / l3array[i]->cachep.executionTime, procdynp.numL3, + procdynp.numL3, procdynp.numL3); + l3.rt_power = l3.rt_power + l3array[i]->rt_power * pppm_t; + rt_power = rt_power + l3.rt_power; + + } else { + set_pppm(pppm_t, 1 / l3array[i]->cachep.executionTime, 1, 1, 1); + l3.rt_power = l3.rt_power + l3array[i]->rt_power * pppm_t; + rt_power = rt_power + l3array[i]->rt_power * pppm_t; + } + } l1dir.rt_power.reset(); - if (numL1Dir >0) - for (i = 0;i < numL1Dir; i++) - { - l1dirarray[i]->rt_power.reset(); - l1dirarray[i]->computeEnergy(false); - if (procdynp.homoL1Dir){ - set_pppm(pppm_t,1/l1dirarray[i]->cachep.executionTime, procdynp.numL1Dir,procdynp.numL1Dir,procdynp.numL1Dir); - l1dir.rt_power = l1dir.rt_power + l1dirarray[i]->rt_power*pppm_t; - rt_power = rt_power + l1dir.rt_power; - - } - else{ - set_pppm(pppm_t,1/l1dirarray[i]->cachep.executionTime, 1, 1, 1); - l1dir.rt_power = l1dir.rt_power + l1dirarray[i]->rt_power*pppm_t; - rt_power = rt_power + l1dirarray[i]->rt_power; - } - } - + if (numL1Dir > 0) + for (i = 0; i < numL1Dir; i++) { + l1dirarray[i]->rt_power.reset(); + l1dirarray[i]->computeEnergy(false); + if (procdynp.homoL1Dir) { + set_pppm(pppm_t, 1 / l1dirarray[i]->cachep.executionTime, + procdynp.numL1Dir, procdynp.numL1Dir, procdynp.numL1Dir); + l1dir.rt_power = l1dir.rt_power + l1dirarray[i]->rt_power * pppm_t; + rt_power = rt_power + l1dir.rt_power; + + } else { + set_pppm(pppm_t, 1 / l1dirarray[i]->cachep.executionTime, 1, 1, 1); + l1dir.rt_power = l1dir.rt_power + l1dirarray[i]->rt_power * pppm_t; + rt_power = rt_power + l1dirarray[i]->rt_power; + } + } l2dir.rt_power.reset(); - if (numL2Dir >0) - for (i = 0;i < numL2Dir; i++) - { - l2dirarray[i]->rt_power.reset(); - l2dirarray[i]->computeEnergy(false); - if (procdynp.homoL2Dir){ - set_pppm(pppm_t,1/l2dirarray[i]->cachep.executionTime, procdynp.numL2Dir,procdynp.numL2Dir,procdynp.numL2Dir); - l2dir.rt_power = l2dir.rt_power + l2dirarray[i]->rt_power*pppm_t; - rt_power = rt_power + l2dir.rt_power; - - } - else{ - set_pppm(pppm_t,1/l2dirarray[i]->cachep.executionTime, 1, 1, 1); - l2dir.rt_power = l2dir.rt_power + l2dirarray[i]->rt_power*pppm_t; - rt_power = rt_power + l2dirarray[i]->rt_power*pppm_t; - } - } - + if (numL2Dir > 0) + for (i = 0; i < numL2Dir; i++) { + l2dirarray[i]->rt_power.reset(); + l2dirarray[i]->computeEnergy(false); + if (procdynp.homoL2Dir) { + set_pppm(pppm_t, 1 / l2dirarray[i]->cachep.executionTime, + procdynp.numL2Dir, procdynp.numL2Dir, procdynp.numL2Dir); + l2dir.rt_power = l2dir.rt_power + l2dirarray[i]->rt_power * pppm_t; + rt_power = rt_power + l2dir.rt_power; + + } else { + set_pppm(pppm_t, 1 / l2dirarray[i]->cachep.executionTime, 1, 1, 1); + l2dir.rt_power = l2dir.rt_power + l2dirarray[i]->rt_power * pppm_t; + rt_power = rt_power + l2dirarray[i]->rt_power * pppm_t; + } + } mcs.rt_power.reset(); - if (XML->sys.mc.number_mcs >0 && XML->sys.mc.memory_channels_per_mc>0) - { - mc->rt_power.reset(); - mc->mcp.executionTime = XML->sys.total_cycles /(XML->sys.core[0].clock_rate*1e6); //Jingwen - mc->computeEnergy(false); - set_pppm(pppm_t,1/mc->mcp.executionTime, XML->sys.mc.number_mcs,XML->sys.mc.number_mcs,XML->sys.mc.number_mcs); - mcs.rt_power = mc->rt_power*pppm_t; - rt_power = rt_power + mcs.rt_power; - + if (XML->sys.mc.number_mcs > 0 && XML->sys.mc.memory_channels_per_mc > 0) { + mc->rt_power.reset(); + mc->mcp.executionTime = + XML->sys.total_cycles / (XML->sys.core[0].clock_rate * 1e6); // Jingwen + mc->computeEnergy(false); + set_pppm(pppm_t, 1 / mc->mcp.executionTime, XML->sys.mc.number_mcs, + XML->sys.mc.number_mcs, XML->sys.mc.number_mcs); + mcs.rt_power = mc->rt_power * pppm_t; + rt_power = rt_power + mcs.rt_power; } - - -/* - if (XML->sys.flashc.number_mcs >0 )//flash controller - { - flashcontrollers.rt_power.reset(); - flashcontroller->computeEnergy(false); - double number_fcs = flashcontroller->fcp.num_mcs; - set_pppm(pppm_t,number_fcs , number_fcs ,number_fcs ,number_fcs ); - flashcontrollers.rt_power = flashcontroller->rt_power*pppm_t; - rt_power = rt_power + flashcontrollers.rt_power; - - } - - if (XML->sys.niu.number_units >0) - { - niu->computeEnergy(false); - nius.rt_power.reset(); - set_pppm(pppm_t,XML->sys.niu.number_units*niu->niup.clockRate, XML->sys.niu.number_units,XML->sys.niu.number_units,XML->sys.niu.number_units); - nius.rt_power = niu->rt_power*pppm_t; - rt_power = rt_power + nius.rt_power; - - } - - if (XML->sys.pcie.number_units >0 && XML->sys.pcie.num_channels >0) - { - pcie->computeEnergy(false); - pcies.rt_power.reset(); - set_pppm(pppm_t,XML->sys.pcie.number_units*pcie->pciep.clockRate, XML->sys.pcie.number_units,XML->sys.pcie.number_units,XML->sys.pcie.number_units); - pcies.rt_power = pcie->rt_power*pppm_t; - rt_power = rt_power + pcies.rt_power; + /* + if (XML->sys.flashc.number_mcs >0 )//flash controller + { + flashcontrollers.rt_power.reset(); + flashcontroller->computeEnergy(false); + double number_fcs = flashcontroller->fcp.num_mcs; + set_pppm(pppm_t,number_fcs , number_fcs ,number_fcs ,number_fcs ); + flashcontrollers.rt_power = flashcontroller->rt_power*pppm_t; + rt_power = rt_power + flashcontrollers.rt_power; + + } + + if (XML->sys.niu.number_units >0) + { + niu->computeEnergy(false); + nius.rt_power.reset(); + set_pppm(pppm_t,XML->sys.niu.number_units*niu->niup.clockRate, + XML->sys.niu.number_units,XML->sys.niu.number_units,XML->sys.niu.number_units); + nius.rt_power = niu->rt_power*pppm_t; + rt_power = rt_power + nius.rt_power; + + } + + if (XML->sys.pcie.number_units >0 && XML->sys.pcie.num_channels >0) + { + pcie->computeEnergy(false); + pcies.rt_power.reset(); + set_pppm(pppm_t,XML->sys.pcie.number_units*pcie->pciep.clockRate, + XML->sys.pcie.number_units,XML->sys.pcie.number_units,XML->sys.pcie.number_units); + pcies.rt_power = pcie->rt_power*pppm_t; + rt_power = rt_power + pcies.rt_power; + + } + + + // * Compute global links associated with each NOC, if any. This + must be done at the end (even after the NOC router part) since the total + chip + // * area must be obtain to decide the link routing + */ + // Compute energy of NoC (w or w/o links) or buses + noc.rt_power.reset(); + for (i = 0; i < numNOC; i++) { + nocs[i]->nocdynp.executionTime = + XML->sys.total_cycles / (XML->sys.core[0].clock_rate * 1e6); + nocs[i]->computeEnergy(false); + if (procdynp.homoNOC) { + set_pppm(pppm_t, 1 / nocs[i]->nocdynp.executionTime, procdynp.numNOC, + procdynp.numNOC, procdynp.numNOC); + noc.rt_power = noc.rt_power + nocs[i]->rt_power * pppm_t; + rt_power = rt_power + noc.rt_power; + } else { + set_pppm(pppm_t, 1 / nocs[i]->nocdynp.executionTime, 1, 1, 1); + noc.rt_power = noc.rt_power + nocs[i]->rt_power * pppm_t; + rt_power = rt_power + nocs[i]->rt_power * pppm_t; + } } - - // * Compute global links associated with each NOC, if any. This must be done at the end (even after the NOC router part) since the total chip - // * area must be obtain to decide the link routing - */ - //Compute energy of NoC (w or w/o links) or buses - noc.rt_power.reset(); - for (i = 0;i < numNOC; i++) - { - nocs[i]->nocdynp.executionTime=XML->sys.total_cycles /(XML->sys.core[0].clock_rate*1e6); - nocs[i]->computeEnergy(false); - if (procdynp.homoNOC){ - set_pppm(pppm_t,1/nocs[i]->nocdynp.executionTime, procdynp.numNOC,procdynp.numNOC,procdynp.numNOC); - noc.rt_power = noc.rt_power + nocs[i]->rt_power*pppm_t; - rt_power = rt_power + noc.rt_power; - } - else - { - set_pppm(pppm_t,1/nocs[i]->nocdynp.executionTime, 1, 1, 1); - noc.rt_power = noc.rt_power + nocs[i]->rt_power*pppm_t; - rt_power = rt_power + nocs[i]->rt_power*pppm_t; - } - } - - -// //clock power -// globalClock.init_wire_external(is_default, &interface_ip); -// globalClock.clk_area =area*1e6; //change it from mm^2 to um^2 -// globalClock.end_wiring_level =5;//toplevel metal -// globalClock.start_wiring_level =5;//toplevel metal -// globalClock.l_ip.with_clock_grid=false;//global clock does not drive local final nodes -// globalClock.optimize_wire(); - + // //clock power + // globalClock.init_wire_external(is_default, &interface_ip); + // globalClock.clk_area =area*1e6; //change it from mm^2 to um^2 + // globalClock.end_wiring_level =5;//toplevel metal + // globalClock.start_wiring_level =5;//toplevel metal + // globalClock.l_ip.with_clock_grid=false;//global clock does not drive local + // final nodes + // globalClock.optimize_wire(); } -void Processor::displayDeviceType(int device_type_, uint32_t indent) -{ - string indent_str(indent, ' '); - - switch ( device_type_ ) { - - case 0 : - cout <sys.longer_channel_device; - string indent_str(indent, ' '); - string indent_str_next(indent+2, ' '); - bool is_tdp=is_tdp_parm; - if (is_tdp_parm) - { - - - if (plevel<5) - { - cout<<"\nMcPAT (version "<< VER_MAJOR <<"."<< VER_MINOR - << " of " << VER_UPDATE << ") results (current print level is "<< plevel - <<", please increase print level to see the details in components): "<sys.core_tech_node<<" nm"<sys.core[0].clock_rate<0){ - cout <sys.number_of_cores << " cores "<sys.device_type,indent); - cout << indent_str_next << "Area = " << core.area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << core.power.readOp.dynamic << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? core.power.readOp.longer_channel_leakage:core.power.readOp.leakage) <<" W" << endl; - //cout << indent_str_next << "Subthreshold Leakage = " << core.power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << core.power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << core.rt_power.readOp.dynamic << " W" << endl; - cout <sys.Private_L2) - { - if (numL2 >0){ - cout <sys.L2[0].device_type,indent); - cout << indent_str_next << "Area = " << l2.area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << l2.power.readOp.dynamic << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? l2.power.readOp.longer_channel_leakage:l2.power.readOp.leakage) <<" W" << endl; - //cout << indent_str_next << "Subthreshold Leakage = " << l2.power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << l2.power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << l2.rt_power.readOp.dynamic << " W" << endl; - cout <0){ - cout <sys.L3[0].device_type, indent); - cout << indent_str_next << "Area = " << l3.area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << l3.power.readOp.dynamic << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? l3.power.readOp.longer_channel_leakage:l3.power.readOp.leakage) <<" W" << endl; - //cout << indent_str_next << "Subthreshold Leakage = " << l3.power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << l3.power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << l3.rt_power.readOp.dynamic << " W" << endl; - cout <0){ - cout <sys.L1Directory[0].device_type, indent); - cout << indent_str_next << "Area = " << l1dir.area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << l1dir.power.readOp.dynamic << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? l1dir.power.readOp.longer_channel_leakage:l1dir.power.readOp.leakage) <<" W" << endl; - //cout << indent_str_next << "Subthreshold Leakage = " << l1dir.power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << l1dir.power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << l1dir.rt_power.readOp.dynamic << " W" << endl; - cout <0){ - cout <sys.L1Directory[0].device_type, indent); - cout << indent_str_next << "Area = " << l2dir.area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << l2dir.power.readOp.dynamic << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? l2dir.power.readOp.longer_channel_leakage:l2dir.power.readOp.leakage) <<" W" << endl; - //cout << indent_str_next << "Subthreshold Leakage = " << l2dir.power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << l2dir.power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << l2dir.rt_power.readOp.dynamic << " W" << endl; - cout <0){ - cout <sys.device_type, indent); - cout << indent_str_next << "Area = " << noc.area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << noc.power.readOp.dynamic << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? noc.power.readOp.longer_channel_leakage:noc.power.readOp.leakage) <<" W" << endl; - //cout << indent_str_next << "Subthreshold Leakage = " << noc.power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << noc.power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << noc.rt_power.readOp.dynamic << " W" << endl; - cout <sys.mc.number_mcs >0 && XML->sys.mc.memory_channels_per_mc>0) - { - cout <sys.mc.number_mcs << " Memory Controllers "<sys.device_type, indent); - cout << indent_str_next << "Area = " << mcs.area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << mcs.power.readOp.dynamic << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? mcs.power.readOp.longer_channel_leakage:mcs.power.readOp.leakage) <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << mcs.power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << mcs.rt_power.readOp.dynamic << " W" << endl; - cout <sys.flashc.number_mcs >0) - { - cout <fcp.num_mcs << " Flash/SSD Controllers "<sys.device_type, indent); - cout << indent_str_next << "Area = " << flashcontrollers.area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << flashcontrollers.power.readOp.dynamic << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? flashcontrollers.power.readOp.longer_channel_leakage:flashcontrollers.power.readOp.leakage) <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << flashcontrollers.power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << flashcontrollers.rt_power.readOp.dynamic << " W" << endl; - cout <sys.niu.number_units >0 ) - { - cout <niup.num_units << " Network Interface Units "<sys.device_type, indent); - cout << indent_str_next << "Area = " << nius.area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << nius.power.readOp.dynamic << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? nius.power.readOp.longer_channel_leakage:nius.power.readOp.leakage) <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << nius.power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << nius.rt_power.readOp.dynamic << " W" << endl; - cout <sys.pcie.number_units >0 && XML->sys.pcie.num_channels>0) - { - cout <pciep.num_units << " PCIe Controllers "<sys.device_type, indent); - cout << indent_str_next << "Area = " << pcies.area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << pcies.power.readOp.dynamic << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? pcies.power.readOp.longer_channel_leakage:pcies.power.readOp.leakage) <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << pcies.power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << pcies.rt_power.readOp.dynamic << " W" << endl; - cout <1) - { - for (i = 0;i < numCore; i++) - { - cores[i]->displayEnergy(indent+4,plevel,is_tdp); - cout <<"*****************************************************************************************"<sys.Private_L2) - { - for (i = 0;i < numL2; i++) - { - l2array[i]->displayEnergy(indent+4,is_tdp); - cout <<"*****************************************************************************************"<displayEnergy(indent+4,is_tdp); - cout <<"*****************************************************************************************"<displayEnergy(indent+4,is_tdp); - cout <<"*****************************************************************************************"<displayEnergy(indent+4,is_tdp); - cout <<"*****************************************************************************************"<sys.mc.number_mcs >0 && XML->sys.mc.memory_channels_per_mc>0) - { - mc->displayEnergy(indent+4,is_tdp); - cout <<"*****************************************************************************************"<sys.flashc.number_mcs >0 && XML->sys.flashc.memory_channels_per_mc>0) - { - flashcontroller->displayEnergy(indent+4,is_tdp); - cout <<"*****************************************************************************************"<sys.niu.number_units >0 ) - { - niu->displayEnergy(indent+4,is_tdp); - cout <<"*****************************************************************************************"<sys.pcie.number_units >0 && XML->sys.pcie.num_channels>0) - { - pcie->displayEnergy(indent+4,is_tdp); - cout <<"*****************************************************************************************"<displayEnergy(indent+4,plevel,is_tdp); - cout <<"*****************************************************************************************"<sys.longer_channel_device; + string indent_str(indent, ' '); + string indent_str_next(indent + 2, ' '); + bool is_tdp = is_tdp_parm; + if (is_tdp_parm) { + if (plevel < 5) { + cout + << "\nMcPAT (version " << VER_MAJOR << "." << VER_MINOR << " of " + << VER_UPDATE << ") results (current print level is " << plevel + << ", please increase print level to see the details in components): " + << endl; + } else { + cout << "\nMcPAT (version " << VER_MAJOR << "." << VER_MINOR << " of " + << VER_UPDATE << ") results (current print level is 5)" << endl; + } + cout << "******************************************************************" + "***********************" + << endl; + cout << indent_str << "Technology " << XML->sys.core_tech_node << " nm" + << endl; + // cout <sys.interconnect_projection_type<sys.interconnect_projection_type, indent); + cout << indent_str << "Core clock Rate(MHz) " << XML->sys.core[0].clock_rate + << endl; + cout << endl; + cout << "******************************************************************" + "***********************" + << endl; + cout << "Processor: " << endl; + cout << indent_str << "Area = " << area.get_area() * 1e-6 << " mm^2" + << endl; + cout << indent_str << "Peak Power = " + << power.readOp.dynamic + + (long_channel ? power.readOp.longer_channel_leakage + : power.readOp.leakage) + + power.readOp.gate_leakage + << " W" << endl; + cout << indent_str << "Total Leakage = " + << (long_channel ? power.readOp.longer_channel_leakage + : power.readOp.leakage) + + power.readOp.gate_leakage + << " W" << endl; + cout << indent_str << "Peak Dynamic = " << power.readOp.dynamic << " W" + << endl; + cout << indent_str << "Subthreshold Leakage = " + << (long_channel ? power.readOp.longer_channel_leakage + : power.readOp.leakage) + << " W" << endl; + // cout << indent_str << "Subthreshold Leakage = " << + // power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str << "Gate Leakage = " << power.readOp.gate_leakage << " W" + << endl; + cout << indent_str << "Runtime Dynamic = " << rt_power.readOp.dynamic + << " W" << endl; + cout << endl; + if (numCore > 0) { + cout << indent_str << "Total Cores: " << XML->sys.number_of_cores + << " cores " << endl; + displayDeviceType(XML->sys.device_type, indent); + cout << indent_str_next << "Area = " << core.area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << core.power.readOp.dynamic + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? core.power.readOp.longer_channel_leakage + : core.power.readOp.leakage) + << " W" << endl; + // cout << indent_str_next << "Subthreshold Leakage = " << + // core.power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str_next + << "Gate Leakage = " << core.power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next + << "Runtime Dynamic = " << core.rt_power.readOp.dynamic << " W" + << endl; + cout << endl; + } + if (!XML->sys.Private_L2) { + if (numL2 > 0) { + cout << indent_str << "Total L2s: " << endl; + displayDeviceType(XML->sys.L2[0].device_type, indent); + cout << indent_str_next << "Area = " << l2.area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << l2.power.readOp.dynamic + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? l2.power.readOp.longer_channel_leakage + : l2.power.readOp.leakage) + << " W" << endl; + // cout << indent_str_next << "Subthreshold Leakage = " << + // l2.power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str_next + << "Gate Leakage = " << l2.power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next + << "Runtime Dynamic = " << l2.rt_power.readOp.dynamic << " W" + << endl; + cout << endl; + } + } + if (numL3 > 0) { + cout << indent_str << "Total L3s: " << endl; + displayDeviceType(XML->sys.L3[0].device_type, indent); + cout << indent_str_next << "Area = " << l3.area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << l3.power.readOp.dynamic + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? l3.power.readOp.longer_channel_leakage + : l3.power.readOp.leakage) + << " W" << endl; + // cout << indent_str_next << "Subthreshold Leakage = " << + // l3.power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str_next + << "Gate Leakage = " << l3.power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next + << "Runtime Dynamic = " << l3.rt_power.readOp.dynamic << " W" + << endl; + cout << endl; + } + if (numL1Dir > 0) { + cout << indent_str << "Total First Level Directory: " << endl; + displayDeviceType(XML->sys.L1Directory[0].device_type, indent); + cout << indent_str_next << "Area = " << l1dir.area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << l1dir.power.readOp.dynamic + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? l1dir.power.readOp.longer_channel_leakage + : l1dir.power.readOp.leakage) + << " W" << endl; + // cout << indent_str_next << "Subthreshold Leakage = " << + // l1dir.power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str_next + << "Gate Leakage = " << l1dir.power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next + << "Runtime Dynamic = " << l1dir.rt_power.readOp.dynamic << " W" + << endl; + cout << endl; + } + if (numL2Dir > 0) { + cout << indent_str << "Total First Level Directory: " << endl; + displayDeviceType(XML->sys.L1Directory[0].device_type, indent); + cout << indent_str_next << "Area = " << l2dir.area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << l2dir.power.readOp.dynamic + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? l2dir.power.readOp.longer_channel_leakage + : l2dir.power.readOp.leakage) + << " W" << endl; + // cout << indent_str_next << "Subthreshold Leakage = " << + // l2dir.power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str_next + << "Gate Leakage = " << l2dir.power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next + << "Runtime Dynamic = " << l2dir.rt_power.readOp.dynamic << " W" + << endl; + cout << endl; + } + if (numNOC > 0) { + cout << indent_str << "Total NoCs (Network/Bus): " << endl; + displayDeviceType(XML->sys.device_type, indent); + cout << indent_str_next << "Area = " << noc.area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << noc.power.readOp.dynamic + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? noc.power.readOp.longer_channel_leakage + : noc.power.readOp.leakage) + << " W" << endl; + // cout << indent_str_next << "Subthreshold Leakage = " << + // noc.power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str_next + << "Gate Leakage = " << noc.power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next + << "Runtime Dynamic = " << noc.rt_power.readOp.dynamic << " W" + << endl; + cout << endl; + } + if (XML->sys.mc.number_mcs > 0 && XML->sys.mc.memory_channels_per_mc > 0) { + cout << indent_str << "Total MCs: " << XML->sys.mc.number_mcs + << " Memory Controllers " << endl; + displayDeviceType(XML->sys.device_type, indent); + cout << indent_str_next << "Area = " << mcs.area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << mcs.power.readOp.dynamic + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? mcs.power.readOp.longer_channel_leakage + : mcs.power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << mcs.power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next + << "Runtime Dynamic = " << mcs.rt_power.readOp.dynamic << " W" + << endl; + cout << endl; + } + if (XML->sys.flashc.number_mcs > 0) { + cout << indent_str + << "Total Flash/SSD Controllers: " << flashcontroller->fcp.num_mcs + << " Flash/SSD Controllers " << endl; + displayDeviceType(XML->sys.device_type, indent); + cout << indent_str_next + << "Area = " << flashcontrollers.area.get_area() * 1e-6 << " mm^2" + << endl; + cout << indent_str_next + << "Peak Dynamic = " << flashcontrollers.power.readOp.dynamic << " W" + << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel + ? flashcontrollers.power.readOp.longer_channel_leakage + : flashcontrollers.power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << flashcontrollers.power.readOp.gate_leakage + << " W" << endl; + cout << indent_str_next + << "Runtime Dynamic = " << flashcontrollers.rt_power.readOp.dynamic + << " W" << endl; + cout << endl; + } + if (XML->sys.niu.number_units > 0) { + cout << indent_str << "Total NIUs: " << niu->niup.num_units + << " Network Interface Units " << endl; + displayDeviceType(XML->sys.device_type, indent); + cout << indent_str_next << "Area = " << nius.area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << nius.power.readOp.dynamic + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? nius.power.readOp.longer_channel_leakage + : nius.power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << nius.power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next + << "Runtime Dynamic = " << nius.rt_power.readOp.dynamic << " W" + << endl; + cout << endl; + } + if (XML->sys.pcie.number_units > 0 && XML->sys.pcie.num_channels > 0) { + cout << indent_str << "Total PCIes: " << pcie->pciep.num_units + << " PCIe Controllers " << endl; + displayDeviceType(XML->sys.device_type, indent); + cout << indent_str_next << "Area = " << pcies.area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << pcies.power.readOp.dynamic + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? pcies.power.readOp.longer_channel_leakage + : pcies.power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << pcies.power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next + << "Runtime Dynamic = " << pcies.rt_power.readOp.dynamic << " W" + << endl; + cout << endl; + } + cout << "******************************************************************" + "***********************" + << endl; + if (plevel > 1) { + for (i = 0; i < numCore; i++) { + cores[i]->displayEnergy(indent + 4, plevel, is_tdp); + cout << "**************************************************************" + "***************************" + << endl; + } + if (!XML->sys.Private_L2) { + for (i = 0; i < numL2; i++) { + l2array[i]->displayEnergy(indent + 4, is_tdp); + cout << "************************************************************" + "*****************************" + << endl; + } + } + for (i = 0; i < numL3; i++) { + l3array[i]->displayEnergy(indent + 4, is_tdp); + cout << "**************************************************************" + "***************************" + << endl; + } + for (i = 0; i < numL1Dir; i++) { + l1dirarray[i]->displayEnergy(indent + 4, is_tdp); + cout << "**************************************************************" + "***************************" + << endl; + } + for (i = 0; i < numL2Dir; i++) { + l2dirarray[i]->displayEnergy(indent + 4, is_tdp); + cout << "**************************************************************" + "***************************" + << endl; + } + if (XML->sys.mc.number_mcs > 0 && + XML->sys.mc.memory_channels_per_mc > 0) { + mc->displayEnergy(indent + 4, is_tdp); + cout << "**************************************************************" + "***************************" + << endl; + } + if (XML->sys.flashc.number_mcs > 0 && + XML->sys.flashc.memory_channels_per_mc > 0) { + flashcontroller->displayEnergy(indent + 4, is_tdp); + cout << "**************************************************************" + "***************************" + << endl; + } + if (XML->sys.niu.number_units > 0) { + niu->displayEnergy(indent + 4, is_tdp); + cout << "**************************************************************" + "***************************" + << endl; + } + if (XML->sys.pcie.number_units > 0 && XML->sys.pcie.num_channels > 0) { + pcie->displayEnergy(indent + 4, is_tdp); + cout << "**************************************************************" + "***************************" + << endl; + } + + for (i = 0; i < numNOC; i++) { + nocs[i]->displayEnergy(indent + 4, plevel, is_tdp); + cout << "**************************************************************" + "***************************" + << endl; + } + } + } else { + } } -void Processor::set_proc_param() -{ - bool debug = false; - - procdynp.homoCore = bool(debug?1:XML->sys.homogeneous_cores); - procdynp.homoL2 = bool(debug?1:XML->sys.homogeneous_L2s); - procdynp.homoL3 = bool(debug?1:XML->sys.homogeneous_L3s); - procdynp.homoNOC = bool(debug?1:XML->sys.homogeneous_NoCs); - procdynp.homoL1Dir = bool(debug?1:XML->sys.homogeneous_L1Directories); - procdynp.homoL2Dir = bool(debug?1:XML->sys.homogeneous_L2Directories); - - procdynp.numCore = XML->sys.number_of_cores; - procdynp.numL2 = XML->sys.number_of_L2s; - procdynp.numL3 = XML->sys.number_of_L3s; - procdynp.numNOC = XML->sys.number_of_NoCs; - procdynp.numL1Dir = XML->sys.number_of_L1Directories; - procdynp.numL2Dir = XML->sys.number_of_L2Directories; - procdynp.numMC = XML->sys.mc.number_mcs; - procdynp.numMCChannel = XML->sys.mc.memory_channels_per_mc; - -// if (procdynp.numCore<1) -// { -// cout<<" The target processor should at least have one core on chip." <2) - // { - // cout <<"number of NOCs must be 1 (only global NOCs) or 2 (both global and local NOCs)"<sys.device_type; - interface_ip.data_arr_peri_global_tech_type = debug?0:XML->sys.device_type; - interface_ip.tag_arr_ram_cell_tech_type = debug?0:XML->sys.device_type; - interface_ip.tag_arr_peri_global_tech_type = debug?0:XML->sys.device_type; - - interface_ip.ic_proj_type = debug?0:XML->sys.interconnect_projection_type; - interface_ip.delay_wt = 100;//Fixed number, make sure timing can be satisfied. - interface_ip.area_wt = 0;//Fixed number, This is used to exhaustive search for individual components. - interface_ip.dynamic_power_wt = 100;//Fixed number, This is used to exhaustive search for individual components. - interface_ip.leakage_power_wt = 0; - interface_ip.cycle_time_wt = 0; - - interface_ip.delay_dev = 10000;//Fixed number, make sure timing can be satisfied. - interface_ip.area_dev = 10000;//Fixed number, This is used to exhaustive search for individual components. - interface_ip.dynamic_power_dev = 10000;//Fixed number, This is used to exhaustive search for individual components. - interface_ip.leakage_power_dev = 10000; - interface_ip.cycle_time_dev = 10000; - - interface_ip.ed = 2; - interface_ip.burst_len = 1;//parameters are fixed for processor section, since memory is processed separately - interface_ip.int_prefetch_w = 1; - interface_ip.page_sz_bits = 0; - interface_ip.temp = debug?360: XML->sys.temperature; - interface_ip.F_sz_nm = debug?90:XML->sys.core_tech_node;//XML->sys.core_tech_node; - interface_ip.F_sz_um = interface_ip.F_sz_nm / 1000; - - //***********This section of code does not have real meaning, they are just to ensure all data will have initial value to prevent errors. - //They will be overridden during each components initialization - interface_ip.cache_sz =64; - interface_ip.line_sz = 1; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.specific_tag = 1; - interface_ip.tag_w = 64; - interface_ip.access_mode = 2; - - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - - interface_ip.is_main_mem = false; - interface_ip.rpters_in_htree = true ; - interface_ip.ver_htree_wires_over_array = 0; - interface_ip.broadcast_addr_din_over_ver_htrees = 0; - - interface_ip.num_rw_ports = 1; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = 1; - interface_ip.nuca = 0; - interface_ip.nuca_bank_count = 0; - interface_ip.is_cache =true; - interface_ip.pure_ram =false; - interface_ip.pure_cam =false; - interface_ip.force_cache_config =false; - if (XML->sys.Embedded) - { - interface_ip.wt =Global_30; - interface_ip.wire_is_mat_type = 0; - interface_ip.wire_os_mat_type = 0; - } - else - { - interface_ip.wt =Global; - interface_ip.wire_is_mat_type = 2; - interface_ip.wire_os_mat_type = 2; - } - interface_ip.force_wiretype = false; - interface_ip.print_detail = 1; - interface_ip.add_ecc_b_ =true; +void Processor::set_proc_param() { + bool debug = false; + + procdynp.homoCore = bool(debug ? 1 : XML->sys.homogeneous_cores); + procdynp.homoL2 = bool(debug ? 1 : XML->sys.homogeneous_L2s); + procdynp.homoL3 = bool(debug ? 1 : XML->sys.homogeneous_L3s); + procdynp.homoNOC = bool(debug ? 1 : XML->sys.homogeneous_NoCs); + procdynp.homoL1Dir = bool(debug ? 1 : XML->sys.homogeneous_L1Directories); + procdynp.homoL2Dir = bool(debug ? 1 : XML->sys.homogeneous_L2Directories); + + procdynp.numCore = XML->sys.number_of_cores; + procdynp.numL2 = XML->sys.number_of_L2s; + procdynp.numL3 = XML->sys.number_of_L3s; + procdynp.numNOC = XML->sys.number_of_NoCs; + procdynp.numL1Dir = XML->sys.number_of_L1Directories; + procdynp.numL2Dir = XML->sys.number_of_L2Directories; + procdynp.numMC = XML->sys.mc.number_mcs; + procdynp.numMCChannel = XML->sys.mc.memory_channels_per_mc; + + // if (procdynp.numCore<1) + // { + // cout<<" The target processor should at least have one core on chip." + //<2) + // { + // cout <<"number of NOCs must be 1 (only global NOCs) or 2 (both global + // and local NOCs)"<sys.device_type; + interface_ip.data_arr_peri_global_tech_type = + debug ? 0 : XML->sys.device_type; + interface_ip.tag_arr_ram_cell_tech_type = debug ? 0 : XML->sys.device_type; + interface_ip.tag_arr_peri_global_tech_type = debug ? 0 : XML->sys.device_type; + + interface_ip.ic_proj_type = debug ? 0 : XML->sys.interconnect_projection_type; + interface_ip.delay_wt = + 100; // Fixed number, make sure timing can be satisfied. + interface_ip.area_wt = 0; // Fixed number, This is used to exhaustive search + // for individual components. + interface_ip.dynamic_power_wt = 100; // Fixed number, This is used to + // exhaustive search for individual + // components. + interface_ip.leakage_power_wt = 0; + interface_ip.cycle_time_wt = 0; + + interface_ip.delay_dev = + 10000; // Fixed number, make sure timing can be satisfied. + interface_ip.area_dev = 10000; // Fixed number, This is used to exhaustive + // search for individual components. + interface_ip.dynamic_power_dev = 10000; // Fixed number, This is used to + // exhaustive search for individual + // components. + interface_ip.leakage_power_dev = 10000; + interface_ip.cycle_time_dev = 10000; + + interface_ip.ed = 2; + interface_ip.burst_len = 1; // parameters are fixed for processor section, + // since memory is processed separately + interface_ip.int_prefetch_w = 1; + interface_ip.page_sz_bits = 0; + interface_ip.temp = debug ? 360 : XML->sys.temperature; + interface_ip.F_sz_nm = + debug ? 90 : XML->sys.core_tech_node; // XML->sys.core_tech_node; + interface_ip.F_sz_um = interface_ip.F_sz_nm / 1000; + + //***********This section of code does not have real meaning, they are just to + //ensure all data will have initial value to prevent errors. + // They will be overridden during each components initialization + interface_ip.cache_sz = 64; + interface_ip.line_sz = 1; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.specific_tag = 1; + interface_ip.tag_w = 64; + interface_ip.access_mode = 2; + + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + + interface_ip.is_main_mem = false; + interface_ip.rpters_in_htree = true; + interface_ip.ver_htree_wires_over_array = 0; + interface_ip.broadcast_addr_din_over_ver_htrees = 0; + + interface_ip.num_rw_ports = 1; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = 1; + interface_ip.nuca = 0; + interface_ip.nuca_bank_count = 0; + interface_ip.is_cache = true; + interface_ip.pure_ram = false; + interface_ip.pure_cam = false; + interface_ip.force_cache_config = false; + if (XML->sys.Embedded) { + interface_ip.wt = Global_30; + interface_ip.wire_is_mat_type = 0; + interface_ip.wire_os_mat_type = 0; + } else { + interface_ip.wt = Global; + interface_ip.wire_is_mat_type = 2; + interface_ip.wire_os_mat_type = 2; + } + interface_ip.force_wiretype = false; + interface_ip.print_detail = 1; + interface_ip.add_ecc_b_ = true; } - -Processor::~Processor(){ - while (!cores.empty()) - { - delete cores.back(); - cores.pop_back(); - } - while (!l2array.empty()) - { - delete l2array.back(); - l2array.pop_back(); - } - while (!l3array.empty()) - { - delete l3array.back(); - l3array.pop_back(); - } - while (!nocs.empty()) - { - delete nocs.back(); - nocs.pop_back(); - } - if (!mc) - { - delete mc; - } - if (!niu) - { - delete niu; - } - if (!pcie) - { - delete pcie; - } - if (!flashcontroller) - { - delete flashcontroller; - } +Processor::~Processor() { + while (!cores.empty()) { + delete cores.back(); + cores.pop_back(); + } + while (!l2array.empty()) { + delete l2array.back(); + l2array.pop_back(); + } + while (!l3array.empty()) { + delete l3array.back(); + l3array.pop_back(); + } + while (!nocs.empty()) { + delete nocs.back(); + nocs.pop_back(); + } + if (!mc) { + delete mc; + } + if (!niu) { + delete niu; + } + if (!pcie) { + delete pcie; + } + if (!flashcontroller) { + delete flashcontroller; + } }; - - -- cgit v1.3 From ca563ea85ead434e0d579026b5e66e829af5efe5 Mon Sep 17 00:00:00 2001 From: Nick Date: Fri, 13 Sep 2019 06:12:34 -0400 Subject: Add additional formatting pass on directories --- src/gpgpu-sim/gpu-cache.h | 4 +- src/gpgpu-sim/gpu-sim.h | 16 +- src/gpgpu-sim/mem_latency_stat.h | 4 +- src/gpgpu-sim/shader.cc | 2 +- src/gpuwattch/XML_Parse.cc | 29 ++-- src/gpuwattch/array.cc | 41 +++-- src/gpuwattch/core.cc | 305 ++++++++++++++++++++-------------- src/gpuwattch/iocontrollers.cc | 10 +- src/gpuwattch/logic.cc | 54 +++--- src/gpuwattch/logic.h | 8 +- src/gpuwattch/memoryctrl.cc | 35 ++-- src/gpuwattch/noc.cc | 46 +++-- src/gpuwattch/processor.cc | 5 +- src/gpuwattch/processor.h | 2 +- src/gpuwattch/sharedcache.cc | 63 +++---- src/gpuwattch/technology_xeon_core.cc | 4 +- src/gpuwattch/xmlParser.cc | 6 +- src/gpuwattch/xmlParser.h | 222 ++++++++++++------------- 18 files changed, 472 insertions(+), 384 deletions(-) (limited to 'src/gpuwattch/processor.cc') diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 9b9898e..9fe14ca 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -1312,9 +1312,9 @@ class baseline_cache : public cache_t { const cache_config &m_config; int m_data_port_occupied_cycles; //< Number of cycle that the data port - //remains used + // remains used int m_fill_port_occupied_cycles; //< Number of cycle that the fill port - //remains used + // remains used }; bandwidth_management m_bandwidth_management; diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h index 40c4482..a24ceea 100644 --- a/src/gpgpu-sim/gpu-sim.h +++ b/src/gpgpu-sim/gpu-sim.h @@ -264,11 +264,11 @@ class memory_config { // GDDR5 this is identical to RTPS, if for other DRAM this is // different, you will need to split them in two - unsigned tCCD; // column to column delay - unsigned tRRD; // minimal time required between activation of rows in - // different banks - unsigned tRCD; // row to column delay - time required to activate a row - // before a read + unsigned tCCD; // column to column delay + unsigned tRRD; // minimal time required between activation of rows in + // different banks + unsigned tRCD; // row to column delay - time required to activate a row + // before a read unsigned tRCDWR; // row to column delay for a write command unsigned tRAS; // time needed to activate row unsigned tRP; // row precharge ie. deactivate row @@ -276,7 +276,7 @@ class memory_config { tRC; // row cycle time ie. precharge current, then activate different row unsigned tCDLR; // Last data-in to Read command (switching from write to // read) - unsigned tWR; // Last data-in to Row precharge + unsigned tWR; // Last data-in to Row precharge unsigned CL; // CAS latency unsigned WL; // WRITE latency @@ -628,9 +628,9 @@ class gpgpu_sim : public gpgpu_t { std::map g_watchpoint_hits; std::string executed_kernel_info_string(); //< format the kernel information - //into a string for stat printout + // into a string for stat printout void clear_executed_kernel_info(); //< clear the kernel information after - //stat printout + // stat printout public: unsigned long long gpu_sim_insn; diff --git a/src/gpgpu-sim/mem_latency_stat.h b/src/gpgpu-sim/mem_latency_stat.h index 21c15ee..d733218 100644 --- a/src/gpgpu-sim/mem_latency_stat.h +++ b/src/gpgpu-sim/mem_latency_stat.h @@ -90,8 +90,8 @@ class memory_stats_t { unsigned int **totalbankreads; // bankreads[dram chip id][bank id] unsigned int **totalbankaccesses; // bankaccesses[dram chip id][bank id] unsigned int *num_MCBs_accessed; // tracks how many memory controllers are - // accessed whenever any thread in a warp - // misses in cache + // accessed whenever any thread in a warp + // misses in cache unsigned int *position_of_mrq_chosen; // position of mrq in m_queue chosen unsigned ***mem_access_type_stats; // dram access type classification diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 73ea8b3..fc1c1e2 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -3460,7 +3460,7 @@ void shader_core_ctx::warp_exit(unsigned warp_id) { for (unsigned i = warp_id * get_config()->warp_size; i < (warp_id + 1) * get_config()->warp_size; i++) { // if(this->m_thread[i]->m_functional_model_thread_state && - //this->m_thread[i].m_functional_model_thread_state->donecycle()==0) { + // this->m_thread[i].m_functional_model_thread_state->donecycle()==0) { // done = false; // } diff --git a/src/gpuwattch/XML_Parse.cc b/src/gpuwattch/XML_Parse.cc index 26115d3..19d3d44 100644 --- a/src/gpuwattch/XML_Parse.cc +++ b/src/gpuwattch/XML_Parse.cc @@ -535,7 +535,7 @@ void ParseXML::parse(char* filepath) { // if (sys.Private_L2 && sys.number_of_cores!=sys.number_of_L2s) // { // cout<<"Private L2: Number of L2s must equal to Number of - //Cores"< OrderofComponents_3layer) { //___________________________get all - //system.core0-n________________________________________________ + // system.core0-n________________________________________________ if (sys.homogeneous_cores == 1) OrderofComponents_3layer = 0; else @@ -2044,9 +2044,8 @@ void ParseXML::parse(char* filepath) { if (strcmp(xNode4.getAttribute("name"), "sharedmemory") == 0) { // find system.core0.sharedmemory itmp = xNode4.nChildNode("param"); - for (k = 0; k < itmp; - k++) { // get all items of param in - // system.core0.sharedmemory--sharedmemory + for (k = 0; k < itmp; k++) { // get all items of param in + // system.core0.sharedmemory--sharedmemory if (strcmp(xNode4.getChildNode("param", k).getAttribute("name"), "sharedmemory_config") == 0) { strtmp.assign( @@ -2483,7 +2482,7 @@ void ParseXML::parse(char* filepath) { } //__________________________________________Get - //system.L1Directory0-n____________________________________________ + // system.L1Directory0-n____________________________________________ int w, tmpOrderofComponents_3layer; w = OrderofComponents_3layer + 1; tmpOrderofComponents_3layer = OrderofComponents_3layer; @@ -2649,7 +2648,7 @@ void ParseXML::parse(char* filepath) { } //__________________________________________Get - //system.L2Directory0-n____________________________________________ + // system.L2Directory0-n____________________________________________ w = OrderofComponents_3layer + 1; tmpOrderofComponents_3layer = OrderofComponents_3layer; if (sys.homogeneous_L2Directories == 1) @@ -2814,7 +2813,7 @@ void ParseXML::parse(char* filepath) { } //__________________________________________Get - //system.L2[0..n]____________________________________________ + // system.L2[0..n]____________________________________________ w = OrderofComponents_3layer + 1; tmpOrderofComponents_3layer = OrderofComponents_3layer; if (sys.homogeneous_L2s == 1) @@ -3102,7 +3101,7 @@ void ParseXML::parse(char* filepath) { } } //__________________________________________Get - //system.L3[0..n]____________________________________________ + // system.L3[0..n]____________________________________________ w = OrderofComponents_3layer + 1; tmpOrderofComponents_3layer = OrderofComponents_3layer; if (sys.homogeneous_L3s == 1) @@ -3390,7 +3389,7 @@ void ParseXML::parse(char* filepath) { } } //__________________________________________Get - //system.NoC[0..n]____________________________________________ + // system.NoC[0..n]____________________________________________ w = OrderofComponents_3layer + 1; tmpOrderofComponents_3layer = OrderofComponents_3layer; if (sys.homogeneous_NoCs == 1) @@ -3641,7 +3640,7 @@ void ParseXML::parse(char* filepath) { } } //__________________________________________Get - //system.mem____________________________________________ + // system.mem____________________________________________ if (OrderofComponents_3layer > 0) OrderofComponents_3layer = OrderofComponents_3layer + 1; xNode3 = xNode2.getChildNode("component", OrderofComponents_3layer); @@ -3757,7 +3756,7 @@ void ParseXML::parse(char* filepath) { exit(0); } //__________________________________________Get - //system.mc____________________________________________ + // system.mc____________________________________________ if (OrderofComponents_3layer > 0) OrderofComponents_3layer = OrderofComponents_3layer + 1; xNode3 = xNode2.getChildNode("component", OrderofComponents_3layer); @@ -3947,7 +3946,7 @@ void ParseXML::parse(char* filepath) { exit(0); } //__________________________________________Get - //system.niu____________________________________________ + // system.niu____________________________________________ if (OrderofComponents_3layer > 0) OrderofComponents_3layer = OrderofComponents_3layer + 1; xNode3 = xNode2.getChildNode("component", OrderofComponents_3layer); @@ -4005,7 +4004,7 @@ void ParseXML::parse(char* filepath) { } //__________________________________________Get - //system.pcie____________________________________________ + // system.pcie____________________________________________ if (OrderofComponents_3layer > 0) OrderofComponents_3layer = OrderofComponents_3layer + 1; xNode3 = xNode2.getChildNode("component", OrderofComponents_3layer); @@ -4074,7 +4073,7 @@ void ParseXML::parse(char* filepath) { exit(0); } //__________________________________________Get - //system.flashcontroller____________________________________________ + // system.flashcontroller____________________________________________ if (OrderofComponents_3layer > 0) OrderofComponents_3layer = OrderofComponents_3layer + 1; xNode3 = xNode2.getChildNode("component", OrderofComponents_3layer); diff --git a/src/gpuwattch/array.cc b/src/gpuwattch/array.cc index aca5a8a..a50cac6 100644 --- a/src/gpuwattch/array.cc +++ b/src/gpuwattch/array.cc @@ -118,7 +118,7 @@ void ArrayST::optimize_array() { 10; // This is the time_dev to be used for next iteration // from best area to worst area -->worst timing to best - //timing + // timing if ((((local_result.cycle_time - throughput) <= 1e-10) && (local_result.access_time - latency) <= 1e-10) || (local_result.data_array2->area_efficiency < @@ -145,8 +145,8 @@ void ArrayST::optimize_array() { if (l_ip.cycle_time_dev > 10) { // if not >10 local_result is the last // result, it cannot be cleaned up - temp_res = &local_result; // Only solutions not saved in the list - // need to be cleaned up + temp_res = &local_result; // Only solutions not saved in the list + // need to be cleaned up temp_res->cleanup(); } } @@ -171,23 +171,36 @@ void ArrayST::optimize_array() { // /*According to "Content-Addressable Memory (CAM) Circuits and // Architectures": A Tutorial and Survey // by Kostas Pagiamtzis et al. - // CAM structures can be heavily pipelined and use look-ahead - //techniques, - // therefore timing can be relaxed. But McPAT does not model the - //advanced - // techniques. If continue optimizing, the area efficiency will be - //too low + // CAM structures can be heavily pipelined and use + // look-ahead + // techniques, + // therefore timing can be relaxed. But McPAT does not + //model + // the + // advanced + // techniques. If continue optimizing, the area efficiency + //will + // be + // too low // */ // //For CAM and FA, stop opt if area efficiency is too low // if (throughput_overflow==true) - // cout<< "Warning: " <<" McPAT stopped optimization on throughput for + // cout<< "Warning: " <<" McPAT stopped optimization on + //throughput + // for //"<< name - // <<" array structure because its area efficiency is below + // <<" array structure because its area efficiency + //is + // below //"<sys.core[ithCore].number_hardware_threads); area.set_area(area.get_area() + iFRAT->area.get_area()); - // //RAHT According to Intel, combine GC with FRAT is - //very costly. - // data = - //int(ceil(coredynp.phy_ireg_width/8.0)*coredynp.num_IRF_entry); + // //RAHT According to Intel, combine GC with FRAT + // is + // very costly. + // data + //= + // int(ceil(coredynp.phy_ireg_width/8.0)*coredynp.num_IRF_entry); // out_w = data; // interface_ip.is_cache = - //false; + // false; // interface_ip.pure_cam = false; // interface_ip.pure_ram = true; // interface_ip.line_sz = data; // interface_ip.cache_sz = - //data*coredynp.globalCheckpoint; + // data*coredynp.globalCheckpoint; // interface_ip.assoc = 1; // interface_ip.nbanks = 1; // interface_ip.out_w = out_w*8; // interface_ip.access_mode = 0; // interface_ip.throughput = - //1.0/clockRate; + // 1.0/clockRate; // interface_ip.latency = - //1.0/clockRate; + // 1.0/clockRate; // interface_ip.obj_func_dyn_energy = 0; // interface_ip.obj_func_dyn_power = 0; // interface_ip.obj_func_leak_power = 0; // interface_ip.obj_func_cycle_t = 1; // interface_ip.num_rw_ports = 1;//the extra one - //port is for GCs + // port is for GCs // interface_ip.num_rd_ports = - //2*coredynp.decodeW; + // 2*coredynp.decodeW; // interface_ip.num_wr_ports = coredynp.decodeW; // interface_ip.num_se_rd_ports = 0; // iFRAT = new ArrayST(&interface_ip, "Int - //FrontRAT"); + // FrontRAT"); // iFRAT->area.set_area(iFRAT->area.get_area()+ - //iFRAT->local_result.area*XML->sys.core[ithCore].number_hardware_threads); + // iFRAT->local_result.area*XML->sys.core[ithCore].number_hardware_threads); // area.set_area(area.get_area()+ - //iFRAT->area.get_area()); + // iFRAT->area.get_area()); // FRAT floating point data = int(ceil(coredynp.phy_freg_width * @@ -3223,30 +3230,39 @@ void BranchPredictor::displayEnergy(uint32_t indent, int plevel, bool is_tdp) { << " W" << endl; cout << endl; } else { - // cout << indent_str_next << "Global Predictor Peak Dynamic = " << - //globalBPT->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Global Predictor Subthreshold Leakage = + // cout << indent_str_next << "Global Predictor Peak Dynamic = " + //<< + // globalBPT->rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout << indent_str_next << "Global Predictor Subthreshold + //Leakage + //= //" << globalBPT->rt_power.readOp.leakage <<" W" << endl; - // cout << indent_str_next << "Global Predictor Gate Leakage = " << - //globalBPT->rt_power.readOp.gate_leakage << " W" << endl; - // cout << indent_str_next << "Local Predictor Peak Dynamic = " << - //L1_localBPT->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Local Predictor Subthreshold Leakage = " + // cout << indent_str_next << "Global Predictor Gate Leakage = " + //<< + // globalBPT->rt_power.readOp.gate_leakage << " W" << endl; + // cout << indent_str_next << "Local Predictor Peak Dynamic = " + //<< + // L1_localBPT->rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout << indent_str_next << "Local Predictor Subthreshold Leakage + //= + //" //<< L1_localBPT->rt_power.readOp.leakage << " W" << endl; - // cout << indent_str_next << "Local Predictor Gate Leakage = " << - //L1_localBPT->rt_power.readOp.gate_leakage << " W" << endl; + // cout << indent_str_next << "Local Predictor Gate Leakage = " + //<< + // L1_localBPT->rt_power.readOp.gate_leakage << " W" << endl; // cout << indent_str_next << "Chooser Peak Dynamic = " << - //chooser->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Chooser Subthreshold Leakage = " << - //chooser->rt_power.readOp.leakage << " W" << endl; + // chooser->rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout << indent_str_next << "Chooser Subthreshold Leakage = " + //<< + // chooser->rt_power.readOp.leakage << " W" << endl; // cout << indent_str_next << "Chooser Gate Leakage = " << - //chooser->rt_power.readOp.gate_leakage << " W" << endl; + // chooser->rt_power.readOp.gate_leakage << " W" << endl; // cout << indent_str_next << "RAS Peak Dynamic = " << - //RAS->rt_power.readOp.dynamic*clockRate << " W" << endl; + // RAS->rt_power.readOp.dynamic*clockRate << " W" << endl; // cout << indent_str_next << "RAS Subthreshold Leakage = " << - //RAS->rt_power.readOp.leakage << " W" << endl; + // RAS->rt_power.readOp.leakage << " W" << endl; // cout << indent_str_next << "RAS Gate Leakage = " << - //RAS->rt_power.readOp.gate_leakage << " W" << endl; + // RAS->rt_power.readOp.gate_leakage << " W" << endl; } } @@ -3593,30 +3609,48 @@ void InstFetchU::displayEnergy(uint32_t indent, int plevel, bool is_tdp) { << " W" << endl; cout << endl; } else { - // cout << indent_str_next << "Instruction Cache Peak Dynamic = " << - //icache.rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Instruction Cache Subthreshold Leakage + // cout << indent_str_next << "Instruction Cache Peak Dynamic = + //" + //<< + // icache.rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout << indent_str_next << "Instruction Cache Subthreshold + // Leakage //= " << icache.rt_power.readOp.leakage <<" W" << endl; - // cout << indent_str_next << "Instruction Cache Gate Leakage = " << - //icache.rt_power.readOp.gate_leakage << " W" << endl; - // cout << indent_str_next << "Instruction Buffer Peak Dynamic = " << - //IB->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Instruction Buffer Subthreshold Leakage + // cout << indent_str_next << "Instruction Cache Gate Leakage = + //" + //<< + // icache.rt_power.readOp.gate_leakage << " W" << endl; + // cout << indent_str_next << "Instruction Buffer Peak Dynamic = + //" + //<< + // IB->rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout << indent_str_next << "Instruction Buffer Subthreshold + // Leakage //= " << IB->rt_power.readOp.leakage << " W" << endl; - // cout << indent_str_next << "Instruction Buffer Gate Leakage = " << - //IB->rt_power.readOp.gate_leakage << " W" << endl; - // cout << indent_str_next << "Branch Target Buffer Peak Dynamic = " << - //BTB->rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout << indent_str_next << "Instruction Buffer Gate Leakage = + //" + //<< + // IB->rt_power.readOp.gate_leakage << " W" << endl; + // cout << indent_str_next << "Branch Target Buffer Peak Dynamic = + //" + //<< + // BTB->rt_power.readOp.dynamic*clockRate << " W" << endl; // cout << indent_str_next << "Branch Target Buffer Subthreshold - //Leakage = " << BTB->rt_power.readOp.leakage << " W" << endl; - // cout << indent_str_next << "Branch Target Buffer Gate Leakage = " << - //BTB->rt_power.readOp.gate_leakage << " W" << endl; - // cout << indent_str_next << "Branch Predictor Peak Dynamic = " << - //BPT->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Branch Predictor Subthreshold Leakage = + // Leakage = " << BTB->rt_power.readOp.leakage << " W" << endl; + // cout << indent_str_next << "Branch Target Buffer Gate Leakage = + //" + //<< + // BTB->rt_power.readOp.gate_leakage << " W" << endl; + // cout << indent_str_next << "Branch Predictor Peak Dynamic = " + //<< + // BPT->rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout << indent_str_next << "Branch Predictor Subthreshold + //Leakage + //= //" << BPT->rt_power.readOp.leakage << " W" << endl; - // cout << indent_str_next << "Branch Predictor Gate Leakage = " << - //BPT->rt_power.readOp.gate_leakage << " W" << endl; + // cout << indent_str_next << "Branch Predictor Gate Leakage = " + //<< + // BPT->rt_power.readOp.gate_leakage << " W" << endl; } } @@ -4214,11 +4248,12 @@ void SchedulerU::computeEnergy(bool is_tdp) { if (!exist) return; double ROB_duty_cycle; // ROB_duty_cycle = ((coredynp.ALU_duty_cycle + - //coredynp.num_muls>0?coredynp.MUL_duty_cycle:0 - // + coredynp.num_fpus>0?coredynp.FPU_duty_cycle:0))*1.1<1 ? + // coredynp.num_muls>0?coredynp.MUL_duty_cycle:0 + // + coredynp.num_fpus>0?coredynp.FPU_duty_cycle:0))*1.1<1 + //? //(coredynp.ALU_duty_cycle + coredynp.num_muls>0?coredynp.MUL_duty_cycle:0 // + - //coredynp.num_fpus>0?coredynp.FPU_duty_cycle:0)*1.1:1; + // coredynp.num_fpus>0?coredynp.FPU_duty_cycle:0)*1.1:1; ROB_duty_cycle = 1; // init stats if (is_tdp) { @@ -4392,7 +4427,7 @@ void SchedulerU::computeEnergy(bool is_tdp) { } else if (coredynp.multithreaded) { // set_pppm(pppm_t, - //XML->sys.core[ithCore].issue_width,1, 1, 1); + // XML->sys.core[ithCore].issue_width,1, 1, 1); int_inst_window->power = int_inst_window->power_t + (int_inst_window->local_result.power + instruction_selection->power) * @@ -4419,7 +4454,7 @@ void SchedulerU::computeEnergy(bool is_tdp) { } else if (coredynp.multithreaded) { // set_pppm(pppm_t, - //XML->sys.core[ithCore].issue_width,1, 1, 1); + // XML->sys.core[ithCore].issue_width,1, 1, 1); int_inst_window->rt_power = int_inst_window->power_t + (int_inst_window->local_result.power + instruction_selection->power) * @@ -4429,9 +4464,9 @@ void SchedulerU::computeEnergy(bool is_tdp) { } // set_pppm(pppm_t, XML->sys.core[ithCore].issue_width,1, 1, 1); // cout<<"Scheduler - //power="<power.readOp.dynamic<<"leakage"<power.readOp.leakage<power_t.readOp.dynamic += - //LSQ->stats_t.readAc.access*(LSQ->local_result.power.searchOp.dynamic + - //LSQ->local_result.power.readOp.dynamic) + // LSQ->stats_t.readAc.access*(LSQ->local_result.power.searchOp.dynamic + + // LSQ->local_result.power.readOp.dynamic) // + - //LSQ->stats_t.writeAc.access*LSQ->local_result.power.writeOp.dynamic;//every - //memory access invloves at least two operations on LSQ + // LSQ->stats_t.writeAc.access*LSQ->local_result.power.writeOp.dynamic;//every + // memory access invloves at least two operations on LSQ // No LSQ in GPUs (Syed) } @@ -5944,7 +5979,7 @@ void EXECU::displayEnergy(uint32_t indent, int plevel, bool is_tdp) { 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; + // bypass->area.get_area() *1e-6 << " mm^2" << endl; if (is_tdp) { cout << indent_str << "Register Files:" << endl; cout << indent_str_next << "Area = " << rfu->area.get_area() * 1e-6 @@ -6151,15 +6186,15 @@ void Core::computeEnergy(bool is_tdp) { coredynp.num_pipelines / num_units, coredynp.num_pipelines / num_units); // cout << "IFU = " << - //ifu->power.readOp.dynamic*clockRate << " W" << endl; + // ifu->power.readOp.dynamic*clockRate << " W" << endl; ifu->power = ifu->power + corepipe->power * pppm_t; // cout << "IFU = " << - //ifu->power.readOp.dynamic*clockRate << " W" << endl; + // ifu->power.readOp.dynamic*clockRate << " W" << endl; // cout << "1/4 pipe = " << - //corepipe->power.readOp.dynamic*clockRate/num_units << " W" << endl; + // corepipe->power.readOp.dynamic*clockRate/num_units << " W" << endl; power = power + ifu->power; // cout << "core = " << - //power.readOp.dynamic*clockRate << " W" << endl; + // power.readOp.dynamic*clockRate << " W" << endl; } if (lsu->exist) { Pipeline_energy += @@ -6172,10 +6207,10 @@ void Core::computeEnergy(bool is_tdp) { coredynp.num_pipelines / num_units); lsu->power = lsu->power + corepipe->power * pppm_t; // cout << "LSU = " << - //lsu->power.readOp.dynamic*clockRate << " W" << endl; + // lsu->power.readOp.dynamic*clockRate << " W" << endl; power = power + lsu->power; // cout << "core = " << - //power.readOp.dynamic*clockRate << " W" << endl; + // power.readOp.dynamic*clockRate << " W" << endl; } if (exu->exist) { Pipeline_energy += @@ -6189,10 +6224,10 @@ void Core::computeEnergy(bool is_tdp) { // cout<<"ExPowerScalingFactor:"<power = exu->power + corepipe->power * pppm_t; // cout << "EXE = " << - //exu->power.readOp.dynamic*clockRate << " W" << endl; + // exu->power.readOp.dynamic*clockRate << " W" << endl; power = power + exu->power; // cout << "core = " << - //power.readOp.dynamic*clockRate << " W" << endl; + // power.readOp.dynamic*clockRate << " W" << endl; } if (mmu->exist) { Pipeline_energy += @@ -6205,10 +6240,10 @@ void Core::computeEnergy(bool is_tdp) { coredynp.num_pipelines / num_units); mmu->power = mmu->power + corepipe->power * pppm_t; // cout << "MMU = " << - //mmu->power.readOp.dynamic*clockRate << " W" << endl; + // mmu->power.readOp.dynamic*clockRate << " W" << endl; power = power + mmu->power; // cout << "core = " << - //power.readOp.dynamic*clockRate << " W" << endl; + // power.readOp.dynamic*clockRate << " W" << endl; } power = power + undiffCore->power; @@ -6276,8 +6311,9 @@ void Core::computeEnergy(bool is_tdp) { } rt_power = rt_power + undiffCore->power; - // cout << "EXE = " << exu->power.readOp.dynamic*clockRate << " W" << - //endl; + // cout << "EXE = " << exu->power.readOp.dynamic*clockRate << " W" + //<< + // endl; if (XML->sys.Private_L2) { l2cache->computeEnergy(is_tdp); // set_pppm(pppm_t,1/l2cache->cachep.executionTime, 1,1,1); @@ -6436,22 +6472,28 @@ void Core::displayEnergy(uint32_t indent, int plevel, bool is_tdp) { // if (undiffCore->exist) // { // cout << indent_str << "Undifferentiated Core" << - //endl; + // endl; // cout << indent_str_next << "Area = " << - //undiffCore->area.get_area()*1e-6<< " mm^2" << endl; + // undiffCore->area.get_area()*1e-6<< " mm^2" << endl; // cout << indent_str_next << "Peak Dynamic = " << - //undiffCore->power.readOp.dynamic*clockRate << " W" << endl; - //// cout << indent_str_next << "Subthreshold Leakage = " << - ///undiffCore->power.readOp.leakage <<" W" << endl; - // cout << indent_str_next << "Subthreshold Leakage = + // undiffCore->power.readOp.dynamic*clockRate << " W" << endl; + //// cout << indent_str_next << "Subthreshold Leakage = + ///" + ///<< + /// undiffCore->power.readOp.leakage <<" W" << endl; + // cout << indent_str_next << "Subthreshold Leakage + //= //" - // << (long_channel? - //undiffCore->power.readOp.longer_channel_leakage:undiffCore->power.readOp.leakage) + // << + //(long_channel? + // undiffCore->power.readOp.longer_channel_leakage:undiffCore->power.readOp.leakage) //<< " W" << endl; // cout << indent_str_next << "Gate Leakage = " << - //undiffCore->power.readOp.gate_leakage << " W" << endl; - // // cout << indent_str_next << "Runtime Dynamic = " << - //undiffCore->rt_power.readOp.dynamic/executionTime << " W" << endl; + // undiffCore->power.readOp.gate_leakage << " W" << endl; + // // cout << indent_str_next << "Runtime Dynamic = + //" + //<< + // undiffCore->rt_power.readOp.dynamic/executionTime << " W" << endl; // cout <rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Instruction Fetch Unit Subthreshold - //Leakage = " << ifu->rt_power.readOp.leakage <<" W" << endl; - // cout << indent_str_next << "Instruction Fetch Unit Gate Leakage = " + // cout << indent_str_next << "Instruction Fetch Unit Subthreshold + // Leakage = " << ifu->rt_power.readOp.leakage <<" W" << endl; + // cout << indent_str_next << "Instruction Fetch Unit Gate Leakage + //= + //" //<< ifu->rt_power.readOp.gate_leakage << " W" << endl; - // cout << indent_str_next << "Load Store Unit Peak Dynamic = " << - //lsu->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Load Store Unit Subthreshold Leakage = " + // cout << indent_str_next << "Load Store Unit Peak Dynamic = " + //<< + // lsu->rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout << indent_str_next << "Load Store Unit Subthreshold Leakage + //= + //" //<< lsu->rt_power.readOp.leakage << " W" << endl; - // cout << indent_str_next << "Load Store Unit Gate Leakage = " << - //lsu->rt_power.readOp.gate_leakage << " W" << endl; - // cout << indent_str_next << "Memory Management Unit Peak Dynamic = " + // cout << indent_str_next << "Load Store Unit Gate Leakage = " + //<< + // lsu->rt_power.readOp.gate_leakage << " W" << endl; + // cout << indent_str_next << "Memory Management Unit Peak Dynamic + //= + //" //<< mmu->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Memory Management Unit Subthreshold - //Leakage = " << mmu->rt_power.readOp.leakage << " W" << endl; - // cout << indent_str_next << "Memory Management Unit Gate Leakage = " + // cout << indent_str_next << "Memory Management Unit Subthreshold + // Leakage = " << mmu->rt_power.readOp.leakage << " W" << endl; + // cout << indent_str_next << "Memory Management Unit Gate Leakage + //= + //" //<< mmu->rt_power.readOp.gate_leakage << " W" << endl; // cout << indent_str_next << "Execution Unit Peak Dynamic = " << - //exu->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Execution Unit Subthreshold Leakage = " + // exu->rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout << indent_str_next << "Execution Unit Subthreshold Leakage + //= + //" //<< exu->rt_power.readOp.leakage << " W" << endl; // cout << indent_str_next << "Execution Unit Gate Leakage = " << - //exu->rt_power.readOp.gate_leakage << " W" << endl; + // exu->rt_power.readOp.gate_leakage << " W" << endl; } } InstFetchU::~InstFetchU() { @@ -6811,8 +6867,9 @@ void Core::set_core_param() { } // if (coredynp.core_ty==OOO) // { - // cout<<"OOO processor models are being updated and will be available - //in next release"<sys.niu.total_load_perc; niup.type = XML->sys.niu.type; // niup.executionTime = - //XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); + // XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); } PCIeController::PCIeController(ParseXML* XML_interface, @@ -276,7 +276,7 @@ PCIeController::PCIeController(ParseXML* XML_interface, 1.1 * (interface_ip.F_sz_nm / 65.0); // //Cadence ChipEstimate using 65nm soft IP; // frontend_dyn = - //0.27e-9/8*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0); + // 0.27e-9/8*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0); // SerDer_dyn is power not energy, scaling from 10mw/Gb/s @90nm SerDer_dyn = 0.01 * 4 * (interface_ip.F_sz_um / 0.09) * g_tp.peri_global.Vdd / 1.2 * g_tp.peri_global.Vdd / @@ -305,7 +305,7 @@ PCIeController::PCIeController(ParseXML* XML_interface, 1.1 * (interface_ip.F_sz_nm / 65.0); // //Cadence ChipEstimate using 65nm soft IP; // frontend_dyn = - //0.27e-9/8*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0); + // 0.27e-9/8*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0); // SerDer_dyn is power not energy, scaling from 10mw/Gb/s @90nm SerDer_dyn = 0.01 * 4 * (interface_ip.F_sz_um / 0.09) * g_tp.peri_global.Vdd / 1.2 * g_tp.peri_global.Vdd / @@ -387,7 +387,7 @@ void PCIeController::set_pcie_param() { pciep.type = XML->sys.pcie.type; pciep.withPHY = XML->sys.pcie.withPHY; // pciep.executionTime = - //XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); + // XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); } FlashController::FlashController(ParseXML* XML_interface, @@ -507,5 +507,5 @@ void FlashController::set_fc_param() { fcp.type = XML->sys.flashc.type; fcp.withPHY = XML->sys.flashc.withPHY; // flashcp.executionTime = - //XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); + // XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); } diff --git a/src/gpuwattch/logic.cc b/src/gpuwattch/logic.cc index 65e3875..d6937ca 100644 --- a/src/gpuwattch/logic.cc +++ b/src/gpuwattch/logic.cc @@ -362,8 +362,8 @@ void Pipeline::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 + // 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 + @@ -578,8 +578,8 @@ FunctionalUnit::FunctionalUnit(ParseXML *XML_interface, int ithCore_, // 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) + // 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; @@ -615,8 +615,8 @@ FunctionalUnit::FunctionalUnit(ParseXML *XML_interface, int ithCore_, 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) + // 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; @@ -645,8 +645,8 @@ FunctionalUnit::FunctionalUnit(ParseXML *XML_interface, int ithCore_, 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) + // 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; @@ -666,7 +666,7 @@ FunctionalUnit::FunctionalUnit(ParseXML *XML_interface, int ithCore_, } per_access_energy *= 0.5; // According to ARM data embedded processor has // much lower per acc energy - } /* if (XML->sys.Embedded) */ + } /* if (XML->sys.Embedded) */ else { if (fu_type == FPU) { num_fu = coredynp.num_fpus; @@ -705,16 +705,14 @@ FunctionalUnit::FunctionalUnit(ParseXML *XML_interface, int ithCore_, 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 + 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 = @@ -938,7 +936,7 @@ void FunctionalUnit::displayEnergy(uint32_t indent, int plevel, bool is_tdp) { 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; + // bypass->area.get_area() *1e-6 << " mm^2" << endl; if (is_tdp) { if (fu_type == FPU) { cout << indent_str @@ -1169,10 +1167,11 @@ UndiffCore::UndiffCore(ParseXML *XML_interface, int ithCore_, // 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; + // 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; @@ -1181,15 +1180,16 @@ UndiffCore::UndiffCore(ParseXML *XML_interface, int ithCore_, // 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.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<local_result.area * XML->sys.mc.memory_channels_per_mc); //***ThreadMasks storage (coalesced threads whose memory requests are - //satisfied by each memory access) + // satisfied by each memory access) /* contents of the thread masks Array * 16-bit bit masks for up to 16 memory requests of a warp | Number of * pending memory requests (5 bits) @@ -983,7 +983,7 @@ MemoryController::MemoryController(ParseXML* XML_interface, area.set_area(area.get_area() + PHY->area.get_area()); } //+++++++++Transaction engine +++++++++++++++++ ////TODO needs better numbers, - //Run the RTL code from OpenSparc. + // Run the RTL code from OpenSparc. // transecEngine.initialize(&interface_ip); // transecEngine.peakDataTransferRate = XML->sys.mem.peak_transfer_rate; // transecEngine.memDataWidth = dataBusWidth; @@ -1023,7 +1023,7 @@ MemoryController::MemoryController(ParseXML* XML_interface, //// //clock //// clockNetwork.init_wire_external(is_default, &interface_ip); //// clockNetwork.clk_area =area*1.1;//10% of placement overhead. - ///rule of thumb + /// rule of thumb //// clockNetwork.end_wiring_level =5;//toplevel metal //// clockNetwork.start_wiring_level =5;//toplevel metal //// clockNetwork.num_regs = pipeLogic.tot_stage_vector; @@ -1199,7 +1199,7 @@ void MemoryController::set_mc_param() { mcp.reads = XML->sys.mc.memory_reads; mcp.writes = XML->sys.mc.memory_writes; //+++++++++Transaction engine +++++++++++++++++ ////TODO needs better - //numbers, Run the RTL code from OpenSparc. + // numbers, Run the RTL code from OpenSparc. mcp.peakDataTransferRate = XML->sys.mc.peak_transfer_rate; mcp.memRank = XML->sys.mc.number_ranks; //++++++++++++++PHY ++++++++++++++++++++++++++ //TODO needs better numbers @@ -1214,16 +1214,17 @@ void MemoryController::set_mc_param() { // else if (mc_type==FLASHC) // { // mcp.clockRate =XML->sys.flashc.mc_clock*2;//DDR double - //pumped + // pumped // mcp.clockRate *= 1e6; // mcp.executionTime = - //XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); + // XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); // // mcp.llcBlockSize //=int(ceil(XML->sys.flashc.llc_line_length/8.0))+XML->sys.flashc.llc_line_length;//ecc - //overhead - // mcp.dataBusWidth =int(ceil(XML->sys.flashc.databus_width/8.0)) + - //XML->sys.flashc.databus_width; + // overhead + // mcp.dataBusWidth =int(ceil(XML->sys.flashc.databus_width/8.0)) + //+ + // XML->sys.flashc.databus_width; // mcp.addressBusWidth //=int(ceil(XML->sys.flashc.addressbus_width));//XML->sys.physical_address_width; // mcp.opcodeW =16; @@ -1232,16 +1233,18 @@ void MemoryController::set_mc_param() { // mcp.reads = XML->sys.flashc.memory_reads; // mcp.writes = XML->sys.flashc.memory_writes; // //+++++++++Transaction engine +++++++++++++++++ ////TODO needs - //better numbers, Run the RTL code from OpenSparc. + // better numbers, Run the RTL code from OpenSparc. // mcp.peakDataTransferRate = XML->sys.flashc.peak_transfer_rate; // mcp.memRank = XML->sys.flashc.number_ranks; - // //++++++++++++++PHY ++++++++++++++++++++++++++ //TODO needs better - //numbers + // //++++++++++++++PHY ++++++++++++++++++++++++++ //TODO needs + // better + // numbers // //PHY.memAccesses=PHY.peakDataTransferRate;//this is the max - //power + // power // //PHY.llcBlocksize=llcBlockSize; - // mcp.frontend_duty_cycle = 0.5;//for max power, the actual off-chip - //links is bidirectional but time shared + // mcp.frontend_duty_cycle = 0.5;//for max power, the actual + // off-chip + // links is bidirectional but time shared // mcp.LVDS = XML->sys.flashc.LVDS; // mcp.type = XML->sys.flashc.type; // } diff --git a/src/gpuwattch/noc.cc b/src/gpuwattch/noc.cc index bf8d8b5..85fc0a9 100644 --- a/src/gpuwattch/noc.cc +++ b/src/gpuwattch/noc.cc @@ -357,30 +357,44 @@ void NoC::displayEnergy(uint32_t indent, int plevel, bool is_tdp) { cout << endl; } } else { - // cout << indent_str_next << "Instruction Fetch Unit Peak Dynamic = " + // cout << indent_str_next << "Instruction Fetch Unit Peak Dynamic + //= + //" //<< ifu->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Instruction Fetch Unit Subthreshold - //Leakage = " << ifu->rt_power.readOp.leakage <<" W" << endl; - // cout << indent_str_next << "Instruction Fetch Unit Gate Leakage = " + // cout << indent_str_next << "Instruction Fetch Unit Subthreshold + // Leakage = " << ifu->rt_power.readOp.leakage <<" W" << endl; + // cout << indent_str_next << "Instruction Fetch Unit Gate Leakage + //= + //" //<< ifu->rt_power.readOp.gate_leakage << " W" << endl; - // cout << indent_str_next << "Load Store Unit Peak Dynamic = " << - //lsu->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Load Store Unit Subthreshold Leakage = " + // cout << indent_str_next << "Load Store Unit Peak Dynamic = " + //<< + // lsu->rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout << indent_str_next << "Load Store Unit Subthreshold Leakage + //= + //" //<< lsu->rt_power.readOp.leakage << " W" << endl; - // cout << indent_str_next << "Load Store Unit Gate Leakage = " << - //lsu->rt_power.readOp.gate_leakage << " W" << endl; - // cout << indent_str_next << "Memory Management Unit Peak Dynamic = " + // cout << indent_str_next << "Load Store Unit Gate Leakage = " + //<< + // lsu->rt_power.readOp.gate_leakage << " W" << endl; + // cout << indent_str_next << "Memory Management Unit Peak Dynamic + //= + //" //<< mmu->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Memory Management Unit Subthreshold - //Leakage = " << mmu->rt_power.readOp.leakage << " W" << endl; - // cout << indent_str_next << "Memory Management Unit Gate Leakage = " + // cout << indent_str_next << "Memory Management Unit Subthreshold + // Leakage = " << mmu->rt_power.readOp.leakage << " W" << endl; + // cout << indent_str_next << "Memory Management Unit Gate Leakage + //= + //" //<< mmu->rt_power.readOp.gate_leakage << " W" << endl; // cout << indent_str_next << "Execution Unit Peak Dynamic = " << - //exu->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Execution Unit Subthreshold Leakage = " + // exu->rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout << indent_str_next << "Execution Unit Subthreshold Leakage + //= + //" //<< exu->rt_power.readOp.leakage << " W" << endl; // cout << indent_str_next << "Execution Unit Gate Leakage = " << - //exu->rt_power.readOp.gate_leakage << " W" << endl; + // exu->rt_power.readOp.gate_leakage << " W" << endl; } } diff --git a/src/gpuwattch/processor.cc b/src/gpuwattch/processor.cc index 96c3351..b5b5cfb 100644 --- a/src/gpuwattch/processor.cc +++ b/src/gpuwattch/processor.cc @@ -1084,7 +1084,8 @@ void Processor::set_proc_param() { // if (procdynp.numCore<1) // { - // cout<<" The target processor should at least have one core on chip." + // cout<<" The target processor should at least have one core on + // chip." //<unicache.caches->local_result.tag_array2->power.writeOp .dynamic; //*(32/4); // removed by Jingwen, the scaling - //of 32/4 is not used in the mcpat + // of 32/4 is not used in the mcpat read_coef += l2array[0]->unicache.caches->local_result.power.writeOp.dynamic; read_coef += diff --git a/src/gpuwattch/sharedcache.cc b/src/gpuwattch/sharedcache.cc index 147be43..d25d1df 100644 --- a/src/gpuwattch/sharedcache.cc +++ b/src/gpuwattch/sharedcache.cc @@ -1106,24 +1106,25 @@ void SharedCache::displayEnergy(uint32_t indent, bool is_tdp) { // ///cout<<"directory.maxPower=" <sys.first_level_dir==1) // { // inv_dir.maxPower = -//inv_dir.caches.local_result.power.searchOp.dynamic*clockRate*XML->sys.domain_size; +// inv_dir.caches.local_result.power.searchOp.dynamic*clockRate*XML->sys.domain_size; // cc.power.readOp.dynamic = -//inv_dir.maxPower*scktRatio*64/XML->sys.domain_size; +// inv_dir.maxPower*scktRatio*64/XML->sys.domain_size; // cc.power.readOp.leakage = -//inv_dir.caches.local_result.power.readOp.leakage*inv_dir.caches.l_ip.nbanks*64/XML->sys.domain_size; +// inv_dir.caches.local_result.power.readOp.leakage*inv_dir.caches.l_ip.nbanks*64/XML->sys.domain_size; // // cc.area.set_area(inv_dir.area*64/XML->sys.domain_size); // cout<<"CC area="< @@ -515,10 +515,10 @@ typedef struct XMLDLLENTRY XMLNode { XMLElementPosition pos = -1); ///< Add a new child node XMLNode addChild(XMLNode nodeToAdd, XMLElementPosition pos = -1); ///< If the "nodeToAdd" has - ///some parents, it will be - ///detached from it's parents - ///before being attached to - ///the current XMLNode + /// some parents, it will be + /// detached from it's parents + /// before being attached to + /// the current XMLNode XMLAttribute *addAttribute(XMLCSTR lpszName, XMLCSTR lpszValuev); ///< Add a new attribute XMLCSTR addText(XMLCSTR lpszValue, @@ -539,41 +539,41 @@ typedef struct XMLDLLENTRY XMLNode { XMLCSTR updateName(XMLCSTR lpszName); ///< change node's name XMLAttribute *updateAttribute(XMLAttribute *newAttribute, XMLAttribute *oldAttribute); ///< if the - ///attribute to - ///update is - ///missing, a new - ///one will be - ///added + /// attribute to + /// update is + /// missing, a new + /// one will be + /// added XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName = NULL, int i = 0); ///< if the attribute to update is - ///missing, a new one will be added + /// missing, a new one will be added XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName, XMLCSTR lpszOldName); ///< set lpszNewName=NULL - ///if you don't want to - ///change the name of the - ///attribute if the - ///attribute to update is - ///missing, a new one - ///will be added + /// if you don't want to + /// change the name of the + /// attribute if the + /// attribute to update is + /// missing, a new one + /// will be added XMLCSTR updateText(XMLCSTR lpszNewValue, int i = 0); ///< if the text to - ///update is missing, a - ///new one will be added + /// update is missing, a + /// new one will be added XMLCSTR updateText(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the text to update is - ///missing, a new one will be added + /// missing, a new one will be added XMLClear *updateClear(XMLCSTR lpszNewContent, int i = 0); ///< if the clearTag to update is missing, - ///a new one will be added + /// a new one will be added XMLClear *updateClear(XMLClear *newP, XMLClear *oldP); ///< if the clearTag - ///to update is - ///missing, a new one - ///will be added + /// to update is + /// missing, a new one + /// will be added XMLClear *updateClear(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the clearTag to update - ///is missing, a new one will be - ///added - /** @} */ + /// is missing, a new one will be + /// added + /** @} */ /** @defgroup xmlDelete Deleting Nodes or Attributes * @ingroup xmlModify @@ -589,33 +589,33 @@ typedef struct XMLDLLENTRY XMLNode { void deleteAttribute( int i = 0); ///< Delete the ith attribute of the current XMLNode void deleteAttribute(XMLCSTR lpszName); ///< Delete the attribute with the - ///given name (the "strcmp" function - ///is used to find the right - ///attribute) + /// given name (the "strcmp" function + /// is used to find the right + /// attribute) void deleteAttribute(XMLAttribute *anAttribute); ///< Delete the attribute - ///with the name - ///"anAttribute->lpszName" - ///(the "strcmp" function is - ///used to find the right - ///attribute) + /// with the name + ///"anAttribute->lpszName" + ///(the "strcmp" function is + /// used to find the right + /// attribute) void deleteText( int i = 0); ///< Delete the Ith text content of the current XMLNode void deleteText(XMLCSTR lpszValue); ///< Delete the text content "lpszValue" - ///inside the current XMLNode (direct - ///"pointer-to-pointer" comparison is - ///used to find the right text) + /// inside the current XMLNode (direct + ///"pointer-to-pointer" comparison is + /// used to find the right text) void deleteClear( int i = 0); ///< Delete the Ith clear tag inside the current XMLNode void deleteClear(XMLCSTR lpszValue); ///< Delete the clear tag "lpszValue" - ///inside the current XMLNode (direct - ///"pointer-to-pointer" comparison is - ///used to find the clear tag) - void deleteClear(XMLClear *p); ///< Delete the clear tag "p" inside the - ///current XMLNode (direct + /// inside the current XMLNode (direct + ///"pointer-to-pointer" comparison is + /// used to find the clear tag) + void deleteClear(XMLClear *p); ///< Delete the clear tag "p" inside the + /// current XMLNode (direct ///"pointer-to-pointer" comparison on the - ///lpszName of the clear tag is used to find - ///the clear tag) - /** @} */ + /// lpszName of the clear tag is used to find + /// the clear tag) + /** @} */ /** @defgroup xmlWOSD ???_WOSD functions. * @ingroup xmlModify @@ -666,49 +666,49 @@ typedef struct XMLDLLENTRY XMLNode { XMLCSTR updateName_WOSD(XMLSTR lpszName); ///< change node's name XMLAttribute *updateAttribute_WOSD(XMLAttribute *newAttribute, XMLAttribute *oldAttribute); ///< if the - ///attribute - ///to update - ///is - ///missing, a - ///new one - ///will be - ///added + /// attribute + /// to update + /// is + /// missing, a + /// new one + /// will be + /// added XMLAttribute *updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName = NULL, int i = 0); ///< if the attribute to - ///update is missing, a new - ///one will be added + /// update is missing, a new + /// one will be added XMLAttribute *updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName, XMLCSTR lpszOldName); ///< set - ///lpszNewName=NULL - ///if you don't want - ///to change the - ///name of the - ///attribute if the - ///attribute to - ///update is - ///missing, a new - ///one will be added + /// lpszNewName=NULL + /// if you don't want + /// to change the + /// name of the + /// attribute if the + /// attribute to + /// update is + /// missing, a new + /// one will be added XMLCSTR updateText_WOSD(XMLSTR lpszNewValue, int i = 0); ///< if the text to - ///update is - ///missing, a new - ///one will be added + /// update is + /// missing, a new + /// one will be added XMLCSTR updateText_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the text to update is - ///missing, a new one will be - ///added + /// missing, a new one will be + /// added XMLClear *updateClear_WOSD(XMLSTR lpszNewContent, int i = 0); ///< if the clearTag to update is - ///missing, a new one will be added + /// missing, a new one will be added XMLClear *updateClear_WOSD(XMLClear *newP, XMLClear *oldP); ///< if the clearTag to update is - ///missing, a new one will be - ///added + /// missing, a new one will be + /// added XMLClear *updateClear_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the clearTag to - ///update is missing, a new - ///one will be added - /** @} */ + /// update is missing, a new + /// one will be added + /** @} */ /** @defgroup xmlPosition Position helper functions (use in conjunction with * the update&add functions @@ -729,7 +729,7 @@ typedef struct XMLDLLENTRY XMLNode { XMLElementPosition positionOfChildNode(XMLNode x) const; XMLElementPosition positionOfChildNode(XMLCSTR name, int i = 0) const; ///< return the position of the ith childNode with the specified - ///name if (name==NULL) return the position of the ith childNode + /// name if (name==NULL) return the position of the ith childNode /** @} */ /// Enumeration for XML character encoding. @@ -970,11 +970,11 @@ typedef struct XMLDLLENTRY ToXMLStringTool { ToXMLStringTool() : buf(NULL), buflen(0) {} ~ToXMLStringTool(); void freeBuffer(); /// Date: Fri, 13 Sep 2019 07:48:04 -0400 Subject: Revert "Add additional formatting pass on directories" This reverts commit ca563ea85ead434e0d579026b5e66e829af5efe5. --- src/gpgpu-sim/gpu-cache.h | 4 +- src/gpgpu-sim/gpu-sim.h | 16 +- src/gpgpu-sim/mem_latency_stat.h | 4 +- src/gpgpu-sim/shader.cc | 2 +- src/gpuwattch/XML_Parse.cc | 29 ++-- src/gpuwattch/array.cc | 41 ++--- src/gpuwattch/core.cc | 305 ++++++++++++++-------------------- src/gpuwattch/iocontrollers.cc | 10 +- src/gpuwattch/logic.cc | 54 +++--- src/gpuwattch/logic.h | 8 +- src/gpuwattch/memoryctrl.cc | 35 ++-- src/gpuwattch/noc.cc | 46 ++--- src/gpuwattch/processor.cc | 5 +- src/gpuwattch/processor.h | 2 +- src/gpuwattch/sharedcache.cc | 63 ++++--- src/gpuwattch/technology_xeon_core.cc | 4 +- src/gpuwattch/xmlParser.cc | 6 +- src/gpuwattch/xmlParser.h | 222 ++++++++++++------------- 18 files changed, 384 insertions(+), 472 deletions(-) (limited to 'src/gpuwattch/processor.cc') diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 9fe14ca..9b9898e 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -1312,9 +1312,9 @@ class baseline_cache : public cache_t { const cache_config &m_config; int m_data_port_occupied_cycles; //< Number of cycle that the data port - // remains used + //remains used int m_fill_port_occupied_cycles; //< Number of cycle that the fill port - // remains used + //remains used }; bandwidth_management m_bandwidth_management; diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h index a24ceea..40c4482 100644 --- a/src/gpgpu-sim/gpu-sim.h +++ b/src/gpgpu-sim/gpu-sim.h @@ -264,11 +264,11 @@ class memory_config { // GDDR5 this is identical to RTPS, if for other DRAM this is // different, you will need to split them in two - unsigned tCCD; // column to column delay - unsigned tRRD; // minimal time required between activation of rows in - // different banks - unsigned tRCD; // row to column delay - time required to activate a row - // before a read + unsigned tCCD; // column to column delay + unsigned tRRD; // minimal time required between activation of rows in + // different banks + unsigned tRCD; // row to column delay - time required to activate a row + // before a read unsigned tRCDWR; // row to column delay for a write command unsigned tRAS; // time needed to activate row unsigned tRP; // row precharge ie. deactivate row @@ -276,7 +276,7 @@ class memory_config { tRC; // row cycle time ie. precharge current, then activate different row unsigned tCDLR; // Last data-in to Read command (switching from write to // read) - unsigned tWR; // Last data-in to Row precharge + unsigned tWR; // Last data-in to Row precharge unsigned CL; // CAS latency unsigned WL; // WRITE latency @@ -628,9 +628,9 @@ class gpgpu_sim : public gpgpu_t { std::map g_watchpoint_hits; std::string executed_kernel_info_string(); //< format the kernel information - // into a string for stat printout + //into a string for stat printout void clear_executed_kernel_info(); //< clear the kernel information after - // stat printout + //stat printout public: unsigned long long gpu_sim_insn; diff --git a/src/gpgpu-sim/mem_latency_stat.h b/src/gpgpu-sim/mem_latency_stat.h index d733218..21c15ee 100644 --- a/src/gpgpu-sim/mem_latency_stat.h +++ b/src/gpgpu-sim/mem_latency_stat.h @@ -90,8 +90,8 @@ class memory_stats_t { unsigned int **totalbankreads; // bankreads[dram chip id][bank id] unsigned int **totalbankaccesses; // bankaccesses[dram chip id][bank id] unsigned int *num_MCBs_accessed; // tracks how many memory controllers are - // accessed whenever any thread in a warp - // misses in cache + // accessed whenever any thread in a warp + // misses in cache unsigned int *position_of_mrq_chosen; // position of mrq in m_queue chosen unsigned ***mem_access_type_stats; // dram access type classification diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index fc1c1e2..73ea8b3 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -3460,7 +3460,7 @@ void shader_core_ctx::warp_exit(unsigned warp_id) { for (unsigned i = warp_id * get_config()->warp_size; i < (warp_id + 1) * get_config()->warp_size; i++) { // if(this->m_thread[i]->m_functional_model_thread_state && - // this->m_thread[i].m_functional_model_thread_state->donecycle()==0) { + //this->m_thread[i].m_functional_model_thread_state->donecycle()==0) { // done = false; // } diff --git a/src/gpuwattch/XML_Parse.cc b/src/gpuwattch/XML_Parse.cc index 19d3d44..26115d3 100644 --- a/src/gpuwattch/XML_Parse.cc +++ b/src/gpuwattch/XML_Parse.cc @@ -535,7 +535,7 @@ void ParseXML::parse(char* filepath) { // if (sys.Private_L2 && sys.number_of_cores!=sys.number_of_L2s) // { // cout<<"Private L2: Number of L2s must equal to Number of - // Cores"< OrderofComponents_3layer) { //___________________________get all - // system.core0-n________________________________________________ + //system.core0-n________________________________________________ if (sys.homogeneous_cores == 1) OrderofComponents_3layer = 0; else @@ -2044,8 +2044,9 @@ void ParseXML::parse(char* filepath) { if (strcmp(xNode4.getAttribute("name"), "sharedmemory") == 0) { // find system.core0.sharedmemory itmp = xNode4.nChildNode("param"); - for (k = 0; k < itmp; k++) { // get all items of param in - // system.core0.sharedmemory--sharedmemory + for (k = 0; k < itmp; + k++) { // get all items of param in + // system.core0.sharedmemory--sharedmemory if (strcmp(xNode4.getChildNode("param", k).getAttribute("name"), "sharedmemory_config") == 0) { strtmp.assign( @@ -2482,7 +2483,7 @@ void ParseXML::parse(char* filepath) { } //__________________________________________Get - // system.L1Directory0-n____________________________________________ + //system.L1Directory0-n____________________________________________ int w, tmpOrderofComponents_3layer; w = OrderofComponents_3layer + 1; tmpOrderofComponents_3layer = OrderofComponents_3layer; @@ -2648,7 +2649,7 @@ void ParseXML::parse(char* filepath) { } //__________________________________________Get - // system.L2Directory0-n____________________________________________ + //system.L2Directory0-n____________________________________________ w = OrderofComponents_3layer + 1; tmpOrderofComponents_3layer = OrderofComponents_3layer; if (sys.homogeneous_L2Directories == 1) @@ -2813,7 +2814,7 @@ void ParseXML::parse(char* filepath) { } //__________________________________________Get - // system.L2[0..n]____________________________________________ + //system.L2[0..n]____________________________________________ w = OrderofComponents_3layer + 1; tmpOrderofComponents_3layer = OrderofComponents_3layer; if (sys.homogeneous_L2s == 1) @@ -3101,7 +3102,7 @@ void ParseXML::parse(char* filepath) { } } //__________________________________________Get - // system.L3[0..n]____________________________________________ + //system.L3[0..n]____________________________________________ w = OrderofComponents_3layer + 1; tmpOrderofComponents_3layer = OrderofComponents_3layer; if (sys.homogeneous_L3s == 1) @@ -3389,7 +3390,7 @@ void ParseXML::parse(char* filepath) { } } //__________________________________________Get - // system.NoC[0..n]____________________________________________ + //system.NoC[0..n]____________________________________________ w = OrderofComponents_3layer + 1; tmpOrderofComponents_3layer = OrderofComponents_3layer; if (sys.homogeneous_NoCs == 1) @@ -3640,7 +3641,7 @@ void ParseXML::parse(char* filepath) { } } //__________________________________________Get - // system.mem____________________________________________ + //system.mem____________________________________________ if (OrderofComponents_3layer > 0) OrderofComponents_3layer = OrderofComponents_3layer + 1; xNode3 = xNode2.getChildNode("component", OrderofComponents_3layer); @@ -3756,7 +3757,7 @@ void ParseXML::parse(char* filepath) { exit(0); } //__________________________________________Get - // system.mc____________________________________________ + //system.mc____________________________________________ if (OrderofComponents_3layer > 0) OrderofComponents_3layer = OrderofComponents_3layer + 1; xNode3 = xNode2.getChildNode("component", OrderofComponents_3layer); @@ -3946,7 +3947,7 @@ void ParseXML::parse(char* filepath) { exit(0); } //__________________________________________Get - // system.niu____________________________________________ + //system.niu____________________________________________ if (OrderofComponents_3layer > 0) OrderofComponents_3layer = OrderofComponents_3layer + 1; xNode3 = xNode2.getChildNode("component", OrderofComponents_3layer); @@ -4004,7 +4005,7 @@ void ParseXML::parse(char* filepath) { } //__________________________________________Get - // system.pcie____________________________________________ + //system.pcie____________________________________________ if (OrderofComponents_3layer > 0) OrderofComponents_3layer = OrderofComponents_3layer + 1; xNode3 = xNode2.getChildNode("component", OrderofComponents_3layer); @@ -4073,7 +4074,7 @@ void ParseXML::parse(char* filepath) { exit(0); } //__________________________________________Get - // system.flashcontroller____________________________________________ + //system.flashcontroller____________________________________________ if (OrderofComponents_3layer > 0) OrderofComponents_3layer = OrderofComponents_3layer + 1; xNode3 = xNode2.getChildNode("component", OrderofComponents_3layer); diff --git a/src/gpuwattch/array.cc b/src/gpuwattch/array.cc index a50cac6..aca5a8a 100644 --- a/src/gpuwattch/array.cc +++ b/src/gpuwattch/array.cc @@ -118,7 +118,7 @@ void ArrayST::optimize_array() { 10; // This is the time_dev to be used for next iteration // from best area to worst area -->worst timing to best - // timing + //timing if ((((local_result.cycle_time - throughput) <= 1e-10) && (local_result.access_time - latency) <= 1e-10) || (local_result.data_array2->area_efficiency < @@ -145,8 +145,8 @@ void ArrayST::optimize_array() { if (l_ip.cycle_time_dev > 10) { // if not >10 local_result is the last // result, it cannot be cleaned up - temp_res = &local_result; // Only solutions not saved in the list - // need to be cleaned up + temp_res = &local_result; // Only solutions not saved in the list + // need to be cleaned up temp_res->cleanup(); } } @@ -171,36 +171,23 @@ void ArrayST::optimize_array() { // /*According to "Content-Addressable Memory (CAM) Circuits and // Architectures": A Tutorial and Survey // by Kostas Pagiamtzis et al. - // CAM structures can be heavily pipelined and use - // look-ahead - // techniques, - // therefore timing can be relaxed. But McPAT does not - //model - // the - // advanced - // techniques. If continue optimizing, the area efficiency - //will - // be - // too low + // CAM structures can be heavily pipelined and use look-ahead + //techniques, + // therefore timing can be relaxed. But McPAT does not model the + //advanced + // techniques. If continue optimizing, the area efficiency will be + //too low // */ // //For CAM and FA, stop opt if area efficiency is too low // if (throughput_overflow==true) - // cout<< "Warning: " <<" McPAT stopped optimization on - //throughput - // for + // cout<< "Warning: " <<" McPAT stopped optimization on throughput for //"<< name - // <<" array structure because its area efficiency - //is - // below + // <<" array structure because its area efficiency is below //"<sys.core[ithCore].number_hardware_threads); area.set_area(area.get_area() + iFRAT->area.get_area()); - // //RAHT According to Intel, combine GC with FRAT - // is - // very costly. - // data - //= - // int(ceil(coredynp.phy_ireg_width/8.0)*coredynp.num_IRF_entry); + // //RAHT According to Intel, combine GC with FRAT is + //very costly. + // data = + //int(ceil(coredynp.phy_ireg_width/8.0)*coredynp.num_IRF_entry); // out_w = data; // interface_ip.is_cache = - // false; + //false; // interface_ip.pure_cam = false; // interface_ip.pure_ram = true; // interface_ip.line_sz = data; // interface_ip.cache_sz = - // data*coredynp.globalCheckpoint; + //data*coredynp.globalCheckpoint; // interface_ip.assoc = 1; // interface_ip.nbanks = 1; // interface_ip.out_w = out_w*8; // interface_ip.access_mode = 0; // interface_ip.throughput = - // 1.0/clockRate; + //1.0/clockRate; // interface_ip.latency = - // 1.0/clockRate; + //1.0/clockRate; // interface_ip.obj_func_dyn_energy = 0; // interface_ip.obj_func_dyn_power = 0; // interface_ip.obj_func_leak_power = 0; // interface_ip.obj_func_cycle_t = 1; // interface_ip.num_rw_ports = 1;//the extra one - // port is for GCs + //port is for GCs // interface_ip.num_rd_ports = - // 2*coredynp.decodeW; + //2*coredynp.decodeW; // interface_ip.num_wr_ports = coredynp.decodeW; // interface_ip.num_se_rd_ports = 0; // iFRAT = new ArrayST(&interface_ip, "Int - // FrontRAT"); + //FrontRAT"); // iFRAT->area.set_area(iFRAT->area.get_area()+ - // iFRAT->local_result.area*XML->sys.core[ithCore].number_hardware_threads); + //iFRAT->local_result.area*XML->sys.core[ithCore].number_hardware_threads); // area.set_area(area.get_area()+ - // iFRAT->area.get_area()); + //iFRAT->area.get_area()); // FRAT floating point data = int(ceil(coredynp.phy_freg_width * @@ -3230,39 +3223,30 @@ void BranchPredictor::displayEnergy(uint32_t indent, int plevel, bool is_tdp) { << " W" << endl; cout << endl; } else { - // cout << indent_str_next << "Global Predictor Peak Dynamic = " - //<< - // globalBPT->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Global Predictor Subthreshold - //Leakage - //= + // cout << indent_str_next << "Global Predictor Peak Dynamic = " << + //globalBPT->rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout << indent_str_next << "Global Predictor Subthreshold Leakage = //" << globalBPT->rt_power.readOp.leakage <<" W" << endl; - // cout << indent_str_next << "Global Predictor Gate Leakage = " - //<< - // globalBPT->rt_power.readOp.gate_leakage << " W" << endl; - // cout << indent_str_next << "Local Predictor Peak Dynamic = " - //<< - // L1_localBPT->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Local Predictor Subthreshold Leakage - //= - //" + // cout << indent_str_next << "Global Predictor Gate Leakage = " << + //globalBPT->rt_power.readOp.gate_leakage << " W" << endl; + // cout << indent_str_next << "Local Predictor Peak Dynamic = " << + //L1_localBPT->rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout << indent_str_next << "Local Predictor Subthreshold Leakage = " //<< L1_localBPT->rt_power.readOp.leakage << " W" << endl; - // cout << indent_str_next << "Local Predictor Gate Leakage = " - //<< - // L1_localBPT->rt_power.readOp.gate_leakage << " W" << endl; + // cout << indent_str_next << "Local Predictor Gate Leakage = " << + //L1_localBPT->rt_power.readOp.gate_leakage << " W" << endl; // cout << indent_str_next << "Chooser Peak Dynamic = " << - // chooser->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Chooser Subthreshold Leakage = " - //<< - // chooser->rt_power.readOp.leakage << " W" << endl; + //chooser->rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout << indent_str_next << "Chooser Subthreshold Leakage = " << + //chooser->rt_power.readOp.leakage << " W" << endl; // cout << indent_str_next << "Chooser Gate Leakage = " << - // chooser->rt_power.readOp.gate_leakage << " W" << endl; + //chooser->rt_power.readOp.gate_leakage << " W" << endl; // cout << indent_str_next << "RAS Peak Dynamic = " << - // RAS->rt_power.readOp.dynamic*clockRate << " W" << endl; + //RAS->rt_power.readOp.dynamic*clockRate << " W" << endl; // cout << indent_str_next << "RAS Subthreshold Leakage = " << - // RAS->rt_power.readOp.leakage << " W" << endl; + //RAS->rt_power.readOp.leakage << " W" << endl; // cout << indent_str_next << "RAS Gate Leakage = " << - // RAS->rt_power.readOp.gate_leakage << " W" << endl; + //RAS->rt_power.readOp.gate_leakage << " W" << endl; } } @@ -3609,48 +3593,30 @@ void InstFetchU::displayEnergy(uint32_t indent, int plevel, bool is_tdp) { << " W" << endl; cout << endl; } else { - // cout << indent_str_next << "Instruction Cache Peak Dynamic = - //" - //<< - // icache.rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Instruction Cache Subthreshold - // Leakage + // cout << indent_str_next << "Instruction Cache Peak Dynamic = " << + //icache.rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout << indent_str_next << "Instruction Cache Subthreshold Leakage //= " << icache.rt_power.readOp.leakage <<" W" << endl; - // cout << indent_str_next << "Instruction Cache Gate Leakage = - //" - //<< - // icache.rt_power.readOp.gate_leakage << " W" << endl; - // cout << indent_str_next << "Instruction Buffer Peak Dynamic = - //" - //<< - // IB->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Instruction Buffer Subthreshold - // Leakage + // cout << indent_str_next << "Instruction Cache Gate Leakage = " << + //icache.rt_power.readOp.gate_leakage << " W" << endl; + // cout << indent_str_next << "Instruction Buffer Peak Dynamic = " << + //IB->rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout << indent_str_next << "Instruction Buffer Subthreshold Leakage //= " << IB->rt_power.readOp.leakage << " W" << endl; - // cout << indent_str_next << "Instruction Buffer Gate Leakage = - //" - //<< - // IB->rt_power.readOp.gate_leakage << " W" << endl; - // cout << indent_str_next << "Branch Target Buffer Peak Dynamic = - //" - //<< - // BTB->rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout << indent_str_next << "Instruction Buffer Gate Leakage = " << + //IB->rt_power.readOp.gate_leakage << " W" << endl; + // cout << indent_str_next << "Branch Target Buffer Peak Dynamic = " << + //BTB->rt_power.readOp.dynamic*clockRate << " W" << endl; // cout << indent_str_next << "Branch Target Buffer Subthreshold - // Leakage = " << BTB->rt_power.readOp.leakage << " W" << endl; - // cout << indent_str_next << "Branch Target Buffer Gate Leakage = - //" - //<< - // BTB->rt_power.readOp.gate_leakage << " W" << endl; - // cout << indent_str_next << "Branch Predictor Peak Dynamic = " - //<< - // BPT->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Branch Predictor Subthreshold - //Leakage - //= + //Leakage = " << BTB->rt_power.readOp.leakage << " W" << endl; + // cout << indent_str_next << "Branch Target Buffer Gate Leakage = " << + //BTB->rt_power.readOp.gate_leakage << " W" << endl; + // cout << indent_str_next << "Branch Predictor Peak Dynamic = " << + //BPT->rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout << indent_str_next << "Branch Predictor Subthreshold Leakage = //" << BPT->rt_power.readOp.leakage << " W" << endl; - // cout << indent_str_next << "Branch Predictor Gate Leakage = " - //<< - // BPT->rt_power.readOp.gate_leakage << " W" << endl; + // cout << indent_str_next << "Branch Predictor Gate Leakage = " << + //BPT->rt_power.readOp.gate_leakage << " W" << endl; } } @@ -4248,12 +4214,11 @@ void SchedulerU::computeEnergy(bool is_tdp) { if (!exist) return; double ROB_duty_cycle; // ROB_duty_cycle = ((coredynp.ALU_duty_cycle + - // coredynp.num_muls>0?coredynp.MUL_duty_cycle:0 - // + coredynp.num_fpus>0?coredynp.FPU_duty_cycle:0))*1.1<1 - //? + //coredynp.num_muls>0?coredynp.MUL_duty_cycle:0 + // + coredynp.num_fpus>0?coredynp.FPU_duty_cycle:0))*1.1<1 ? //(coredynp.ALU_duty_cycle + coredynp.num_muls>0?coredynp.MUL_duty_cycle:0 // + - // coredynp.num_fpus>0?coredynp.FPU_duty_cycle:0)*1.1:1; + //coredynp.num_fpus>0?coredynp.FPU_duty_cycle:0)*1.1:1; ROB_duty_cycle = 1; // init stats if (is_tdp) { @@ -4427,7 +4392,7 @@ void SchedulerU::computeEnergy(bool is_tdp) { } else if (coredynp.multithreaded) { // set_pppm(pppm_t, - // XML->sys.core[ithCore].issue_width,1, 1, 1); + //XML->sys.core[ithCore].issue_width,1, 1, 1); int_inst_window->power = int_inst_window->power_t + (int_inst_window->local_result.power + instruction_selection->power) * @@ -4454,7 +4419,7 @@ void SchedulerU::computeEnergy(bool is_tdp) { } else if (coredynp.multithreaded) { // set_pppm(pppm_t, - // XML->sys.core[ithCore].issue_width,1, 1, 1); + //XML->sys.core[ithCore].issue_width,1, 1, 1); int_inst_window->rt_power = int_inst_window->power_t + (int_inst_window->local_result.power + instruction_selection->power) * @@ -4464,9 +4429,9 @@ void SchedulerU::computeEnergy(bool is_tdp) { } // set_pppm(pppm_t, XML->sys.core[ithCore].issue_width,1, 1, 1); // cout<<"Scheduler - // power="<power.readOp.dynamic<<"leakage"<power.readOp.leakage<power_t.readOp.dynamic += - // LSQ->stats_t.readAc.access*(LSQ->local_result.power.searchOp.dynamic + - // LSQ->local_result.power.readOp.dynamic) + //LSQ->stats_t.readAc.access*(LSQ->local_result.power.searchOp.dynamic + + //LSQ->local_result.power.readOp.dynamic) // + - // LSQ->stats_t.writeAc.access*LSQ->local_result.power.writeOp.dynamic;//every - // memory access invloves at least two operations on LSQ + //LSQ->stats_t.writeAc.access*LSQ->local_result.power.writeOp.dynamic;//every + //memory access invloves at least two operations on LSQ // No LSQ in GPUs (Syed) } @@ -5979,7 +5944,7 @@ void EXECU::displayEnergy(uint32_t indent, int plevel, bool is_tdp) { 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; + //bypass->area.get_area() *1e-6 << " mm^2" << endl; if (is_tdp) { cout << indent_str << "Register Files:" << endl; cout << indent_str_next << "Area = " << rfu->area.get_area() * 1e-6 @@ -6186,15 +6151,15 @@ void Core::computeEnergy(bool is_tdp) { coredynp.num_pipelines / num_units, coredynp.num_pipelines / num_units); // cout << "IFU = " << - // ifu->power.readOp.dynamic*clockRate << " W" << endl; + //ifu->power.readOp.dynamic*clockRate << " W" << endl; ifu->power = ifu->power + corepipe->power * pppm_t; // cout << "IFU = " << - // ifu->power.readOp.dynamic*clockRate << " W" << endl; + //ifu->power.readOp.dynamic*clockRate << " W" << endl; // cout << "1/4 pipe = " << - // corepipe->power.readOp.dynamic*clockRate/num_units << " W" << endl; + //corepipe->power.readOp.dynamic*clockRate/num_units << " W" << endl; power = power + ifu->power; // cout << "core = " << - // power.readOp.dynamic*clockRate << " W" << endl; + //power.readOp.dynamic*clockRate << " W" << endl; } if (lsu->exist) { Pipeline_energy += @@ -6207,10 +6172,10 @@ void Core::computeEnergy(bool is_tdp) { coredynp.num_pipelines / num_units); lsu->power = lsu->power + corepipe->power * pppm_t; // cout << "LSU = " << - // lsu->power.readOp.dynamic*clockRate << " W" << endl; + //lsu->power.readOp.dynamic*clockRate << " W" << endl; power = power + lsu->power; // cout << "core = " << - // power.readOp.dynamic*clockRate << " W" << endl; + //power.readOp.dynamic*clockRate << " W" << endl; } if (exu->exist) { Pipeline_energy += @@ -6224,10 +6189,10 @@ void Core::computeEnergy(bool is_tdp) { // cout<<"ExPowerScalingFactor:"<power = exu->power + corepipe->power * pppm_t; // cout << "EXE = " << - // exu->power.readOp.dynamic*clockRate << " W" << endl; + //exu->power.readOp.dynamic*clockRate << " W" << endl; power = power + exu->power; // cout << "core = " << - // power.readOp.dynamic*clockRate << " W" << endl; + //power.readOp.dynamic*clockRate << " W" << endl; } if (mmu->exist) { Pipeline_energy += @@ -6240,10 +6205,10 @@ void Core::computeEnergy(bool is_tdp) { coredynp.num_pipelines / num_units); mmu->power = mmu->power + corepipe->power * pppm_t; // cout << "MMU = " << - // mmu->power.readOp.dynamic*clockRate << " W" << endl; + //mmu->power.readOp.dynamic*clockRate << " W" << endl; power = power + mmu->power; // cout << "core = " << - // power.readOp.dynamic*clockRate << " W" << endl; + //power.readOp.dynamic*clockRate << " W" << endl; } power = power + undiffCore->power; @@ -6311,9 +6276,8 @@ void Core::computeEnergy(bool is_tdp) { } rt_power = rt_power + undiffCore->power; - // cout << "EXE = " << exu->power.readOp.dynamic*clockRate << " W" - //<< - // endl; + // cout << "EXE = " << exu->power.readOp.dynamic*clockRate << " W" << + //endl; if (XML->sys.Private_L2) { l2cache->computeEnergy(is_tdp); // set_pppm(pppm_t,1/l2cache->cachep.executionTime, 1,1,1); @@ -6472,28 +6436,22 @@ void Core::displayEnergy(uint32_t indent, int plevel, bool is_tdp) { // if (undiffCore->exist) // { // cout << indent_str << "Undifferentiated Core" << - // endl; + //endl; // cout << indent_str_next << "Area = " << - // undiffCore->area.get_area()*1e-6<< " mm^2" << endl; + //undiffCore->area.get_area()*1e-6<< " mm^2" << endl; // cout << indent_str_next << "Peak Dynamic = " << - // undiffCore->power.readOp.dynamic*clockRate << " W" << endl; - //// cout << indent_str_next << "Subthreshold Leakage = - ///" - ///<< - /// undiffCore->power.readOp.leakage <<" W" << endl; - // cout << indent_str_next << "Subthreshold Leakage - //= + //undiffCore->power.readOp.dynamic*clockRate << " W" << endl; + //// cout << indent_str_next << "Subthreshold Leakage = " << + ///undiffCore->power.readOp.leakage <<" W" << endl; + // cout << indent_str_next << "Subthreshold Leakage = //" - // << - //(long_channel? - // undiffCore->power.readOp.longer_channel_leakage:undiffCore->power.readOp.leakage) + // << (long_channel? + //undiffCore->power.readOp.longer_channel_leakage:undiffCore->power.readOp.leakage) //<< " W" << endl; // cout << indent_str_next << "Gate Leakage = " << - // undiffCore->power.readOp.gate_leakage << " W" << endl; - // // cout << indent_str_next << "Runtime Dynamic = - //" - //<< - // undiffCore->rt_power.readOp.dynamic/executionTime << " W" << endl; + //undiffCore->power.readOp.gate_leakage << " W" << endl; + // // cout << indent_str_next << "Runtime Dynamic = " << + //undiffCore->rt_power.readOp.dynamic/executionTime << " W" << endl; // cout <rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout << indent_str_next << "Execution Unit Subthreshold Leakage = " //<< exu->rt_power.readOp.leakage << " W" << endl; // cout << indent_str_next << "Execution Unit Gate Leakage = " << - // exu->rt_power.readOp.gate_leakage << " W" << endl; + //exu->rt_power.readOp.gate_leakage << " W" << endl; } } InstFetchU::~InstFetchU() { @@ -6867,9 +6811,8 @@ void Core::set_core_param() { } // if (coredynp.core_ty==OOO) // { - // cout<<"OOO processor models are being updated and will be - // available - // in next release"<sys.niu.total_load_perc; niup.type = XML->sys.niu.type; // niup.executionTime = - // XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); + //XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); } PCIeController::PCIeController(ParseXML* XML_interface, @@ -276,7 +276,7 @@ PCIeController::PCIeController(ParseXML* XML_interface, 1.1 * (interface_ip.F_sz_nm / 65.0); // //Cadence ChipEstimate using 65nm soft IP; // frontend_dyn = - // 0.27e-9/8*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0); + //0.27e-9/8*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0); // SerDer_dyn is power not energy, scaling from 10mw/Gb/s @90nm SerDer_dyn = 0.01 * 4 * (interface_ip.F_sz_um / 0.09) * g_tp.peri_global.Vdd / 1.2 * g_tp.peri_global.Vdd / @@ -305,7 +305,7 @@ PCIeController::PCIeController(ParseXML* XML_interface, 1.1 * (interface_ip.F_sz_nm / 65.0); // //Cadence ChipEstimate using 65nm soft IP; // frontend_dyn = - // 0.27e-9/8*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0); + //0.27e-9/8*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0); // SerDer_dyn is power not energy, scaling from 10mw/Gb/s @90nm SerDer_dyn = 0.01 * 4 * (interface_ip.F_sz_um / 0.09) * g_tp.peri_global.Vdd / 1.2 * g_tp.peri_global.Vdd / @@ -387,7 +387,7 @@ void PCIeController::set_pcie_param() { pciep.type = XML->sys.pcie.type; pciep.withPHY = XML->sys.pcie.withPHY; // pciep.executionTime = - // XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); + //XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); } FlashController::FlashController(ParseXML* XML_interface, @@ -507,5 +507,5 @@ void FlashController::set_fc_param() { fcp.type = XML->sys.flashc.type; fcp.withPHY = XML->sys.flashc.withPHY; // flashcp.executionTime = - // XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); + //XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); } diff --git a/src/gpuwattch/logic.cc b/src/gpuwattch/logic.cc index d6937ca..65e3875 100644 --- a/src/gpuwattch/logic.cc +++ b/src/gpuwattch/logic.cc @@ -362,8 +362,8 @@ void Pipeline::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 + //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 + @@ -578,8 +578,8 @@ FunctionalUnit::FunctionalUnit(ParseXML *XML_interface, int ithCore_, // 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) + //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; @@ -615,8 +615,8 @@ FunctionalUnit::FunctionalUnit(ParseXML *XML_interface, int ithCore_, 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) + //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; @@ -645,8 +645,8 @@ FunctionalUnit::FunctionalUnit(ParseXML *XML_interface, int ithCore_, 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) + //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; @@ -666,7 +666,7 @@ FunctionalUnit::FunctionalUnit(ParseXML *XML_interface, int ithCore_, } per_access_energy *= 0.5; // According to ARM data embedded processor has // much lower per acc energy - } /* if (XML->sys.Embedded) */ + } /* if (XML->sys.Embedded) */ else { if (fu_type == FPU) { num_fu = coredynp.num_fpus; @@ -705,14 +705,16 @@ FunctionalUnit::FunctionalUnit(ParseXML *XML_interface, int ithCore_, 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 + 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 = @@ -936,7 +938,7 @@ void FunctionalUnit::displayEnergy(uint32_t indent, int plevel, bool is_tdp) { 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; + //bypass->area.get_area() *1e-6 << " mm^2" << endl; if (is_tdp) { if (fu_type == FPU) { cout << indent_str @@ -1167,11 +1169,10 @@ UndiffCore::UndiffCore(ParseXML *XML_interface, int ithCore_, // 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; + //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; @@ -1180,16 +1181,15 @@ UndiffCore::UndiffCore(ParseXML *XML_interface, int ithCore_, // 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.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<local_result.area * XML->sys.mc.memory_channels_per_mc); //***ThreadMasks storage (coalesced threads whose memory requests are - // satisfied by each memory access) + //satisfied by each memory access) /* contents of the thread masks Array * 16-bit bit masks for up to 16 memory requests of a warp | Number of * pending memory requests (5 bits) @@ -983,7 +983,7 @@ MemoryController::MemoryController(ParseXML* XML_interface, area.set_area(area.get_area() + PHY->area.get_area()); } //+++++++++Transaction engine +++++++++++++++++ ////TODO needs better numbers, - // Run the RTL code from OpenSparc. + //Run the RTL code from OpenSparc. // transecEngine.initialize(&interface_ip); // transecEngine.peakDataTransferRate = XML->sys.mem.peak_transfer_rate; // transecEngine.memDataWidth = dataBusWidth; @@ -1023,7 +1023,7 @@ MemoryController::MemoryController(ParseXML* XML_interface, //// //clock //// clockNetwork.init_wire_external(is_default, &interface_ip); //// clockNetwork.clk_area =area*1.1;//10% of placement overhead. - /// rule of thumb + ///rule of thumb //// clockNetwork.end_wiring_level =5;//toplevel metal //// clockNetwork.start_wiring_level =5;//toplevel metal //// clockNetwork.num_regs = pipeLogic.tot_stage_vector; @@ -1199,7 +1199,7 @@ void MemoryController::set_mc_param() { mcp.reads = XML->sys.mc.memory_reads; mcp.writes = XML->sys.mc.memory_writes; //+++++++++Transaction engine +++++++++++++++++ ////TODO needs better - // numbers, Run the RTL code from OpenSparc. + //numbers, Run the RTL code from OpenSparc. mcp.peakDataTransferRate = XML->sys.mc.peak_transfer_rate; mcp.memRank = XML->sys.mc.number_ranks; //++++++++++++++PHY ++++++++++++++++++++++++++ //TODO needs better numbers @@ -1214,17 +1214,16 @@ void MemoryController::set_mc_param() { // else if (mc_type==FLASHC) // { // mcp.clockRate =XML->sys.flashc.mc_clock*2;//DDR double - // pumped + //pumped // mcp.clockRate *= 1e6; // mcp.executionTime = - // XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); + //XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); // // mcp.llcBlockSize //=int(ceil(XML->sys.flashc.llc_line_length/8.0))+XML->sys.flashc.llc_line_length;//ecc - // overhead - // mcp.dataBusWidth =int(ceil(XML->sys.flashc.databus_width/8.0)) - //+ - // XML->sys.flashc.databus_width; + //overhead + // mcp.dataBusWidth =int(ceil(XML->sys.flashc.databus_width/8.0)) + + //XML->sys.flashc.databus_width; // mcp.addressBusWidth //=int(ceil(XML->sys.flashc.addressbus_width));//XML->sys.physical_address_width; // mcp.opcodeW =16; @@ -1233,18 +1232,16 @@ void MemoryController::set_mc_param() { // mcp.reads = XML->sys.flashc.memory_reads; // mcp.writes = XML->sys.flashc.memory_writes; // //+++++++++Transaction engine +++++++++++++++++ ////TODO needs - // better numbers, Run the RTL code from OpenSparc. + //better numbers, Run the RTL code from OpenSparc. // mcp.peakDataTransferRate = XML->sys.flashc.peak_transfer_rate; // mcp.memRank = XML->sys.flashc.number_ranks; - // //++++++++++++++PHY ++++++++++++++++++++++++++ //TODO needs - // better - // numbers + // //++++++++++++++PHY ++++++++++++++++++++++++++ //TODO needs better + //numbers // //PHY.memAccesses=PHY.peakDataTransferRate;//this is the max - // power + //power // //PHY.llcBlocksize=llcBlockSize; - // mcp.frontend_duty_cycle = 0.5;//for max power, the actual - // off-chip - // links is bidirectional but time shared + // mcp.frontend_duty_cycle = 0.5;//for max power, the actual off-chip + //links is bidirectional but time shared // mcp.LVDS = XML->sys.flashc.LVDS; // mcp.type = XML->sys.flashc.type; // } diff --git a/src/gpuwattch/noc.cc b/src/gpuwattch/noc.cc index 85fc0a9..bf8d8b5 100644 --- a/src/gpuwattch/noc.cc +++ b/src/gpuwattch/noc.cc @@ -357,44 +357,30 @@ void NoC::displayEnergy(uint32_t indent, int plevel, bool is_tdp) { cout << endl; } } else { - // cout << indent_str_next << "Instruction Fetch Unit Peak Dynamic - //= - //" + // cout << indent_str_next << "Instruction Fetch Unit Peak Dynamic = " //<< ifu->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Instruction Fetch Unit Subthreshold - // Leakage = " << ifu->rt_power.readOp.leakage <<" W" << endl; - // cout << indent_str_next << "Instruction Fetch Unit Gate Leakage - //= - //" + // cout << indent_str_next << "Instruction Fetch Unit Subthreshold + //Leakage = " << ifu->rt_power.readOp.leakage <<" W" << endl; + // cout << indent_str_next << "Instruction Fetch Unit Gate Leakage = " //<< ifu->rt_power.readOp.gate_leakage << " W" << endl; - // cout << indent_str_next << "Load Store Unit Peak Dynamic = " - //<< - // lsu->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Load Store Unit Subthreshold Leakage - //= - //" + // cout << indent_str_next << "Load Store Unit Peak Dynamic = " << + //lsu->rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout << indent_str_next << "Load Store Unit Subthreshold Leakage = " //<< lsu->rt_power.readOp.leakage << " W" << endl; - // cout << indent_str_next << "Load Store Unit Gate Leakage = " - //<< - // lsu->rt_power.readOp.gate_leakage << " W" << endl; - // cout << indent_str_next << "Memory Management Unit Peak Dynamic - //= - //" + // cout << indent_str_next << "Load Store Unit Gate Leakage = " << + //lsu->rt_power.readOp.gate_leakage << " W" << endl; + // cout << indent_str_next << "Memory Management Unit Peak Dynamic = " //<< mmu->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Memory Management Unit Subthreshold - // Leakage = " << mmu->rt_power.readOp.leakage << " W" << endl; - // cout << indent_str_next << "Memory Management Unit Gate Leakage - //= - //" + // cout << indent_str_next << "Memory Management Unit Subthreshold + //Leakage = " << mmu->rt_power.readOp.leakage << " W" << endl; + // cout << indent_str_next << "Memory Management Unit Gate Leakage = " //<< mmu->rt_power.readOp.gate_leakage << " W" << endl; // cout << indent_str_next << "Execution Unit Peak Dynamic = " << - // exu->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Execution Unit Subthreshold Leakage - //= - //" + //exu->rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout << indent_str_next << "Execution Unit Subthreshold Leakage = " //<< exu->rt_power.readOp.leakage << " W" << endl; // cout << indent_str_next << "Execution Unit Gate Leakage = " << - // exu->rt_power.readOp.gate_leakage << " W" << endl; + //exu->rt_power.readOp.gate_leakage << " W" << endl; } } diff --git a/src/gpuwattch/processor.cc b/src/gpuwattch/processor.cc index b5b5cfb..96c3351 100644 --- a/src/gpuwattch/processor.cc +++ b/src/gpuwattch/processor.cc @@ -1084,8 +1084,7 @@ void Processor::set_proc_param() { // if (procdynp.numCore<1) // { - // cout<<" The target processor should at least have one core on - // chip." + // cout<<" The target processor should at least have one core on chip." //<unicache.caches->local_result.tag_array2->power.writeOp .dynamic; //*(32/4); // removed by Jingwen, the scaling - // of 32/4 is not used in the mcpat + //of 32/4 is not used in the mcpat read_coef += l2array[0]->unicache.caches->local_result.power.writeOp.dynamic; read_coef += diff --git a/src/gpuwattch/sharedcache.cc b/src/gpuwattch/sharedcache.cc index d25d1df..147be43 100644 --- a/src/gpuwattch/sharedcache.cc +++ b/src/gpuwattch/sharedcache.cc @@ -1106,25 +1106,24 @@ void SharedCache::displayEnergy(uint32_t indent, bool is_tdp) { // ///cout<<"directory.maxPower=" <sys.first_level_dir==1) // { // inv_dir.maxPower = -// inv_dir.caches.local_result.power.searchOp.dynamic*clockRate*XML->sys.domain_size; +//inv_dir.caches.local_result.power.searchOp.dynamic*clockRate*XML->sys.domain_size; // cc.power.readOp.dynamic = -// inv_dir.maxPower*scktRatio*64/XML->sys.domain_size; +//inv_dir.maxPower*scktRatio*64/XML->sys.domain_size; // cc.power.readOp.leakage = -// inv_dir.caches.local_result.power.readOp.leakage*inv_dir.caches.l_ip.nbanks*64/XML->sys.domain_size; +//inv_dir.caches.local_result.power.readOp.leakage*inv_dir.caches.l_ip.nbanks*64/XML->sys.domain_size; // // cc.area.set_area(inv_dir.area*64/XML->sys.domain_size); // cout<<"CC area="< @@ -515,10 +515,10 @@ typedef struct XMLDLLENTRY XMLNode { XMLElementPosition pos = -1); ///< Add a new child node XMLNode addChild(XMLNode nodeToAdd, XMLElementPosition pos = -1); ///< If the "nodeToAdd" has - /// some parents, it will be - /// detached from it's parents - /// before being attached to - /// the current XMLNode + ///some parents, it will be + ///detached from it's parents + ///before being attached to + ///the current XMLNode XMLAttribute *addAttribute(XMLCSTR lpszName, XMLCSTR lpszValuev); ///< Add a new attribute XMLCSTR addText(XMLCSTR lpszValue, @@ -539,41 +539,41 @@ typedef struct XMLDLLENTRY XMLNode { XMLCSTR updateName(XMLCSTR lpszName); ///< change node's name XMLAttribute *updateAttribute(XMLAttribute *newAttribute, XMLAttribute *oldAttribute); ///< if the - /// attribute to - /// update is - /// missing, a new - /// one will be - /// added + ///attribute to + ///update is + ///missing, a new + ///one will be + ///added XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName = NULL, int i = 0); ///< if the attribute to update is - /// missing, a new one will be added + ///missing, a new one will be added XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName, XMLCSTR lpszOldName); ///< set lpszNewName=NULL - /// if you don't want to - /// change the name of the - /// attribute if the - /// attribute to update is - /// missing, a new one - /// will be added + ///if you don't want to + ///change the name of the + ///attribute if the + ///attribute to update is + ///missing, a new one + ///will be added XMLCSTR updateText(XMLCSTR lpszNewValue, int i = 0); ///< if the text to - /// update is missing, a - /// new one will be added + ///update is missing, a + ///new one will be added XMLCSTR updateText(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the text to update is - /// missing, a new one will be added + ///missing, a new one will be added XMLClear *updateClear(XMLCSTR lpszNewContent, int i = 0); ///< if the clearTag to update is missing, - /// a new one will be added + ///a new one will be added XMLClear *updateClear(XMLClear *newP, XMLClear *oldP); ///< if the clearTag - /// to update is - /// missing, a new one - /// will be added + ///to update is + ///missing, a new one + ///will be added XMLClear *updateClear(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the clearTag to update - /// is missing, a new one will be - /// added - /** @} */ + ///is missing, a new one will be + ///added + /** @} */ /** @defgroup xmlDelete Deleting Nodes or Attributes * @ingroup xmlModify @@ -589,33 +589,33 @@ typedef struct XMLDLLENTRY XMLNode { void deleteAttribute( int i = 0); ///< Delete the ith attribute of the current XMLNode void deleteAttribute(XMLCSTR lpszName); ///< Delete the attribute with the - /// given name (the "strcmp" function - /// is used to find the right - /// attribute) + ///given name (the "strcmp" function + ///is used to find the right + ///attribute) void deleteAttribute(XMLAttribute *anAttribute); ///< Delete the attribute - /// with the name - ///"anAttribute->lpszName" - ///(the "strcmp" function is - /// used to find the right - /// attribute) + ///with the name + ///"anAttribute->lpszName" + ///(the "strcmp" function is + ///used to find the right + ///attribute) void deleteText( int i = 0); ///< Delete the Ith text content of the current XMLNode void deleteText(XMLCSTR lpszValue); ///< Delete the text content "lpszValue" - /// inside the current XMLNode (direct - ///"pointer-to-pointer" comparison is - /// used to find the right text) + ///inside the current XMLNode (direct + ///"pointer-to-pointer" comparison is + ///used to find the right text) void deleteClear( int i = 0); ///< Delete the Ith clear tag inside the current XMLNode void deleteClear(XMLCSTR lpszValue); ///< Delete the clear tag "lpszValue" - /// inside the current XMLNode (direct - ///"pointer-to-pointer" comparison is - /// used to find the clear tag) - void deleteClear(XMLClear *p); ///< Delete the clear tag "p" inside the - /// current XMLNode (direct + ///inside the current XMLNode (direct + ///"pointer-to-pointer" comparison is + ///used to find the clear tag) + void deleteClear(XMLClear *p); ///< Delete the clear tag "p" inside the + ///current XMLNode (direct ///"pointer-to-pointer" comparison on the - /// lpszName of the clear tag is used to find - /// the clear tag) - /** @} */ + ///lpszName of the clear tag is used to find + ///the clear tag) + /** @} */ /** @defgroup xmlWOSD ???_WOSD functions. * @ingroup xmlModify @@ -666,49 +666,49 @@ typedef struct XMLDLLENTRY XMLNode { XMLCSTR updateName_WOSD(XMLSTR lpszName); ///< change node's name XMLAttribute *updateAttribute_WOSD(XMLAttribute *newAttribute, XMLAttribute *oldAttribute); ///< if the - /// attribute - /// to update - /// is - /// missing, a - /// new one - /// will be - /// added + ///attribute + ///to update + ///is + ///missing, a + ///new one + ///will be + ///added XMLAttribute *updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName = NULL, int i = 0); ///< if the attribute to - /// update is missing, a new - /// one will be added + ///update is missing, a new + ///one will be added XMLAttribute *updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName, XMLCSTR lpszOldName); ///< set - /// lpszNewName=NULL - /// if you don't want - /// to change the - /// name of the - /// attribute if the - /// attribute to - /// update is - /// missing, a new - /// one will be added + ///lpszNewName=NULL + ///if you don't want + ///to change the + ///name of the + ///attribute if the + ///attribute to + ///update is + ///missing, a new + ///one will be added XMLCSTR updateText_WOSD(XMLSTR lpszNewValue, int i = 0); ///< if the text to - /// update is - /// missing, a new - /// one will be added + ///update is + ///missing, a new + ///one will be added XMLCSTR updateText_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the text to update is - /// missing, a new one will be - /// added + ///missing, a new one will be + ///added XMLClear *updateClear_WOSD(XMLSTR lpszNewContent, int i = 0); ///< if the clearTag to update is - /// missing, a new one will be added + ///missing, a new one will be added XMLClear *updateClear_WOSD(XMLClear *newP, XMLClear *oldP); ///< if the clearTag to update is - /// missing, a new one will be - /// added + ///missing, a new one will be + ///added XMLClear *updateClear_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the clearTag to - /// update is missing, a new - /// one will be added - /** @} */ + ///update is missing, a new + ///one will be added + /** @} */ /** @defgroup xmlPosition Position helper functions (use in conjunction with * the update&add functions @@ -729,7 +729,7 @@ typedef struct XMLDLLENTRY XMLNode { XMLElementPosition positionOfChildNode(XMLNode x) const; XMLElementPosition positionOfChildNode(XMLCSTR name, int i = 0) const; ///< return the position of the ith childNode with the specified - /// name if (name==NULL) return the position of the ith childNode + ///name if (name==NULL) return the position of the ith childNode /** @} */ /// Enumeration for XML character encoding. @@ -970,11 +970,11 @@ typedef struct XMLDLLENTRY ToXMLStringTool { ToXMLStringTool() : buf(NULL), buflen(0) {} ~ToXMLStringTool(); void freeBuffer(); /// Date: Fri, 13 Sep 2019 07:48:05 -0400 Subject: Revert "add /src/gpuwattch formatting" This reverts commit b7776785a18d3f4e6229cd625f92c11b55894b75. --- src/gpuwattch/XML_Parse.cc | 6554 ++++++------------ src/gpuwattch/XML_Parse.h | 1195 ++-- src/gpuwattch/arch_const.h | 359 +- src/gpuwattch/array.cc | 463 +- src/gpuwattch/array.h | 87 +- src/gpuwattch/basic_components.cc | 142 +- src/gpuwattch/basic_components.h | 486 +- src/gpuwattch/core.cc | 11772 ++++++++++++++------------------ src/gpuwattch/core.h | 926 ++- src/gpuwattch/globalvar.h | 7 +- src/gpuwattch/gpgpu_sim_wrapper.cc | 1432 ++-- src/gpuwattch/gpgpu_sim_wrapper.h | 234 +- src/gpuwattch/interconnect.cc | 201 +- src/gpuwattch/interconnect.h | 109 +- src/gpuwattch/iocontrollers.cc | 800 +-- src/gpuwattch/iocontrollers.h | 68 +- src/gpuwattch/logic.cc | 2221 +++--- src/gpuwattch/logic.h | 348 +- src/gpuwattch/main.cc | 104 +- src/gpuwattch/memoryctrl.cc | 1970 +++--- src/gpuwattch/memoryctrl.h | 156 +- src/gpuwattch/noc.cc | 706 +- src/gpuwattch/noc.h | 72 +- src/gpuwattch/processor.cc | 2033 +++--- src/gpuwattch/processor.h | 511 +- src/gpuwattch/sharedcache.cc | 1697 ++--- src/gpuwattch/sharedcache.h | 83 +- src/gpuwattch/technology_xeon_core.cc | 3360 +++++---- src/gpuwattch/version.h | 6 +- src/gpuwattch/xmlParser.cc | 5377 +++++++-------- src/gpuwattch/xmlParser.h | 1443 ++-- 31 files changed, 19279 insertions(+), 25643 deletions(-) (limited to 'src/gpuwattch/processor.cc') diff --git a/src/gpuwattch/XML_Parse.cc b/src/gpuwattch/XML_Parse.cc index 26115d3..39bf2a1 100644 --- a/src/gpuwattch/XML_Parse.cc +++ b/src/gpuwattch/XML_Parse.cc @@ -29,4558 +29,2102 @@ * ***************************************************************************/ /******************************************************************** -* Modified by: -** +* 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 "XML_Parse.h" #include -#include #include "xmlParser.h" +#include +#include "XML_Parse.h" using namespace std; -const char* perf_count_label[] = { - "TOT_INST,", "FP_INT,", "IC_H,", "IC_M,", "DC_RH,", - "DC_RM,", "DC_WH,", "DC_WM,", "TC_H,", "TC_M,", - "CC_H,", "CC_M,", "SHRD_ACC,", "REG_RD,", "REG_WR,", - "NON_REG_OPs,", "SP_ACC,", "SFU_ACC,", "FPU_ACC,", "MEM_RD,", - "MEM_WR,", "MEM_PRE,", "L2_RH,", "L2_RM,", "L2_WH,", - "L2_WM,", "NOC_A,", "PIPE_A,", "IDLE_CORE_N,", "CONST_DYNAMICN"}; +const char * perf_count_label[] = {"TOT_INST,", "FP_INT,", "IC_H,", "IC_M,", "DC_RH,", "DC_RM,", "DC_WH,", "DC_WM,", + "TC_H,", "TC_M,", "CC_H,", "CC_M,", "SHRD_ACC,", "REG_RD,", "REG_WR,", "NON_REG_OPs,", + "SP_ACC,", "SFU_ACC,", "FPU_ACC,", "MEM_RD,","MEM_WR,", "MEM_PRE,", "L2_RH,", "L2_RM,", "L2_WH,", + "L2_WM,", "NOC_A,", "PIPE_A,", "IDLE_CORE_N,", "CONST_DYNAMICN"}; + +void ParseXML::parse(char* filepath) +{ + unsigned int i,j,k,m,n; + unsigned int NumofCom_4; + unsigned int itmp; + //Initialize all structures + ParseXML::initialize(); + string strtmp; + char chtmp[60]; + char chtmp1[60]; + chtmp1[0]='\0'; + // this open and parse the XML file: + XMLNode xMainNode=XMLNode::openFileHelper(filepath,"component"); //the 'component' in the first layer + + XMLNode xNode2=xMainNode.getChildNode("component"); // the 'component' in the second layer + //get all params in the second layer + itmp=xNode2.nChildNode("param"); + for(i=0; iOrderofComponents_3layer) + { + //___________________________get all system.core0-n________________________________________________ + if (sys.homogeneous_cores==1) OrderofComponents_3layer=0; + else OrderofComponents_3layer=sys.number_of_cores-1; + for (i=0; i<=OrderofComponents_3layer; i++) + { + xNode3=xNode2.getChildNode("component",i); + if (xNode3.isEmpty()==1) { + printf("The value of homogeneous_cores or number_of_cores is not correct!"); + exit(0); + } + else{ + if (strstr(xNode3.getAttribute("name"),"core")!=NULL) + { + { //For cpu0-cpui + //Get all params with system.core? + itmp=xNode3.nChildNode("param"); + for(k=0; k OrderofComponents_3layer) { - //___________________________get all - //system.core0-n________________________________________________ - if (sys.homogeneous_cores == 1) - OrderofComponents_3layer = 0; - else - OrderofComponents_3layer = sys.number_of_cores - 1; - for (i = 0; i <= OrderofComponents_3layer; i++) { - xNode3 = xNode2.getChildNode("component", i); - if (xNode3.isEmpty() == 1) { - printf( - "The value of homogeneous_cores or number_of_cores is not " - "correct!"); - exit(0); - } else { - if (strstr(xNode3.getAttribute("name"), "core") != NULL) { - { // For cpu0-cpui - // Get all params with system.core? - itmp = xNode3.nChildNode("param"); - for (k = 0; k < itmp; k++) { - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "clock_rate") == 0) { - sys.core[i].clock_rate = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "opt_local") == 0) { - sys.core[i].opt_local = (bool)atoi( - xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "x86") == 0) { - sys.core[i].x86 = (bool)atoi( - xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "machine_bits") == 0) { - sys.core[i].machine_bits = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "virtual_address_width") == 0) { - sys.core[i].virtual_address_width = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "physical_address_width") == 0) { - sys.core[i].physical_address_width = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "instruction_length") == 0) { - sys.core[i].instruction_length = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "opcode_width") == 0) { - sys.core[i].opcode_width = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "micro_opcode_width") == 0) { - sys.core[i].micro_opcode_width = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "machine_type") == 0) { - sys.core[i].machine_type = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "internal_datapath_width") == 0) { - sys.core[i].internal_datapath_width = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "number_hardware_threads") == 0) { - sys.core[i].number_hardware_threads = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "fetch_width") == 0) { - sys.core[i].fetch_width = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "number_instruction_fetch_ports") == 0) { - sys.core[i].number_instruction_fetch_ports = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "decode_width") == 0) { - sys.core[i].decode_width = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "issue_width") == 0) { - sys.core[i].issue_width = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "peak_issue_width") == 0) { - sys.core[i].peak_issue_width = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "commit_width") == 0) { - sys.core[i].commit_width = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "fp_issue_width") == 0) { - sys.core[i].fp_issue_width = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "prediction_width") == 0) { - sys.core[i].prediction_width = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } + if (strcmp(xNode4.getAttribute("name"),"dcache")==0) + {//find system.core0.dcache + itmp=xNode4.nChildNode("param"); + for(k=0; k0) OrderofComponents_3layer=OrderofComponents_3layer+1; + xNode3=xNode2.getChildNode("component",OrderofComponents_3layer); + if (xNode3.isEmpty()==1) { + printf("some value(s) of number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are not correct!"); + exit(0); + } + if (strstr(xNode3.getAttribute("id"),"system.mem")!=NULL) + { - for (i = 0; i < (OrderofComponents_3layer - tmpOrderofComponents_3layer); - i++) { - xNode3 = xNode2.getChildNode("component", w); - if (xNode3.isEmpty() == 1) { - printf("The value of homogeneous_L2s or number_of_L2s is not correct!"); - exit(0); - } else { - if (strstr(xNode3.getAttribute("name"), "L2") != NULL) { - { // For L20-L2i - // Get all params with system.L2? - itmp = xNode3.nChildNode("param"); - for (k = 0; k < itmp; k++) { - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "L2_config") == 0) { - strtmp.assign( - xNode3.getChildNode("param", k).getAttribute("value")); - m = 0; - for (n = 0; n < strtmp.length(); n++) { - if (strtmp[n] != ',') { - sprintf(chtmp, "%c", strtmp[n]); - strcat(chtmp1, chtmp); - } else { - sys.L2[i].L2_config[m] = atof(chtmp1); - m++; - chtmp1[0] = '\0'; - } - } - sys.L2[i].L2_config[m] = atof(chtmp1); - m++; - chtmp1[0] = '\0'; - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "clockrate") == 0) { - sys.L2[i].clockrate = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "merged_dir") == 0) { - sys.L2[i].merged_dir = (bool)atoi( - xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "ports") == 0) { - strtmp.assign( - xNode3.getChildNode("param", k).getAttribute("value")); - m = 0; - for (n = 0; n < strtmp.length(); n++) { - if (strtmp[n] != ',') { - sprintf(chtmp, "%c", strtmp[n]); - strcat(chtmp1, chtmp); - } else { - sys.L2[i].ports[m] = atoi(chtmp1); - m++; - chtmp1[0] = '\0'; - } - } - sys.L2[i].ports[m] = atoi(chtmp1); - m++; - chtmp1[0] = '\0'; - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "device_type") == 0) { - sys.L2[i].device_type = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "threeD_stack") == 0) { - strcpy(sys.L2[i].threeD_stack, - (xNode3.getChildNode("param", k).getAttribute("value"))); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "buffer_sizes") == 0) { - strtmp.assign( - xNode3.getChildNode("param", k).getAttribute("value")); - m = 0; - for (n = 0; n < strtmp.length(); n++) { - if (strtmp[n] != ',') { - sprintf(chtmp, "%c", strtmp[n]); - strcat(chtmp1, chtmp); - } else { - sys.L2[i].buffer_sizes[m] = atoi(chtmp1); - m++; - chtmp1[0] = '\0'; - } - } - sys.L2[i].buffer_sizes[m] = atoi(chtmp1); - m++; - chtmp1[0] = '\0'; - continue; - } - } - // Get all stats with system.L2? - itmp = xNode3.nChildNode("stat"); - for (k = 0; k < itmp; k++) { - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "total_accesses") == 0) { - sys.L2[i].total_accesses = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "read_accesses") == 0) { - sys.L2[i].read_accesses = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "write_accesses") == 0) { - sys.L2[i].write_accesses = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "total_hits") == 0) { - sys.L2[i].total_hits = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "total_misses") == 0) { - sys.L2[i].total_misses = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "read_hits") == 0) { - sys.L2[i].read_hits = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "write_hits") == 0) { - sys.L2[i].write_hits = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "read_misses") == 0) { - sys.L2[i].read_misses = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "write_misses") == 0) { - sys.L2[i].write_misses = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "replacements") == 0) { - sys.L2[i].replacements = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "write_backs") == 0) { - sys.L2[i].write_backs = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "miss_buffer_accesses") == 0) { - sys.L2[i].miss_buffer_accesses = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "fill_buffer_accesses") == 0) { - sys.L2[i].fill_buffer_accesses = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "prefetch_buffer_accesses") == 0) { - sys.L2[i].prefetch_buffer_accesses = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "prefetch_buffer_writes") == 0) { - sys.L2[i].prefetch_buffer_writes = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "prefetch_buffer_reads") == 0) { - sys.L2[i].prefetch_buffer_reads = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "prefetch_buffer_hits") == 0) { - sys.L2[i].prefetch_buffer_hits = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "wbb_writes") == 0) { - sys.L2[i].wbb_writes = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "wbb_reads") == 0) { - sys.L2[i].wbb_reads = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "conflicts") == 0) { - sys.L2[i].conflicts = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "duty_cycle") == 0) { - sys.L2[i].duty_cycle = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } + itmp=xNode3.nChildNode("param"); + for(k=0; k0) OrderofComponents_3layer=OrderofComponents_3layer+1; + xNode3=xNode2.getChildNode("component",OrderofComponents_3layer); + if (xNode3.isEmpty()==1) { + printf("some value(s) of number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are not correct!"); + exit(0); + } + if (strstr(xNode3.getAttribute("id"),"system.mc")!=NULL) + { + itmp=xNode3.nChildNode("param"); + for(k=0; k0) OrderofComponents_3layer=OrderofComponents_3layer+1; + xNode3=xNode2.getChildNode("component",OrderofComponents_3layer); + if (xNode3.isEmpty()==1) { + printf("some value(s) of number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are not correct!"); + exit(0); + } + if (strstr(xNode3.getAttribute("id"),"system.niu")!=NULL) + { + itmp=xNode3.nChildNode("param"); + for(k=0; k0) OrderofComponents_3layer=OrderofComponents_3layer+1; + xNode3=xNode2.getChildNode("component",OrderofComponents_3layer); + if (xNode3.isEmpty()==1) { + printf("some value(s) of number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are not correct!"); + exit(0); + } + if (strstr(xNode3.getAttribute("id"),"system.pcie")!=NULL) + { + itmp=xNode3.nChildNode("param"); + for(k=0; k0) OrderofComponents_3layer=OrderofComponents_3layer+1; + xNode3=xNode2.getChildNode("component",OrderofComponents_3layer); + if (xNode3.isEmpty()==1) { + printf("some value(s) of number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are not correct!"); + exit(0); + } + if (strstr(xNode3.getAttribute("id"),"system.flashc")!=NULL) + { + itmp=xNode3.nChildNode("param"); + for(k=0; k 0) - OrderofComponents_3layer = OrderofComponents_3layer + 1; - xNode3 = xNode2.getChildNode("component", OrderofComponents_3layer); - if (xNode3.isEmpty() == 1) { - printf( - "some value(s) of " - "number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are " - "not correct!"); - exit(0); - } - if (strstr(xNode3.getAttribute("id"), "system.mem") != NULL) { - itmp = xNode3.nChildNode("param"); - for (k = 0; k < itmp; k++) { // get all items of param in system.mem - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "mem_tech_node") == 0) { - sys.mem.mem_tech_node = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "device_clock") == 0) { - sys.mem.device_clock = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "peak_transfer_rate") == 0) { - sys.mem.peak_transfer_rate = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "capacity_per_channel") == 0) { - sys.mem.capacity_per_channel = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "number_ranks") == 0) { - sys.mem.number_ranks = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "num_banks_of_DRAM_chip") == 0) { - sys.mem.num_banks_of_DRAM_chip = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "Block_width_of_DRAM_chip") == 0) { - sys.mem.Block_width_of_DRAM_chip = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "output_width_of_DRAM_chip") == 0) { - sys.mem.output_width_of_DRAM_chip = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "page_size_of_DRAM_chip") == 0) { - sys.mem.page_size_of_DRAM_chip = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "burstlength_of_DRAM_chip") == 0) { - sys.mem.burstlength_of_DRAM_chip = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "internal_prefetch_of_DRAM_chip") == 0) { - sys.mem.internal_prefetch_of_DRAM_chip = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - } - itmp = xNode3.nChildNode("stat"); - for (k = 0; k < itmp; k++) { // get all items of stat in system.mem - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "memory_accesses") == 0) { - sys.mem.memory_accesses = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "memory_reads") == 0) { - sys.mem.memory_reads = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "memory_writes") == 0) { - sys.mem.memory_writes = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "dram_pre") == 0) { - sys.mem.dram_pre = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - } - } else { - printf( - "some value(s) of " - "number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are " - "not correct!"); - exit(0); - } - //__________________________________________Get - //system.mc____________________________________________ - if (OrderofComponents_3layer > 0) - OrderofComponents_3layer = OrderofComponents_3layer + 1; - xNode3 = xNode2.getChildNode("component", OrderofComponents_3layer); - if (xNode3.isEmpty() == 1) { - printf( - "some value(s) of " - "number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are " - "not correct!"); - exit(0); - } - if (strstr(xNode3.getAttribute("id"), "system.mc") != NULL) { - itmp = xNode3.nChildNode("param"); - for (k = 0; k < itmp; k++) { // get all items of param in system.mem - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "mc_clock") == 0) { - sys.mc.mc_clock = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "block_size") == 0) { - sys.mc.llc_line_length = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "number_mcs") == 0) { - sys.mc.number_mcs = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "memory_channels_per_mc") == 0) { - sys.mc.memory_channels_per_mc = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "req_window_size_per_channel") == 0) { - sys.mc.req_window_size_per_channel = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "IO_buffer_size_per_channel") == 0) { - sys.mc.IO_buffer_size_per_channel = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "databus_width") == 0) { - sys.mc.databus_width = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "addressbus_width") == 0) { - sys.mc.addressbus_width = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "PRT_entries") == 0) { - sys.mc.PRT_entries = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "peak_transfer_rate") == 0) { - sys.mc.peak_transfer_rate = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "number_ranks") == 0) { - sys.mc.number_ranks = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "LVDS") == 0) { - sys.mc.LVDS = - (bool)atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "type") == 0) { - sys.mc.type = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "withPHY") == 0) { - sys.mc.withPHY = - (bool)atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } + } + itmp=xNode3.nChildNode("stat"); + for(k=0; k 0) - OrderofComponents_3layer = OrderofComponents_3layer + 1; - xNode3 = xNode2.getChildNode("component", OrderofComponents_3layer); - if (xNode3.isEmpty() == 1) { - printf( - "some value(s) of " - "number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are " - "not correct!"); - exit(0); - } - if (strstr(xNode3.getAttribute("id"), "system.niu") != NULL) { - itmp = xNode3.nChildNode("param"); - for (k = 0; k < itmp; k++) { // get all items of param in system.mem - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "clockrate") == 0) { - sys.niu.clockrate = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "number_units") == 0) { - sys.niu.number_units = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "type") == 0) { - sys.niu.type = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - } - itmp = xNode3.nChildNode("stat"); - for (k = 0; k < itmp; - k++) { // get all items of stat in system.mendirectory - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "duty_cycle") == 0) { - sys.niu.duty_cycle = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "total_load_perc") == 0) { - sys.niu.total_load_perc = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - } - } else { - printf( - "some value(s) of " - "number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are " - "not correct!"); - exit(0); - } + } + } + else{ + printf("some value(s) of number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are not correct!"); + exit(0); + } - //__________________________________________Get - //system.pcie____________________________________________ - if (OrderofComponents_3layer > 0) - OrderofComponents_3layer = OrderofComponents_3layer + 1; - xNode3 = xNode2.getChildNode("component", OrderofComponents_3layer); - if (xNode3.isEmpty() == 1) { - printf( - "some value(s) of " - "number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are " - "not correct!"); - exit(0); - } - if (strstr(xNode3.getAttribute("id"), "system.pcie") != NULL) { - itmp = xNode3.nChildNode("param"); - for (k = 0; k < itmp; k++) { // get all items of param in system.mem - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "clockrate") == 0) { - sys.pcie.clockrate = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "number_units") == 0) { - sys.pcie.number_units = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "num_channels") == 0) { - sys.pcie.num_channels = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "type") == 0) { - sys.pcie.type = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "withPHY") == 0) { - sys.pcie.withPHY = - (bool)atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - } - itmp = xNode3.nChildNode("stat"); - for (k = 0; k < itmp; - k++) { // get all items of stat in system.mendirectory - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "duty_cycle") == 0) { - sys.pcie.duty_cycle = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "total_load_perc") == 0) { - sys.pcie.total_load_perc = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - } - } else { - printf( - "some value(s) of " - "number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are " - "not correct!"); - exit(0); - } - //__________________________________________Get - //system.flashcontroller____________________________________________ - if (OrderofComponents_3layer > 0) - OrderofComponents_3layer = OrderofComponents_3layer + 1; - xNode3 = xNode2.getChildNode("component", OrderofComponents_3layer); - if (xNode3.isEmpty() == 1) { - printf( - "some value(s) of " - "number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are " - "not correct!"); - exit(0); - } - if (strstr(xNode3.getAttribute("id"), "system.flashc") != NULL) { - itmp = xNode3.nChildNode("param"); - for (k = 0; k < itmp; k++) { // get all items of param in system.mem - // if - //(strcmp(xNode3.getChildNode("param",k).getAttribute("name"),"flashc_clock")==0) - //{sys.flashc.mc_clock=atoi(xNode3.getChildNode("param",k).getAttribute("value"));continue;} - // if - //(strcmp(xNode3.getChildNode("param",k).getAttribute("name"),"block_size")==0) - //{sys.flashc.llc_line_length=atoi(xNode3.getChildNode("param",k).getAttribute("value"));continue;} - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "number_flashcs") == 0) { - sys.flashc.number_mcs = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - // if - //(strcmp(xNode3.getChildNode("param",k).getAttribute("name"),"memory_channels_per_flashc")==0) - //{sys.flashc.memory_channels_per_mc=atoi(xNode3.getChildNode("param",k).getAttribute("value"));continue;} - // if - //(strcmp(xNode3.getChildNode("param",k).getAttribute("name"),"req_window_size_per_channel")==0) - //{sys.flashc.req_window_size_per_channel=atoi(xNode3.getChildNode("param",k).getAttribute("value"));continue;} - // if - //(strcmp(xNode3.getChildNode("param",k).getAttribute("name"),"IO_buffer_size_per_channel")==0) - //{sys.flashc.IO_buffer_size_per_channel=atoi(xNode3.getChildNode("param",k).getAttribute("value"));continue;} - // if - //(strcmp(xNode3.getChildNode("param",k).getAttribute("name"),"databus_width")==0) - //{sys.flashc.databus_width=atoi(xNode3.getChildNode("param",k).getAttribute("value"));continue;} - // if - //(strcmp(xNode3.getChildNode("param",k).getAttribute("name"),"addressbus_width")==0) - //{sys.flashc.addressbus_width=atoi(xNode3.getChildNode("param",k).getAttribute("value"));continue;} - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "peak_transfer_rate") == 0) { - sys.flashc.peak_transfer_rate = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - // if - //(strcmp(xNode3.getChildNode("param",k).getAttribute("name"),"number_ranks")==0) - //{sys.flashc.number_ranks=atoi(xNode3.getChildNode("param",k).getAttribute("value"));continue;} - // if - //(strcmp(xNode3.getChildNode("param",k).getAttribute("name"),"LVDS")==0) - //{sys.flashc.LVDS=(bool)atoi(xNode3.getChildNode("param",k).getAttribute("value"));continue;} - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "type") == 0) { - sys.flashc.type = - atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), - "withPHY") == 0) { - sys.flashc.withPHY = - (bool)atoi(xNode3.getChildNode("param", k).getAttribute("value")); - continue; - } - } - itmp = xNode3.nChildNode("stat"); - for (k = 0; k < itmp; - k++) { // get all items of stat in system.mendirectory - // if - //(strcmp(xNode3.getChildNode("stat",k).getAttribute("name"),"memory_accesses")==0) - //{sys.flashc.memory_accesses=atof(xNode3.getChildNode("stat",k).getAttribute("value"));continue;} - // if - //(strcmp(xNode3.getChildNode("stat",k).getAttribute("name"),"memory_reads")==0) - //{sys.flashc.memory_reads=atof(xNode3.getChildNode("stat",k).getAttribute("value"));continue;} - // if - //(strcmp(xNode3.getChildNode("stat",k).getAttribute("name"),"memory_writes")==0) - //{sys.flashc.memory_writes=atof(xNode3.getChildNode("stat",k).getAttribute("value"));continue;} - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "duty_cycle") == 0) { - sys.flashc.duty_cycle = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), - "total_load_perc") == 0) { - sys.flashc.total_load_perc = - atof(xNode3.getChildNode("stat", k).getAttribute("value")); - continue; - } - } - } else { - printf( - "some value(s) of " - "number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are " - "not correct!"); - exit(0); - } - } + } } -void ParseXML::initialize() // Initialize all +void ParseXML::initialize() //Initialize all { - // All number_of_* at the level of 'system' 03/21/2009 - sys.number_of_cores = 1; - sys.architecture = 1; // 1 - fermi - sys.number_of_L1Directories = 1; - sys.number_of_L2Directories = 1; - sys.number_of_L2s = 1; - sys.Private_L2 = false; - sys.number_of_L3s = 1; - sys.number_of_NoCs = 1; - // All params at the level of 'system' - // strcpy(sys.homogeneous_cores,"default"); - sys.core_tech_node = 1; - sys.target_core_clockrate = 1; - sys.target_chip_area = 1; - sys.temperature = 1; - sys.number_cache_levels = 1; - sys.homogeneous_cores = 1; - sys.homogeneous_L1Directories = 1; - sys.homogeneous_L2Directories = 1; - sys.homogeneous_L2s = 1; - sys.homogeneous_L3s = 1; - sys.homogeneous_NoCs = 1; - sys.homogeneous_ccs = 1; + //All number_of_* at the level of 'system' 03/21/2009 + sys.number_of_cores=1; + sys.architecture=1; //1 - fermi + sys.number_of_L1Directories=1; + sys.number_of_L2Directories=1; + sys.number_of_L2s=1; + sys.Private_L2 = false; + sys.number_of_L3s=1; + sys.number_of_NoCs=1; + // All params at the level of 'system' + //strcpy(sys.homogeneous_cores,"default"); + sys.core_tech_node=1; + sys.target_core_clockrate=1; + sys.target_chip_area=1; + sys.temperature=1; + sys.number_cache_levels=1; + sys.homogeneous_cores=1; + sys.homogeneous_L1Directories=1; + sys.homogeneous_L2Directories=1; + sys.homogeneous_L2s=1; + sys.homogeneous_L3s=1; + sys.homogeneous_NoCs=1; + sys.homogeneous_ccs=1; - sys.Max_area_deviation = 1; - sys.Max_power_deviation = 1; - sys.device_type = 1; - sys.longer_channel_device = true; - sys.Embedded = false; - sys.opt_dynamic_power = false; - sys.opt_lakage_power = false; - sys.opt_clockrate = true; - sys.opt_area = false; - sys.interconnect_projection_type = 1; - sys.idle_core_power = 0; - int i, j; - for (i = 0; i <= 63; i++) { - sys.scaling_coefficients[i] = 1; - sys.core[i].clock_rate = 1; - sys.core[i].opt_local = true; - sys.core[i].x86 = false; - sys.core[i].machine_bits = 1; - sys.core[i].virtual_address_width = 1; - sys.core[i].physical_address_width = 1; - sys.core[i].opcode_width = 1; - sys.core[i].micro_opcode_width = 1; - // strcpy(sys.core[i].machine_type,"default"); - sys.core[i].internal_datapath_width = 1; - sys.core[i].number_hardware_threads = 1; - sys.core[i].fetch_width = 1; - sys.core[i].number_instruction_fetch_ports = 1; - sys.core[i].decode_width = 1; - sys.core[i].issue_width = 1; - sys.core[i].peak_issue_width = 1; - sys.core[i].commit_width = 1; - for (j = 0; j < 20; j++) sys.core[i].pipelines_per_core[j] = 1; - for (j = 0; j < 20; j++) sys.core[i].pipeline_depth[j] = 1; - strcpy(sys.core[i].FPU, "default"); - strcpy(sys.core[i].divider_multiplier, "default"); - sys.core[i].ALU_per_core = 1; - sys.core[i].FPU_per_core = 1.0; - sys.core[i].MUL_per_core = 1; - sys.core[i].instruction_buffer_size = 1; - sys.core[i].decoded_stream_buffer_size = 1; - // strcpy(sys.core[i].instruction_window_scheme,"default"); - sys.core[i].instruction_window_size = 1; - sys.core[i].ROB_size = 1; - sys.core[i].archi_Regs_IRF_size = 1; - sys.core[i].archi_Regs_FRF_size = 1; - sys.core[i].phy_Regs_IRF_size = 1; - sys.core[i].phy_Regs_FRF_size = 1; - // strcpy(sys.core[i].rename_scheme,"default"); - sys.core[i].register_windows_size = 1; - strcpy(sys.core[i].LSU_order, "default"); - sys.core[i].store_buffer_size = 1; - sys.core[i].load_buffer_size = 1; - sys.core[i].memory_ports = 1; - strcpy(sys.core[i].Dcache_dual_pump, "default"); - sys.core[i].RAS_size = 1; - // all stats at the level of system.core(0-n) - sys.core[i].total_instructions = 1; - sys.core[i].int_instructions = 1; - sys.core[i].fp_instructions = 1; - sys.core[i].branch_instructions = 1; - sys.core[i].branch_mispredictions = 1; - sys.core[i].committed_instructions = 1; - sys.core[i].load_instructions = 1; - sys.core[i].store_instructions = 1; - sys.core[i].total_cycles = 1; - sys.core[i].idle_cycles = 1; - sys.core[i].busy_cycles = 1; - sys.core[i].instruction_buffer_reads = 1; - sys.core[i].instruction_buffer_write = 1; - sys.core[i].ROB_reads = 1; - sys.core[i].ROB_writes = 1; - sys.core[i].rename_accesses = 1; - sys.core[i].inst_window_reads = 1; - sys.core[i].inst_window_writes = 1; - sys.core[i].inst_window_wakeup_accesses = 1; - sys.core[i].inst_window_selections = 1; - sys.core[i].archi_int_regfile_reads = 1; - sys.core[i].archi_float_regfile_reads = 1; - sys.core[i].phy_int_regfile_reads = 1; - sys.core[i].phy_float_regfile_reads = 1; - sys.core[i].windowed_reg_accesses = 1; - sys.core[i].windowed_reg_transports = 1; - sys.core[i].function_calls = 1; - sys.core[i].ialu_accesses = 1; - sys.core[i].fpu_accesses = 1; - sys.core[i].mul_accesses = 1; - sys.core[i].cdb_alu_accesses = 1; - sys.core[i].cdb_mul_accesses = 1; - sys.core[i].cdb_fpu_accesses = 1; - sys.core[i].load_buffer_reads = 1; - sys.core[i].load_buffer_writes = 1; - sys.core[i].load_buffer_cams = 1; - sys.core[i].store_buffer_reads = 1; - sys.core[i].store_buffer_writes = 1; - sys.core[i].store_buffer_cams = 1; - sys.core[i].store_buffer_forwards = 1; - sys.core[i].main_memory_access = 1; - sys.core[i].main_memory_read = 1; - sys.core[i].main_memory_write = 1; - sys.core[i].IFU_duty_cycle = 1; - sys.core[i].BR_duty_cycle = 1; - sys.core[i].LSU_duty_cycle = 1; - sys.core[i].MemManU_I_duty_cycle = 1; - sys.core[i].MemManU_D_duty_cycle = 1; - sys.core[i].ALU_duty_cycle = 1; - sys.core[i].MUL_duty_cycle = 1; - sys.core[i].FPU_duty_cycle = 1; - sys.core[i].ALU_cdb_duty_cycle = 1; - sys.core[i].MUL_cdb_duty_cycle = 1; - sys.core[i].FPU_cdb_duty_cycle = 1; - // system.core?.predictor - sys.core[i].predictor.prediction_width = 1; - strcpy(sys.core[i].predictor.prediction_scheme, "default"); - sys.core[i].predictor.predictor_size = 1; - sys.core[i].predictor.predictor_entries = 1; - sys.core[i].predictor.local_predictor_entries = 1; - for (j = 0; j < 20; j++) sys.core[i].predictor.local_predictor_size[j] = 1; - sys.core[i].predictor.global_predictor_entries = 1; - sys.core[i].predictor.global_predictor_bits = 1; - sys.core[i].predictor.chooser_predictor_entries = 1; - sys.core[i].predictor.chooser_predictor_bits = 1; - sys.core[i].predictor.predictor_accesses = 1; - // system.core?.itlb - sys.core[i].itlb.number_entries = 1; - sys.core[i].itlb.total_hits = 1; - sys.core[i].itlb.total_accesses = 1; - sys.core[i].itlb.total_misses = 1; - // system.core?.icache - for (j = 0; j < 20; j++) sys.core[i].icache.icache_config[j] = 1; - // strcpy(sys.core[i].icache.buffer_sizes,"default"); - sys.core[i].icache.total_accesses = 1; - sys.core[i].icache.read_accesses = 1; - sys.core[i].icache.read_misses = 1; - sys.core[i].icache.replacements = 1; - sys.core[i].icache.read_hits = 1; - sys.core[i].icache.total_hits = 1; - sys.core[i].icache.total_misses = 1; - sys.core[i].icache.miss_buffer_access = 1; - sys.core[i].icache.fill_buffer_accesses = 1; - sys.core[i].icache.prefetch_buffer_accesses = 1; - sys.core[i].icache.prefetch_buffer_writes = 1; - sys.core[i].icache.prefetch_buffer_reads = 1; - sys.core[i].icache.prefetch_buffer_hits = 1; - // system.core?.dtlb - sys.core[i].dtlb.number_entries = 1; - sys.core[i].dtlb.total_accesses = 1; - sys.core[i].dtlb.read_accesses = 1; - sys.core[i].dtlb.write_accesses = 1; - sys.core[i].dtlb.write_hits = 1; - sys.core[i].dtlb.read_hits = 1; - sys.core[i].dtlb.read_misses = 1; - sys.core[i].dtlb.write_misses = 1; - sys.core[i].dtlb.total_hits = 1; - sys.core[i].dtlb.total_misses = 1; - // system.core?.dcache - for (j = 0; j < 20; j++) sys.core[i].dcache.dcache_config[j] = 1; - // strcpy(sys.core[i].dcache.buffer_sizes,"default"); - sys.core[i].dcache.total_accesses = 1; - sys.core[i].dcache.read_accesses = 1; - sys.core[i].dcache.write_accesses = 1; - sys.core[i].dcache.total_hits = 1; - sys.core[i].dcache.total_misses = 1; - sys.core[i].dcache.read_hits = 1; - sys.core[i].dcache.write_hits = 1; - sys.core[i].dcache.read_misses = 1; - sys.core[i].dcache.write_misses = 1; - sys.core[i].dcache.replacements = 1; - sys.core[i].dcache.write_backs = 1; - sys.core[i].dcache.miss_buffer_access = 1; - sys.core[i].dcache.fill_buffer_accesses = 1; - sys.core[i].dcache.prefetch_buffer_accesses = 1; - sys.core[i].dcache.prefetch_buffer_writes = 1; - sys.core[i].dcache.prefetch_buffer_reads = 1; - sys.core[i].dcache.prefetch_buffer_hits = 1; - sys.core[i].dcache.wbb_writes = 1; - sys.core[i].dcache.wbb_reads = 1; - // system.core?.BTB - for (j = 0; j < 20; j++) sys.core[i].BTB.BTB_config[j] = 1; - sys.core[i].BTB.total_accesses = 1; - sys.core[i].BTB.read_accesses = 1; - sys.core[i].BTB.write_accesses = 1; - sys.core[i].BTB.total_hits = 1; - sys.core[i].BTB.total_misses = 1; - sys.core[i].BTB.read_hits = 1; - sys.core[i].BTB.write_hits = 1; - sys.core[i].BTB.read_misses = 1; - sys.core[i].BTB.write_misses = 1; - sys.core[i].BTB.replacements = 1; - } + sys.Max_area_deviation=1; + sys.Max_power_deviation=1; + sys.device_type=1; + sys.longer_channel_device =true; + sys.Embedded =false; + sys.opt_dynamic_power=false; + sys.opt_lakage_power=false; + sys.opt_clockrate=true; + sys.opt_area=false; + sys.interconnect_projection_type=1; + sys.idle_core_power=0; + int i,j; + for (i=0; i<=63; i++) + { + sys.scaling_coefficients[i]=1; + sys.core[i].clock_rate=1; + sys.core[i].opt_local = true; + sys.core[i].x86 = false; + sys.core[i].machine_bits=1; + sys.core[i].virtual_address_width=1; + sys.core[i].physical_address_width=1; + sys.core[i].opcode_width=1; + sys.core[i].micro_opcode_width=1; + //strcpy(sys.core[i].machine_type,"default"); + sys.core[i].internal_datapath_width=1; + sys.core[i].number_hardware_threads=1; + sys.core[i].fetch_width=1; + sys.core[i].number_instruction_fetch_ports=1; + sys.core[i].decode_width=1; + sys.core[i].issue_width=1; + sys.core[i].peak_issue_width=1; + sys.core[i].commit_width=1; + for (j=0; j<20; j++) sys.core[i].pipelines_per_core[j]=1; + for (j=0; j<20; j++) sys.core[i].pipeline_depth[j]=1; + strcpy(sys.core[i].FPU,"default"); + strcpy(sys.core[i]. divider_multiplier,"default"); + sys.core[i].ALU_per_core=1; + sys.core[i].FPU_per_core=1.0; + sys.core[i].MUL_per_core=1; + sys.core[i].instruction_buffer_size=1; + sys.core[i].decoded_stream_buffer_size=1; + //strcpy(sys.core[i].instruction_window_scheme,"default"); + sys.core[i].instruction_window_size=1; + sys.core[i].ROB_size=1; + sys.core[i].archi_Regs_IRF_size=1; + sys.core[i].archi_Regs_FRF_size=1; + sys.core[i].phy_Regs_IRF_size=1; + sys.core[i].phy_Regs_FRF_size=1; + //strcpy(sys.core[i].rename_scheme,"default"); + sys.core[i].register_windows_size=1; + strcpy(sys.core[i].LSU_order,"default"); + sys.core[i].store_buffer_size=1; + sys.core[i].load_buffer_size=1; + sys.core[i].memory_ports=1; + strcpy(sys.core[i].Dcache_dual_pump,"default"); + sys.core[i].RAS_size=1; + //all stats at the level of system.core(0-n) + sys.core[i].total_instructions=1; + sys.core[i].int_instructions=1; + sys.core[i].fp_instructions=1; + sys.core[i].branch_instructions=1; + sys.core[i].branch_mispredictions=1; + sys.core[i].committed_instructions=1; + sys.core[i].load_instructions=1; + sys.core[i].store_instructions=1; + sys.core[i].total_cycles=1; + sys.core[i].idle_cycles=1; + sys.core[i].busy_cycles=1; + sys.core[i].instruction_buffer_reads=1; + sys.core[i].instruction_buffer_write=1; + sys.core[i].ROB_reads=1; + sys.core[i].ROB_writes=1; + sys.core[i].rename_accesses=1; + sys.core[i].inst_window_reads=1; + sys.core[i].inst_window_writes=1; + sys.core[i].inst_window_wakeup_accesses=1; + sys.core[i].inst_window_selections=1; + sys.core[i].archi_int_regfile_reads=1; + sys.core[i].archi_float_regfile_reads=1; + sys.core[i].phy_int_regfile_reads=1; + sys.core[i].phy_float_regfile_reads=1; + sys.core[i].windowed_reg_accesses=1; + sys.core[i].windowed_reg_transports=1; + sys.core[i].function_calls=1; + sys.core[i].ialu_accesses=1; + sys.core[i].fpu_accesses=1; + sys.core[i].mul_accesses=1; + sys.core[i].cdb_alu_accesses=1; + sys.core[i].cdb_mul_accesses=1; + sys.core[i].cdb_fpu_accesses=1; + sys.core[i].load_buffer_reads=1; + sys.core[i].load_buffer_writes=1; + sys.core[i].load_buffer_cams=1; + sys.core[i].store_buffer_reads=1; + sys.core[i].store_buffer_writes=1; + sys.core[i].store_buffer_cams=1; + sys.core[i].store_buffer_forwards=1; + sys.core[i].main_memory_access=1; + sys.core[i].main_memory_read=1; + sys.core[i].main_memory_write=1; + sys.core[i].IFU_duty_cycle = 1; + sys.core[i].BR_duty_cycle = 1; + sys.core[i].LSU_duty_cycle = 1; + sys.core[i].MemManU_I_duty_cycle =1; + sys.core[i].MemManU_D_duty_cycle =1; + sys.core[i].ALU_duty_cycle =1; + sys.core[i].MUL_duty_cycle =1; + sys.core[i].FPU_duty_cycle =1; + sys.core[i].ALU_cdb_duty_cycle =1; + sys.core[i].MUL_cdb_duty_cycle =1; + sys.core[i].FPU_cdb_duty_cycle =1; + //system.core?.predictor + sys.core[i].predictor.prediction_width=1; + strcpy(sys.core[i].predictor.prediction_scheme,"default"); + sys.core[i].predictor.predictor_size=1; + sys.core[i].predictor.predictor_entries=1; + sys.core[i].predictor.local_predictor_entries=1; + for (j=0; j<20; j++) sys.core[i].predictor.local_predictor_size[j]=1; + sys.core[i].predictor.global_predictor_entries=1; + sys.core[i].predictor.global_predictor_bits=1; + sys.core[i].predictor.chooser_predictor_entries=1; + sys.core[i].predictor.chooser_predictor_bits=1; + sys.core[i].predictor.predictor_accesses=1; + //system.core?.itlb + sys.core[i].itlb.number_entries=1; + sys.core[i].itlb.total_hits=1; + sys.core[i].itlb.total_accesses=1; + sys.core[i].itlb.total_misses=1; + //system.core?.icache + for (j=0; j<20; j++) sys.core[i].icache.icache_config[j]=1; + //strcpy(sys.core[i].icache.buffer_sizes,"default"); + sys.core[i].icache.total_accesses=1; + sys.core[i].icache.read_accesses=1; + sys.core[i].icache.read_misses=1; + sys.core[i].icache.replacements=1; + sys.core[i].icache.read_hits=1; + sys.core[i].icache.total_hits=1; + sys.core[i].icache.total_misses=1; + sys.core[i].icache.miss_buffer_access=1; + sys.core[i].icache.fill_buffer_accesses=1; + sys.core[i].icache.prefetch_buffer_accesses=1; + sys.core[i].icache.prefetch_buffer_writes=1; + sys.core[i].icache.prefetch_buffer_reads=1; + sys.core[i].icache.prefetch_buffer_hits=1; + //system.core?.dtlb + sys.core[i].dtlb.number_entries=1; + sys.core[i].dtlb.total_accesses=1; + sys.core[i].dtlb.read_accesses=1; + sys.core[i].dtlb.write_accesses=1; + sys.core[i].dtlb.write_hits=1; + sys.core[i].dtlb.read_hits=1; + sys.core[i].dtlb.read_misses=1; + sys.core[i].dtlb.write_misses=1; + sys.core[i].dtlb.total_hits=1; + sys.core[i].dtlb.total_misses=1; + //system.core?.dcache + for (j=0; j<20; j++) sys.core[i].dcache.dcache_config[j]=1; + //strcpy(sys.core[i].dcache.buffer_sizes,"default"); + sys.core[i].dcache.total_accesses=1; + sys.core[i].dcache.read_accesses=1; + sys.core[i].dcache.write_accesses=1; + sys.core[i].dcache.total_hits=1; + sys.core[i].dcache.total_misses=1; + sys.core[i].dcache.read_hits=1; + sys.core[i].dcache.write_hits=1; + sys.core[i].dcache.read_misses=1; + sys.core[i].dcache.write_misses=1; + sys.core[i].dcache.replacements=1; + sys.core[i].dcache.write_backs=1; + sys.core[i].dcache.miss_buffer_access=1; + sys.core[i].dcache.fill_buffer_accesses=1; + sys.core[i].dcache.prefetch_buffer_accesses=1; + sys.core[i].dcache.prefetch_buffer_writes=1; + sys.core[i].dcache.prefetch_buffer_reads=1; + sys.core[i].dcache.prefetch_buffer_hits=1; + sys.core[i].dcache.wbb_writes=1; + sys.core[i].dcache.wbb_reads=1; + //system.core?.BTB + for (j=0; j<20; j++) sys.core[i].BTB.BTB_config[j]=1; + sys.core[i].BTB.total_accesses=1; + sys.core[i].BTB.read_accesses=1; + sys.core[i].BTB.write_accesses=1; + sys.core[i].BTB.total_hits=1; + sys.core[i].BTB.total_misses=1; + sys.core[i].BTB.read_hits=1; + sys.core[i].BTB.write_hits=1; + sys.core[i].BTB.read_misses=1; + sys.core[i].BTB.write_misses=1; + sys.core[i].BTB.replacements=1; + } - // system_L1directory - for (i = 0; i <= 63; i++) { - for (j = 0; j < 20; j++) sys.L1Directory[i].Dir_config[j] = 1; - for (j = 0; j < 20; j++) sys.L1Directory[i].buffer_sizes[j] = 1; - sys.L1Directory[i].clockrate = 1; - sys.L1Directory[i].ports[20] = 1; - sys.L1Directory[i].device_type = 1; - strcpy(sys.L1Directory[i].threeD_stack, "default"); - sys.L1Directory[i].total_accesses = 1; - sys.L1Directory[i].read_accesses = 1; - sys.L1Directory[i].write_accesses = 1; - sys.L1Directory[i].duty_cycle = 1; - } - // system_L2directory - for (i = 0; i <= 63; i++) { - for (j = 0; j < 20; j++) sys.L2Directory[i].Dir_config[j] = 1; - for (j = 0; j < 20; j++) sys.L2Directory[i].buffer_sizes[j] = 1; - sys.L2Directory[i].clockrate = 1; - sys.L2Directory[i].ports[20] = 1; - sys.L2Directory[i].device_type = 1; - strcpy(sys.L2Directory[i].threeD_stack, "default"); - sys.L2Directory[i].total_accesses = 1; - sys.L2Directory[i].read_accesses = 1; - sys.L2Directory[i].write_accesses = 1; - sys.L2Directory[i].duty_cycle = 1; - } - for (i = 0; i <= 63; i++) { - // system_L2 - for (j = 0; j < 20; j++) sys.L2[i].L2_config[j] = 1; - sys.L2[i].clockrate = 1; - for (j = 0; j < 20; j++) sys.L2[i].ports[j] = 1; - sys.L2[i].device_type = 1; - strcpy(sys.L2[i].threeD_stack, "default"); - for (j = 0; j < 20; j++) sys.L2[i].buffer_sizes[j] = 1; - sys.L2[i].total_accesses = 1; - sys.L2[i].read_accesses = 1; - sys.L2[i].write_accesses = 1; - sys.L2[i].total_hits = 1; - sys.L2[i].total_misses = 1; - sys.L2[i].read_hits = 1; - sys.L2[i].write_hits = 1; - sys.L2[i].read_misses = 1; - sys.L2[i].write_misses = 1; - sys.L2[i].replacements = 1; - sys.L2[i].write_backs = 1; - sys.L2[i].miss_buffer_accesses = 1; - sys.L2[i].fill_buffer_accesses = 1; - sys.L2[i].prefetch_buffer_accesses = 1; - sys.L2[i].prefetch_buffer_writes = 1; - sys.L2[i].prefetch_buffer_reads = 1; - sys.L2[i].prefetch_buffer_hits = 1; - sys.L2[i].wbb_writes = 1; - sys.L2[i].wbb_reads = 1; - sys.L2[i].duty_cycle = 1; - sys.L2[i].merged_dir = false; - sys.L2[i].homenode_read_accesses = 1; - sys.L2[i].homenode_write_accesses = 1; - sys.L2[i].homenode_read_hits = 1; - sys.L2[i].homenode_write_hits = 1; - sys.L2[i].homenode_read_misses = 1; - sys.L2[i].homenode_write_misses = 1; - sys.L2[i].dir_duty_cycle = 1; - } - for (i = 0; i <= 63; i++) { - // system_L3 - for (j = 0; j < 20; j++) sys.L3[i].L3_config[j] = 1; - sys.L3[i].clockrate = 1; - for (j = 0; j < 20; j++) sys.L3[i].ports[j] = 1; - sys.L3[i].device_type = 1; - strcpy(sys.L3[i].threeD_stack, "default"); - for (j = 0; j < 20; j++) sys.L3[i].buffer_sizes[j] = 1; - sys.L3[i].total_accesses = 1; - sys.L3[i].read_accesses = 1; - sys.L3[i].write_accesses = 1; - sys.L3[i].total_hits = 1; - sys.L3[i].total_misses = 1; - sys.L3[i].read_hits = 1; - sys.L3[i].write_hits = 1; - sys.L3[i].read_misses = 1; - sys.L3[i].write_misses = 1; - sys.L3[i].replacements = 1; - sys.L3[i].write_backs = 1; - sys.L3[i].miss_buffer_accesses = 1; - sys.L3[i].fill_buffer_accesses = 1; - sys.L3[i].prefetch_buffer_accesses = 1; - sys.L3[i].prefetch_buffer_writes = 1; - sys.L3[i].prefetch_buffer_reads = 1; - sys.L3[i].prefetch_buffer_hits = 1; - sys.L3[i].wbb_writes = 1; - sys.L3[i].wbb_reads = 1; - sys.L3[i].duty_cycle = 1; - sys.L3[i].merged_dir = false; - sys.L3[i].homenode_read_accesses = 1; - sys.L3[i].homenode_write_accesses = 1; - sys.L3[i].homenode_read_hits = 1; - sys.L3[i].homenode_write_hits = 1; - sys.L3[i].homenode_read_misses = 1; - sys.L3[i].homenode_write_misses = 1; - sys.L3[i].dir_duty_cycle = 1; - } - // system_NoC - for (i = 0; i <= 63; i++) { - sys.NoC[i].clockrate = 1; - sys.NoC[i].type = true; - sys.NoC[i].chip_coverage = 1; - sys.NoC[i].has_global_link = true; - strcpy(sys.NoC[i].topology, "default"); - sys.NoC[i].horizontal_nodes = 1; - sys.NoC[i].vertical_nodes = 1; - sys.NoC[i].input_ports = 1; - sys.NoC[i].output_ports = 1; - sys.NoC[i].virtual_channel_per_port = 1; - sys.NoC[i].flit_bits = 1; - sys.NoC[i].input_buffer_entries_per_vc = 1; - sys.NoC[i].total_accesses = 1; - sys.NoC[i].duty_cycle = 1; - sys.NoC[i].route_over_perc = 0.5; - for (j = 0; j < 20; j++) sys.NoC[i].ports_of_input_buffer[j] = 1; - sys.NoC[i].number_of_crossbars = 1; - strcpy(sys.NoC[i].crossbar_type, "default"); - strcpy(sys.NoC[i].crosspoint_type, "default"); - // system.NoC?.xbar0; - sys.NoC[i].xbar0.number_of_inputs_of_crossbars = 1; - sys.NoC[i].xbar0.number_of_outputs_of_crossbars = 1; - sys.NoC[i].xbar0.flit_bits = 1; - sys.NoC[i].xbar0.input_buffer_entries_per_port = 1; - sys.NoC[i].xbar0.ports_of_input_buffer[20] = 1; - sys.NoC[i].xbar0.crossbar_accesses = 1; - } - // system_mem - sys.mem.mem_tech_node = 1; - sys.mem.device_clock = 1; - sys.mem.capacity_per_channel = 1; - sys.mem.number_ranks = 1; - sys.mem.peak_transfer_rate = 1; - sys.mem.num_banks_of_DRAM_chip = 1; - sys.mem.Block_width_of_DRAM_chip = 1; - sys.mem.output_width_of_DRAM_chip = 1; - sys.mem.page_size_of_DRAM_chip = 1; - sys.mem.burstlength_of_DRAM_chip = 1; - sys.mem.internal_prefetch_of_DRAM_chip = 1; - sys.mem.memory_accesses = 1; - sys.mem.memory_reads = 1; - sys.mem.memory_writes = 1; + //system_L1directory + for (i=0; i<=63; i++) + { + for (j=0; j<20; j++) sys.L1Directory[i].Dir_config[j]=1; + for (j=0; j<20; j++) sys.L1Directory[i].buffer_sizes[j]=1; + sys.L1Directory[i].clockrate=1; + sys.L1Directory[i].ports[20]=1; + sys.L1Directory[i].device_type=1; + strcpy(sys.L1Directory[i].threeD_stack,"default"); + sys.L1Directory[i].total_accesses=1; + sys.L1Directory[i].read_accesses=1; + sys.L1Directory[i].write_accesses=1; + sys.L1Directory[i].duty_cycle =1; + } + //system_L2directory + for (i=0; i<=63; i++) + { + for (j=0; j<20; j++) sys.L2Directory[i].Dir_config[j]=1; + for (j=0; j<20; j++) sys.L2Directory[i].buffer_sizes[j]=1; + sys.L2Directory[i].clockrate=1; + sys.L2Directory[i].ports[20]=1; + sys.L2Directory[i].device_type=1; + strcpy(sys.L2Directory[i].threeD_stack,"default"); + sys.L2Directory[i].total_accesses=1; + sys.L2Directory[i].read_accesses=1; + sys.L2Directory[i].write_accesses=1; + sys.L2Directory[i].duty_cycle =1; + } + for (i=0; i<=63; i++) + { + //system_L2 + for (j=0; j<20; j++) sys.L2[i].L2_config[j]=1; + sys.L2[i].clockrate=1; + for (j=0; j<20; j++) sys.L2[i].ports[j]=1; + sys.L2[i].device_type=1; + strcpy(sys.L2[i].threeD_stack,"default"); + for (j=0; j<20; j++) sys.L2[i].buffer_sizes[j]=1; + sys.L2[i].total_accesses=1; + sys.L2[i].read_accesses=1; + sys.L2[i].write_accesses=1; + sys.L2[i].total_hits=1; + sys.L2[i].total_misses=1; + sys.L2[i].read_hits=1; + sys.L2[i].write_hits=1; + sys.L2[i].read_misses=1; + sys.L2[i].write_misses=1; + sys.L2[i].replacements=1; + sys.L2[i].write_backs=1; + sys.L2[i].miss_buffer_accesses=1; + sys.L2[i].fill_buffer_accesses=1; + sys.L2[i].prefetch_buffer_accesses=1; + sys.L2[i].prefetch_buffer_writes=1; + sys.L2[i].prefetch_buffer_reads=1; + sys.L2[i].prefetch_buffer_hits=1; + sys.L2[i].wbb_writes=1; + sys.L2[i].wbb_reads=1; + sys.L2[i].duty_cycle =1; + sys.L2[i].merged_dir=false; + sys.L2[i].homenode_read_accesses =1; + sys.L2[i].homenode_write_accesses=1; + sys.L2[i].homenode_read_hits=1; + sys.L2[i].homenode_write_hits=1; + sys.L2[i].homenode_read_misses=1; + sys.L2[i].homenode_write_misses=1; + sys.L2[i].dir_duty_cycle=1; + } + for (i=0; i<=63; i++) + { + //system_L3 + for (j=0; j<20; j++) sys.L3[i].L3_config[j]=1; + sys.L3[i].clockrate=1; + for (j=0; j<20; j++) sys.L3[i].ports[j]=1; + sys.L3[i].device_type=1; + strcpy(sys.L3[i].threeD_stack,"default"); + for (j=0; j<20; j++) sys.L3[i].buffer_sizes[j]=1; + sys.L3[i].total_accesses=1; + sys.L3[i].read_accesses=1; + sys.L3[i].write_accesses=1; + sys.L3[i].total_hits=1; + sys.L3[i].total_misses=1; + sys.L3[i].read_hits=1; + sys.L3[i].write_hits=1; + sys.L3[i].read_misses=1; + sys.L3[i].write_misses=1; + sys.L3[i].replacements=1; + sys.L3[i].write_backs=1; + sys.L3[i].miss_buffer_accesses=1; + sys.L3[i].fill_buffer_accesses=1; + sys.L3[i].prefetch_buffer_accesses=1; + sys.L3[i].prefetch_buffer_writes=1; + sys.L3[i].prefetch_buffer_reads=1; + sys.L3[i].prefetch_buffer_hits=1; + sys.L3[i].wbb_writes=1; + sys.L3[i].wbb_reads=1; + sys.L3[i].duty_cycle =1; + sys.L3[i].merged_dir=false; + sys.L3[i].homenode_read_accesses =1; + sys.L3[i].homenode_write_accesses=1; + sys.L3[i].homenode_read_hits=1; + sys.L3[i].homenode_write_hits=1; + sys.L3[i].homenode_read_misses=1; + sys.L3[i].homenode_write_misses=1; + sys.L3[i].dir_duty_cycle=1; + } + //system_NoC + for (i=0; i<=63; i++) + { + sys.NoC[i].clockrate=1; + sys.NoC[i].type=true; + sys.NoC[i].chip_coverage=1; + sys.NoC[i].has_global_link = true; + strcpy(sys.NoC[i].topology,"default"); + sys.NoC[i].horizontal_nodes=1; + sys.NoC[i].vertical_nodes=1; + sys.NoC[i].input_ports=1; + sys.NoC[i].output_ports=1; + sys.NoC[i].virtual_channel_per_port=1; + sys.NoC[i].flit_bits=1; + sys.NoC[i].input_buffer_entries_per_vc=1; + sys.NoC[i].total_accesses=1; + sys.NoC[i].duty_cycle=1; + sys.NoC[i].route_over_perc = 0.5; + for (j=0; j<20; j++) sys.NoC[i].ports_of_input_buffer[j]=1; + sys.NoC[i].number_of_crossbars=1; + strcpy(sys.NoC[i].crossbar_type,"default"); + strcpy(sys.NoC[i].crosspoint_type,"default"); + //system.NoC?.xbar0; + sys.NoC[i].xbar0.number_of_inputs_of_crossbars=1; + sys.NoC[i].xbar0.number_of_outputs_of_crossbars=1; + sys.NoC[i].xbar0.flit_bits=1; + sys.NoC[i].xbar0.input_buffer_entries_per_port=1; + sys.NoC[i].xbar0.ports_of_input_buffer[20]=1; + sys.NoC[i].xbar0.crossbar_accesses=1; + } + //system_mem + sys.mem.mem_tech_node=1; + sys.mem.device_clock=1; + sys.mem.capacity_per_channel=1; + sys.mem.number_ranks=1; + sys.mem.peak_transfer_rate =1; + sys.mem.num_banks_of_DRAM_chip=1; + sys.mem.Block_width_of_DRAM_chip=1; + sys.mem.output_width_of_DRAM_chip=1; + sys.mem.page_size_of_DRAM_chip=1; + sys.mem.burstlength_of_DRAM_chip=1; + sys.mem.internal_prefetch_of_DRAM_chip=1; + sys.mem.memory_accesses=1; + sys.mem.memory_reads=1; + sys.mem.memory_writes=1; - // system_mc - sys.mc.mc_clock = 1; - sys.mc.number_mcs = 1; - sys.mc.peak_transfer_rate = 1; - sys.mc.memory_channels_per_mc = 1; - sys.mc.number_ranks = 1; - sys.mc.req_window_size_per_channel = 1; - sys.mc.IO_buffer_size_per_channel = 1; - sys.mc.databus_width = 1; - sys.mc.addressbus_width = 1; - sys.mc.memory_accesses = 1; - sys.mc.memory_reads = 1; - sys.mc.memory_writes = 1; - sys.mc.LVDS = true; - sys.mc.type = 1; + //system_mc + sys.mc.mc_clock =1; + sys.mc.number_mcs=1; + sys.mc.peak_transfer_rate =1; + sys.mc.memory_channels_per_mc=1; + sys.mc.number_ranks=1; + sys.mc.req_window_size_per_channel=1; + sys.mc.IO_buffer_size_per_channel=1; + sys.mc.databus_width=1; + sys.mc.addressbus_width=1; + sys.mc.memory_accesses=1; + sys.mc.memory_reads=1; + sys.mc.memory_writes=1; + sys.mc.LVDS=true; + sys.mc.type=1; - // system_niu - sys.niu.clockrate = 1; - sys.niu.number_units = 1; - sys.niu.type = 1; - sys.niu.duty_cycle = 1; - sys.niu.total_load_perc = 1; - // system_pcie - sys.pcie.clockrate = 1; - sys.pcie.number_units = 1; - sys.pcie.num_channels = 1; - sys.pcie.type = 1; - sys.pcie.withPHY = false; - sys.pcie.duty_cycle = 1; - sys.pcie.total_load_perc = 1; - // system_flash_controller - sys.flashc.mc_clock = 1; - sys.flashc.number_mcs = 1; - sys.flashc.peak_transfer_rate = 1; - sys.flashc.memory_channels_per_mc = 1; - sys.flashc.number_ranks = 1; - sys.flashc.req_window_size_per_channel = 1; - sys.flashc.IO_buffer_size_per_channel = 1; - sys.flashc.databus_width = 1; - sys.flashc.addressbus_width = 1; - sys.flashc.memory_accesses = 1; - sys.flashc.memory_reads = 1; - sys.flashc.memory_writes = 1; - sys.flashc.LVDS = true; - sys.flashc.withPHY = false; - sys.flashc.type = 1; - sys.flashc.duty_cycle = 1; - sys.flashc.total_load_perc = 1; + //system_niu + sys.niu.clockrate =1; + sys.niu.number_units=1; + sys.niu.type = 1; + sys.niu.duty_cycle =1; + sys.niu.total_load_perc=1; + //system_pcie + sys.pcie.clockrate =1; + sys.pcie.number_units=1; + sys.pcie.num_channels=1; + sys.pcie.type = 1; + sys.pcie.withPHY = false; + sys.pcie.duty_cycle =1; + sys.pcie.total_load_perc=1; + //system_flash_controller + sys.flashc.mc_clock =1; + sys.flashc.number_mcs=1; + sys.flashc.peak_transfer_rate =1; + sys.flashc.memory_channels_per_mc=1; + sys.flashc.number_ranks=1; + sys.flashc.req_window_size_per_channel=1; + sys.flashc.IO_buffer_size_per_channel=1; + sys.flashc.databus_width=1; + sys.flashc.addressbus_width=1; + sys.flashc.memory_accesses=1; + sys.flashc.memory_reads=1; + sys.flashc.memory_writes=1; + sys.flashc.LVDS=true; + sys.flashc.withPHY = false; + sys.flashc.type =1; + sys.flashc.duty_cycle =1; + sys.flashc.total_load_perc=1; } diff --git a/src/gpuwattch/XML_Parse.h b/src/gpuwattch/XML_Parse.h index 7e5d651..d2f82be 100644 --- a/src/gpuwattch/XML_Parse.h +++ b/src/gpuwattch/XML_Parse.h @@ -27,10 +27,9 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.” * - ***************************************************************************/ + ***************************************************************************/ /******************************************************************** -* Modified by: -** +* Modified by: * * Jingwen Leng, Univeristy of Texas, Austin * * Syed Gilani, University of Wisconsin–Madison * * Tayler Hetherington, University of British Columbia * @@ -40,656 +39,650 @@ #ifndef XML_PARSE_H_ #define XML_PARSE_H_ + //#ifdef WIN32 //#define _CRT_SECURE_NO_DEPRECATE //#endif #include +#include "xmlParser.h" #include #include -#include "xmlParser.h" using namespace std; /* void myfree(char *t); // {free(t);} ToXMLStringTool tx,tx2; */ -// all subnodes at the level of system.core(0-n) -// cache_policy is added into cache property arrays;//0 no write or write-though -// with non-write allocate;1 write-back with write-allocate -// -// tgrogers - This was a static array declared in the header... -// Not too sure why the authors did this, maybe they didn't understand -// the context -// of the "static" keyword outside a class declaration. As it was -// written, each object file -// had it's own copy of the string list - which is okay, since the -// string is constant but -// wastes space and causes the compiler to complain about unused vars -// in files where this header -// is included but they don't use the variable. Now this is extern'd -// here and the storage/definition -// is in the XML_Parse.cc file -extern const char* perf_count_label[]; - +//all subnodes at the level of system.core(0-n) +//cache_policy is added into cache property arrays;//0 no write or write-though with non-write allocate;1 write-back with write-allocate +// +//tgrogers - This was a static array declared in the header... +// Not too sure why the authors did this, maybe they didn't understand the context +// of the "static" keyword outside a class declaration. As it was written, each object file +// had it's own copy of the string list - which is okay, since the string is constant but +// wastes space and causes the compiler to complain about unused vars in files where this header +// is included but they don't use the variable. Now this is extern'd here and the storage/definition +// is in the XML_Parse.cc file +extern const char * perf_count_label[]; + enum perf_count_t { - TOT_INST = 0, - FP_INT, - IC_H, - IC_M, - DC_RH, - DC_RM, - DC_WH, - DC_WM, - TC_H, - TC_M, - CC_H, - CC_M, - SHRD_ACC, - REG_RD, - REG_WR, - NON_REG_OPs, - SP_ACC, - SFU_ACC, - FPU_ACC, - MEM_RD, - MEM_WR, - MEM_PRE, - L2_RH, - L2_RM, - L2_WH, - L2_WM, - NOC_A, - PIPE_A, - IDLE_CORE_N, - CONST_DYNAMICN, - NUM_PERFORMANCE_COUNTERS + TOT_INST=0, + FP_INT, + IC_H, + IC_M, + DC_RH, + DC_RM, + DC_WH, + DC_WM, + TC_H, + TC_M, + CC_H, + CC_M, + SHRD_ACC, + REG_RD, + REG_WR, + NON_REG_OPs, + SP_ACC, + SFU_ACC, + FPU_ACC, + MEM_RD, + MEM_WR, + MEM_PRE, + L2_RH, + L2_RM, + L2_WH, + L2_WM, + NOC_A, + PIPE_A, + IDLE_CORE_N, + CONST_DYNAMICN, + NUM_PERFORMANCE_COUNTERS }; -typedef struct { - int prediction_width; - char prediction_scheme[20]; - int predictor_size; - int predictor_entries; - int local_predictor_size[20]; - int local_predictor_entries; - int global_predictor_entries; - int global_predictor_bits; - int chooser_predictor_entries; - int chooser_predictor_bits; - double predictor_accesses; +typedef struct{ + int prediction_width; + char prediction_scheme[20]; + int predictor_size; + int predictor_entries; + int local_predictor_size[20]; + int local_predictor_entries; + int global_predictor_entries; + int global_predictor_bits; + int chooser_predictor_entries; + int chooser_predictor_bits; + double predictor_accesses; } predictor_systemcore; -typedef struct { - int number_entries; - int cache_policy; // 0 no write or write-though with non-write allocate;1 - // write-back with write-allocate - double total_hits; - double total_accesses; - double total_misses; - double conflicts; +typedef struct{ + int number_entries; + int cache_policy;//0 no write or write-though with non-write allocate;1 write-back with write-allocate + double total_hits; + double total_accesses; + double total_misses; + double conflicts; } itlb_systemcore; -typedef struct { - // params - double icache_config[20]; - int buffer_sizes[20]; - int cache_policy; // 0 no write or write-though with non-write allocate;1 - // write-back with write-allocate - // stats - double total_accesses; - double read_accesses; - double read_misses; - double replacements; - double read_hits; - double total_hits; - double total_misses; - double miss_buffer_access; - double fill_buffer_accesses; - double prefetch_buffer_accesses; - double prefetch_buffer_writes; - double prefetch_buffer_reads; - double prefetch_buffer_hits; - double conflicts; +typedef struct{ + //params + double icache_config[20]; + int buffer_sizes[20]; + int cache_policy;//0 no write or write-though with non-write allocate;1 write-back with write-allocate + //stats + double total_accesses; + double read_accesses; + double read_misses; + double replacements; + double read_hits; + double total_hits; + double total_misses; + double miss_buffer_access; + double fill_buffer_accesses; + double prefetch_buffer_accesses; + double prefetch_buffer_writes; + double prefetch_buffer_reads; + double prefetch_buffer_hits; + double conflicts; } icache_systemcore; -typedef struct { - // params - int number_entries; - int cache_policy; // 0 no write or write-though with non-write allocate;1 - // write-back with write-allocate - // stats - double total_accesses; - double read_accesses; - double write_accesses; - double write_hits; - double read_hits; - double read_misses; - double write_misses; - double total_hits; - double total_misses; - double conflicts; +typedef struct{ + //params + int number_entries; + int cache_policy;//0 no write or write-though with non-write allocate;1 write-back with write-allocate + //stats + double total_accesses; + double read_accesses; + double write_accesses; + double write_hits; + double read_hits; + double read_misses; + double write_misses; + double total_hits; + double total_misses; + double conflicts; } dtlb_systemcore; -typedef struct { - // params - double dcache_config[20]; - int buffer_sizes[20]; - int cache_policy; // 0 no write or write-though with non-write allocate;1 - // write-back with write-allocate - // stats - double total_accesses; - double read_accesses; - double write_accesses; - double total_hits; - double total_misses; - double read_hits; - double write_hits; - double read_misses; - double write_misses; - double replacements; - double write_backs; - double miss_buffer_access; - double fill_buffer_accesses; - double prefetch_buffer_accesses; - double prefetch_buffer_writes; - double prefetch_buffer_reads; - double prefetch_buffer_hits; - double wbb_writes; - double wbb_reads; - double conflicts; +typedef struct{ + //params + double dcache_config[20]; + int buffer_sizes[20]; + int cache_policy;//0 no write or write-though with non-write allocate;1 write-back with write-allocate + //stats + double total_accesses; + double read_accesses; + double write_accesses; + double total_hits; + double total_misses; + double read_hits; + double write_hits; + double read_misses; + double write_misses; + double replacements; + double write_backs; + double miss_buffer_access; + double fill_buffer_accesses; + double prefetch_buffer_accesses; + double prefetch_buffer_writes; + double prefetch_buffer_reads; + double prefetch_buffer_hits; + double wbb_writes; + double wbb_reads; + double conflicts; } dcache_systemcore; -typedef struct { - // params - int BTB_config[20]; - // stats - double total_accesses; - double read_accesses; - double write_accesses; - double total_hits; - double total_misses; - double read_hits; - double write_hits; - double read_misses; - double write_misses; - double replacements; +typedef struct{ + //params + int BTB_config[20]; + //stats + double total_accesses; + double read_accesses; + double write_accesses; + double total_hits; + double total_misses; + double read_hits; + double write_hits; + double read_misses; + double write_misses; + double replacements; } BTB_systemcore; -typedef struct { - // all params at the level of system.core(0-n) - int clock_rate; - bool opt_local; - bool x86; - int machine_bits; - int virtual_address_width; - int physical_address_width; - int opcode_width; - int micro_opcode_width; - int instruction_length; - int machine_type; - int internal_datapath_width; - int number_hardware_threads; - int fetch_width; - int number_instruction_fetch_ports; - int decode_width; - int issue_width; - int peak_issue_width; - int commit_width; - int pipelines_per_core[20]; - int pipeline_depth[20]; - char FPU[20]; - char divider_multiplier[20]; - int ALU_per_core; - double FPU_per_core; - int MUL_per_core; - int instruction_buffer_size; - int decoded_stream_buffer_size; - int instruction_window_scheme; - int instruction_window_size; - int fp_instruction_window_size; - int ROB_size; - int archi_Regs_IRF_size; - int archi_Regs_FRF_size; - int phy_Regs_IRF_size; - int phy_Regs_FRF_size; - int rename_scheme; - int register_windows_size; - char LSU_order[20]; - int store_buffer_size; - int load_buffer_size; - int memory_ports; - char Dcache_dual_pump[20]; - int RAS_size; - int fp_issue_width; - int prediction_width; - int number_of_BTB; - int number_of_BPT; - bool gpgpu_clock_gated_lanes; +typedef struct{ + //all params at the level of system.core(0-n) + int clock_rate; + bool opt_local; + bool x86; + int machine_bits; + int virtual_address_width; + int physical_address_width; + int opcode_width; + int micro_opcode_width; + int instruction_length; + int machine_type; + int internal_datapath_width; + int number_hardware_threads; + int fetch_width; + int number_instruction_fetch_ports; + int decode_width; + int issue_width; + int peak_issue_width; + int commit_width; + int pipelines_per_core[20]; + int pipeline_depth[20]; + char FPU[20]; + char divider_multiplier[20]; + int ALU_per_core; + double FPU_per_core; + int MUL_per_core; + int instruction_buffer_size; + int decoded_stream_buffer_size; + int instruction_window_scheme; + int instruction_window_size; + int fp_instruction_window_size; + int ROB_size; + int archi_Regs_IRF_size; + int archi_Regs_FRF_size; + int phy_Regs_IRF_size; + int phy_Regs_FRF_size; + int rename_scheme; + int register_windows_size; + char LSU_order[20]; + int store_buffer_size; + int load_buffer_size; + int memory_ports; + char Dcache_dual_pump[20]; + int RAS_size; + int fp_issue_width; + int prediction_width; + int number_of_BTB; + int number_of_BPT; + bool gpgpu_clock_gated_lanes; - // all stats at the level of system.core(0-n) - double total_instructions; - double int_instructions; - double fp_instructions; - double branch_instructions; - double branch_mispredictions; - double committed_instructions; - double committed_int_instructions; - double committed_fp_instructions; - double load_instructions; - double store_instructions; - double total_cycles; - double idle_cycles; - double busy_cycles; - double instruction_buffer_reads; - double instruction_buffer_write; - double ROB_reads; - double ROB_writes; - double rename_accesses; - double fp_rename_accesses; - double rename_reads; - double rename_writes; - double fp_rename_reads; - double fp_rename_writes; - double inst_window_reads; - double inst_window_writes; - double inst_window_wakeup_accesses; - double inst_window_selections; - double fp_inst_window_reads; - double fp_inst_window_writes; - double fp_inst_window_wakeup_accesses; - double fp_inst_window_selections; - double archi_int_regfile_reads; - double archi_float_regfile_reads; - double phy_int_regfile_reads; - double phy_float_regfile_reads; - double phy_int_regfile_writes; - double phy_float_regfile_writes; - double archi_int_regfile_writes; - double archi_float_regfile_writes; - double int_regfile_reads; - double float_regfile_reads; - double int_regfile_writes; - double float_regfile_writes; - double non_rf_operands; - double windowed_reg_accesses; - double windowed_reg_transports; - double function_calls; - double context_switches; - double ialu_accesses; - double fpu_accesses; - double mul_accesses; - double sp_average_active_lanes; - double sfu_average_active_lanes; - double cdb_alu_accesses; - double cdb_mul_accesses; - double cdb_fpu_accesses; - double load_buffer_reads; - double load_buffer_writes; - double load_buffer_cams; - double store_buffer_reads; - double store_buffer_writes; - double store_buffer_cams; - double store_buffer_forwards; - double main_memory_access; - double main_memory_read; - double main_memory_write; - double pipeline_duty_cycle; + //all stats at the level of system.core(0-n) + double total_instructions; + double int_instructions; + double fp_instructions; + double branch_instructions; + double branch_mispredictions; + double committed_instructions; + double committed_int_instructions; + double committed_fp_instructions; + double load_instructions; + double store_instructions; + double total_cycles; + double idle_cycles; + double busy_cycles; + double instruction_buffer_reads; + double instruction_buffer_write; + double ROB_reads; + double ROB_writes; + double rename_accesses; + double fp_rename_accesses; + double rename_reads; + double rename_writes; + double fp_rename_reads; + double fp_rename_writes; + double inst_window_reads; + double inst_window_writes; + double inst_window_wakeup_accesses; + double inst_window_selections; + double fp_inst_window_reads; + double fp_inst_window_writes; + double fp_inst_window_wakeup_accesses; + double fp_inst_window_selections; + double archi_int_regfile_reads; + double archi_float_regfile_reads; + double phy_int_regfile_reads; + double phy_float_regfile_reads; + double phy_int_regfile_writes; + double phy_float_regfile_writes; + double archi_int_regfile_writes; + double archi_float_regfile_writes; + double int_regfile_reads; + double float_regfile_reads; + double int_regfile_writes; + double float_regfile_writes; + double non_rf_operands; + double windowed_reg_accesses; + double windowed_reg_transports; + double function_calls; + double context_switches; + double ialu_accesses; + double fpu_accesses; + double mul_accesses; + double sp_average_active_lanes; + double sfu_average_active_lanes; + double cdb_alu_accesses; + double cdb_mul_accesses; + double cdb_fpu_accesses; + double load_buffer_reads; + double load_buffer_writes; + double load_buffer_cams; + double store_buffer_reads; + double store_buffer_writes; + double store_buffer_cams; + double store_buffer_forwards; + double main_memory_access; + double main_memory_read; + double main_memory_write; + double pipeline_duty_cycle; - double IFU_duty_cycle; - double BR_duty_cycle; - double LSU_duty_cycle; - double MemManU_I_duty_cycle; - double MemManU_D_duty_cycle; - double ALU_duty_cycle; - double MUL_duty_cycle; - double FPU_duty_cycle; - double ALU_cdb_duty_cycle; - double MUL_cdb_duty_cycle; - double FPU_cdb_duty_cycle; + double IFU_duty_cycle ; + double BR_duty_cycle ; + double LSU_duty_cycle ; + double MemManU_I_duty_cycle; + double MemManU_D_duty_cycle ; + double ALU_duty_cycle ; + double MUL_duty_cycle ; + double FPU_duty_cycle ; + double ALU_cdb_duty_cycle ; + double MUL_cdb_duty_cycle ; + double FPU_cdb_duty_cycle ; - double num_idle_cores; + double num_idle_cores; - int rf_banks; // (4) - int simd_width; // (8) - int collector_units; // (4) - double core_clock_ratio; // (2.0) - int warp_size; // (32) - // all subnodes at the level of system.core(0-n) - predictor_systemcore predictor; - itlb_systemcore itlb; - icache_systemcore icache; - dtlb_systemcore dtlb; - dcache_systemcore dcache; - dcache_systemcore ccache; - dcache_systemcore tcache; - dcache_systemcore sharedmemory; // added by Jingwen - BTB_systemcore BTB; + int rf_banks;// (4) + int simd_width;// (8) + int collector_units;// (4) + double core_clock_ratio;// (2.0) + int warp_size;// (32) + + //all subnodes at the level of system.core(0-n) + predictor_systemcore predictor; + itlb_systemcore itlb; + icache_systemcore icache; + dtlb_systemcore dtlb; + dcache_systemcore dcache; + dcache_systemcore ccache; + dcache_systemcore tcache; + dcache_systemcore sharedmemory; // added by Jingwen + BTB_systemcore BTB; } system_core; -typedef struct { - // params - int Directory_type; - double Dir_config[20]; - int buffer_sizes[20]; - int clockrate; - int ports[20]; - int device_type; - int cache_policy; // 0 no write or write-though with non-write allocate;1 - // write-back with write-allocate - char threeD_stack[20]; - // stats - double total_accesses; - double read_accesses; - double write_accesses; - double read_misses; - double write_misses; - double conflicts; - double duty_cycle; +typedef struct{ + //params + int Directory_type; + double Dir_config[20]; + int buffer_sizes[20]; + int clockrate; + int ports[20]; + int device_type; + int cache_policy;//0 no write or write-though with non-write allocate;1 write-back with write-allocate + char threeD_stack[20]; + //stats + double total_accesses; + double read_accesses; + double write_accesses; + double read_misses; + double write_misses; + double conflicts; + double duty_cycle; } system_L1Directory; -typedef struct { - // params - int Directory_type; - double Dir_config[20]; - int buffer_sizes[20]; - int clockrate; - int ports[20]; - int device_type; - int cache_policy; // 0 no write or write-though with non-write allocate;1 - // write-back with write-allocate - char threeD_stack[20]; - // stats - double total_accesses; - double read_accesses; - double write_accesses; - double read_misses; - double write_misses; - double conflicts; - double duty_cycle; +typedef struct{ + //params + int Directory_type; + double Dir_config[20]; + int buffer_sizes[20]; + int clockrate; + int ports[20]; + int device_type; + int cache_policy;//0 no write or write-though with non-write allocate;1 write-back with write-allocate + char threeD_stack[20]; + //stats + double total_accesses; + double read_accesses; + double write_accesses; + double read_misses; + double write_misses; + double conflicts; + double duty_cycle; } system_L2Directory; -typedef struct { - // params - double L2_config[20]; - int clockrate; - int ports[20]; - int device_type; - int cache_policy; // 0 no write or write-though with non-write allocate;1 - // write-back with write-allocate - char threeD_stack[20]; - int buffer_sizes[20]; - // stats - double total_accesses; - double read_accesses; - double write_accesses; - double total_hits; - double total_misses; - double read_hits; - double write_hits; - double read_misses; - double write_misses; - double replacements; - double write_backs; - double miss_buffer_accesses; - double fill_buffer_accesses; - double prefetch_buffer_accesses; - double prefetch_buffer_writes; - double prefetch_buffer_reads; - double prefetch_buffer_hits; - double wbb_writes; - double wbb_reads; - double conflicts; - double duty_cycle; +typedef struct{ + //params + double L2_config[20]; + int clockrate; + int ports[20]; + int device_type; + int cache_policy;//0 no write or write-though with non-write allocate;1 write-back with write-allocate + char threeD_stack[20]; + int buffer_sizes[20]; + //stats + double total_accesses; + double read_accesses; + double write_accesses; + double total_hits; + double total_misses; + double read_hits; + double write_hits; + double read_misses; + double write_misses; + double replacements; + double write_backs; + double miss_buffer_accesses; + double fill_buffer_accesses; + double prefetch_buffer_accesses; + double prefetch_buffer_writes; + double prefetch_buffer_reads; + double prefetch_buffer_hits; + double wbb_writes; + double wbb_reads; + double conflicts; + double duty_cycle; - bool merged_dir; - double homenode_read_accesses; - double homenode_write_accesses; - double homenode_read_hits; - double homenode_write_hits; - double homenode_read_misses; - double homenode_write_misses; - double dir_duty_cycle; + bool merged_dir; + double homenode_read_accesses; + double homenode_write_accesses; + double homenode_read_hits; + double homenode_write_hits; + double homenode_read_misses; + double homenode_write_misses; + double dir_duty_cycle; } system_L2; -typedef struct { - // params - double L3_config[20]; - int clockrate; - int ports[20]; - int device_type; - int cache_policy; // 0 no write or write-though with non-write allocate;1 - // write-back with write-allocate - char threeD_stack[20]; - int buffer_sizes[20]; - // stats - double total_accesses; - double read_accesses; - double write_accesses; - double total_hits; - double total_misses; - double read_hits; - double write_hits; - double read_misses; - double write_misses; - double replacements; - double write_backs; - double miss_buffer_accesses; - double fill_buffer_accesses; - double prefetch_buffer_accesses; - double prefetch_buffer_writes; - double prefetch_buffer_reads; - double prefetch_buffer_hits; - double wbb_writes; - double wbb_reads; - double conflicts; - double duty_cycle; +typedef struct{ + //params + double L3_config[20]; + int clockrate; + int ports[20]; + int device_type; + int cache_policy;//0 no write or write-though with non-write allocate;1 write-back with write-allocate + char threeD_stack[20]; + int buffer_sizes[20]; + //stats + double total_accesses; + double read_accesses; + double write_accesses; + double total_hits; + double total_misses; + double read_hits; + double write_hits; + double read_misses; + double write_misses; + double replacements; + double write_backs; + double miss_buffer_accesses; + double fill_buffer_accesses; + double prefetch_buffer_accesses; + double prefetch_buffer_writes; + double prefetch_buffer_reads; + double prefetch_buffer_hits; + double wbb_writes; + double wbb_reads; + double conflicts; + double duty_cycle; - bool merged_dir; - double homenode_read_accesses; - double homenode_write_accesses; - double homenode_read_hits; - double homenode_write_hits; - double homenode_read_misses; - double homenode_write_misses; - double dir_duty_cycle; + bool merged_dir; + double homenode_read_accesses; + double homenode_write_accesses; + double homenode_read_hits; + double homenode_write_hits; + double homenode_read_misses; + double homenode_write_misses; + double dir_duty_cycle; } system_L3; -typedef struct { - // params - int number_of_inputs_of_crossbars; - int number_of_outputs_of_crossbars; - int flit_bits; - int input_buffer_entries_per_port; - int ports_of_input_buffer[20]; - // stats - double crossbar_accesses; +typedef struct{ + //params + int number_of_inputs_of_crossbars; + int number_of_outputs_of_crossbars; + int flit_bits; + int input_buffer_entries_per_port; + int ports_of_input_buffer[20]; + //stats + double crossbar_accesses; } xbar0_systemNoC; -typedef struct { - // params - int clockrate; - bool type; - bool has_global_link; - char topology[20]; - int horizontal_nodes; - int vertical_nodes; - int link_throughput; - int link_latency; - int input_ports; - int output_ports; - int virtual_channel_per_port; - int flit_bits; - int input_buffer_entries_per_vc; - int ports_of_input_buffer[20]; - int dual_pump; - int number_of_crossbars; - char crossbar_type[20]; - char crosspoint_type[20]; - xbar0_systemNoC xbar0; - int arbiter_type; - double chip_coverage; - // stats - double total_accesses; - double duty_cycle; - double route_over_perc; +typedef struct{ + //params + int clockrate; + bool type; + bool has_global_link; + char topology[20]; + int horizontal_nodes; + int vertical_nodes; + int link_throughput; + int link_latency; + int input_ports; + int output_ports; + int virtual_channel_per_port; + int flit_bits; + int input_buffer_entries_per_vc; + int ports_of_input_buffer[20]; + int dual_pump; + int number_of_crossbars; + char crossbar_type[20]; + char crosspoint_type[20]; + xbar0_systemNoC xbar0; + int arbiter_type; + double chip_coverage; + //stats + double total_accesses; + double duty_cycle; + double route_over_perc; } system_NoC; -typedef struct { - // params - int mem_tech_node; - int device_clock; - int peak_transfer_rate; - int internal_prefetch_of_DRAM_chip; - int capacity_per_channel; - int number_ranks; - int num_banks_of_DRAM_chip; - int Block_width_of_DRAM_chip; - int output_width_of_DRAM_chip; - int page_size_of_DRAM_chip; - int burstlength_of_DRAM_chip; - - // stats - double memory_accesses; - double memory_reads; - double memory_writes; - double dram_pre; +typedef struct{ + //params + int mem_tech_node; + int device_clock; + int peak_transfer_rate; + int internal_prefetch_of_DRAM_chip; + int capacity_per_channel; + int number_ranks; + int num_banks_of_DRAM_chip; + int Block_width_of_DRAM_chip; + int output_width_of_DRAM_chip; + int page_size_of_DRAM_chip; + int burstlength_of_DRAM_chip; + + //stats + double memory_accesses; + double memory_reads; + double memory_writes; + double dram_pre; } system_mem; -typedef struct { - // params - // Common Param for mc and fc - double peak_transfer_rate; - int number_mcs; - bool withPHY; - int type; +typedef struct{ + //params + //Common Param for mc and fc + double peak_transfer_rate; + int number_mcs; + bool withPHY; + int type; - // FCParam - // stats - double duty_cycle; - double total_load_perc; + //FCParam + //stats + double duty_cycle; + double total_load_perc; - // McParam - int mc_clock; - int llc_line_length; - int memory_channels_per_mc; - int number_ranks; - int req_window_size_per_channel; - int IO_buffer_size_per_channel; - int databus_width; - int addressbus_width; - int PRT_entries; - bool LVDS; + //McParam + int mc_clock; + int llc_line_length; + int memory_channels_per_mc; + int number_ranks; + int req_window_size_per_channel; + int IO_buffer_size_per_channel; + int databus_width; + int addressbus_width; + int PRT_entries; + bool LVDS; + + // emprical DRAM coeff + double dram_cmd_coeff; + double dram_act_coeff; + double dram_nop_coeff; + double dram_activity_coeff; + double dram_pre_coeff; + double dram_rd_coeff; + double dram_wr_coeff; + double dram_req_coeff; + double dram_const_coeff; - // emprical DRAM coeff - double dram_cmd_coeff; - double dram_act_coeff; - double dram_nop_coeff; - double dram_activity_coeff; - double dram_pre_coeff; - double dram_rd_coeff; - double dram_wr_coeff; - double dram_req_coeff; - double dram_const_coeff; + //stats + double memory_accesses; + double memory_reads; + double memory_writes; - // stats - double memory_accesses; - double memory_reads; - double memory_writes; + //dram stats + double dram_cmd; + double dram_activity; + double dram_nop; + double dram_act; + double dram_pre; + double dram_rd; + double dram_wr; + double dram_req; - // dram stats - double dram_cmd; - double dram_activity; - double dram_nop; - double dram_act; - double dram_pre; - double dram_rd; - double dram_wr; - double dram_req; } system_mc; -typedef struct { - // params - int clockrate; - int number_units; - int type; - // stats - double duty_cycle; - double total_load_perc; +typedef struct{ + //params + int clockrate; + int number_units; + int type; + //stats + double duty_cycle; + double total_load_perc; } system_niu; -typedef struct { - // params - int clockrate; - int number_units; - int num_channels; - int type; - bool withPHY; - // stats - double duty_cycle; - double total_load_perc; +typedef struct{ + //params + int clockrate; + int number_units; + int num_channels; + int type; + bool withPHY; + //stats + double duty_cycle; + double total_load_perc; } system_pcie; -typedef struct { - // All number_of_* at the level of 'system' Ying 03/21/2009 - int GPU_Architecture; - int number_of_cores; - int architecture; - int number_of_L1Directories; - int number_of_L2Directories; - int number_of_L2s; - bool Private_L2; - int number_of_L3s; - int number_of_NoCs; - int number_of_dir_levels; - int domain_size; - int first_level_dir; - // All params at the level of 'system' - int homogeneous_cores; - int homogeneous_L1Directories; - int homogeneous_L2Directories; - double core_tech_node; - int target_core_clockrate; - int target_chip_area; - int temperature; - int number_cache_levels; - int L1_property; - int L2_property; - int homogeneous_L2s; - int L3_property; - int homogeneous_L3s; - int homogeneous_NoCs; - int homogeneous_ccs; - int Max_area_deviation; - int Max_power_deviation; - int device_type; - bool longer_channel_device; - bool Embedded; - bool opt_dynamic_power; - bool opt_lakage_power; - bool opt_clockrate; - bool opt_area; - int interconnect_projection_type; - int machine_bits; - int virtual_address_width; - int physical_address_width; - int virtual_memory_page_size; - double idle_core_power; - double num_idle_cores; - int arch; - double total_cycles; - // system.core(0-n):3rd level - double scaling_coefficients[64]; - system_core core[64]; - system_L1Directory L1Directory[64]; - system_L2Directory L2Directory[64]; - system_L2 L2[64]; - system_L2 l2; - system_L3 L3[64]; - system_NoC NoC[64]; - system_mem mem; - system_mc mc; - system_mc flashc; - system_niu niu; - system_pcie pcie; +typedef struct{ + //All number_of_* at the level of 'system' Ying 03/21/2009 + int GPU_Architecture; + int number_of_cores; + int architecture; + int number_of_L1Directories; + int number_of_L2Directories; + int number_of_L2s; + bool Private_L2; + int number_of_L3s; + int number_of_NoCs; + int number_of_dir_levels; + int domain_size; + int first_level_dir; + // All params at the level of 'system' + int homogeneous_cores; + int homogeneous_L1Directories; + int homogeneous_L2Directories; + double core_tech_node; + int target_core_clockrate; + int target_chip_area; + int temperature; + int number_cache_levels; + int L1_property; + int L2_property; + int homogeneous_L2s; + int L3_property; + int homogeneous_L3s; + int homogeneous_NoCs; + int homogeneous_ccs; + int Max_area_deviation; + int Max_power_deviation; + int device_type; + bool longer_channel_device; + bool Embedded; + bool opt_dynamic_power; + bool opt_lakage_power; + bool opt_clockrate; + bool opt_area; + int interconnect_projection_type; + int machine_bits; + int virtual_address_width; + int physical_address_width; + int virtual_memory_page_size; + double idle_core_power; + double num_idle_cores; + int arch; + double total_cycles; + //system.core(0-n):3rd level + double scaling_coefficients[64]; + system_core core[64]; + system_L1Directory L1Directory[64]; + system_L2Directory L2Directory[64]; + system_L2 L2[64]; + system_L2 l2; + system_L3 L3[64]; + system_NoC NoC[64]; + system_mem mem; + system_mc mc; + system_mc flashc; + system_niu niu; + system_pcie pcie; } root_system; -class ParseXML { - public: - void parse(char* filepath); - void initialize(); - - public: - root_system sys; +class ParseXML +{ +public: + void parse(char* filepath); + void initialize(); +public: + root_system sys; }; + #endif /* XML_PARSE_H_ */ + + + + diff --git a/src/gpuwattch/arch_const.h b/src/gpuwattch/arch_const.h index 77e26a8..feffa6c 100644 --- a/src/gpuwattch/arch_const.h +++ b/src/gpuwattch/arch_const.h @@ -32,190 +32,202 @@ #ifndef ARCH_CONST_H_ #define ARCH_CONST_H_ -typedef struct { - unsigned int capacity; - unsigned int assoc; // fully - unsigned int blocksize; +typedef struct{ + unsigned int capacity; + unsigned int assoc;//fully + unsigned int blocksize; } array_inputs; -// Do Not change, unless you want to bypass the XML interface and do not care -// about the default values. -// Global parameters -const int number_of_cores = 8; -const int number_of_L2s = 1; -const int number_of_L3s = 1; -const int number_of_NoCs = 1; - -const double archi_F_sz_nm = 90.0; -const unsigned int dev_type = 0; -const double CLOCKRATE = 1.2 * 1e9; -const double AF = 0.5; -// const bool inorder = true; -const bool embedded = false; // NEW - -const bool homogeneous_cores = true; -const bool temperature = 360; -const int number_cache_levels = 3; -const int L1_property = 0; // private 0; coherent 1, shared 2. -const int L2_property = 2; -const bool homogeneous_L2s = true; -const bool L3_property = 2; -const bool homogeneous_L3s = true; -const double Max_area_deviation = 50; -const double Max_dynamic_deviation = 50; // New -const int opt_dynamic_power = 1; -const int opt_lakage_power = 0; -const int opt_area = 0; -const int interconnect_projection_type = 0; +//Do Not change, unless you want to bypass the XML interface and do not care about the default values. +//Global parameters +const int number_of_cores = 8; +const int number_of_L2s = 1; +const int number_of_L3s = 1; +const int number_of_NoCs = 1; + +const double archi_F_sz_nm = 90.0; +const unsigned int dev_type = 0; +const double CLOCKRATE = 1.2*1e9; +const double AF = 0.5; +//const bool inorder = true; +const bool embedded = false; //NEW + +const bool homogeneous_cores = true; +const bool temperature = 360; +const int number_cache_levels = 3; +const int L1_property = 0; //private 0; coherent 1, shared 2. +const int L2_property = 2; +const bool homogeneous_L2s = true; +const bool L3_property = 2; +const bool homogeneous_L3s = true; +const double Max_area_deviation = 50; +const double Max_dynamic_deviation =50; //New +const int opt_dynamic_power = 1; +const int opt_lakage_power = 0; +const int opt_area = 0; +const int interconnect_projection_type = 0; //******************************Core Parameters #if (inorder) -const int opcode_length = 8; // Niagara -const int reg_length = 5; // Niagara -const int instruction_length = 32; // Niagara -const int data_width = 64; +const int opcode_length = 8;//Niagara +const int reg_length = 5;//Niagara +const int instruction_length = 32;//Niagara +const int data_width = 64; #else -const int opcode_length = 8; // 16;//Niagara -const int reg_length = 7; // Niagara -const int instruction_length = 32; // Niagara -const int data_width = 64; +const int opcode_length = 8;//16;//Niagara +const int reg_length = 7;//Niagara +const int instruction_length = 32;//Niagara +const int data_width = 64; #endif -// Caches -// itlb -const int itlbsize = 512; -const int itlbassoc = 0; // fully -const int itlbblocksize = 8; -// icache -const int icachesize = 32768; -const int icacheassoc = 4; -const int icacheblocksize = 32; -// dtlb -const int dtlbsize = 512; -const int dtlbassoc = 0; // fully -const int dtlbblocksize = 8; -// dcache -const int dcachesize = 32768; -const int dcacheassoc = 4; -const int dcacheblocksize = 32; -const int dcache_write_buffers = 8; - -// cache controllers -// IB, -const int numIBEntries = 64; -const int IBsize = 64; // 2*4*instruction_length/8*2; -const int IBassoc = 0; // In Niagara it is still fully associ -const int IBblocksize = 4; - -// IFB and MIL should have the same parameters CAM -const int IFBsize = 128; // -const int IFBassoc = 0; // In Niagara it is still fully associ -const int IFBblocksize = 4; - -const int icache_write_buffers = 8; - -// register file RAM -const int regfilesize = 5760; -const int regfileassoc = 1; -const int regfileblocksize = 18; -// regwin RAM -const int regwinsize = 256; -const int regwinassoc = 1; -const int regwinblocksize = 8; - -// store buffer, lsq -const int lsqsize = 512; -const int lsqassoc = 0; -const int lsqblocksize = 8; - -// data fill queue RAM -const int dfqsize = 1024; -const int dfqassoc = 1; -const int dfqblocksize = 16; - -// outside the cores -// L2 cache bank -const int l2cachesize = 262144; -const int l2cacheassoc = 16; -const int l2cacheblocksize = 64; - -// L2 directory -const int l2dirsize = 1024; -const int l2dirassoc = 0; -const int l2dirblocksize = 2; - -// crossbar -// PCX + +//Caches +//itlb +const int itlbsize=512; +const int itlbassoc=0;//fully +const int itlbblocksize=8; +//icache +const int icachesize=32768; +const int icacheassoc=4; +const int icacheblocksize=32; +//dtlb +const int dtlbsize=512; +const int dtlbassoc=0;//fully +const int dtlbblocksize=8; +//dcache +const int dcachesize=32768; +const int dcacheassoc=4; +const int dcacheblocksize=32; +const int dcache_write_buffers=8; + +//cache controllers +//IB, +const int numIBEntries = 64; +const int IBsize = 64;//2*4*instruction_length/8*2; +const int IBassoc = 0;//In Niagara it is still fully associ +const int IBblocksize = 4; + +//IFB and MIL should have the same parameters CAM +const int IFBsize=128;// +const int IFBassoc=0;//In Niagara it is still fully associ +const int IFBblocksize=4; + + + + +const int icache_write_buffers=8; + +//register file RAM +const int regfilesize=5760; +const int regfileassoc=1; +const int regfileblocksize=18; +//regwin RAM +const int regwinsize=256; +const int regwinassoc=1; +const int regwinblocksize=8; + + + +//store buffer, lsq +const int lsqsize=512; +const int lsqassoc=0; +const int lsqblocksize=8; + +//data fill queue RAM +const int dfqsize=1024; +const int dfqassoc=1; +const int dfqblocksize=16; + +//outside the cores +//L2 cache bank +const int l2cachesize=262144; +const int l2cacheassoc=16; +const int l2cacheblocksize=64; + +//L2 directory +const int l2dirsize=1024; +const int l2dirassoc=0; +const int l2dirblocksize=2; + +//crossbar +//PCX const int PCX_NUMBER_INPUT_PORTS_CROSSBAR = 8; const int PCX_NUMBER_OUTPUT_PORTS_CROSSBAR = 9; -const int PCX_NUMBER_SIGNALS_PER_PORT_CROSSBAR = 144; -// PCX buffer RAM -const int pcx_buffersize = 1024; -const int pcx_bufferassoc = 1; -const int pcx_bufferblocksize = 32; -const int pcx_numbuffer = 5; -// pcx arbiter -const int pcx_arbsize = 128; -const int pcx_arbassoc = 1; -const int pcx_arbblocksize = 2; -const int pcx_numarb = 5; - -// CPX +const int PCX_NUMBER_SIGNALS_PER_PORT_CROSSBAR =144; +//PCX buffer RAM +const int pcx_buffersize=1024; +const int pcx_bufferassoc=1; +const int pcx_bufferblocksize=32; +const int pcx_numbuffer=5; +//pcx arbiter +const int pcx_arbsize=128; +const int pcx_arbassoc=1; +const int pcx_arbblocksize=2; +const int pcx_numarb=5; + +//CPX const int CPX_NUMBER_INPUT_PORTS_CROSSBAR = 5; const int CPX_NUMBER_OUTPUT_PORTS_CROSSBAR = 8; -const int CPX_NUMBER_SIGNALS_PER_PORT_CROSSBAR = 150; -// CPX buffer RAM -const int cpx_buffersize = 1024; -const int cpx_bufferassoc = 1; -const int cpx_bufferblocksize = 32; -const int cpx_numbuffer = 8; -// cpx arbiter -const int cpx_arbsize = 128; -const int cpx_arbassoc = 1; -const int cpx_arbblocksize = 2; -const int cpx_numarb = 8; - -const int numPhysFloatRegs = 256; -const int numPhysIntRegs = 32; -const int numROBEntries = 192; -const int umRobs = 1; - -const int BTBEntries = 4096; -const int BTBTagSize = 16; -const int LFSTSize = 1024; -const int LQEntries = 32; -const int RASSize = 16; -const int SQEntries = 32; -const int SSITSize = 1024; -const int activity = 0; -const int backComSize = 5; -const int cachePorts = 200; -const int choiceCtrBits = 2; -const int choicePredictorSize = 8192; - -const int commitWidth = 8; -const int decodeWidth = 8; -const int dispatchWidth = 8; -const int fetchWidth = 8; -const int issueWidth = 1; -const int renameWidth = 8; -// what is this forwardComSize=5?? - -const int globalCtrBits = 2; -const int globalHistoryBits = 13; -const int globalPredictorSize = 8192; - -const int localCtrBits = 2; -const int localHistoryBits = 11; -const int localHistoryTableSize = 2048; -const int localPredictorSize = 2048; - -const double Woutdrvnandn = 30 * 0.09; //(24.0 * LSCALE) -const double Woutdrvnandp = 12.5 * 0.09; //(10.0 * LSCALE) -const double Woutdrvnorn = 7.5 * 0.09; //(6.0 * LSCALE) -const double Woutdrvnorp = 50 * 0.09; // (40.0 * LSCALE) -const double Woutdrivern = 60 * 0.09; //(48.0 * LSCALE) -const double Woutdriverp = 100 * 0.09; //(80.0 * LSCALE) +const int CPX_NUMBER_SIGNALS_PER_PORT_CROSSBAR =150; +//CPX buffer RAM +const int cpx_buffersize=1024; +const int cpx_bufferassoc=1; +const int cpx_bufferblocksize=32; +const int cpx_numbuffer=8; +//cpx arbiter +const int cpx_arbsize=128; +const int cpx_arbassoc=1; +const int cpx_arbblocksize=2; +const int cpx_numarb=8; + + + + + +const int numPhysFloatRegs=256; +const int numPhysIntRegs=32; +const int numROBEntries=192; +const int umRobs=1; + +const int BTBEntries=4096; +const int BTBTagSize=16; +const int LFSTSize=1024; +const int LQEntries=32; +const int RASSize=16; +const int SQEntries=32; +const int SSITSize=1024; +const int activity=0; +const int backComSize=5; +const int cachePorts=200; +const int choiceCtrBits=2; +const int choicePredictorSize=8192; + + +const int commitWidth=8; +const int decodeWidth=8; +const int dispatchWidth=8; +const int fetchWidth=8; +const int issueWidth=1; +const int renameWidth=8; +//what is this forwardComSize=5?? + +const int globalCtrBits=2; +const int globalHistoryBits=13; +const int globalPredictorSize=8192; + + + +const int localCtrBits=2; +const int localHistoryBits=11; +const int localHistoryTableSize=2048; +const int localPredictorSize=2048; + +const double Woutdrvnandn =30 *0.09;//(24.0 * LSCALE) +const double Woutdrvnandp =12.5 *0.09;//(10.0 * LSCALE) +const double Woutdrvnorn =7.5*0.09;//(6.0 * LSCALE) +const double Woutdrvnorp =50 * 0.09;// (40.0 * LSCALE) +const double Woutdrivern =60*0.09;//(48.0 * LSCALE) +const double Woutdriverp =100 * 0.09;//(80.0 * LSCALE) /* smtCommitPolicy=RoundRobin @@ -258,6 +270,7 @@ mem_side=system.tol2bus.port[2] */ //[system.cpu0.dtb] -// type=AlphaDT +//type=AlphaDT + #endif /* ARCH_CONST_H_ */ diff --git a/src/gpuwattch/array.cc b/src/gpuwattch/array.cc index aca5a8a..a67e857 100644 --- a/src/gpuwattch/array.cc +++ b/src/gpuwattch/array.cc @@ -29,280 +29,273 @@ * ***************************************************************************/ -#define GLOBALVAR -#include "array.h" -#include -#include -#include +#define GLOBALVAR #include "cacti/area.h" #include "decoder.h" -#include "globalvar.h" #include "parameter.h" +#include "array.h" +#include +#include +#include +#include "globalvar.h" using namespace std; -ArrayST::ArrayST(const InputParameter *configure_interface, string _name, - enum Device_ty device_ty_, bool opt_local_, - enum Core_type core_ty_, bool _is_default) - : l_ip(*configure_interface), - name(_name), - device_ty(device_ty_), - opt_local(opt_local_), - core_ty(core_ty_), - is_default(_is_default) { - if (l_ip.cache_sz < 64) l_ip.cache_sz = 64; - l_ip.error_checking(); // not only do the error checking but also fill some - // missing parameters - optimize_array(); -} - -void ArrayST::compute_base_power() { - // l_ip.out_w =l_ip.line_sz*8; - local_result = cacti_interface(&l_ip); -} - -void ArrayST::optimize_array() { - list candidate_solutions(0); - list::iterator candidate_iter, min_dynamic_energy_iter; - - uca_org_t *temp_res = 0; - local_result.valid = false; - - double throughput = l_ip.throughput, latency = l_ip.latency; - double area_efficiency_threshold = 20.0; - bool throughput_overflow = true, latency_overflow = true; - compute_base_power(); - - if ((local_result.cycle_time - throughput) <= 1e-10) - throughput_overflow = false; - if ((local_result.access_time - latency) <= 1e-10) latency_overflow = false; - - if (opt_for_clk && opt_local) { - if (throughput_overflow || latency_overflow) { - l_ip.ed = 0; - - l_ip.delay_wt = 100; // Fixed number, make sure timing can be satisfied. - l_ip.cycle_time_wt = 1000; - - l_ip.area_wt = 10; // Fixed number, This is used to exhaustive search for - // individual components. - l_ip.dynamic_power_wt = 10; // Fixed number, This is used to exhaustive - // search for individual components. - l_ip.leakage_power_wt = 10; - - l_ip.delay_dev = - 1000000; // Fixed number, make sure timing can be satisfied. - l_ip.cycle_time_dev = 100; +ArrayST::ArrayST(const InputParameter *configure_interface, + string _name, + enum Device_ty device_ty_, + bool opt_local_, + enum Core_type core_ty_, + bool _is_default) +:l_ip(*configure_interface), + name(_name), + device_ty(device_ty_), + opt_local(opt_local_), + core_ty(core_ty_), + is_default(_is_default) + { - l_ip.area_dev = 1000000; // Fixed number, This is used to exhaustive - // search for individual components. - l_ip.dynamic_power_dev = 1000000; // Fixed number, This is used to - // exhaustive search for individual - // components. - l_ip.leakage_power_dev = 1000000; + if (l_ip.cache_sz<64) l_ip.cache_sz=64; + l_ip.error_checking();//not only do the error checking but also fill some missing parameters + optimize_array(); - throughput_overflow = - true; // Reset overflow flag before start optimization iterations - latency_overflow = true; +} - temp_res = &local_result; // Clean up the result for optimized for ED^2P - temp_res->cleanup(); - } - while ((throughput_overflow || latency_overflow) && - l_ip.cycle_time_dev > 10) // && l_ip.delay_dev > 10 +void ArrayST::compute_base_power() { - compute_base_power(); - - l_ip.cycle_time_dev -= - 10; // This is the time_dev to be used for next iteration - - // from best area to worst area -->worst timing to best - //timing - if ((((local_result.cycle_time - throughput) <= 1e-10) && - (local_result.access_time - latency) <= 1e-10) || - (local_result.data_array2->area_efficiency < - area_efficiency_threshold && - l_ip.assoc == 0)) { // if no satisfiable solution is found,the most - // aggressive one is left - candidate_solutions.push_back(local_result); - // output_data_csv(candidate_solutions.back()); - if (((local_result.cycle_time - throughput) <= 1e-10) && - ((local_result.access_time - latency) <= 1e-10)) - // ensure stop opt not because of cam - { - throughput_overflow = false; - latency_overflow = false; - } - - } else { - // TODO: whether checking the partial satisfied results too, or just - // change the mark??? - if ((local_result.cycle_time - throughput) <= 1e-10) - throughput_overflow = false; - if ((local_result.access_time - latency) <= 1e-10) - latency_overflow = false; - - if (l_ip.cycle_time_dev > 10) { // if not >10 local_result is the last - // result, it cannot be cleaned up - temp_res = &local_result; // Only solutions not saved in the list - // need to be cleaned up - temp_res->cleanup(); - } - } - // l_ip.cycle_time_dev-=10; - // l_ip.delay_dev-=10; - } - - if (l_ip.assoc > 0) { - // For array structures except CAM and FA, Give warning but still provide - // a result with best timing found - if (throughput_overflow == true) - cout << "Warning: " << name - << " array structure cannot satisfy throughput constraint." - << endl; - if (latency_overflow == true) - cout << "Warning: " << name - << " array structure cannot satisfy latency constraint." << endl; - } + //l_ip.out_w =l_ip.line_sz*8; + local_result=cacti_interface(&l_ip); - // else - // { - // /*According to "Content-Addressable Memory (CAM) Circuits and - // Architectures": A Tutorial and Survey - // by Kostas Pagiamtzis et al. - // CAM structures can be heavily pipelined and use look-ahead - //techniques, - // therefore timing can be relaxed. But McPAT does not model the - //advanced - // techniques. If continue optimizing, the area efficiency will be - //too low - // */ - // //For CAM and FA, stop opt if area efficiency is too low - // if (throughput_overflow==true) - // cout<< "Warning: " <<" McPAT stopped optimization on throughput for - //"<< name - // <<" array structure because its area efficiency is below - //"< (candidate_iter)->power.readOp.dynamic) { - min_dynamic_energy = (candidate_iter)->power.readOp.dynamic; - min_dynamic_energy_iter = candidate_iter; - local_result = *(min_dynamic_energy_iter); - // TODO: since results are reordered results and l_ip may miss match. - // Therefore, the final output spread sheets may show the miss match. - - } else { - candidate_iter->cleanup(); - } - } } - candidate_solutions.clear(); - } - - double long_channel_device_reduction = - longer_channel_device_reduction(device_ty, core_ty); - double macro_layout_overhead = g_tp.macro_layout_overhead; - double chip_PR_overhead = g_tp.chip_layout_overhead; - double total_overhead = macro_layout_overhead * chip_PR_overhead; - local_result.area *= total_overhead; +void ArrayST::optimize_array() +{ + list candidate_solutions(0); + list::iterator candidate_iter, min_dynamic_energy_iter; + + uca_org_t * temp_res = 0; + local_result.valid=false; + + double throughput=l_ip.throughput, latency=l_ip.latency; + double area_efficiency_threshold = 20.0; + bool throughput_overflow=true, latency_overflow=true; + compute_base_power(); + + if ((local_result.cycle_time - throughput) <= 1e-10 ) + throughput_overflow=false; + if ((local_result.access_time - latency)<= 1e-10) + latency_overflow=false; + + if (opt_for_clk && opt_local) + { + if (throughput_overflow || latency_overflow) + { + l_ip.ed=0; + + l_ip.delay_wt = 100;//Fixed number, make sure timing can be satisfied. + l_ip.cycle_time_wt = 1000; + + l_ip.area_wt = 10;//Fixed number, This is used to exhaustive search for individual components. + l_ip.dynamic_power_wt = 10;//Fixed number, This is used to exhaustive search for individual components. + l_ip.leakage_power_wt = 10; + + l_ip.delay_dev = 1000000;//Fixed number, make sure timing can be satisfied. + l_ip.cycle_time_dev = 100; + + l_ip.area_dev = 1000000;//Fixed number, This is used to exhaustive search for individual components. + l_ip.dynamic_power_dev = 1000000;//Fixed number, This is used to exhaustive search for individual components. + l_ip.leakage_power_dev = 1000000; + + throughput_overflow=true; //Reset overflow flag before start optimization iterations + latency_overflow=true; + + temp_res = &local_result; //Clean up the result for optimized for ED^2P + temp_res->cleanup(); + } + + + while ((throughput_overflow || latency_overflow)&&l_ip.cycle_time_dev > 10)// && l_ip.delay_dev > 10 + { + compute_base_power(); + + l_ip.cycle_time_dev-=10;//This is the time_dev to be used for next iteration + + // from best area to worst area -->worst timing to best timing + if ((((local_result.cycle_time - throughput) <= 1e-10 ) && (local_result.access_time - latency)<= 1e-10)|| + (local_result.data_array2->area_efficiency < area_efficiency_threshold && l_ip.assoc == 0)) + { //if no satisfiable solution is found,the most aggressive one is left + candidate_solutions.push_back(local_result); + //output_data_csv(candidate_solutions.back()); + if (((local_result.cycle_time - throughput) <= 1e-10) && ((local_result.access_time - latency)<= 1e-10)) + //ensure stop opt not because of cam + { + throughput_overflow=false; + latency_overflow=false; + } + + } + else + { + //TODO: whether checking the partial satisfied results too, or just change the mark??? + if ((local_result.cycle_time - throughput) <= 1e-10) + throughput_overflow=false; + if ((local_result.access_time - latency)<= 1e-10) + latency_overflow=false; + + if (l_ip.cycle_time_dev > 10) + { //if not >10 local_result is the last result, it cannot be cleaned up + temp_res = &local_result; //Only solutions not saved in the list need to be cleaned up + temp_res->cleanup(); + } + } +// l_ip.cycle_time_dev-=10; +// l_ip.delay_dev-=10; + + } + + + if (l_ip.assoc > 0) + { + //For array structures except CAM and FA, Give warning but still provide a result with best timing found + if (throughput_overflow==true) + cout<< "Warning: " << name<<" array structure cannot satisfy throughput constraint." << endl; + if (latency_overflow==true) + cout<< "Warning: " << name<<" array structure cannot satisfy latency constraint." << endl; + } + +// else +// { +// /*According to "Content-Addressable Memory (CAM) Circuits and +// Architectures": A Tutorial and Survey +// by Kostas Pagiamtzis et al. +// CAM structures can be heavily pipelined and use look-ahead techniques, +// therefore timing can be relaxed. But McPAT does not model the advanced +// techniques. If continue optimizing, the area efficiency will be too low +// */ +// //For CAM and FA, stop opt if area efficiency is too low +// if (throughput_overflow==true) +// cout<< "Warning: " <<" McPAT stopped optimization on throughput for "<< name +// <<" array structure because its area efficiency is below "< (candidate_iter)->power.readOp.dynamic) + { + min_dynamic_energy = (candidate_iter)->power.readOp.dynamic; + min_dynamic_energy_iter = candidate_iter; + local_result = *(min_dynamic_energy_iter); + //TODO: since results are reordered results and l_ip may miss match. Therefore, the final output spread sheets may show the miss match. + + } + else + { + candidate_iter->cleanup() ; + } + + } + + + } + candidate_solutions.clear(); + } + + double long_channel_device_reduction = longer_channel_device_reduction(device_ty,core_ty); + + double macro_layout_overhead = g_tp.macro_layout_overhead; + double chip_PR_overhead = g_tp.chip_layout_overhead; + double total_overhead = macro_layout_overhead*chip_PR_overhead; + local_result.area *= total_overhead; + + //maintain constant power density + double pppm_t[4] = {total_overhead,1,1,total_overhead}; + + double sckRation = g_tp.sckt_co_eff; + local_result.power.readOp.dynamic *= sckRation; + local_result.power.writeOp.dynamic *= sckRation; + local_result.power.searchOp.dynamic *= sckRation; + local_result.power.readOp.leakage *= l_ip.nbanks; + local_result.power.readOp.longer_channel_leakage = + local_result.power.readOp.leakage*long_channel_device_reduction; + local_result.power = local_result.power* pppm_t; + + local_result.data_array2->power.readOp.dynamic *= sckRation; + local_result.data_array2->power.writeOp.dynamic *= sckRation; + local_result.data_array2->power.searchOp.dynamic *= sckRation; + local_result.data_array2->power.readOp.leakage *= l_ip.nbanks; + local_result.data_array2->power.readOp.longer_channel_leakage = + local_result.data_array2->power.readOp.leakage*long_channel_device_reduction; + local_result.data_array2->power = local_result.data_array2->power* pppm_t; + + + if (!(l_ip.pure_cam || l_ip.pure_ram || l_ip.fully_assoc) && l_ip.is_cache) + { + local_result.tag_array2->power.readOp.dynamic *= sckRation; + local_result.tag_array2->power.writeOp.dynamic *= sckRation; + local_result.tag_array2->power.searchOp.dynamic *= sckRation; + local_result.tag_array2->power.readOp.leakage *= l_ip.nbanks; + local_result.tag_array2->power.readOp.longer_channel_leakage = + local_result.tag_array2->power.readOp.leakage*long_channel_device_reduction; + local_result.tag_array2->power = local_result.tag_array2->power* pppm_t; + } - // maintain constant power density - double pppm_t[4] = {total_overhead, 1, 1, total_overhead}; - - double sckRation = g_tp.sckt_co_eff; - local_result.power.readOp.dynamic *= sckRation; - local_result.power.writeOp.dynamic *= sckRation; - local_result.power.searchOp.dynamic *= sckRation; - local_result.power.readOp.leakage *= l_ip.nbanks; - local_result.power.readOp.longer_channel_leakage = - local_result.power.readOp.leakage * long_channel_device_reduction; - local_result.power = local_result.power * pppm_t; - local_result.data_array2->power.readOp.dynamic *= sckRation; - local_result.data_array2->power.writeOp.dynamic *= sckRation; - local_result.data_array2->power.searchOp.dynamic *= sckRation; - local_result.data_array2->power.readOp.leakage *= l_ip.nbanks; - local_result.data_array2->power.readOp.longer_channel_leakage = - local_result.data_array2->power.readOp.leakage * - long_channel_device_reduction; - local_result.data_array2->power = local_result.data_array2->power * pppm_t; - - if (!(l_ip.pure_cam || l_ip.pure_ram || l_ip.fully_assoc) && l_ip.is_cache) { - local_result.tag_array2->power.readOp.dynamic *= sckRation; - local_result.tag_array2->power.writeOp.dynamic *= sckRation; - local_result.tag_array2->power.searchOp.dynamic *= sckRation; - local_result.tag_array2->power.readOp.leakage *= l_ip.nbanks; - local_result.tag_array2->power.readOp.longer_channel_leakage = - local_result.tag_array2->power.readOp.leakage * - long_channel_device_reduction; - local_result.tag_array2->power = local_result.tag_array2->power * pppm_t; - } } -void ArrayST::leakage_feedback(double temperature) { - // Update the temperature. l_ip is already set and error-checked in the - // creator function. - l_ip.temp = (unsigned int)round(temperature / 10.0) * 10; +void ArrayST::leakage_feedback(double temperature) +{ + // Update the temperature. l_ip is already set and error-checked in the creator function. + l_ip.temp = (unsigned int)round(temperature/10.0)*10; - // This corresponds to cacti_interface() in the initialization process. - // Leakage power is updated here. - reconfigure(&l_ip, &local_result); + // This corresponds to cacti_interface() in the initialization process. Leakage power is updated here. + reconfigure(&l_ip,&local_result); // Scale the power values. This is part of ArrayST::optimize_array(). - double long_channel_device_reduction = - longer_channel_device_reduction(device_ty, core_ty); + double long_channel_device_reduction = longer_channel_device_reduction(device_ty,core_ty); - double macro_layout_overhead = g_tp.macro_layout_overhead; - double chip_PR_overhead = g_tp.chip_layout_overhead; - double total_overhead = macro_layout_overhead * chip_PR_overhead; + double macro_layout_overhead = g_tp.macro_layout_overhead; + double chip_PR_overhead = g_tp.chip_layout_overhead; + double total_overhead = macro_layout_overhead*chip_PR_overhead; - double pppm_t[4] = {total_overhead, 1, 1, total_overhead}; + double pppm_t[4] = {total_overhead,1,1,total_overhead}; double sckRation = g_tp.sckt_co_eff; local_result.power.readOp.dynamic *= sckRation; local_result.power.writeOp.dynamic *= sckRation; local_result.power.searchOp.dynamic *= sckRation; local_result.power.readOp.leakage *= l_ip.nbanks; - local_result.power.readOp.longer_channel_leakage = - local_result.power.readOp.leakage * long_channel_device_reduction; - local_result.power = local_result.power * pppm_t; + local_result.power.readOp.longer_channel_leakage = local_result.power.readOp.leakage*long_channel_device_reduction; + local_result.power = local_result.power* pppm_t; local_result.data_array2->power.readOp.dynamic *= sckRation; local_result.data_array2->power.writeOp.dynamic *= sckRation; local_result.data_array2->power.searchOp.dynamic *= sckRation; local_result.data_array2->power.readOp.leakage *= l_ip.nbanks; - local_result.data_array2->power.readOp.longer_channel_leakage = - local_result.data_array2->power.readOp.leakage * - long_channel_device_reduction; - local_result.data_array2->power = local_result.data_array2->power * pppm_t; + local_result.data_array2->power.readOp.longer_channel_leakage = local_result.data_array2->power.readOp.leakage*long_channel_device_reduction; + local_result.data_array2->power = local_result.data_array2->power* pppm_t; - if (!(l_ip.pure_cam || l_ip.pure_ram || l_ip.fully_assoc) && l_ip.is_cache) { + if (!(l_ip.pure_cam || l_ip.pure_ram || l_ip.fully_assoc) && l_ip.is_cache) + { local_result.tag_array2->power.readOp.dynamic *= sckRation; local_result.tag_array2->power.writeOp.dynamic *= sckRation; local_result.tag_array2->power.searchOp.dynamic *= sckRation; local_result.tag_array2->power.readOp.leakage *= l_ip.nbanks; - local_result.tag_array2->power.readOp.longer_channel_leakage = - local_result.tag_array2->power.readOp.leakage * - long_channel_device_reduction; - local_result.tag_array2->power = local_result.tag_array2->power * pppm_t; + local_result.tag_array2->power.readOp.longer_channel_leakage = local_result.tag_array2->power.readOp.leakage*long_channel_device_reduction; + local_result.tag_array2->power = local_result.tag_array2->power* pppm_t; } } -ArrayST::~ArrayST() { local_result.cleanup(); } +ArrayST:: ~ArrayST() +{ + local_result.cleanup(); +} diff --git a/src/gpuwattch/array.h b/src/gpuwattch/array.h index e2dc3d1..b7f77dc 100644 --- a/src/gpuwattch/array.h +++ b/src/gpuwattch/array.h @@ -32,86 +32,69 @@ #ifndef ARRAY_H_ #define ARRAY_H_ -#include -#include #include "basic_components.h" -#include "cacti/cacti_interface.h" -#include "cacti/component.h" #include "cacti/const.h" +#include "cacti/cacti_interface.h" #include "cacti/parameter.h" +#include "cacti/component.h" +#include +#include using namespace std; -class ArrayST : public Component { +class ArrayST :public Component{ public: ArrayST(){}; - ArrayST(const InputParameter* configure_interface, string _name, - enum Device_ty device_ty_, bool opt_local_ = true, - enum Core_type core_ty_ = Inorder, bool _is_default = true); + ArrayST(const InputParameter *configure_interface, string _name, enum Device_ty device_ty_, bool opt_local_=true, enum Core_type core_ty_=Inorder, bool _is_default=true); InputParameter l_ip; - string name; + string name; enum Device_ty device_ty; bool opt_local; enum Core_type core_ty; - bool is_default; - uca_org_t local_result; + bool is_default; + uca_org_t local_result; - statsDef tdp_stats; - statsDef rtp_stats; - statsDef stats_t; - powerDef power_t; + statsDef tdp_stats; + statsDef rtp_stats; + statsDef stats_t; + powerDef power_t; virtual void optimize_array(); virtual void compute_base_power(); virtual ~ArrayST(); - + void leakage_feedback(double temperature); }; -class InstCache : public Component { - public: +class InstCache :public Component{ +public: ArrayST* caches; ArrayST* missb; ArrayST* ifb; ArrayST* prefetchb; - powerDef power_t; // temp value holder for both (max) power and runtime power - InstCache() { - caches = 0; - missb = 0; - ifb = 0; - prefetchb = 0; - }; - ~InstCache() { - if (caches) { // caches->local_result.cleanup(); - delete caches; - caches = 0; - } - if (missb) { // missb->local_result.cleanup(); - delete missb; - missb = 0; - } - if (ifb) { // ifb->local_result.cleanup(); - delete ifb; - ifb = 0; - } - if (prefetchb) { // prefetchb->local_result.cleanup(); - delete prefetchb; - prefetchb = 0; - } - }; + powerDef power_t;//temp value holder for both (max) power and runtime power + InstCache(){caches=0;missb=0;ifb=0;prefetchb=0;}; + ~InstCache(){ + if (caches) {//caches->local_result.cleanup(); + delete caches; caches=0;} + if (missb) {//missb->local_result.cleanup(); + delete missb; missb=0;} + if (ifb) {//ifb->local_result.cleanup(); + delete ifb; ifb=0;} + if (prefetchb) {//prefetchb->local_result.cleanup(); + delete prefetchb; prefetchb=0;} + }; }; -class DataCache : public InstCache { - public: +class DataCache :public InstCache{ +public: ArrayST* wbb; - DataCache() { wbb = 0; }; - ~DataCache() { - if (wbb) { // wbb->local_result.cleanup(); - delete wbb; - wbb = 0; - } - }; + DataCache(){wbb=0;}; + ~DataCache(){ + if (wbb) {//wbb->local_result.cleanup(); + delete wbb; wbb=0;} + }; }; #endif /* TLB_H_ */ diff --git a/src/gpuwattch/basic_components.cc b/src/gpuwattch/basic_components.cc index d58023a..d66c280 100644 --- a/src/gpuwattch/basic_components.cc +++ b/src/gpuwattch/basic_components.cc @@ -30,87 +30,97 @@ ***************************************************************************/ #include "basic_components.h" +#include #include #include -#include -double longer_channel_device_reduction(enum Device_ty device_ty, - enum Core_type core_ty) { - double longer_channel_device_percentage_core; - double longer_channel_device_percentage_uncore; - double longer_channel_device_percentage_llc; - - double long_channel_device_reduction; - - longer_channel_device_percentage_llc = 1.0; - longer_channel_device_percentage_uncore = 0.82; - if (core_ty == OOO) { - longer_channel_device_percentage_core = - 0.56; // 0.54 Xeon Tulsa //0.58 Nehelam - // longer_channel_device_percentage_uncore = 0.76;//0.85 Nehelam - - } else { - longer_channel_device_percentage_core = 0.8; // 0.8;//Niagara - // longer_channel_device_percentage_uncore = 0.9;//Niagara - } - - if (device_ty == Core_device) { - long_channel_device_reduction = - (1 - longer_channel_device_percentage_core) + - longer_channel_device_percentage_core * - g_tp.peri_global.long_channel_leakage_reduction; - } else if (device_ty == Uncore_device) { - long_channel_device_reduction = - (1 - longer_channel_device_percentage_uncore) + - longer_channel_device_percentage_uncore * - g_tp.peri_global.long_channel_leakage_reduction; - } else if (device_ty == LLC_device) { - long_channel_device_reduction = - (1 - longer_channel_device_percentage_llc) + - longer_channel_device_percentage_llc * - g_tp.peri_global.long_channel_leakage_reduction; - } else { - cout << "unknown device category" << endl; - exit(0); - } - - return long_channel_device_reduction; +double longer_channel_device_reduction( + enum Device_ty device_ty, + enum Core_type core_ty) +{ + + double longer_channel_device_percentage_core; + double longer_channel_device_percentage_uncore; + double longer_channel_device_percentage_llc; + + double long_channel_device_reduction; + + longer_channel_device_percentage_llc = 1.0; + longer_channel_device_percentage_uncore = 0.82; + if (core_ty==OOO) + { + longer_channel_device_percentage_core = 0.56;//0.54 Xeon Tulsa //0.58 Nehelam + //longer_channel_device_percentage_uncore = 0.76;//0.85 Nehelam + + } + else + { + longer_channel_device_percentage_core = 0.8;//0.8;//Niagara + //longer_channel_device_percentage_uncore = 0.9;//Niagara + } + + if (device_ty==Core_device) + { + long_channel_device_reduction = (1- longer_channel_device_percentage_core) + + longer_channel_device_percentage_core * g_tp.peri_global.long_channel_leakage_reduction; + } + else if (device_ty==Uncore_device) + { + long_channel_device_reduction = (1- longer_channel_device_percentage_uncore) + + longer_channel_device_percentage_uncore * g_tp.peri_global.long_channel_leakage_reduction; + } + else if (device_ty==LLC_device) + { + long_channel_device_reduction = (1- longer_channel_device_percentage_llc) + + longer_channel_device_percentage_llc * g_tp.peri_global.long_channel_leakage_reduction; + } + else + { + cout<<"unknown device category"< #include "XML_Parse.h" #include "cacti/parameter.h" +#include const double cdb_overhead = 1.1; -enum FU_type { FPU, ALU, MUL }; +enum FU_type { + FPU, + ALU, + MUL +}; -enum Core_type { OOO, Inorder }; +enum Core_type { + OOO, + Inorder +}; -enum Renaming_type { RAMbased, CAMbased }; +enum Renaming_type { + RAMbased, + CAMbased +}; -enum Scheduler_type { PhysicalRegFile, ReservationStation }; +enum Scheduler_type { + PhysicalRegFile, + ReservationStation +}; -enum cache_level { L2, L3, L1Directory, L2Directory }; +enum cache_level { + L2, + L3, + L1Directory, + L2Directory +}; enum MemoryCtrl_type { - MC, // memory controller - FLASHC // flash controller + MC, //memory controller + FLASHC //flash controller +}; + +enum Dram_type { + GDDR5, + GDDR3 }; -enum Dram_type { GDDR5, GDDR3 }; enum Dir_type { - ST, // shadowed tag - DC, // directory cache - SBT, // static bank tag - NonDir + ST,//shadowed tag + DC,//directory cache + SBT,//static bank tag + NonDir + +}; +enum Cache_policy { + Write_through, + Write_back }; -enum Cache_policy { Write_through, Write_back }; - -enum Device_ty { Core_device, Uncore_device, LLC_device }; - -class statsComponents { - public: - double access; - double hit; - double miss; - - statsComponents() : access(0), hit(0), miss(0) {} - statsComponents(const statsComponents &obj) { *this = obj; } - statsComponents &operator=(const statsComponents &rhs) { - access = rhs.access; - hit = rhs.hit; - miss = rhs.miss; - return *this; - } - void reset() { - access = 0; - hit = 0; - miss = 0; - } - - friend statsComponents operator+(const statsComponents &x, - const statsComponents &y); - friend statsComponents operator*(const statsComponents &x, - double const *const y); +enum Device_ty { + Core_device, + Uncore_device, + LLC_device }; -class statsDef { - public: - statsComponents readAc; - statsComponents writeAc; - statsComponents searchAc; - - statsDef() : readAc(), writeAc(), searchAc() {} - void reset() { - readAc.reset(); - writeAc.reset(); - searchAc.reset(); - } - - friend statsDef operator+(const statsDef &x, const statsDef &y); - friend statsDef operator*(const statsDef &x, double const *const y); +class statsComponents +{ + public: + double access; + double hit; + double miss; + + statsComponents() : access(0), hit(0), miss(0) {} + statsComponents(const statsComponents & obj) { *this = obj; } + statsComponents & operator=(const statsComponents & rhs) + { + access = rhs.access; + hit = rhs.hit; + miss = rhs.miss; + return *this; + } + void reset() { access = 0; hit = 0; miss = 0;} + + friend statsComponents operator+(const statsComponents & x, const statsComponents & y); + friend statsComponents operator*(const statsComponents & x, double const * const y); +}; + +class statsDef +{ + public: + statsComponents readAc; + statsComponents writeAc; + statsComponents searchAc; + + statsDef() : readAc(), writeAc(),searchAc() { } + void reset() { readAc.reset(); writeAc.reset();searchAc.reset();} + + friend statsDef operator+(const statsDef & x, const statsDef & y); + friend statsDef operator*(const statsDef & x, double const * const y); }; -double longer_channel_device_reduction(enum Device_ty device_ty = Core_device, - enum Core_type core_ty = Inorder); +double longer_channel_device_reduction( + enum Device_ty device_ty=Core_device, + enum Core_type core_ty=Inorder); class CoreDynParam { - public: - CoreDynParam(){}; - CoreDynParam(ParseXML *XML_interface, int ithCore_); - // :XML(XML_interface), - // ithCore(ithCore_) - // core_ty(inorder), - // rm_ty(CAMbased), - // scheu_ty(PhysicalRegFile), - // clockRate(1e9),//1GHz - // arch_ireg_width(32), - // arch_freg_width(32), - // phy_ireg_width(128), - // phy_freg_width(128), - // perThreadState(8), - // globalCheckpoint(32), - // instructionLength(32){}; - // ParseXML * XML; - bool opt_local; - bool x86; - bool Embedded; - enum Core_type core_ty; - enum Renaming_type rm_ty; - enum Scheduler_type scheu_ty; - double clockRate, executionTime; - int arch_ireg_width, arch_freg_width, phy_ireg_width, phy_freg_width; - int num_IRF_entry, num_FRF_entry, num_ifreelist_entries, - num_ffreelist_entries; - int fetchW, decodeW, issueW, peak_issueW, commitW, peak_commitW, predictionW, - fp_issueW, fp_decodeW; - int perThreadState, globalCheckpoint, instruction_length, pc_width, - opcode_length, micro_opcode_length; - int num_hthreads, pipeline_stages, fp_pipeline_stages, num_pipelines, - num_fp_pipelines; - int num_alus, num_muls; - double num_fpus; - int int_data_width, fp_data_width, v_address_width, p_address_width; - double pipeline_duty_cycle, total_cycles, busy_cycles, idle_cycles; - bool regWindowing, multithreaded; - double pppm_lkg_multhread[4]; - double IFU_duty_cycle, BR_duty_cycle, LSU_duty_cycle, MemManU_I_duty_cycle, - MemManU_D_duty_cycle, ALU_duty_cycle, MUL_duty_cycle, FPU_duty_cycle, - ALU_cdb_duty_cycle, MUL_cdb_duty_cycle, FPU_cdb_duty_cycle; - ~CoreDynParam(){}; +public: + CoreDynParam(){}; + CoreDynParam(ParseXML *XML_interface, int ithCore_); + // :XML(XML_interface), + // ithCore(ithCore_) + // core_ty(inorder), + // rm_ty(CAMbased), + // scheu_ty(PhysicalRegFile), + // clockRate(1e9),//1GHz + // arch_ireg_width(32), + // arch_freg_width(32), + // phy_ireg_width(128), + // phy_freg_width(128), + // perThreadState(8), + // globalCheckpoint(32), + // instructionLength(32){}; + //ParseXML * XML; + bool opt_local; + bool x86; + bool Embedded; + enum Core_type core_ty; + enum Renaming_type rm_ty; + enum Scheduler_type scheu_ty; + double clockRate,executionTime; + int arch_ireg_width, arch_freg_width, phy_ireg_width, phy_freg_width; + int num_IRF_entry, num_FRF_entry, num_ifreelist_entries, num_ffreelist_entries; + int fetchW, decodeW,issueW,peak_issueW, commitW,peak_commitW, predictionW, fp_issueW, fp_decodeW; + int perThreadState, globalCheckpoint, instruction_length, pc_width, opcode_length, micro_opcode_length; + int num_hthreads, pipeline_stages, fp_pipeline_stages, num_pipelines, num_fp_pipelines; + int num_alus, num_muls; + double num_fpus; + int int_data_width, fp_data_width,v_address_width, p_address_width; + double pipeline_duty_cycle, total_cycles, busy_cycles, idle_cycles; + bool regWindowing,multithreaded; + double pppm_lkg_multhread[4]; + double IFU_duty_cycle,BR_duty_cycle,LSU_duty_cycle,MemManU_I_duty_cycle, + MemManU_D_duty_cycle, ALU_duty_cycle,MUL_duty_cycle, + FPU_duty_cycle, ALU_cdb_duty_cycle,MUL_cdb_duty_cycle, + FPU_cdb_duty_cycle; + ~CoreDynParam(){}; }; class CacheDynParam { - public: - CacheDynParam(){}; - CacheDynParam(ParseXML *XML_interface, int ithCache_); - string name; - enum Dir_type dir_ty; - double clockRate, executionTime; - double capacity, blockW, assoc, nbanks; - double throughput, latency; - double duty_cycle, dir_duty_cycle; - // double duty_cycle; - int missb_size, fu_size, prefetchb_size, wbb_size; - ~CacheDynParam(){}; +public: + CacheDynParam(){}; + CacheDynParam(ParseXML *XML_interface, int ithCache_); + string name; + enum Dir_type dir_ty; + double clockRate,executionTime; + double capacity, blockW, assoc, nbanks; + double throughput, latency; + double duty_cycle, dir_duty_cycle; + //double duty_cycle; + int missb_size, fu_size, prefetchb_size, wbb_size; + ~CacheDynParam(){}; }; class DRAMParam { - public: - DRAMParam(){}; - DRAMParam(ParseXML *XML_interface, int ithCache_); - string name; - double clockRate; - double executionTime; - double cmd_coeff; - double activity_coeff; - double nop_coeff; - double act_coeff; - double pre_coeff; - double rd_coeff; - double wr_coeff; - double req_coeff; - double const_coeff; - - int detailed_dram_model; // 1 - to use newly added DRAM model (GDDR5 only), 0 - // - use empirical model - // the following are the current specified by DATA SHEET - // unit: mA - int idd0; - int idd1; - int idd2p; - int idd2n; - int idd3p; - int idd3n; - int idd4r; - int idd4w; - int idd5; - int idd6; - int idd7; - - // the following are the vdd specified by DATA SHEET; NOT the actual VDD - double datasheet_vdd; - double actual_vdd; - - // the following are the timing parameters specified by DATA SHEET - // unit: ns - int t_ccd; - int t_rrd; - int t_rcd; - int t_ras; - int t_rp; - int t_rc; - int t_cl; - int t_cdlr; - int t_wr; - - // the following are the DRAM clocks - // unit: MHz - int datasheet_operating_clock; // this is specified by DATA SHEET. This is - // NOT the actual DRAM clock - int actual_operating_clock; - - // the following are each DRAM bank's IO info - int bank_width; // in bits - int dqs_signal_width; // in bits - int extra_dq_write_signal_width; // in bits - int per_dq_read_power; // in mW - int per_dq_write_power; // in mW - - ~DRAMParam(){}; +public: + DRAMParam(){}; + DRAMParam(ParseXML *XML_interface, int ithCache_); + string name; + double clockRate; + double executionTime; + double cmd_coeff; + double activity_coeff; + double nop_coeff; + double act_coeff; + double pre_coeff; + double rd_coeff; + double wr_coeff; + double req_coeff; + double const_coeff; + + int detailed_dram_model; // 1 - to use newly added DRAM model (GDDR5 only), 0 - use empirical model + // the following are the current specified by DATA SHEET + // unit: mA + int idd0; + int idd1; + int idd2p; + int idd2n; + int idd3p; + int idd3n; + int idd4r; + int idd4w; + int idd5; + int idd6; + int idd7; + + // the following are the vdd specified by DATA SHEET; NOT the actual VDD + double datasheet_vdd; + double actual_vdd; + + // the following are the timing parameters specified by DATA SHEET + // unit: ns + int t_ccd; + int t_rrd; + int t_rcd; + int t_ras; + int t_rp; + int t_rc; + int t_cl; + int t_cdlr; + int t_wr; + + // the following are the DRAM clocks + // unit: MHz + int datasheet_operating_clock; // this is specified by DATA SHEET. This is NOT the actual DRAM clock + int actual_operating_clock; + + // the following are each DRAM bank's IO info + int bank_width; // in bits + int dqs_signal_width; // in bits + int extra_dq_write_signal_width; //in bits + int per_dq_read_power; // in mW + int per_dq_write_power; // in mW + + ~DRAMParam(){}; }; class MCParam { - public: - MCParam(){}; - MCParam(ParseXML *XML_interface, int ithCache_); - string name; - double clockRate, num_mcs, peakDataTransferRate, num_channels; - // double mcTEPowerperGhz; - // double mcPHYperGbit; - // double area; - int llcBlockSize, dataBusWidth, addressBusWidth; - int opcodeW; - int memAccesses; - int memRank; - int type; - double frontend_duty_cycle, duty_cycle, perc_load; - double executionTime, reads, writes; - bool LVDS, withPHY; - - ~MCParam(){}; +public: + MCParam(){}; + MCParam(ParseXML *XML_interface, int ithCache_); + string name; + double clockRate,num_mcs, peakDataTransferRate, num_channels; + // double mcTEPowerperGhz; + // double mcPHYperGbit; + // double area; + int llcBlockSize, dataBusWidth, addressBusWidth; + int opcodeW; + int memAccesses; + int memRank; + int type; + double frontend_duty_cycle, duty_cycle, perc_load; + double executionTime, reads, writes; + bool LVDS, withPHY; + + ~MCParam(){}; }; class NoCParam { - public: - NoCParam(){}; - NoCParam(ParseXML *XML_interface, int ithCache_); - string name; - double clockRate; - int flit_size; - int input_ports, output_ports, min_ports, global_linked_ports; - int virtual_channel_per_port, input_buffer_entries_per_vc; - int horizontal_nodes, vertical_nodes, total_nodes; - double executionTime, total_access, link_throughput, link_latency, duty_cycle, - chip_coverage, route_over_perc; - bool has_global_link, type; - - ~NoCParam(){}; +public: + NoCParam(){}; + NoCParam(ParseXML *XML_interface, int ithCache_); + string name; + double clockRate; + int flit_size; + int input_ports, output_ports, min_ports, global_linked_ports; + int virtual_channel_per_port,input_buffer_entries_per_vc; + int horizontal_nodes,vertical_nodes, total_nodes; + double executionTime, total_access, link_throughput,link_latency, + duty_cycle, chip_coverage, route_over_perc; + bool has_global_link, type; + + ~NoCParam(){}; }; class ProcParam { - public: - ProcParam(){}; - ProcParam(ParseXML *XML_interface, int ithCache_); - string name; - int numCore, numL2, numL3, numNOC, numL1Dir, numL2Dir, numMC, numMCChannel; - bool homoCore, homoL2, homoL3, homoNOC, homoL1Dir, homoL2Dir; - - ~ProcParam(){}; +public: + ProcParam(){}; + ProcParam(ParseXML *XML_interface, int ithCache_); + string name; + int numCore, numL2, numL3, numNOC, numL1Dir, numL2Dir,numMC, numMCChannel; + bool homoCore, homoL2, homoL3, homoNOC, homoL1Dir, homoL2Dir; + + ~ProcParam(){}; }; class NIUParam { - public: - NIUParam(){}; - NIUParam(ParseXML *XML_interface, int ithCache_); - string name; - double clockRate; - int num_units; - int type; - double duty_cycle, perc_load; - ~NIUParam(){}; +public: + NIUParam(){}; + NIUParam(ParseXML *XML_interface, int ithCache_); + string name; + double clockRate; + int num_units; + int type; + double duty_cycle, perc_load; + ~NIUParam(){}; }; class PCIeParam { - public: - PCIeParam(){}; - PCIeParam(ParseXML *XML_interface, int ithCache_); - string name; - double clockRate; - int num_channels, num_units; - bool withPHY; - int type; - double duty_cycle, perc_load; - ~PCIeParam(){}; +public: + PCIeParam(){}; + PCIeParam(ParseXML *XML_interface, int ithCache_); + string name; + double clockRate; + int num_channels, num_units; + bool withPHY; + int type; + double duty_cycle, perc_load; + ~PCIeParam(){}; }; #endif /* BASIC_COMPONENTS_H_ */ diff --git a/src/gpuwattch/core.cc b/src/gpuwattch/core.cc index 9e9f1ab..a5c3bf3 100644 --- a/src/gpuwattch/core.cc +++ b/src/gpuwattch/core.cc @@ -29,6835 +29,5309 @@ * ***************************************************************************/ /******************************************************************** -* Modified by: -** +* 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 "core.h" -#include -#include -#include -#include -#include -#include "XML_Parse.h" -#include "cacti/basic_circuit.h" -#include "const.h" #include "io.h" #include "parameter.h" +#include "const.h" +#include "cacti/basic_circuit.h" +#include +#include +#include "XML_Parse.h" +#include +#include +#include +#include "core.h" //#include "globalvar.h" -// double exClockRate; +//double exClockRate; //********************* -// Operand collector (OC) modelling (Syed Gilani) +//Operand collector (OC) modelling (Syed Gilani) //********************* -// The OCs are modelled similar to the GPGPU-Sim v3.x documentation and -// nVIDIA patents. -// the OC need the following GPGPU-Sim config options: -//-gpgpu_num_reg_banks 8 # Number of register banks (default -//= 8) -//-gpgpu_reg_bank_use_warp_id 0 # Use warp ID in mapping -//registers to banks (default = off) -//-gpgpu_operand_collector_num_units_sp 6 # number of -//collector units (default = 4) -//-gpgpu_operand_collector_num_units_sfu 8 # number of -//collector units (default = 4) -//-gpgpu_operand_collector_num_units_mem 2 # number of -//collector units (default = 2) -//-gpgpu_operand_collector_num_units_gen 0 # number of -//collector units (default = 0) -//-gpgpu_operand_collector_num_in_ports_sp 1 # number of -//collector unit in ports (default = 1) -//-gpgpu_operand_collector_num_in_ports_sfu 1 # number of -//collector unit in ports (default = 1) -//-gpgpu_operand_collector_num_in_ports_mem 1 # number of -//collector unit in ports (default = 1) -//-gpgpu_operand_collector_num_in_ports_gen 0 # number of -//collector unit in ports (default = 0) -//-gpgpu_operand_collector_num_out_ports_sp 1 # number of -//collector unit in ports (default = 1) -//-gpgpu_operand_collector_num_out_ports_sfu 1 # number of -//collector unit in ports (default = 1) -//-gpgpu_operand_collector_num_out_ports_mem 1 # number of -//collector unit in ports (default = 1) -//-gpgpu_operand_collector_num_out_ports_gen 0 # number of -//collector unit in ports (default = 0) - -// The total number of collector units and their input ports, and the number of -// register file banks -// determine the crossbar size. - -InstFetchU::InstFetchU(ParseXML* XML_interface, int ithCore_, - InputParameter* interface_ip_, - const CoreDynParam& dyn_p_, bool exist_) - : XML(XML_interface), - ithCore(ithCore_), - interface_ip(*interface_ip_), - coredynp(dyn_p_), - IB(0), - BTB(0), - ID_inst(0), - ID_operand(0), - ID_misc(0), - exist(exist_) { - if (!exist) return; - int idx, tag, data, size, line, assoc, banks; - bool debug = false, is_default = true; - - clockRate = coredynp.clockRate; - executionTime = coredynp.executionTime; - - cache_p = (Cache_policy)XML->sys.core[ithCore].icache.icache_config[7]; - // Assuming all L1 caches are virtually idxed physically tagged. - // cache - - size = (int)XML->sys.core[ithCore].icache.icache_config[0]; - line = (int)XML->sys.core[ithCore].icache.icache_config[1]; - assoc = (int)XML->sys.core[ithCore].icache.icache_config[2]; - banks = (int)XML->sys.core[ithCore].icache.icache_config[3]; - idx = debug ? 9 : int(ceil(log2(size / line / assoc))); - tag = debug ? 51 : (int)XML->sys.physical_address_width - idx - - int(ceil(log2(line))) + EXTRA_TAG_BITS; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.cache_sz = - debug ? 32768 : (int)XML->sys.core[ithCore].icache.icache_config[0]; - interface_ip.line_sz = - debug ? 64 : (int)XML->sys.core[ithCore].icache.icache_config[1]; - interface_ip.assoc = - debug ? 8 : (int)XML->sys.core[ithCore].icache.icache_config[2]; - interface_ip.nbanks = - debug ? 1 : (int)XML->sys.core[ithCore].icache.icache_config[3]; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = - 0; // debug?0:XML->sys.core[ithCore].icache.icache_config[5]; - interface_ip.throughput = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].icache.icache_config[4] / clockRate; - interface_ip.latency = - debug ? 3.0 / clockRate - : XML->sys.core[ithCore].icache.icache_config[5] / clockRate; - interface_ip.is_cache = true; - interface_ip.pure_cam = false; - interface_ip.pure_ram = false; - // interface_ip.obj_func_dyn_energy = 0; - // interface_ip.obj_func_dyn_power = 0; - // interface_ip.obj_func_leak_power = 0; - // interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = - debug ? 1 : XML->sys.core[ithCore].number_instruction_fetch_ports; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - icache.caches = new ArrayST(&interface_ip, "icache", Core_device, - coredynp.opt_local, coredynp.core_ty); - scktRatio = g_tp.sckt_co_eff; - chip_PR_overhead = g_tp.chip_layout_overhead; - macro_PR_overhead = g_tp.macro_layout_overhead; - icache.area.set_area(icache.area.get_area() + - icache.caches->local_result.area); - area.set_area(area.get_area() + icache.caches->local_result.area); - // output_data_csv(icache.caches.local_result); +//The OCs are modelled similar to the GPGPU-Sim v3.x documentation and +//nVIDIA patents. +//the OC need the following GPGPU-Sim config options: +//-gpgpu_num_reg_banks 8 # Number of register banks (default = 8) +//-gpgpu_reg_bank_use_warp_id 0 # Use warp ID in mapping registers to banks (default = off) +//-gpgpu_operand_collector_num_units_sp 6 # number of collector units (default = 4) +//-gpgpu_operand_collector_num_units_sfu 8 # number of collector units (default = 4) +//-gpgpu_operand_collector_num_units_mem 2 # number of collector units (default = 2) +//-gpgpu_operand_collector_num_units_gen 0 # number of collector units (default = 0) +//-gpgpu_operand_collector_num_in_ports_sp 1 # number of collector unit in ports (default = 1) +//-gpgpu_operand_collector_num_in_ports_sfu 1 # number of collector unit in ports (default = 1) +//-gpgpu_operand_collector_num_in_ports_mem 1 # number of collector unit in ports (default = 1) +//-gpgpu_operand_collector_num_in_ports_gen 0 # number of collector unit in ports (default = 0) +//-gpgpu_operand_collector_num_out_ports_sp 1 # number of collector unit in ports (default = 1) +//-gpgpu_operand_collector_num_out_ports_sfu 1 # number of collector unit in ports (default = 1) +//-gpgpu_operand_collector_num_out_ports_mem 1 # number of collector unit in ports (default = 1) +//-gpgpu_operand_collector_num_out_ports_gen 0 # number of collector unit in ports (default = 0) + +//The total number of collector units and their input ports, and the number of register file banks +//determine the crossbar size. + +InstFetchU::InstFetchU(ParseXML* XML_interface, int ithCore_, InputParameter* interface_ip_, const CoreDynParam & dyn_p_, bool exist_) +:XML(XML_interface), + ithCore(ithCore_), + interface_ip(*interface_ip_), + coredynp(dyn_p_), + IB (0), + BTB (0), + ID_inst (0), + ID_operand (0), + ID_misc (0), + exist(exist_) +{ + if (!exist) return; + int idx, tag, data, size, line, assoc, banks; + bool debug= false, is_default = true; + + clockRate = coredynp.clockRate; + executionTime = coredynp.executionTime; + + cache_p = (Cache_policy)XML->sys.core[ithCore].icache.icache_config[7]; + //Assuming all L1 caches are virtually idxed physically tagged. + //cache + + size = (int)XML->sys.core[ithCore].icache.icache_config[0]; + line = (int)XML->sys.core[ithCore].icache.icache_config[1]; + assoc = (int)XML->sys.core[ithCore].icache.icache_config[2]; + banks = (int)XML->sys.core[ithCore].icache.icache_config[3]; + idx = debug?9:int(ceil(log2(size/line/assoc))); + tag = debug?51:(int)XML->sys.physical_address_width-idx-int(ceil(log2(line))) + EXTRA_TAG_BITS; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.cache_sz = debug?32768:(int)XML->sys.core[ithCore].icache.icache_config[0]; + interface_ip.line_sz = debug?64:(int)XML->sys.core[ithCore].icache.icache_config[1]; + interface_ip.assoc = debug?8:(int)XML->sys.core[ithCore].icache.icache_config[2]; + interface_ip.nbanks = debug?1:(int)XML->sys.core[ithCore].icache.icache_config[3]; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 0;//debug?0:XML->sys.core[ithCore].icache.icache_config[5]; + interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].icache.icache_config[4]/clockRate; + interface_ip.latency = debug?3.0/clockRate:XML->sys.core[ithCore].icache.icache_config[5]/clockRate; + interface_ip.is_cache = true; + interface_ip.pure_cam = false; + interface_ip.pure_ram = false; + // interface_ip.obj_func_dyn_energy = 0; + // interface_ip.obj_func_dyn_power = 0; + // interface_ip.obj_func_leak_power = 0; + // interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].number_instruction_fetch_ports; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + icache.caches = new ArrayST(&interface_ip, "icache", Core_device, coredynp.opt_local, coredynp.core_ty); + scktRatio = g_tp.sckt_co_eff; + chip_PR_overhead = g_tp.chip_layout_overhead; + macro_PR_overhead = g_tp.macro_layout_overhead; + icache.area.set_area(icache.area.get_area()+ icache.caches->local_result.area); + area.set_area(area.get_area()+ icache.caches->local_result.area); + //output_data_csv(icache.caches.local_result); + + + /* + *iCache controllers + *miss buffer Each MSHR contains enough state + *to handle one or more accesses of any type to a single memory line. + *Due to the generality of the MSHR mechanism, + *the amount of state involved is non-trivial: + *including the address, pointers to the cache entry and destination register, + *written data, and various other pieces of state. + */ + interface_ip.num_search_ports = debug?1:XML->sys.core[ithCore].number_instruction_fetch_ports; + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = (XML->sys.physical_address_width) + int(ceil(log2(size/line))) + icache.caches->l_ip.line_sz*8; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = int(ceil(data/8.0));//int(ceil(pow(2.0,ceil(log2(data)))/8.0)); + interface_ip.cache_sz = XML->sys.core[ithCore].icache.buffer_sizes[0]*interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 0; + interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].icache.icache_config[4]/clockRate;//means cycle time + interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].icache.icache_config[5]/clockRate;//means access time + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].number_instruction_fetch_ports; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = XML->sys.core[ithCore].number_instruction_fetch_ports; + icache.missb = new ArrayST(&interface_ip, "icacheMissBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); + icache.area.set_area(icache.area.get_area()+ icache.missb->local_result.area); + area.set_area(area.get_area()+ icache.missb->local_result.area); + //output_data_csv(icache.missb.local_result); + + //fill buffer + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = icache.caches->l_ip.line_sz; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); + interface_ip.cache_sz = data*XML->sys.core[ithCore].icache.buffer_sizes[1]; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 0; + interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].icache.icache_config[4]/clockRate; + interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].icache.icache_config[5]/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].number_instruction_fetch_ports; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = XML->sys.core[ithCore].number_instruction_fetch_ports; + icache.ifb = new ArrayST(&interface_ip, "icacheFillBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); + icache.area.set_area(icache.area.get_area()+ icache.ifb->local_result.area); + area.set_area(area.get_area()+ icache.ifb->local_result.area); + //output_data_csv(icache.ifb.local_result); + + //prefetch buffer + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS;//check with previous entries to decide wthether to merge. + data = icache.caches->l_ip.line_sz;//separate queue to prevent from cache polution. + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); + interface_ip.cache_sz = XML->sys.core[ithCore].icache.buffer_sizes[2]*interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 0; + interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].icache.icache_config[4]/clockRate; + interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].icache.icache_config[5]/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].number_instruction_fetch_ports; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = XML->sys.core[ithCore].number_instruction_fetch_ports; + icache.prefetchb = new ArrayST(&interface_ip, "icacheprefetchBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); + icache.area.set_area(icache.area.get_area()+ icache.prefetchb->local_result.area); + area.set_area(area.get_area()+ icache.prefetchb->local_result.area); + //output_data_csv(icache.prefetchb.local_result); + + //Instruction buffer + data = XML->sys.core[ithCore].instruction_length*XML->sys.core[ithCore].peak_issue_width;//icache.caches.l_ip.line_sz; //multiple threads timing sharing the instruction buffer. + interface_ip.is_cache = false; + interface_ip.pure_ram = true; + interface_ip.pure_cam = false; + interface_ip.line_sz = int(ceil(data/8.0)); + interface_ip.cache_sz = XML->sys.core[ithCore].number_hardware_threads*XML->sys.core[ithCore].instruction_buffer_size*interface_ip.line_sz>64? + XML->sys.core[ithCore].number_hardware_threads*XML->sys.core[ithCore].instruction_buffer_size*interface_ip.line_sz:64; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 0; + interface_ip.throughput = 1.0/clockRate; + interface_ip.latency = 1.0/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + //NOTE: Assuming IB is time slice shared among threads, every fetch op will at least fetch "fetch width" instructions. + interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].number_instruction_fetch_ports;//XML->sys.core[ithCore].fetch_width; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + IB = new ArrayST(&interface_ip, "InstBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); + IB->area.set_area(IB->area.get_area()+ IB->local_result.area); + area.set_area(area.get_area()+ IB->local_result.area); + //output_data_csv(IB.IB.local_result); + + // inst_decoder.opcode_length = XML->sys.core[ithCore].opcode_width; + // inst_decoder.init_decoder(is_default, &interface_ip); + // inst_decoder.full_decoder_power(); + + if (coredynp.predictionW>0) + { + /* + * BTB branch target buffer, accessed during IF stage. Virtually indexed and virtually tagged + * It is only a cache without all the buffers in the cache controller since it is more like a + * look up table than a cache with cache controller. When access miss, no load from other places + * such as main memory (not actively fill the misses), it is passively updated under two circumstances: + * 1) when BPT@ID stage finds out current is a taken branch while BTB missed + * 2) When BPT@ID stage predicts differently than BTB + * 3) When ID stage finds out current instruction is not a branch while BTB had a hit.(mark as invalid) + * 4) when EXEU find out wrong target has been provided from BTB. + * + */ + size = XML->sys.core[ithCore].BTB.BTB_config[0]; + line = XML->sys.core[ithCore].BTB.BTB_config[1]; + assoc = XML->sys.core[ithCore].BTB.BTB_config[2]; + banks = XML->sys.core[ithCore].BTB.BTB_config[3]; + idx = debug?9:int(ceil(log2(size/line/assoc))); +// tag = debug?51:XML->sys.virtual_address_width-idx-int(ceil(log2(line))) + int(ceil(log2(XML->sys.core[ithCore].number_hardware_threads))) +EXTRA_TAG_BITS; + tag = debug?51:XML->sys.virtual_address_width + int(ceil(log2(XML->sys.core[ithCore].number_hardware_threads))) +EXTRA_TAG_BITS; + interface_ip.is_cache = true; + interface_ip.pure_ram = false; + interface_ip.pure_cam = false; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.cache_sz = debug?32768:size; + interface_ip.line_sz = debug?64:line; + interface_ip.assoc = debug?8:assoc; + interface_ip.nbanks = debug?1:banks; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 0;//debug?0:XML->sys.core[ithCore].dcache.dcache_config[5]; + interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].BTB.BTB_config[4]/clockRate; + interface_ip.latency = debug?3.0/clockRate:XML->sys.core[ithCore].BTB.BTB_config[5]/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1; + interface_ip.num_rd_ports = coredynp.predictionW; + interface_ip.num_wr_ports = coredynp.predictionW; + interface_ip.num_se_rd_ports = 0; + BTB = new ArrayST(&interface_ip, "Branch Target Buffer", Core_device, coredynp.opt_local, coredynp.core_ty); + BTB->area.set_area(BTB->area.get_area()+ BTB->local_result.area); + area.set_area(area.get_area()+ BTB->local_result.area); + ///cout<<"area="<area.get_area()); + } - /* - *iCache controllers - *miss buffer Each MSHR contains enough state - *to handle one or more accesses of any type to a single memory line. - *Due to the generality of the MSHR mechanism, - *the amount of state involved is non-trivial: - *including the address, pointers to the cache entry and destination register, - *written data, and various other pieces of state. - */ - interface_ip.num_search_ports = - debug ? 1 : XML->sys.core[ithCore].number_instruction_fetch_ports; - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = (XML->sys.physical_address_width) + int(ceil(log2(size / line))) + - icache.caches->l_ip.line_sz * 8; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = - int(ceil(data / 8.0)); // int(ceil(pow(2.0,ceil(log2(data)))/8.0)); - interface_ip.cache_sz = - XML->sys.core[ithCore].icache.buffer_sizes[0] * interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 0; - interface_ip.throughput = - debug ? 1.0 / clockRate : XML->sys.core[ithCore].icache.icache_config[4] / - clockRate; // means cycle time - interface_ip.latency = - debug ? 1.0 / clockRate : XML->sys.core[ithCore].icache.icache_config[5] / - clockRate; // means access time - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = - debug ? 1 : XML->sys.core[ithCore].number_instruction_fetch_ports; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = - XML->sys.core[ithCore].number_instruction_fetch_ports; - icache.missb = new ArrayST(&interface_ip, "icacheMissBuffer", Core_device, - coredynp.opt_local, coredynp.core_ty); - icache.area.set_area(icache.area.get_area() + - icache.missb->local_result.area); - area.set_area(area.get_area() + icache.missb->local_result.area); - // output_data_csv(icache.missb.local_result); - - // fill buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = icache.caches->l_ip.line_sz; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data; // int(pow(2.0,ceil(log2(data)))); - interface_ip.cache_sz = data * XML->sys.core[ithCore].icache.buffer_sizes[1]; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 0; - interface_ip.throughput = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].icache.icache_config[4] / clockRate; - interface_ip.latency = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].icache.icache_config[5] / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = - debug ? 1 : XML->sys.core[ithCore].number_instruction_fetch_ports; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = - XML->sys.core[ithCore].number_instruction_fetch_ports; - icache.ifb = new ArrayST(&interface_ip, "icacheFillBuffer", Core_device, - coredynp.opt_local, coredynp.core_ty); - icache.area.set_area(icache.area.get_area() + icache.ifb->local_result.area); - area.set_area(area.get_area() + icache.ifb->local_result.area); - // output_data_csv(icache.ifb.local_result); - - // prefetch buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; // check with - // previous entries - // to decide wthether - // to merge. - data = icache.caches->l_ip - .line_sz; // separate queue to prevent from cache polution. - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data; // int(pow(2.0,ceil(log2(data)))); - interface_ip.cache_sz = - XML->sys.core[ithCore].icache.buffer_sizes[2] * interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 0; - interface_ip.throughput = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].icache.icache_config[4] / clockRate; - interface_ip.latency = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].icache.icache_config[5] / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = - debug ? 1 : XML->sys.core[ithCore].number_instruction_fetch_ports; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = - XML->sys.core[ithCore].number_instruction_fetch_ports; - icache.prefetchb = - new ArrayST(&interface_ip, "icacheprefetchBuffer", Core_device, - coredynp.opt_local, coredynp.core_ty); - icache.area.set_area(icache.area.get_area() + - icache.prefetchb->local_result.area); - area.set_area(area.get_area() + icache.prefetchb->local_result.area); - // output_data_csv(icache.prefetchb.local_result); - - // Instruction buffer - data = - XML->sys.core[ithCore].instruction_length * - XML->sys.core[ithCore].peak_issue_width; // icache.caches.l_ip.line_sz; - // //multiple threads timing - // sharing the instruction - // buffer. - interface_ip.is_cache = false; - interface_ip.pure_ram = true; - interface_ip.pure_cam = false; - interface_ip.line_sz = int(ceil(data / 8.0)); - interface_ip.cache_sz = - XML->sys.core[ithCore].number_hardware_threads * - XML->sys.core[ithCore].instruction_buffer_size * - interface_ip.line_sz > - 64 - ? XML->sys.core[ithCore].number_hardware_threads * - XML->sys.core[ithCore].instruction_buffer_size * - interface_ip.line_sz - : 64; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 0; - interface_ip.throughput = 1.0 / clockRate; - interface_ip.latency = 1.0 / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - // NOTE: Assuming IB is time slice shared among threads, every fetch op will - // at least fetch "fetch width" instructions. - interface_ip.num_rw_ports = - debug - ? 1 - : XML->sys.core[ithCore] - .number_instruction_fetch_ports; // XML->sys.core[ithCore].fetch_width; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - IB = new ArrayST(&interface_ip, "InstBuffer", Core_device, coredynp.opt_local, - coredynp.core_ty); - IB->area.set_area(IB->area.get_area() + IB->local_result.area); - area.set_area(area.get_area() + IB->local_result.area); - // output_data_csv(IB.IB.local_result); - - // inst_decoder.opcode_length = XML->sys.core[ithCore].opcode_width; - // inst_decoder.init_decoder(is_default, &interface_ip); - // inst_decoder.full_decoder_power(); - - if (coredynp.predictionW > 0) { - /* - * BTB branch target buffer, accessed during IF stage. Virtually indexed and - * virtually tagged - * It is only a cache without all the buffers in the cache controller since - * it is more like a - * look up table than a cache with cache controller. When access miss, no - * load from other places - * such as main memory (not actively fill the misses), it is passively - * updated under two circumstances: - * 1) when BPT@ID stage finds out current is a taken branch while BTB - * missed - * 2) When BPT@ID stage predicts differently than BTB - * 3) When ID stage finds out current instruction is not a branch while BTB - * had a hit.(mark as invalid) - * 4) when EXEU find out wrong target has been provided from BTB. - * - */ - size = XML->sys.core[ithCore].BTB.BTB_config[0]; - line = XML->sys.core[ithCore].BTB.BTB_config[1]; - assoc = XML->sys.core[ithCore].BTB.BTB_config[2]; - banks = XML->sys.core[ithCore].BTB.BTB_config[3]; - idx = debug ? 9 : int(ceil(log2(size / line / assoc))); - // tag = - // debug?51:XML->sys.virtual_address_width-idx-int(ceil(log2(line))) + - // int(ceil(log2(XML->sys.core[ithCore].number_hardware_threads))) - // +EXTRA_TAG_BITS; - tag = - debug ? 51 : XML->sys.virtual_address_width + - int(ceil(log2( - XML->sys.core[ithCore].number_hardware_threads))) + - EXTRA_TAG_BITS; - interface_ip.is_cache = true; - interface_ip.pure_ram = false; - interface_ip.pure_cam = false; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.cache_sz = debug ? 32768 : size; - interface_ip.line_sz = debug ? 64 : line; - interface_ip.assoc = debug ? 8 : assoc; - interface_ip.nbanks = debug ? 1 : banks; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = - 0; // debug?0:XML->sys.core[ithCore].dcache.dcache_config[5]; - interface_ip.throughput = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].BTB.BTB_config[4] / clockRate; - interface_ip.latency = - debug ? 3.0 / clockRate - : XML->sys.core[ithCore].BTB.BTB_config[5] / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; - interface_ip.num_rd_ports = coredynp.predictionW; - interface_ip.num_wr_ports = coredynp.predictionW; - interface_ip.num_se_rd_ports = 0; - BTB = new ArrayST(&interface_ip, "Branch Target Buffer", Core_device, - coredynp.opt_local, coredynp.core_ty); - BTB->area.set_area(BTB->area.get_area() + BTB->local_result.area); - area.set_area(area.get_area() + BTB->local_result.area); - /// cout<<"area="<area.get_area()); - } + ID_inst = new inst_decoder(is_default, &interface_ip, + coredynp.opcode_length, 1/*Decoder should not know how many by itself*/, + coredynp.x86, + Core_device, coredynp.core_ty); + + ID_operand = new inst_decoder(is_default, &interface_ip, + coredynp.arch_ireg_width, 1, + coredynp.x86, + Core_device, coredynp.core_ty); + + ID_misc = new inst_decoder(is_default, &interface_ip, + 8/* Prefix field etc upto 14B*/, 1, + coredynp.x86, + Core_device, coredynp.core_ty); + //TODO: X86 decoder should decode the inst in cyclic mode under the control of squencer. + //So the dynamic power should be multiplied by a few times. + area.set_area(area.get_area()+ (ID_inst->area.get_area() + +ID_operand->area.get_area() + +ID_misc->area.get_area())*coredynp.decodeW); - ID_inst = new inst_decoder(is_default, &interface_ip, coredynp.opcode_length, - 1 /*Decoder should not know how many by itself*/, - coredynp.x86, Core_device, coredynp.core_ty); - - ID_operand = - new inst_decoder(is_default, &interface_ip, coredynp.arch_ireg_width, 1, - coredynp.x86, Core_device, coredynp.core_ty); - - ID_misc = new inst_decoder(is_default, &interface_ip, - 8 /* Prefix field etc upto 14B*/, 1, coredynp.x86, - Core_device, coredynp.core_ty); - // TODO: X86 decoder should decode the inst in cyclic mode under the control - // of squencer. - // So the dynamic power should be multiplied by a few times. - area.set_area(area.get_area() + - (ID_inst->area.get_area() + ID_operand->area.get_area() + - ID_misc->area.get_area()) * - coredynp.decodeW); } -BranchPredictor::BranchPredictor(ParseXML* XML_interface, int ithCore_, - InputParameter* interface_ip_, - const CoreDynParam& dyn_p_, bool exist_) - : XML(XML_interface), - ithCore(ithCore_), - interface_ip(*interface_ip_), - coredynp(dyn_p_), - globalBPT(0), - localBPT(0), - L1_localBPT(0), - L2_localBPT(0), - chooser(0), - RAS(0), - exist(exist_) { - /* - * Branch Predictor, accessed during ID stage. - * McPAT's branch predictor model is the tournament branch predictor used in - * Alpha 21264, - * including global predictor, local two level predictor, and Chooser. - * The Branch predictor also includes a RAS (return address stack) for - * function calls - * Branch predictors are tagged by thread ID and modeled as 1-way associative - * $ - * However RAS return address stacks are duplicated for each thread. - * TODO:Data Width need to be computed more precisely * - */ - if (!exist) return; - int tag, data; - - clockRate = coredynp.clockRate; - executionTime = coredynp.executionTime; - interface_ip.assoc = 1; - interface_ip.pure_cam = false; - if (coredynp.multithreaded) { - tag = int(log2(coredynp.num_hthreads) + EXTRA_TAG_BITS); - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - - interface_ip.is_cache = true; - interface_ip.pure_ram = false; - } else { - interface_ip.is_cache = false; - interface_ip.pure_ram = true; - } - // Global predictor - data = - int(ceil(XML->sys.core[ithCore].predictor.global_predictor_bits / 8.0)); - interface_ip.line_sz = data; - interface_ip.cache_sz = - data * XML->sys.core[ithCore].predictor.global_predictor_entries; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 2; - interface_ip.throughput = 1.0 / clockRate; - interface_ip.latency = 1.0 / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = coredynp.predictionW; - interface_ip.num_wr_ports = coredynp.predictionW; - interface_ip.num_se_rd_ports = 0; - globalBPT = new ArrayST(&interface_ip, "Global Predictor", Core_device, - coredynp.opt_local, coredynp.core_ty); - globalBPT->area.set_area(globalBPT->area.get_area() + - globalBPT->local_result.area); - area.set_area(area.get_area() + globalBPT->local_result.area); - - // Local BPT (Level 1) - data = - int(ceil(XML->sys.core[ithCore].predictor.local_predictor_size[0] / 8.0)); - interface_ip.line_sz = data; - interface_ip.cache_sz = - data * XML->sys.core[ithCore].predictor.local_predictor_entries; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 2; - interface_ip.throughput = 1.0 / clockRate; - interface_ip.latency = 1.0 / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = coredynp.predictionW; - interface_ip.num_wr_ports = coredynp.predictionW; - interface_ip.num_se_rd_ports = 0; - L1_localBPT = new ArrayST(&interface_ip, "L1 local Predictor", Core_device, - coredynp.opt_local, coredynp.core_ty); - L1_localBPT->area.set_area(L1_localBPT->area.get_area() + - L1_localBPT->local_result.area); - area.set_area(area.get_area() + L1_localBPT->local_result.area); - - // Local BPT (Level 2) - data = - int(ceil(XML->sys.core[ithCore].predictor.local_predictor_size[1] / 8.0)); - interface_ip.line_sz = data; - interface_ip.cache_sz = - data * XML->sys.core[ithCore].predictor.local_predictor_entries; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 2; - interface_ip.throughput = 1.0 / clockRate; - interface_ip.latency = 1.0 / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = coredynp.predictionW; - interface_ip.num_wr_ports = coredynp.predictionW; - interface_ip.num_se_rd_ports = 0; - L2_localBPT = new ArrayST(&interface_ip, "L2 local Predictor", Core_device, - coredynp.opt_local, coredynp.core_ty); - L2_localBPT->area.set_area(L2_localBPT->area.get_area() + - L2_localBPT->local_result.area); - area.set_area(area.get_area() + L2_localBPT->local_result.area); - - // Chooser - data = - int(ceil(XML->sys.core[ithCore].predictor.chooser_predictor_bits / 8.0)); - interface_ip.line_sz = data; - interface_ip.cache_sz = - data * XML->sys.core[ithCore].predictor.chooser_predictor_entries; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 2; - interface_ip.throughput = 1.0 / clockRate; - interface_ip.latency = 1.0 / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = coredynp.predictionW; - interface_ip.num_wr_ports = coredynp.predictionW; - interface_ip.num_se_rd_ports = 0; - chooser = new ArrayST(&interface_ip, "Predictor Chooser", Core_device, - coredynp.opt_local, coredynp.core_ty); - chooser->area.set_area(chooser->area.get_area() + chooser->local_result.area); - area.set_area(area.get_area() + chooser->local_result.area); - - // RAS return address stacks are Duplicated for each thread. - interface_ip.is_cache = false; - interface_ip.pure_ram = true; - data = int(ceil(coredynp.pc_width / 8.0)); - interface_ip.line_sz = data; - interface_ip.cache_sz = data * XML->sys.core[ithCore].RAS_size; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 2; - interface_ip.throughput = 1.0 / clockRate; - interface_ip.latency = 1.0 / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = coredynp.predictionW; - interface_ip.num_wr_ports = coredynp.predictionW; - interface_ip.num_se_rd_ports = 0; - RAS = new ArrayST(&interface_ip, "RAS", Core_device, coredynp.opt_local, - coredynp.core_ty); - RAS->area.set_area(RAS->area.get_area() + - RAS->local_result.area * coredynp.num_hthreads); - area.set_area(area.get_area() + - RAS->local_result.area * coredynp.num_hthreads); -} -SchedulerU::SchedulerU(ParseXML* XML_interface, int ithCore_, - InputParameter* interface_ip_, - const CoreDynParam& dyn_p_, bool exist_) - : XML(XML_interface), - ithCore(ithCore_), - interface_ip(*interface_ip_), - coredynp(dyn_p_), - int_inst_window(0), - fp_inst_window(0), - ROB(0), - instruction_selection(0), - exist(exist_) { - if (!exist) return; - int tag, data; - bool is_default = true; - string tmp_name; +BranchPredictor::BranchPredictor(ParseXML* XML_interface, int ithCore_, InputParameter* interface_ip_, const CoreDynParam & dyn_p_, bool exist_) +:XML(XML_interface), + ithCore(ithCore_), + interface_ip(*interface_ip_), + coredynp(dyn_p_), + globalBPT(0), + localBPT(0), + L1_localBPT(0), + L2_localBPT(0), + chooser(0), + RAS(0), + exist(exist_) +{ + /* + * Branch Predictor, accessed during ID stage. + * McPAT's branch predictor model is the tournament branch predictor used in Alpha 21264, + * including global predictor, local two level predictor, and Chooser. + * The Branch predictor also includes a RAS (return address stack) for function calls + * Branch predictors are tagged by thread ID and modeled as 1-way associative $ + * However RAS return address stacks are duplicated for each thread. + * TODO:Data Width need to be computed more precisely * + */ + if (!exist) return; + int tag, data; + + clockRate = coredynp.clockRate; + executionTime = coredynp.executionTime; + interface_ip.assoc = 1; + interface_ip.pure_cam = false; + if (coredynp.multithreaded) + { + + tag = int(log2(coredynp.num_hthreads)+ EXTRA_TAG_BITS); + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + + interface_ip.is_cache = true; + interface_ip.pure_ram = false; + } + else + { + interface_ip.is_cache = false; + interface_ip.pure_ram = true; + + } + //Global predictor + data = int(ceil(XML->sys.core[ithCore].predictor.global_predictor_bits/8.0)); + interface_ip.line_sz = data; + interface_ip.cache_sz = data*XML->sys.core[ithCore].predictor.global_predictor_entries; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 2; + interface_ip.throughput = 1.0/clockRate; + interface_ip.latency = 1.0/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = coredynp.predictionW; + interface_ip.num_wr_ports = coredynp.predictionW; + interface_ip.num_se_rd_ports = 0; + globalBPT = new ArrayST(&interface_ip, "Global Predictor", Core_device, coredynp.opt_local, coredynp.core_ty); + globalBPT->area.set_area(globalBPT->area.get_area()+ globalBPT->local_result.area); + area.set_area(area.get_area()+ globalBPT->local_result.area); + + //Local BPT (Level 1) + data = int(ceil(XML->sys.core[ithCore].predictor.local_predictor_size[0]/8.0)); + interface_ip.line_sz = data; + interface_ip.cache_sz = data*XML->sys.core[ithCore].predictor.local_predictor_entries; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 2; + interface_ip.throughput = 1.0/clockRate; + interface_ip.latency = 1.0/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = coredynp.predictionW; + interface_ip.num_wr_ports = coredynp.predictionW; + interface_ip.num_se_rd_ports = 0; + L1_localBPT = new ArrayST(&interface_ip, "L1 local Predictor", Core_device, coredynp.opt_local, coredynp.core_ty); + L1_localBPT->area.set_area(L1_localBPT->area.get_area()+ L1_localBPT->local_result.area); + area.set_area(area.get_area()+ L1_localBPT->local_result.area); + + //Local BPT (Level 2) + data = int(ceil(XML->sys.core[ithCore].predictor.local_predictor_size[1]/8.0)); + interface_ip.line_sz = data; + interface_ip.cache_sz = data*XML->sys.core[ithCore].predictor.local_predictor_entries; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 2; + interface_ip.throughput = 1.0/clockRate; + interface_ip.latency = 1.0/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = coredynp.predictionW; + interface_ip.num_wr_ports = coredynp.predictionW; + interface_ip.num_se_rd_ports = 0; + L2_localBPT = new ArrayST(&interface_ip, "L2 local Predictor", Core_device, coredynp.opt_local, coredynp.core_ty); + L2_localBPT->area.set_area(L2_localBPT->area.get_area()+ L2_localBPT->local_result.area); + area.set_area(area.get_area()+ L2_localBPT->local_result.area); + + //Chooser + data = int(ceil(XML->sys.core[ithCore].predictor.chooser_predictor_bits/8.0)); + interface_ip.line_sz = data; + interface_ip.cache_sz = data*XML->sys.core[ithCore].predictor.chooser_predictor_entries; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 2; + interface_ip.throughput = 1.0/clockRate; + interface_ip.latency = 1.0/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = coredynp.predictionW; + interface_ip.num_wr_ports = coredynp.predictionW; + interface_ip.num_se_rd_ports = 0; + chooser = new ArrayST(&interface_ip, "Predictor Chooser", Core_device, coredynp.opt_local, coredynp.core_ty); + chooser->area.set_area(chooser->area.get_area()+ chooser->local_result.area); + area.set_area(area.get_area()+ chooser->local_result.area); + + //RAS return address stacks are Duplicated for each thread. + interface_ip.is_cache = false; + interface_ip.pure_ram = true; + data = int(ceil(coredynp.pc_width/8.0)); + interface_ip.line_sz = data; + interface_ip.cache_sz = data*XML->sys.core[ithCore].RAS_size; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 2; + interface_ip.throughput = 1.0/clockRate; + interface_ip.latency = 1.0/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = coredynp.predictionW; + interface_ip.num_wr_ports = coredynp.predictionW; + interface_ip.num_se_rd_ports = 0; + RAS = new ArrayST(&interface_ip, "RAS", Core_device, coredynp.opt_local, coredynp.core_ty); + RAS->area.set_area(RAS->area.get_area()+ RAS->local_result.area*coredynp.num_hthreads); + area.set_area(area.get_area()+ RAS->local_result.area*coredynp.num_hthreads); - clockRate = coredynp.clockRate; - executionTime = coredynp.executionTime; - if ((coredynp.core_ty == Inorder && coredynp.multithreaded)) { - // Instruction issue queue, in-order multi-issue or multithreaded processor - // also has this structure. Unified window for Inorder processors - tag = int(log2(XML->sys.core[ithCore].number_hardware_threads) * - coredynp.perThreadState); // This is the normal thread state bits - // based on Niagara Design - data = XML->sys.core[ithCore].instruction_length; - // NOTE: x86 inst can be very lengthy, up to 15B. Source: Intel® 64 and - // IA-32 Architectures - // Software Developer’s Manual - interface_ip.is_cache = true; - interface_ip.pure_cam = false; - interface_ip.pure_ram = false; - interface_ip.line_sz = int(ceil(data / 8.0)); - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.cache_sz = - XML->sys.core[ithCore].instruction_window_size * interface_ip.line_sz > - 64 - ? XML->sys.core[ithCore].instruction_window_size * - interface_ip.line_sz - : 64; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 1; - interface_ip.throughput = 1.0 / clockRate; - interface_ip.latency = 1.0 / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = coredynp.peak_issueW; - interface_ip.num_wr_ports = coredynp.peak_issueW; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = coredynp.peak_issueW; - int_inst_window = new ArrayST(&interface_ip, "InstFetchQueue", Core_device, - coredynp.opt_local, coredynp.core_ty); - int_inst_window->area.set_area(int_inst_window->area.get_area() + - int_inst_window->local_result.area * - coredynp.num_pipelines); - area.set_area(area.get_area() + - int_inst_window->local_result.area * coredynp.num_pipelines); - // output_data_csv(iRS.RS.local_result); - Iw_height = int_inst_window->local_result.cache_ht; - - /* - * selection logic - * In a single-issue Inorder multithreaded processor like Niagara, issue - * width=1*number_of_threads since the processor does need to pick up - * instructions from multiple ready ones(although these ready ones are from - * different threads).While SMT processors do not distinguish which thread - * belongs to who - * at the issue stage. - */ - - instruction_selection = new selection_logic( - is_default, XML->sys.core[ithCore].instruction_window_size, - coredynp.peak_issueW * XML->sys.core[ithCore].number_hardware_threads, - &interface_ip, Core_device, coredynp.core_ty); - } +} - if (coredynp.core_ty == OOO) { - /* - * CAM based instruction window - * For physicalRegFilebased OOO it is the instruction issue queue, where - * only tags of phy regs are stored - * For RS based OOO it is the Reservation station, where both tags and - * values of phy regs are stored - * It is written once and read twice(two operands) before an instruction can - * be issued. - * X86 instruction can be very long up to 15B. add instruction length in XML - */ - if (coredynp.scheu_ty == PhysicalRegFile) { - tag = coredynp.phy_ireg_width; - // Each time only half of the tag is compared, but two tag should be - // stored. - // This underestimate the search power - data = - int((ceil((coredynp.instruction_length + - 2 * (coredynp.phy_ireg_width - coredynp.arch_ireg_width)) / - 2.0) / - 8.0)); - // Data width being divided by 2 means only after both operands available - // the whole data will be read out. - // This is modeled using two equivalent readouts with half of the data - // width - tmp_name = "InstIssueQueue"; - } else { - tag = coredynp.phy_ireg_width; - // Each time only half of the tag is compared, but two tag should be - // stored. - // This underestimate the search power - data = - int(ceil(((coredynp.instruction_length + - 2 * (coredynp.phy_ireg_width - coredynp.arch_ireg_width) + - 2 * coredynp.int_data_width) / - 2.0) / - 8.0)); - // Data width being divided by 2 means only after both operands available - // the whole data will be read out. - // This is modeled using two equivalent readouts with half of the data - // width - - tmp_name = "IntReservationStation"; - } - interface_ip.is_cache = true; - interface_ip.pure_cam = false; - interface_ip.pure_ram = false; - interface_ip.line_sz = data; - interface_ip.cache_sz = - data * XML->sys.core[ithCore].instruction_window_size; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.access_mode = 0; - interface_ip.throughput = 2 * 1.0 / clockRate; - interface_ip.latency = 2 * 1.0 / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = coredynp.peak_issueW; - interface_ip.num_wr_ports = coredynp.peak_issueW; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = coredynp.peak_issueW; - int_inst_window = new ArrayST(&interface_ip, tmp_name, Core_device, - coredynp.opt_local, coredynp.core_ty); - int_inst_window->area.set_area(int_inst_window->area.get_area() + - int_inst_window->local_result.area * - coredynp.num_pipelines); - area.set_area(area.get_area() + - int_inst_window->local_result.area * coredynp.num_pipelines); - Iw_height = int_inst_window->local_result.cache_ht; - // FU inst window - if (coredynp.scheu_ty == PhysicalRegFile) { - tag = 2 * coredynp.phy_freg_width; // TODO: each time only half of the - // tag is compared - data = - int(ceil((coredynp.instruction_length + - 2 * (coredynp.phy_freg_width - coredynp.arch_freg_width)) / - 8.0)); - tmp_name = "FPIssueQueue"; - } else { - tag = 2 * coredynp.phy_ireg_width; - data = - int(ceil((coredynp.instruction_length + - 2 * (coredynp.phy_freg_width - coredynp.arch_freg_width) + - 2 * coredynp.fp_data_width) / - 8.0)); - tmp_name = "FPReservationStation"; - } - interface_ip.is_cache = true; - interface_ip.pure_cam = false; - interface_ip.pure_ram = false; - interface_ip.line_sz = data; - interface_ip.cache_sz = - data * XML->sys.core[ithCore].fp_instruction_window_size; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.access_mode = 0; - interface_ip.throughput = 1.0 / clockRate; - interface_ip.latency = 1.0 / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = coredynp.fp_issueW; - interface_ip.num_wr_ports = coredynp.fp_issueW; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = coredynp.fp_issueW; - fp_inst_window = new ArrayST(&interface_ip, tmp_name, Core_device, - coredynp.opt_local, coredynp.core_ty); - fp_inst_window->area.set_area(fp_inst_window->area.get_area() + - fp_inst_window->local_result.area * - coredynp.num_fp_pipelines); - area.set_area(area.get_area() + - fp_inst_window->local_result.area * - coredynp.num_fp_pipelines); - fp_Iw_height = fp_inst_window->local_result.cache_ht; - - if (XML->sys.core[ithCore].ROB_size > 0) { - /* - * if ROB_size = 0, then the target processor does not support - *hardware-based - * speculation, i.e. , the processor allow OOO issue as well as OOO - *completion, which - * means branch must be resolved before instruction issued into - *instruction window, since - * there is no change to flush miss-predict branch path after - *instructions are issued in this situation. - * - * ROB.ROB size = inflight inst. ROB is unified for int and fp inst. - * One old approach is to combine the RAT and ROB as a huge CAM structure - *as in AMD K7. - * However, this approach is abandoned due to its high power and poor - *scalablility. - * McPAT uses current implementation of ROB as circular buffer. - * ROB is written once when instruction is issued and read once - *when the instruction is committed. * - */ - int robExtra = int(ceil(5 + log2(coredynp.num_hthreads))); - // 5 bits are: busy, Issued, Finished, speculative, valid - if (coredynp.scheu_ty == PhysicalRegFile) { - // PC is to id the instruction for recover exception. - // inst is used to map the renamed dest. registers.so that commit stage - // can know which reg/RRAT to update - // data = int(ceil((robExtra+coredynp.pc_width - //+ - // coredynp.instruction_length + - //2*coredynp.phy_ireg_width)/8.0)); - data = int(ceil( - (robExtra + coredynp.pc_width + coredynp.phy_ireg_width) / 8.0)); - } else { - // in RS based OOO, ROB also contains value of destination reg - // data = int(ceil((robExtra+coredynp.pc_width - //+ - // coredynp.instruction_length + - //2*coredynp.phy_ireg_width + coredynp.fp_data_width)/8.0)); - data = int(ceil((robExtra + coredynp.pc_width + - coredynp.phy_ireg_width + coredynp.fp_data_width) / - 8.0)); - } - interface_ip.is_cache = false; - interface_ip.pure_cam = false; - interface_ip.pure_ram = true; - interface_ip.line_sz = data; - interface_ip.cache_sz = - data * - XML->sys.core[ithCore] - .ROB_size; // The XML ROB size is for all threads - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 1; - interface_ip.throughput = 1.0 / clockRate; - interface_ip.latency = 1.0 / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = coredynp.peak_commitW; - interface_ip.num_wr_ports = coredynp.peak_issueW; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = 0; - ROB = new ArrayST(&interface_ip, "ReorderBuffer", Core_device, - coredynp.opt_local, coredynp.core_ty); - ROB->area.set_area(ROB->area.get_area() + - ROB->local_result.area * coredynp.num_pipelines); - area.set_area(area.get_area() + - ROB->local_result.area * coredynp.num_pipelines); - ROB_height = ROB->local_result.cache_ht; +SchedulerU::SchedulerU(ParseXML* XML_interface, int ithCore_, InputParameter* interface_ip_, const CoreDynParam & dyn_p_, bool exist_) +:XML(XML_interface), + ithCore(ithCore_), + interface_ip(*interface_ip_), + coredynp(dyn_p_), + int_inst_window(0), + fp_inst_window(0), + ROB(0), + instruction_selection(0), + exist(exist_) + { + if (!exist) return; + int tag, data; + bool is_default=true; + string tmp_name; + + clockRate = coredynp.clockRate; + executionTime = coredynp.executionTime; + if ((coredynp.core_ty==Inorder && coredynp.multithreaded)) + { + //Instruction issue queue, in-order multi-issue or multithreaded processor also has this structure. Unified window for Inorder processors + tag = int(log2(XML->sys.core[ithCore].number_hardware_threads)*coredynp.perThreadState);//This is the normal thread state bits based on Niagara Design + data = XML->sys.core[ithCore].instruction_length; + //NOTE: x86 inst can be very lengthy, up to 15B. Source: Intel® 64 and IA-32 Architectures + //Software Developer’s Manual + interface_ip.is_cache = true; + interface_ip.pure_cam = false; + interface_ip.pure_ram = false; + interface_ip.line_sz = int(ceil(data/8.0)); + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.cache_sz = XML->sys.core[ithCore].instruction_window_size*interface_ip.line_sz>64?XML->sys.core[ithCore].instruction_window_size*interface_ip.line_sz:64; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 1; + interface_ip.throughput = 1.0/clockRate; + interface_ip.latency = 1.0/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = coredynp.peak_issueW; + interface_ip.num_wr_ports = coredynp.peak_issueW; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = coredynp.peak_issueW; + int_inst_window = new ArrayST(&interface_ip, "InstFetchQueue", Core_device, coredynp.opt_local, coredynp.core_ty); + int_inst_window->area.set_area(int_inst_window->area.get_area()+ int_inst_window->local_result.area*coredynp.num_pipelines); + area.set_area(area.get_area()+ int_inst_window->local_result.area*coredynp.num_pipelines); + //output_data_csv(iRS.RS.local_result); + Iw_height =int_inst_window->local_result.cache_ht; + + /* + * selection logic + * In a single-issue Inorder multithreaded processor like Niagara, issue width=1*number_of_threads since the processor does need to pick up + * instructions from multiple ready ones(although these ready ones are from different threads).While SMT processors do not distinguish which thread belongs to who + * at the issue stage. + */ + + instruction_selection = new selection_logic(is_default, XML->sys.core[ithCore].instruction_window_size, + coredynp.peak_issueW*XML->sys.core[ithCore].number_hardware_threads, + &interface_ip, Core_device, coredynp.core_ty); + } + + if (coredynp.core_ty==OOO) + { + /* + * CAM based instruction window + * For physicalRegFilebased OOO it is the instruction issue queue, where only tags of phy regs are stored + * For RS based OOO it is the Reservation station, where both tags and values of phy regs are stored + * It is written once and read twice(two operands) before an instruction can be issued. + * X86 instruction can be very long up to 15B. add instruction length in XML + */ + if(coredynp.scheu_ty==PhysicalRegFile) + { + tag = coredynp.phy_ireg_width; + // Each time only half of the tag is compared, but two tag should be stored. + // This underestimate the search power + data = int((ceil((coredynp.instruction_length+2*(coredynp.phy_ireg_width - coredynp.arch_ireg_width))/2.0)/8.0)); + //Data width being divided by 2 means only after both operands available the whole data will be read out. + //This is modeled using two equivalent readouts with half of the data width + tmp_name = "InstIssueQueue"; + } + else + { + tag = coredynp.phy_ireg_width; + // Each time only half of the tag is compared, but two tag should be stored. + // This underestimate the search power + data = int(ceil(((coredynp.instruction_length+2*(coredynp.phy_ireg_width - coredynp.arch_ireg_width)+ + 2*coredynp.int_data_width)/2.0)/8.0)); + //Data width being divided by 2 means only after both operands available the whole data will be read out. + //This is modeled using two equivalent readouts with half of the data width + + tmp_name = "IntReservationStation"; + } + interface_ip.is_cache = true; + interface_ip.pure_cam = false; + interface_ip.pure_ram = false; + interface_ip.line_sz = data; + interface_ip.cache_sz = data*XML->sys.core[ithCore].instruction_window_size; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.access_mode = 0; + interface_ip.throughput = 2*1.0/clockRate; + interface_ip.latency = 2*1.0/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = coredynp.peak_issueW; + interface_ip.num_wr_ports = coredynp.peak_issueW; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = coredynp.peak_issueW; + int_inst_window = new ArrayST(&interface_ip, tmp_name, Core_device, coredynp.opt_local, coredynp.core_ty); + int_inst_window->area.set_area(int_inst_window->area.get_area()+ int_inst_window->local_result.area*coredynp.num_pipelines); + area.set_area(area.get_area()+ int_inst_window->local_result.area*coredynp.num_pipelines); + Iw_height =int_inst_window->local_result.cache_ht; + //FU inst window + if(coredynp.scheu_ty==PhysicalRegFile) + { + tag = 2*coredynp.phy_freg_width;// TODO: each time only half of the tag is compared + data = int(ceil((coredynp.instruction_length+2*(coredynp.phy_freg_width - coredynp.arch_freg_width))/8.0)); + tmp_name = "FPIssueQueue"; + } + else + { + tag = 2*coredynp.phy_ireg_width; + data = int(ceil((coredynp.instruction_length+2*(coredynp.phy_freg_width - coredynp.arch_freg_width)+ + 2*coredynp.fp_data_width)/8.0)); + tmp_name = "FPReservationStation"; + } + interface_ip.is_cache = true; + interface_ip.pure_cam = false; + interface_ip.pure_ram = false; + interface_ip.line_sz = data; + interface_ip.cache_sz = data*XML->sys.core[ithCore].fp_instruction_window_size; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.access_mode = 0; + interface_ip.throughput = 1.0/clockRate; + interface_ip.latency = 1.0/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = coredynp.fp_issueW; + interface_ip.num_wr_ports = coredynp.fp_issueW; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = coredynp.fp_issueW; + fp_inst_window = new ArrayST(&interface_ip, tmp_name, Core_device, coredynp.opt_local, coredynp.core_ty); + fp_inst_window->area.set_area(fp_inst_window->area.get_area()+ fp_inst_window->local_result.area*coredynp.num_fp_pipelines); + area.set_area(area.get_area()+ fp_inst_window->local_result.area*coredynp.num_fp_pipelines); + fp_Iw_height =fp_inst_window->local_result.cache_ht; + + if (XML->sys.core[ithCore].ROB_size >0) + { + /* + * if ROB_size = 0, then the target processor does not support hardware-based + * speculation, i.e. , the processor allow OOO issue as well as OOO completion, which + * means branch must be resolved before instruction issued into instruction window, since + * there is no change to flush miss-predict branch path after instructions are issued in this situation. + * + * ROB.ROB size = inflight inst. ROB is unified for int and fp inst. + * One old approach is to combine the RAT and ROB as a huge CAM structure as in AMD K7. + * However, this approach is abandoned due to its high power and poor scalablility. + * McPAT uses current implementation of ROB as circular buffer. + * ROB is written once when instruction is issued and read once when the instruction is committed. * + */ + int robExtra = int(ceil(5 + log2(coredynp.num_hthreads))); + //5 bits are: busy, Issued, Finished, speculative, valid + if(coredynp.scheu_ty==PhysicalRegFile) + { + //PC is to id the instruction for recover exception. + //inst is used to map the renamed dest. registers.so that commit stage can know which reg/RRAT to update +// data = int(ceil((robExtra+coredynp.pc_width + +// coredynp.instruction_length + 2*coredynp.phy_ireg_width)/8.0)); + data = int(ceil((robExtra+coredynp.pc_width + + coredynp.phy_ireg_width)/8.0)); + } + else + { + //in RS based OOO, ROB also contains value of destination reg +// data = int(ceil((robExtra+coredynp.pc_width + +// coredynp.instruction_length + 2*coredynp.phy_ireg_width + coredynp.fp_data_width)/8.0)); + data = int(ceil((robExtra + coredynp.pc_width + + coredynp.phy_ireg_width + coredynp.fp_data_width)/8.0)); + } + interface_ip.is_cache = false; + interface_ip.pure_cam = false; + interface_ip.pure_ram = true; + interface_ip.line_sz = data; + interface_ip.cache_sz = data*XML->sys.core[ithCore].ROB_size;//The XML ROB size is for all threads + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 1; + interface_ip.throughput = 1.0/clockRate; + interface_ip.latency = 1.0/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = coredynp.peak_commitW; + interface_ip.num_wr_ports = coredynp.peak_issueW; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = 0; + ROB = new ArrayST(&interface_ip, "ReorderBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); + ROB->area.set_area(ROB->area.get_area()+ ROB->local_result.area*coredynp.num_pipelines); + area.set_area(area.get_area()+ ROB->local_result.area*coredynp.num_pipelines); + ROB_height =ROB->local_result.cache_ht; + } + + instruction_selection = new selection_logic(is_default, XML->sys.core[ithCore].instruction_window_size, + coredynp.peak_issueW, &interface_ip, Core_device, coredynp.core_ty); } - - instruction_selection = new selection_logic( - is_default, XML->sys.core[ithCore].instruction_window_size, - coredynp.peak_issueW, &interface_ip, Core_device, coredynp.core_ty); - } } -LoadStoreU::LoadStoreU(ParseXML* XML_interface, int ithCore_, - InputParameter* interface_ip_, - const CoreDynParam& dyn_p_, bool exist_) - : XML(XML_interface), - ithCore(ithCore_), - interface_ip(*interface_ip_), - coredynp(dyn_p_), - LSQ(0), - exist(exist_) { - if (!exist) return; - int idx, tag, data, size, line, assoc; - bool debug = false; - int ldst_opcode = XML->sys.core[ithCore].opcode_width; // 16; - - clockRate = coredynp.clockRate; - executionTime = coredynp.executionTime; - cache_p = (Cache_policy)XML->sys.core[ithCore].dcache.dcache_config[7]; - - interface_ip.num_search_ports = XML->sys.core[ithCore].memory_ports; - interface_ip.is_cache = true; - interface_ip.pure_cam = false; - interface_ip.pure_ram = false; - - // Crossbar based interconnect for shared memory accesses, added by Syed - // Crossbar - - if (XML->sys.architecture == 1) { - xbar_shared = new Crossbar( - coredynp.num_fpus, coredynp.num_fpus, 32, - &(g_tp.peri_global)); // Syed: coredynp.num_fpus is used as simd_width - } else { - xbar_shared = new Crossbar( - coredynp.num_fpus, coredynp.num_fpus, 32, - &(g_tp.peri_global)); // Syed: coredynp.num_fpus is used as simd_width - } - - // TODO: Check if this line should be changed to - // new - // Crossbar(simd_width,shared_memory_banks,word_length*simd_width,&(g_tp.peri_global)); - - // shared memory added by Jingwen - size = (int)XML->sys.core[ithCore].sharedmemory.dcache_config[0]; - line = (int)XML->sys.core[ithCore].sharedmemory.dcache_config[1]; - assoc = (int)XML->sys.core[ithCore].sharedmemory.dcache_config[2]; - idx = debug ? 9 : int(ceil(log2(size / line / assoc))); - tag = debug ? 51 : XML->sys.physical_address_width - idx - - int(ceil(log2(line))) + EXTRA_TAG_BITS; - interface_ip.specific_tag = 1; - interface_ip.tag_w = 1; - interface_ip.cache_sz = - debug ? 32768 : (int)XML->sys.core[ithCore].sharedmemory.dcache_config[0]; - interface_ip.line_sz = - debug ? 64 : (int)XML->sys.core[ithCore].sharedmemory.dcache_config[1]; - interface_ip.assoc = - debug ? 8 : (int)XML->sys.core[ithCore].sharedmemory.dcache_config[2]; - interface_ip.nbanks = - debug ? 1 : (int)XML->sys.core[ithCore].sharedmemory.dcache_config[3]; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = - 0; // debug?0:XML->sys.core[ithCore].sharedmemory.dcache_config[5]; - interface_ip.throughput = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].sharedmemory.dcache_config[4] / clockRate; - interface_ip.latency = - debug ? 3.0 / clockRate - : XML->sys.core[ithCore].sharedmemory.dcache_config[5] / clockRate; - interface_ip.is_cache = true; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = - debug ? 1 : XML->sys.core[ithCore].memory_ports; // usually In-order has - // 1 and OOO has 2 at - // least. - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - sharedmemory.caches = new ArrayST(&interface_ip, "sharedmemory", Core_device, - coredynp.opt_local, coredynp.core_ty); - sharedmemory.area.set_area(sharedmemory.area.get_area() + - sharedmemory.caches->local_result.area); - area.set_area(area.get_area() + sharedmemory.caches->local_result.area + - xbar_shared->area.get_area()); - - // shared memory buffer - // miss buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = (XML->sys.physical_address_width) + int(ceil(log2(size / line))) + - sharedmemory.caches->l_ip.line_sz * 8; - interface_ip.specific_tag = 1; - interface_ip.tag_w = 1; - interface_ip.line_sz = - int(ceil(data / 8.0)); // int(ceil(pow(2.0,ceil(log2(data)))/8.0)); - interface_ip.cache_sz = XML->sys.core[ithCore].sharedmemory.buffer_sizes[0] * - interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 2; - interface_ip.throughput = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].sharedmemory.dcache_config[4] / clockRate; - interface_ip.latency = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].sharedmemory.dcache_config[5] / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug ? 1 : XML->sys.core[ithCore].memory_ports; - ; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - sharedmemory.missb = - new ArrayST(&interface_ip, "SharedmemoryMissBuffer", Core_device, - coredynp.opt_local, coredynp.core_ty); - sharedmemory.area.set_area(sharedmemory.area.get_area() + - sharedmemory.missb->local_result.area); - area.set_area(area.get_area() + sharedmemory.missb->local_result.area); - - // sharedmemory fill buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = sharedmemory.caches->l_ip.line_sz; - interface_ip.specific_tag = 1; - interface_ip.tag_w = 1; - interface_ip.line_sz = data; // int(pow(2.0,ceil(log2(data)))); - interface_ip.cache_sz = - data * XML->sys.core[ithCore].sharedmemory.buffer_sizes[1]; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 2; - interface_ip.throughput = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].sharedmemory.dcache_config[4] / clockRate; - interface_ip.latency = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].sharedmemory.dcache_config[5] / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug ? 1 : XML->sys.core[ithCore].memory_ports; - ; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - sharedmemory.ifb = - new ArrayST(&interface_ip, "SharedMemoryFillBuffer", Core_device, - coredynp.opt_local, coredynp.core_ty); - sharedmemory.area.set_area(sharedmemory.area.get_area() + - sharedmemory.ifb->local_result.area); - area.set_area(area.get_area() + sharedmemory.ifb->local_result.area); - - // sharedmemory prefetch buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; // check with - // previous entries - // to decide wthether - // to merge. - data = sharedmemory.caches->l_ip - .line_sz; // separate queue to prevent from cache polution. - interface_ip.specific_tag = 1; - interface_ip.tag_w = 1; - interface_ip.line_sz = data; // int(pow(2.0,ceil(log2(data)))); - interface_ip.cache_sz = XML->sys.core[ithCore].sharedmemory.buffer_sizes[2] * - interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 2; - interface_ip.throughput = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].sharedmemory.dcache_config[4] / clockRate; - interface_ip.latency = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].sharedmemory.dcache_config[5] / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug ? 1 : XML->sys.core[ithCore].memory_ports; - ; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - sharedmemory.prefetchb = - new ArrayST(&interface_ip, "dcacheprefetchBuffer", Core_device, - coredynp.opt_local, coredynp.core_ty); - sharedmemory.area.set_area(sharedmemory.area.get_area() + - sharedmemory.prefetchb->local_result.area); - area.set_area(area.get_area() + sharedmemory.prefetchb->local_result.area); - - // shared memory WBB - if (cache_p == Write_back) { - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = sharedmemory.caches->l_ip.line_sz; - interface_ip.specific_tag = 1; - interface_ip.tag_w = 1; - interface_ip.line_sz = data; - interface_ip.cache_sz = - XML->sys.core[ithCore].sharedmemory.buffer_sizes[3] * - interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 2; - interface_ip.throughput = - debug - ? 1.0 / clockRate - : XML->sys.core[ithCore].sharedmemory.dcache_config[4] / clockRate; - interface_ip.latency = - debug - ? 1.0 / clockRate - : XML->sys.core[ithCore].sharedmemory.dcache_config[5] / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = XML->sys.core[ithCore].memory_ports; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - sharedmemory.wbb = new ArrayST(&interface_ip, "dcacheWBB", Core_device, - coredynp.opt_local, coredynp.core_ty); - sharedmemory.area.set_area(sharedmemory.area.get_area() + - sharedmemory.wbb->local_result.area); - area.set_area(area.get_area() + sharedmemory.wbb->local_result.area); - // output_data_csv(sharedmemory.wbb.local_result); - } - - /* - * ccache starts here - */ - // Constant cache - size = (int)XML->sys.core[ithCore].ccache.dcache_config[0]; - line = (int)XML->sys.core[ithCore].ccache.dcache_config[1]; - assoc = (int)XML->sys.core[ithCore].ccache.dcache_config[2]; - idx = debug ? 9 : int(ceil(log2(size / line / assoc))); - tag = debug ? 51 : XML->sys.physical_address_width - idx - - int(ceil(log2(line))) + EXTRA_TAG_BITS; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.cache_sz = - debug ? 32768 : (int)XML->sys.core[ithCore].ccache.dcache_config[0]; - interface_ip.line_sz = - debug ? 64 : (int)XML->sys.core[ithCore].ccache.dcache_config[1]; - interface_ip.assoc = - debug ? 8 : (int)XML->sys.core[ithCore].ccache.dcache_config[2]; - interface_ip.nbanks = - debug ? 1 : (int)XML->sys.core[ithCore].ccache.dcache_config[3]; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = - 0; // debug?0:XML->sys.core[ithCore].ccache.dcache_config[5]; - interface_ip.throughput = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].ccache.dcache_config[4] / clockRate; - interface_ip.latency = - debug ? 3.0 / clockRate - : XML->sys.core[ithCore].ccache.dcache_config[5] / clockRate; - interface_ip.is_cache = true; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = - debug ? 1 : XML->sys.core[ithCore].memory_ports; // usually In-order has - // 1 and OOO has 2 at - // least. - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - ccache.caches = new ArrayST(&interface_ip, "ccache", Core_device, - coredynp.opt_local, coredynp.core_ty); - ccache.area.set_area(ccache.area.get_area() + - ccache.caches->local_result.area); - area.set_area(area.get_area() + ccache.caches->local_result.area); - // output_data_csv(ccache.caches.local_result); - - // cCache controllers - // miss buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = (XML->sys.physical_address_width) + int(ceil(log2(size / line))) + - ccache.caches->l_ip.line_sz * 8; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = - int(ceil(data / 8.0)); // int(ceil(pow(2.0,ceil(log2(data)))/8.0)); - interface_ip.cache_sz = - XML->sys.core[ithCore].ccache.buffer_sizes[0] * interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 2; - interface_ip.throughput = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].ccache.dcache_config[4] / clockRate; - interface_ip.latency = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].ccache.dcache_config[5] / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug ? 1 : XML->sys.core[ithCore].memory_ports; - ; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - ccache.missb = new ArrayST(&interface_ip, "ccacheMissBuffer", Core_device, - coredynp.opt_local, coredynp.core_ty); - ccache.area.set_area(ccache.area.get_area() + - ccache.missb->local_result.area); - area.set_area(area.get_area() + ccache.missb->local_result.area); - // output_data_csv(ccache.missb.local_result); - - // fill buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = ccache.caches->l_ip.line_sz; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data; // int(pow(2.0,ceil(log2(data)))); - interface_ip.cache_sz = data * XML->sys.core[ithCore].ccache.buffer_sizes[1]; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 2; - interface_ip.throughput = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].ccache.dcache_config[4] / clockRate; - interface_ip.latency = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].ccache.dcache_config[5] / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug ? 1 : XML->sys.core[ithCore].memory_ports; - ; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - ccache.ifb = new ArrayST(&interface_ip, "ccacheFillBuffer", Core_device, - coredynp.opt_local, coredynp.core_ty); - ccache.area.set_area(ccache.area.get_area() + ccache.ifb->local_result.area); - area.set_area(area.get_area() + ccache.ifb->local_result.area); - // output_data_csv(ccache.ifb.local_result); - - // prefetch buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; // check with - // previous entries - // to decide wthether - // to merge. - data = ccache.caches->l_ip - .line_sz; // separate queue to prevent from cache polution. - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data; // int(pow(2.0,ceil(log2(data)))); - interface_ip.cache_sz = - XML->sys.core[ithCore].ccache.buffer_sizes[2] * interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 2; - interface_ip.throughput = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].ccache.dcache_config[4] / clockRate; - interface_ip.latency = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].ccache.dcache_config[5] / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug ? 1 : XML->sys.core[ithCore].memory_ports; - ; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - ccache.prefetchb = - new ArrayST(&interface_ip, "ccacheprefetchBuffer", Core_device, - coredynp.opt_local, coredynp.core_ty); - ccache.area.set_area(ccache.area.get_area() + - ccache.prefetchb->local_result.area); - area.set_area(area.get_area() + ccache.prefetchb->local_result.area); - // output_data_csv(ccache.prefetchb.local_result); - - // WBB - if (cache_p == Write_back) { - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = ccache.caches->l_ip.line_sz; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data; - interface_ip.cache_sz = - XML->sys.core[ithCore].ccache.buffer_sizes[3] * interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 2; - interface_ip.throughput = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].ccache.dcache_config[4] / clockRate; - interface_ip.latency = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].ccache.dcache_config[5] / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = XML->sys.core[ithCore].memory_ports; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - ccache.wbb = new ArrayST(&interface_ip, "ccacheWBB", Core_device, - coredynp.opt_local, coredynp.core_ty); - ccache.area.set_area(ccache.area.get_area() + - ccache.wbb->local_result.area); - area.set_area(area.get_area() + ccache.wbb->local_result.area); - // output_data_csv(ccache.wbb.local_result); - } - - /* - * tcache starts here - */ - // Texture cache - size = (int)XML->sys.core[ithCore].tcache.dcache_config[0]; - line = (int)XML->sys.core[ithCore].tcache.dcache_config[1]; - assoc = (int)XML->sys.core[ithCore].tcache.dcache_config[2]; - idx = debug ? 9 : int(ceil(log2(size / line / assoc))); - tag = debug ? 51 : XML->sys.physical_address_width - idx - - int(ceil(log2(line))) + EXTRA_TAG_BITS; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.cache_sz = - debug ? 32768 : (int)XML->sys.core[ithCore].tcache.dcache_config[0]; - interface_ip.line_sz = - debug ? 64 : (int)XML->sys.core[ithCore].tcache.dcache_config[1]; - interface_ip.assoc = - debug ? 8 : (int)XML->sys.core[ithCore].tcache.dcache_config[2]; - interface_ip.nbanks = - debug ? 1 : (int)XML->sys.core[ithCore].tcache.dcache_config[3]; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = - 0; // debug?0:XML->sys.core[ithCore].tcache.dcache_config[5]; - interface_ip.throughput = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].tcache.dcache_config[4] / clockRate; - interface_ip.latency = - debug ? 3.0 / clockRate - : XML->sys.core[ithCore].tcache.dcache_config[5] / clockRate; - interface_ip.is_cache = true; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = - debug ? 1 : XML->sys.core[ithCore].memory_ports; // usually In-order has - // 1 and OOO has 2 at - // least. - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - tcache.caches = new ArrayST(&interface_ip, "tcache", Core_device, - coredynp.opt_local, coredynp.core_ty); - tcache.area.set_area(tcache.area.get_area() + - tcache.caches->local_result.area); - area.set_area(area.get_area() + tcache.caches->local_result.area); - // output_data_csv(tcache.caches.local_result); - - // tCache controllers - // miss buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = (XML->sys.physical_address_width) + int(ceil(log2(size / line))) + - tcache.caches->l_ip.line_sz * 8; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = - int(ceil(data / 8.0)); // int(ceil(pow(2.0,ceil(log2(data)))/8.0)); - interface_ip.cache_sz = - XML->sys.core[ithCore].tcache.buffer_sizes[0] * interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 2; - interface_ip.throughput = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].tcache.dcache_config[4] / clockRate; - interface_ip.latency = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].tcache.dcache_config[5] / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug ? 1 : XML->sys.core[ithCore].memory_ports; - ; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - tcache.missb = new ArrayST(&interface_ip, "tcacheMissBuffer", Core_device, - coredynp.opt_local, coredynp.core_ty); - tcache.area.set_area(tcache.area.get_area() + - tcache.missb->local_result.area); - area.set_area(area.get_area() + tcache.missb->local_result.area); - // output_data_csv(tcache.missb.local_result); - - // fill buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = tcache.caches->l_ip.line_sz; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data; // int(pow(2.0,ceil(log2(data)))); - interface_ip.cache_sz = data * XML->sys.core[ithCore].tcache.buffer_sizes[1]; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 2; - interface_ip.throughput = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].tcache.dcache_config[4] / clockRate; - interface_ip.latency = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].tcache.dcache_config[5] / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug ? 1 : XML->sys.core[ithCore].memory_ports; - ; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - tcache.ifb = new ArrayST(&interface_ip, "tcacheFillBuffer", Core_device, - coredynp.opt_local, coredynp.core_ty); - tcache.area.set_area(tcache.area.get_area() + tcache.ifb->local_result.area); - area.set_area(area.get_area() + tcache.ifb->local_result.area); - // output_data_csv(tcache.ifb.local_result); - - // prefetch buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; // check with - // previous entries - // to decide wthether - // to merge. - data = tcache.caches->l_ip - .line_sz; // separate queue to prevent from cache polution. - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data; // int(pow(2.0,ceil(log2(data)))); - interface_ip.cache_sz = - XML->sys.core[ithCore].tcache.buffer_sizes[2] * interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 2; - interface_ip.throughput = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].tcache.dcache_config[4] / clockRate; - interface_ip.latency = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].tcache.dcache_config[5] / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug ? 1 : XML->sys.core[ithCore].memory_ports; - ; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - tcache.prefetchb = - new ArrayST(&interface_ip, "tcacheprefetchBuffer", Core_device, - coredynp.opt_local, coredynp.core_ty); - tcache.area.set_area(tcache.area.get_area() + - tcache.prefetchb->local_result.area); - area.set_area(area.get_area() + tcache.prefetchb->local_result.area); - // output_data_csv(tcache.prefetchb.local_result); - - // WBB - if (cache_p == Write_back) { - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = tcache.caches->l_ip.line_sz; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data; - interface_ip.cache_sz = - XML->sys.core[ithCore].tcache.buffer_sizes[3] * interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 2; - interface_ip.throughput = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].tcache.dcache_config[4] / clockRate; - interface_ip.latency = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].tcache.dcache_config[5] / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = XML->sys.core[ithCore].memory_ports; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - tcache.wbb = new ArrayST(&interface_ip, "tcacheWBB", Core_device, - coredynp.opt_local, coredynp.core_ty); - tcache.area.set_area(tcache.area.get_area() + - tcache.wbb->local_result.area); - area.set_area(area.get_area() + tcache.wbb->local_result.area); - // output_data_csv(tcache.wbb.local_result); - } - - /* - * dcache starts here - */ - // Dcache - size = (int)XML->sys.core[ithCore].dcache.dcache_config[0]; - line = (int)XML->sys.core[ithCore].dcache.dcache_config[1]; - assoc = (int)XML->sys.core[ithCore].dcache.dcache_config[2]; - idx = debug ? 9 : int(ceil(log2(size / line / assoc))); - tag = debug ? 51 : XML->sys.physical_address_width - idx - - int(ceil(log2(line))) + EXTRA_TAG_BITS; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.cache_sz = - debug ? 32768 : (int)XML->sys.core[ithCore].dcache.dcache_config[0]; - interface_ip.line_sz = - debug ? 64 : (int)XML->sys.core[ithCore].dcache.dcache_config[1]; - interface_ip.assoc = - debug ? 8 : (int)XML->sys.core[ithCore].dcache.dcache_config[2]; - interface_ip.nbanks = - debug ? 1 : (int)XML->sys.core[ithCore].dcache.dcache_config[3]; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = - 0; // debug?0:XML->sys.core[ithCore].dcache.dcache_config[5]; - interface_ip.throughput = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].dcache.dcache_config[4] / clockRate; - interface_ip.latency = - debug ? 3.0 / clockRate - : XML->sys.core[ithCore].dcache.dcache_config[5] / clockRate; - interface_ip.is_cache = true; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = - debug ? 1 : XML->sys.core[ithCore].memory_ports; // usually In-order has - // 1 and OOO has 2 at - // least. - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - dcache.caches = new ArrayST(&interface_ip, "dcache", Core_device, - coredynp.opt_local, coredynp.core_ty); - dcache.area.set_area(dcache.area.get_area() + - dcache.caches->local_result.area); - area.set_area(area.get_area() + dcache.caches->local_result.area); - // output_data_csv(dcache.caches.local_result); - - // dCache controllers - // miss buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = (XML->sys.physical_address_width) + int(ceil(log2(size / line))) + - dcache.caches->l_ip.line_sz * 8; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = - int(ceil(data / 8.0)); // int(ceil(pow(2.0,ceil(log2(data)))/8.0)); - interface_ip.cache_sz = - XML->sys.core[ithCore].dcache.buffer_sizes[0] * interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 2; - interface_ip.throughput = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].dcache.dcache_config[4] / clockRate; - interface_ip.latency = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].dcache.dcache_config[5] / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug ? 1 : XML->sys.core[ithCore].memory_ports; - ; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - dcache.missb = new ArrayST(&interface_ip, "dcacheMissBuffer", Core_device, - coredynp.opt_local, coredynp.core_ty); - dcache.area.set_area(dcache.area.get_area() + - dcache.missb->local_result.area); - area.set_area(area.get_area() + dcache.missb->local_result.area); - // output_data_csv(dcache.missb.local_result); - - // fill buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = dcache.caches->l_ip.line_sz; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data; // int(pow(2.0,ceil(log2(data)))); - interface_ip.cache_sz = data * XML->sys.core[ithCore].dcache.buffer_sizes[1]; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 2; - interface_ip.throughput = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].dcache.dcache_config[4] / clockRate; - interface_ip.latency = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].dcache.dcache_config[5] / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug ? 1 : XML->sys.core[ithCore].memory_ports; - ; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - dcache.ifb = new ArrayST(&interface_ip, "dcacheFillBuffer", Core_device, - coredynp.opt_local, coredynp.core_ty); - dcache.area.set_area(dcache.area.get_area() + dcache.ifb->local_result.area); - area.set_area(area.get_area() + dcache.ifb->local_result.area); - // output_data_csv(dcache.ifb.local_result); - - // prefetch buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; // check with - // previous entries - // to decide wthether - // to merge. - data = dcache.caches->l_ip - .line_sz; // separate queue to prevent from cache polution. - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data; // int(pow(2.0,ceil(log2(data)))); - interface_ip.cache_sz = - XML->sys.core[ithCore].dcache.buffer_sizes[2] * interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 2; - interface_ip.throughput = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].dcache.dcache_config[4] / clockRate; - interface_ip.latency = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].dcache.dcache_config[5] / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug ? 1 : XML->sys.core[ithCore].memory_ports; - ; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - dcache.prefetchb = - new ArrayST(&interface_ip, "dcacheprefetchBuffer", Core_device, - coredynp.opt_local, coredynp.core_ty); - dcache.area.set_area(dcache.area.get_area() + - dcache.prefetchb->local_result.area); - area.set_area(area.get_area() + dcache.prefetchb->local_result.area); - // output_data_csv(dcache.prefetchb.local_result); - - // WBB - if (cache_p == Write_back) { - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = dcache.caches->l_ip.line_sz; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data; - interface_ip.cache_sz = - XML->sys.core[ithCore].dcache.buffer_sizes[3] * interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 2; - interface_ip.throughput = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].dcache.dcache_config[4] / clockRate; - interface_ip.latency = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].dcache.dcache_config[5] / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = XML->sys.core[ithCore].memory_ports; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - dcache.wbb = new ArrayST(&interface_ip, "dcacheWBB", Core_device, - coredynp.opt_local, coredynp.core_ty); - dcache.area.set_area(dcache.area.get_area() + - dcache.wbb->local_result.area); - area.set_area(area.get_area() + dcache.wbb->local_result.area); - // output_data_csv(dcache.wbb.local_result); - } +LoadStoreU::LoadStoreU(ParseXML* XML_interface, int ithCore_, InputParameter* interface_ip_, const CoreDynParam & dyn_p_,bool exist_) +:XML(XML_interface), + ithCore(ithCore_), + interface_ip(*interface_ip_), + coredynp(dyn_p_), + LSQ(0), + exist(exist_) +{ + if (!exist) return; + int idx, tag, data, size, line, assoc; + bool debug= false; + int ldst_opcode = XML->sys.core[ithCore].opcode_width;//16; + + clockRate = coredynp.clockRate; + executionTime = coredynp.executionTime; + cache_p = (Cache_policy)XML->sys.core[ithCore].dcache.dcache_config[7]; + + interface_ip.num_search_ports = XML->sys.core[ithCore].memory_ports; + interface_ip.is_cache = true; + interface_ip.pure_cam = false; + interface_ip.pure_ram = false; + + + //Crossbar based interconnect for shared memory accesses, added by Syed + //Crossbar + + if(XML->sys.architecture==1){ + xbar_shared = new Crossbar(coredynp.num_fpus,coredynp.num_fpus,32,&(g_tp.peri_global));//Syed: coredynp.num_fpus is used as simd_width + } + else{ + xbar_shared = new Crossbar(coredynp.num_fpus,coredynp.num_fpus,32,&(g_tp.peri_global));//Syed: coredynp.num_fpus is used as simd_width + } + + + //TODO: Check if this line should be changed to + //new Crossbar(simd_width,shared_memory_banks,word_length*simd_width,&(g_tp.peri_global)); + + //shared memory added by Jingwen + size = (int)XML->sys.core[ithCore].sharedmemory.dcache_config[0]; + line = (int)XML->sys.core[ithCore].sharedmemory.dcache_config[1]; + assoc = (int)XML->sys.core[ithCore].sharedmemory.dcache_config[2]; + idx = debug?9:int(ceil(log2(size/line/assoc))); + tag = debug?51:XML->sys.physical_address_width-idx-int(ceil(log2(line))) + EXTRA_TAG_BITS; + interface_ip.specific_tag = 1; + interface_ip.tag_w = 1; + interface_ip.cache_sz = debug?32768:(int)XML->sys.core[ithCore].sharedmemory.dcache_config[0]; + interface_ip.line_sz = debug?64:(int)XML->sys.core[ithCore].sharedmemory.dcache_config[1]; + interface_ip.assoc = debug?8:(int)XML->sys.core[ithCore].sharedmemory.dcache_config[2]; + interface_ip.nbanks = debug?1:(int)XML->sys.core[ithCore].sharedmemory.dcache_config[3]; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 0;//debug?0:XML->sys.core[ithCore].sharedmemory.dcache_config[5]; + interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].sharedmemory.dcache_config[4]/clockRate; + interface_ip.latency = debug?3.0/clockRate:XML->sys.core[ithCore].sharedmemory.dcache_config[5]/clockRate; + interface_ip.is_cache = true; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;//usually In-order has 1 and OOO has 2 at least. + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + sharedmemory.caches = new ArrayST(&interface_ip, "sharedmemory", Core_device, coredynp.opt_local, coredynp.core_ty); + sharedmemory.area.set_area(sharedmemory.area.get_area()+ sharedmemory.caches->local_result.area); + area.set_area(area.get_area()+ sharedmemory.caches->local_result.area + xbar_shared->area.get_area()); + + + //shared memory buffer + //miss buffer + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = (XML->sys.physical_address_width) + int(ceil(log2(size/line))) + sharedmemory.caches->l_ip.line_sz*8; + interface_ip.specific_tag = 1; + interface_ip.tag_w = 1; + interface_ip.line_sz = int(ceil(data/8.0));//int(ceil(pow(2.0,ceil(log2(data)))/8.0)); + interface_ip.cache_sz = XML->sys.core[ithCore].sharedmemory.buffer_sizes[0]*interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 2; + interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].sharedmemory.dcache_config[4]/clockRate; + interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].sharedmemory.dcache_config[5]/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + sharedmemory.missb = new ArrayST(&interface_ip, "SharedmemoryMissBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); + sharedmemory.area.set_area(sharedmemory.area.get_area()+ sharedmemory.missb->local_result.area); + area.set_area(area.get_area()+ sharedmemory.missb->local_result.area); + + + //sharedmemory fill buffer + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = sharedmemory.caches->l_ip.line_sz; + interface_ip.specific_tag = 1; + interface_ip.tag_w = 1; + interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); + interface_ip.cache_sz = data*XML->sys.core[ithCore].sharedmemory.buffer_sizes[1]; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 2; + interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].sharedmemory.dcache_config[4]/clockRate; + interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].sharedmemory.dcache_config[5]/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + sharedmemory.ifb = new ArrayST(&interface_ip, "SharedMemoryFillBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); + sharedmemory.area.set_area(sharedmemory.area.get_area()+ sharedmemory.ifb->local_result.area); + area.set_area(area.get_area()+ sharedmemory.ifb->local_result.area); + + //sharedmemory prefetch buffer + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS;//check with previous entries to decide wthether to merge. + data = sharedmemory.caches->l_ip.line_sz;//separate queue to prevent from cache polution. + interface_ip.specific_tag = 1; + interface_ip.tag_w = 1; + interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); + interface_ip.cache_sz = XML->sys.core[ithCore].sharedmemory.buffer_sizes[2]*interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 2; + interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].sharedmemory.dcache_config[4]/clockRate; + interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].sharedmemory.dcache_config[5]/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + sharedmemory.prefetchb = new ArrayST(&interface_ip, "dcacheprefetchBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); + sharedmemory.area.set_area(sharedmemory.area.get_area()+ sharedmemory.prefetchb->local_result.area); + area.set_area(area.get_area()+ sharedmemory.prefetchb->local_result.area); + + //shared memory WBB + if (cache_p==Write_back) + { + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = sharedmemory.caches->l_ip.line_sz; + interface_ip.specific_tag = 1; + interface_ip.tag_w = 1; + interface_ip.line_sz = data; + interface_ip.cache_sz = XML->sys.core[ithCore].sharedmemory.buffer_sizes[3]*interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 2; + interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].sharedmemory.dcache_config[4]/clockRate; + interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].sharedmemory.dcache_config[5]/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = XML->sys.core[ithCore].memory_ports; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + sharedmemory.wbb = new ArrayST(&interface_ip, "dcacheWBB", Core_device, coredynp.opt_local, coredynp.core_ty); + sharedmemory.area.set_area(sharedmemory.area.get_area()+ sharedmemory.wbb->local_result.area); + area.set_area(area.get_area()+ sharedmemory.wbb->local_result.area); + //output_data_csv(sharedmemory.wbb.local_result); + } + + + /* + * ccache starts here + */ + //Constant cache + size = (int)XML->sys.core[ithCore].ccache.dcache_config[0]; + line = (int)XML->sys.core[ithCore].ccache.dcache_config[1]; + assoc = (int)XML->sys.core[ithCore].ccache.dcache_config[2]; + idx = debug?9:int(ceil(log2(size/line/assoc))); + tag = debug?51:XML->sys.physical_address_width-idx-int(ceil(log2(line))) + EXTRA_TAG_BITS; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.cache_sz = debug?32768:(int)XML->sys.core[ithCore].ccache.dcache_config[0]; + interface_ip.line_sz = debug?64:(int)XML->sys.core[ithCore].ccache.dcache_config[1]; + interface_ip.assoc = debug?8:(int)XML->sys.core[ithCore].ccache.dcache_config[2]; + interface_ip.nbanks = debug?1:(int)XML->sys.core[ithCore].ccache.dcache_config[3]; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 0;//debug?0:XML->sys.core[ithCore].ccache.dcache_config[5]; + interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].ccache.dcache_config[4]/clockRate; + interface_ip.latency = debug?3.0/clockRate:XML->sys.core[ithCore].ccache.dcache_config[5]/clockRate; + interface_ip.is_cache = true; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;//usually In-order has 1 and OOO has 2 at least. + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + ccache.caches = new ArrayST(&interface_ip, "ccache", Core_device, coredynp.opt_local, coredynp.core_ty); + ccache.area.set_area(ccache.area.get_area()+ ccache.caches->local_result.area); + area.set_area(area.get_area()+ ccache.caches->local_result.area); + //output_data_csv(ccache.caches.local_result); + + + + //cCache controllers + //miss buffer + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = (XML->sys.physical_address_width) + int(ceil(log2(size/line))) + ccache.caches->l_ip.line_sz*8; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = int(ceil(data/8.0));//int(ceil(pow(2.0,ceil(log2(data)))/8.0)); + interface_ip.cache_sz = XML->sys.core[ithCore].ccache.buffer_sizes[0]*interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 2; + interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].ccache.dcache_config[4]/clockRate; + interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].ccache.dcache_config[5]/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + ccache.missb = new ArrayST(&interface_ip, "ccacheMissBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); + ccache.area.set_area(ccache.area.get_area()+ ccache.missb->local_result.area); + area.set_area(area.get_area()+ ccache.missb->local_result.area); + //output_data_csv(ccache.missb.local_result); + + //fill buffer + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = ccache.caches->l_ip.line_sz; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); + interface_ip.cache_sz = data*XML->sys.core[ithCore].ccache.buffer_sizes[1]; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 2; + interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].ccache.dcache_config[4]/clockRate; + interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].ccache.dcache_config[5]/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + ccache.ifb = new ArrayST(&interface_ip, "ccacheFillBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); + ccache.area.set_area(ccache.area.get_area()+ ccache.ifb->local_result.area); + area.set_area(area.get_area()+ ccache.ifb->local_result.area); + //output_data_csv(ccache.ifb.local_result); + + //prefetch buffer + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS;//check with previous entries to decide wthether to merge. + data = ccache.caches->l_ip.line_sz;//separate queue to prevent from cache polution. + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); + interface_ip.cache_sz = XML->sys.core[ithCore].ccache.buffer_sizes[2]*interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 2; + interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].ccache.dcache_config[4]/clockRate; + interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].ccache.dcache_config[5]/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + ccache.prefetchb = new ArrayST(&interface_ip, "ccacheprefetchBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); + ccache.area.set_area(ccache.area.get_area()+ ccache.prefetchb->local_result.area); + area.set_area(area.get_area()+ ccache.prefetchb->local_result.area); + //output_data_csv(ccache.prefetchb.local_result); + + //WBB + if (cache_p==Write_back) + { + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = ccache.caches->l_ip.line_sz; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data; + interface_ip.cache_sz = XML->sys.core[ithCore].ccache.buffer_sizes[3]*interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 2; + interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].ccache.dcache_config[4]/clockRate; + interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].ccache.dcache_config[5]/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = XML->sys.core[ithCore].memory_ports; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + ccache.wbb = new ArrayST(&interface_ip, "ccacheWBB", Core_device, coredynp.opt_local, coredynp.core_ty); + ccache.area.set_area(ccache.area.get_area()+ ccache.wbb->local_result.area); + area.set_area(area.get_area()+ ccache.wbb->local_result.area); + //output_data_csv(ccache.wbb.local_result); + } + + /* + * tcache starts here + */ + //Texture cache + size = (int)XML->sys.core[ithCore].tcache.dcache_config[0]; + line = (int)XML->sys.core[ithCore].tcache.dcache_config[1]; + assoc = (int)XML->sys.core[ithCore].tcache.dcache_config[2]; + idx = debug?9:int(ceil(log2(size/line/assoc))); + tag = debug?51:XML->sys.physical_address_width-idx-int(ceil(log2(line))) + EXTRA_TAG_BITS; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.cache_sz = debug?32768:(int)XML->sys.core[ithCore].tcache.dcache_config[0]; + interface_ip.line_sz = debug?64:(int)XML->sys.core[ithCore].tcache.dcache_config[1]; + interface_ip.assoc = debug?8:(int)XML->sys.core[ithCore].tcache.dcache_config[2]; + interface_ip.nbanks = debug?1:(int)XML->sys.core[ithCore].tcache.dcache_config[3]; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 0;//debug?0:XML->sys.core[ithCore].tcache.dcache_config[5]; + interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].tcache.dcache_config[4]/clockRate; + interface_ip.latency = debug?3.0/clockRate:XML->sys.core[ithCore].tcache.dcache_config[5]/clockRate; + interface_ip.is_cache = true; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;//usually In-order has 1 and OOO has 2 at least. + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + tcache.caches = new ArrayST(&interface_ip, "tcache", Core_device, coredynp.opt_local, coredynp.core_ty); + tcache.area.set_area(tcache.area.get_area()+ tcache.caches->local_result.area); + area.set_area(area.get_area()+ tcache.caches->local_result.area); + //output_data_csv(tcache.caches.local_result); + + + //tCache controllers + //miss buffer + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = (XML->sys.physical_address_width) + int(ceil(log2(size/line))) + tcache.caches->l_ip.line_sz*8; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = int(ceil(data/8.0));//int(ceil(pow(2.0,ceil(log2(data)))/8.0)); + interface_ip.cache_sz = XML->sys.core[ithCore].tcache.buffer_sizes[0]*interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 2; + interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].tcache.dcache_config[4]/clockRate; + interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].tcache.dcache_config[5]/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + tcache.missb = new ArrayST(&interface_ip, "tcacheMissBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); + tcache.area.set_area(tcache.area.get_area()+ tcache.missb->local_result.area); + area.set_area(area.get_area()+ tcache.missb->local_result.area); + //output_data_csv(tcache.missb.local_result); + + //fill buffer + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = tcache.caches->l_ip.line_sz; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); + interface_ip.cache_sz = data*XML->sys.core[ithCore].tcache.buffer_sizes[1]; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 2; + interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].tcache.dcache_config[4]/clockRate; + interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].tcache.dcache_config[5]/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + tcache.ifb = new ArrayST(&interface_ip, "tcacheFillBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); + tcache.area.set_area(tcache.area.get_area()+ tcache.ifb->local_result.area); + area.set_area(area.get_area()+ tcache.ifb->local_result.area); + //output_data_csv(tcache.ifb.local_result); + + //prefetch buffer + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS;//check with previous entries to decide wthether to merge. + data = tcache.caches->l_ip.line_sz;//separate queue to prevent from cache polution. + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); + interface_ip.cache_sz = XML->sys.core[ithCore].tcache.buffer_sizes[2]*interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 2; + interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].tcache.dcache_config[4]/clockRate; + interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].tcache.dcache_config[5]/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + tcache.prefetchb = new ArrayST(&interface_ip, "tcacheprefetchBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); + tcache.area.set_area(tcache.area.get_area()+ tcache.prefetchb->local_result.area); + area.set_area(area.get_area()+ tcache.prefetchb->local_result.area); + //output_data_csv(tcache.prefetchb.local_result); + + //WBB + if (cache_p==Write_back) + { + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = tcache.caches->l_ip.line_sz; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data; + interface_ip.cache_sz = XML->sys.core[ithCore].tcache.buffer_sizes[3]*interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 2; + interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].tcache.dcache_config[4]/clockRate; + interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].tcache.dcache_config[5]/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = XML->sys.core[ithCore].memory_ports; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + tcache.wbb = new ArrayST(&interface_ip, "tcacheWBB", Core_device, coredynp.opt_local, coredynp.core_ty); + tcache.area.set_area(tcache.area.get_area()+ tcache.wbb->local_result.area); + area.set_area(area.get_area()+ tcache.wbb->local_result.area); + //output_data_csv(tcache.wbb.local_result); + } + + + + + /* + * dcache starts here + */ + //Dcache + size = (int)XML->sys.core[ithCore].dcache.dcache_config[0]; + line = (int)XML->sys.core[ithCore].dcache.dcache_config[1]; + assoc = (int)XML->sys.core[ithCore].dcache.dcache_config[2]; + idx = debug?9:int(ceil(log2(size/line/assoc))); + tag = debug?51:XML->sys.physical_address_width-idx-int(ceil(log2(line))) + EXTRA_TAG_BITS; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.cache_sz = debug?32768:(int)XML->sys.core[ithCore].dcache.dcache_config[0]; + interface_ip.line_sz = debug?64:(int)XML->sys.core[ithCore].dcache.dcache_config[1]; + interface_ip.assoc = debug?8:(int)XML->sys.core[ithCore].dcache.dcache_config[2]; + interface_ip.nbanks = debug?1:(int)XML->sys.core[ithCore].dcache.dcache_config[3]; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 0;//debug?0:XML->sys.core[ithCore].dcache.dcache_config[5]; + interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].dcache.dcache_config[4]/clockRate; + interface_ip.latency = debug?3.0/clockRate:XML->sys.core[ithCore].dcache.dcache_config[5]/clockRate; + interface_ip.is_cache = true; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;//usually In-order has 1 and OOO has 2 at least. + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + dcache.caches = new ArrayST(&interface_ip, "dcache", Core_device, coredynp.opt_local, coredynp.core_ty); + dcache.area.set_area(dcache.area.get_area()+ dcache.caches->local_result.area); + area.set_area(area.get_area()+ dcache.caches->local_result.area); + //output_data_csv(dcache.caches.local_result); + + + //dCache controllers + //miss buffer + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = (XML->sys.physical_address_width) + int(ceil(log2(size/line))) + dcache.caches->l_ip.line_sz*8; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = int(ceil(data/8.0));//int(ceil(pow(2.0,ceil(log2(data)))/8.0)); + interface_ip.cache_sz = XML->sys.core[ithCore].dcache.buffer_sizes[0]*interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 2; + interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].dcache.dcache_config[4]/clockRate; + interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].dcache.dcache_config[5]/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + dcache.missb = new ArrayST(&interface_ip, "dcacheMissBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); + dcache.area.set_area(dcache.area.get_area()+ dcache.missb->local_result.area); + area.set_area(area.get_area()+ dcache.missb->local_result.area); + //output_data_csv(dcache.missb.local_result); + + //fill buffer + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = dcache.caches->l_ip.line_sz; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); + interface_ip.cache_sz = data*XML->sys.core[ithCore].dcache.buffer_sizes[1]; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 2; + interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].dcache.dcache_config[4]/clockRate; + interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].dcache.dcache_config[5]/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + dcache.ifb = new ArrayST(&interface_ip, "dcacheFillBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); + dcache.area.set_area(dcache.area.get_area()+ dcache.ifb->local_result.area); + area.set_area(area.get_area()+ dcache.ifb->local_result.area); + //output_data_csv(dcache.ifb.local_result); + + //prefetch buffer + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS;//check with previous entries to decide wthether to merge. + data = dcache.caches->l_ip.line_sz;//separate queue to prevent from cache polution. + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); + interface_ip.cache_sz = XML->sys.core[ithCore].dcache.buffer_sizes[2]*interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 2; + interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].dcache.dcache_config[4]/clockRate; + interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].dcache.dcache_config[5]/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + dcache.prefetchb = new ArrayST(&interface_ip, "dcacheprefetchBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); + dcache.area.set_area(dcache.area.get_area()+ dcache.prefetchb->local_result.area); + area.set_area(area.get_area()+ dcache.prefetchb->local_result.area); + //output_data_csv(dcache.prefetchb.local_result); + + //WBB + if (cache_p==Write_back) + { + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = dcache.caches->l_ip.line_sz; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data; + interface_ip.cache_sz = XML->sys.core[ithCore].dcache.buffer_sizes[3]*interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 2; + interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].dcache.dcache_config[4]/clockRate; + interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].dcache.dcache_config[5]/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = XML->sys.core[ithCore].memory_ports; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + dcache.wbb = new ArrayST(&interface_ip, "dcacheWBB", Core_device, coredynp.opt_local, coredynp.core_ty); + dcache.area.set_area(dcache.area.get_area()+ dcache.wbb->local_result.area); + area.set_area(area.get_area()+ dcache.wbb->local_result.area); + //output_data_csv(dcache.wbb.local_result); + } + + /* + * LSU--in-order processors do not have separate load queue: unified lsq + * partitioned among threads + * it is actually the store queue but for inorder processors it serves as both loadQ and StoreQ + */ + tag = ldst_opcode+XML->sys.virtual_address_width +int(ceil(log2(XML->sys.core[ithCore].number_hardware_threads))) + EXTRA_TAG_BITS; + data = XML->sys.machine_bits; + interface_ip.is_cache = true; + interface_ip.line_sz = int(ceil(data/32.0))*4; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.cache_sz = XML->sys.core[ithCore].store_buffer_size*interface_ip.line_sz*XML->sys.core[ithCore].number_hardware_threads; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 1; + interface_ip.throughput = 1.0/clockRate; + interface_ip.latency = 1.0/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = XML->sys.core[ithCore].memory_ports; + interface_ip.num_wr_ports = XML->sys.core[ithCore].memory_ports; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports =XML->sys.core[ithCore].memory_ports; + LSQ = new ArrayST(&interface_ip, "Load(Store)Queue", Core_device, coredynp.opt_local, coredynp.core_ty); + LSQ->area.set_area(LSQ->area.get_area()+ LSQ->local_result.area); + area.set_area(area.get_area()+ LSQ->local_result.area); + area.set_area(area.get_area()*cdb_overhead); + //output_data_csv(LSQ.LSQ.local_result); + lsq_height=LSQ->local_result.cache_ht*sqrt(cdb_overhead);/*XML->sys.core[ithCore].number_hardware_threads*/ + + if ((coredynp.core_ty==OOO) && (XML->sys.core[ithCore].load_buffer_size >0)) + { + interface_ip.line_sz = int(ceil(data/32.0))*4; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.cache_sz = XML->sys.core[ithCore].load_buffer_size*interface_ip.line_sz*XML->sys.core[ithCore].number_hardware_threads; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 1; + interface_ip.throughput = 1.0/clockRate; + interface_ip.latency = 1.0/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = XML->sys.core[ithCore].memory_ports; + interface_ip.num_wr_ports = XML->sys.core[ithCore].memory_ports; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports =XML->sys.core[ithCore].memory_ports; + LoadQ = new ArrayST(&interface_ip, "LoadQueue", Core_device, coredynp.opt_local, coredynp.core_ty); + LoadQ->area.set_area(LoadQ->area.get_area()+ LoadQ->local_result.area); + area.set_area(area.get_area()+ LoadQ->local_result.area); + area.set_area(area.get_area()*cdb_overhead); + //output_data_csv(LoadQ.LoadQ.local_result); + lsq_height=(LSQ->local_result.cache_ht + LoadQ->local_result.cache_ht)*sqrt(cdb_overhead);/*XML->sys.core[ithCore].number_hardware_threads*/ + } - /* - * LSU--in-order processors do not have separate load queue: unified lsq - * partitioned among threads - * it is actually the store queue but for inorder processors it serves as both - * loadQ and StoreQ - */ - tag = ldst_opcode + XML->sys.virtual_address_width + - int(ceil(log2(XML->sys.core[ithCore].number_hardware_threads))) + - EXTRA_TAG_BITS; - data = XML->sys.machine_bits; - interface_ip.is_cache = true; - interface_ip.line_sz = int(ceil(data / 32.0)) * 4; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.cache_sz = XML->sys.core[ithCore].store_buffer_size * - interface_ip.line_sz * - XML->sys.core[ithCore].number_hardware_threads; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 1; - interface_ip.throughput = 1.0 / clockRate; - interface_ip.latency = 1.0 / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = XML->sys.core[ithCore].memory_ports; - interface_ip.num_wr_ports = XML->sys.core[ithCore].memory_ports; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = XML->sys.core[ithCore].memory_ports; - LSQ = new ArrayST(&interface_ip, "Load(Store)Queue", Core_device, - coredynp.opt_local, coredynp.core_ty); - LSQ->area.set_area(LSQ->area.get_area() + LSQ->local_result.area); - area.set_area(area.get_area() + LSQ->local_result.area); - area.set_area(area.get_area() * cdb_overhead); - // output_data_csv(LSQ.LSQ.local_result); - lsq_height = - LSQ->local_result.cache_ht * - sqrt(cdb_overhead); /*XML->sys.core[ithCore].number_hardware_threads*/ - - if ((coredynp.core_ty == OOO) && - (XML->sys.core[ithCore].load_buffer_size > 0)) { - interface_ip.line_sz = int(ceil(data / 32.0)) * 4; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.cache_sz = XML->sys.core[ithCore].load_buffer_size * - interface_ip.line_sz * - XML->sys.core[ithCore].number_hardware_threads; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 1; - interface_ip.throughput = 1.0 / clockRate; - interface_ip.latency = 1.0 / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = XML->sys.core[ithCore].memory_ports; - interface_ip.num_wr_ports = XML->sys.core[ithCore].memory_ports; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = XML->sys.core[ithCore].memory_ports; - LoadQ = new ArrayST(&interface_ip, "LoadQueue", Core_device, - coredynp.opt_local, coredynp.core_ty); - LoadQ->area.set_area(LoadQ->area.get_area() + LoadQ->local_result.area); - area.set_area(area.get_area() + LoadQ->local_result.area); - area.set_area(area.get_area() * cdb_overhead); - // output_data_csv(LoadQ.LoadQ.local_result); - lsq_height = - (LSQ->local_result.cache_ht + LoadQ->local_result.cache_ht) * - sqrt(cdb_overhead); /*XML->sys.core[ithCore].number_hardware_threads*/ - } } -MemManU::MemManU(ParseXML* XML_interface, int ithCore_, - InputParameter* interface_ip_, const CoreDynParam& dyn_p_, - bool exist_) - : XML(XML_interface), - ithCore(ithCore_), - interface_ip(*interface_ip_), - coredynp(dyn_p_), - itlb(0), - dtlb(0), - exist(exist_) { - if (!exist) return; - int tag, data; - bool debug = false; +MemManU::MemManU(ParseXML* XML_interface, int ithCore_, InputParameter* interface_ip_, const CoreDynParam & dyn_p_,bool exist_) +:XML(XML_interface), + ithCore(ithCore_), + interface_ip(*interface_ip_), + coredynp(dyn_p_), + itlb(0), + dtlb(0), + exist(exist_) +{ + if (!exist) return; + int tag, data; + bool debug= false; + + clockRate = coredynp.clockRate; + executionTime = coredynp.executionTime; + + interface_ip.is_cache = true; + interface_ip.pure_cam = false; + interface_ip.pure_ram = false; + interface_ip.specific_tag = 1; + //Itlb TLBs are partioned among threads according to Nigara and Nehalem + tag = XML->sys.virtual_address_width- int(floor(log2(XML->sys.virtual_memory_page_size))) + int(ceil(log2(XML->sys.core[ithCore].number_hardware_threads)))+ EXTRA_TAG_BITS; + data = XML->sys.physical_address_width- int(floor(log2(XML->sys.virtual_memory_page_size))); + interface_ip.tag_w = tag; + interface_ip.line_sz = int(ceil(data/8.0));//int(ceil(pow(2.0,ceil(log2(data)))/8.0)); + interface_ip.cache_sz = XML->sys.core[ithCore].itlb.number_entries*interface_ip.line_sz;//*XML->sys.core[ithCore].number_hardware_threads; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 0; + interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].icache.icache_config[4]/clockRate; + interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].icache.icache_config[5]/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = debug?1:XML->sys.core[ithCore].number_instruction_fetch_ports; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = debug?1:XML->sys.core[ithCore].number_instruction_fetch_ports; + itlb = new ArrayST(&interface_ip, "ITLB", Core_device, coredynp.opt_local, coredynp.core_ty); + itlb->area.set_area(itlb->area.get_area()+ itlb->local_result.area); + area.set_area(area.get_area()+ itlb->local_result.area); + //output_data_csv(itlb.tlb.local_result); + + //dtlb + tag = XML->sys.virtual_address_width- int(floor(log2(XML->sys.virtual_memory_page_size))) +int(ceil(log2(XML->sys.core[ithCore].number_hardware_threads)))+ EXTRA_TAG_BITS; + data = XML->sys.physical_address_width- int(floor(log2(XML->sys.virtual_memory_page_size))); + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = int(ceil(data/8.0));//int(ceil(pow(2.0,ceil(log2(data)))/8.0)); + interface_ip.cache_sz = XML->sys.core[ithCore].dtlb.number_entries*interface_ip.line_sz;//*XML->sys.core[ithCore].number_hardware_threads; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 0; + interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].dcache.dcache_config[4]/clockRate; + interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].dcache.dcache_config[5]/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = XML->sys.core[ithCore].memory_ports; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = XML->sys.core[ithCore].memory_ports; + dtlb = new ArrayST(&interface_ip, "DTLB", Core_device, coredynp.opt_local, coredynp.core_ty); + dtlb->area.set_area(dtlb->area.get_area()+ dtlb->local_result.area); + area.set_area(area.get_area()+ dtlb->local_result.area); + //output_data_csv(dtlb.tlb.local_result); - clockRate = coredynp.clockRate; - executionTime = coredynp.executionTime; - - interface_ip.is_cache = true; - interface_ip.pure_cam = false; - interface_ip.pure_ram = false; - interface_ip.specific_tag = 1; - // Itlb TLBs are partioned among threads according to Nigara and Nehalem - tag = XML->sys.virtual_address_width - - int(floor(log2(XML->sys.virtual_memory_page_size))) + - int(ceil(log2(XML->sys.core[ithCore].number_hardware_threads))) + - EXTRA_TAG_BITS; - data = XML->sys.physical_address_width - - int(floor(log2(XML->sys.virtual_memory_page_size))); - interface_ip.tag_w = tag; - interface_ip.line_sz = - int(ceil(data / 8.0)); // int(ceil(pow(2.0,ceil(log2(data)))/8.0)); - interface_ip.cache_sz = - XML->sys.core[ithCore].itlb.number_entries * - interface_ip.line_sz; //*XML->sys.core[ithCore].number_hardware_threads; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 0; - interface_ip.throughput = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].icache.icache_config[4] / clockRate; - interface_ip.latency = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].icache.icache_config[5] / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = - debug ? 1 : XML->sys.core[ithCore].number_instruction_fetch_ports; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = - debug ? 1 : XML->sys.core[ithCore].number_instruction_fetch_ports; - itlb = new ArrayST(&interface_ip, "ITLB", Core_device, coredynp.opt_local, - coredynp.core_ty); - itlb->area.set_area(itlb->area.get_area() + itlb->local_result.area); - area.set_area(area.get_area() + itlb->local_result.area); - // output_data_csv(itlb.tlb.local_result); - - // dtlb - tag = XML->sys.virtual_address_width - - int(floor(log2(XML->sys.virtual_memory_page_size))) + - int(ceil(log2(XML->sys.core[ithCore].number_hardware_threads))) + - EXTRA_TAG_BITS; - data = XML->sys.physical_address_width - - int(floor(log2(XML->sys.virtual_memory_page_size))); - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = - int(ceil(data / 8.0)); // int(ceil(pow(2.0,ceil(log2(data)))/8.0)); - interface_ip.cache_sz = - XML->sys.core[ithCore].dtlb.number_entries * - interface_ip.line_sz; //*XML->sys.core[ithCore].number_hardware_threads; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 0; - interface_ip.throughput = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].dcache.dcache_config[4] / clockRate; - interface_ip.latency = - debug ? 1.0 / clockRate - : XML->sys.core[ithCore].dcache.dcache_config[5] / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = XML->sys.core[ithCore].memory_ports; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = XML->sys.core[ithCore].memory_ports; - dtlb = new ArrayST(&interface_ip, "DTLB", Core_device, coredynp.opt_local, - coredynp.core_ty); - dtlb->area.set_area(dtlb->area.get_area() + dtlb->local_result.area); - area.set_area(area.get_area() + dtlb->local_result.area); - // output_data_csv(dtlb.tlb.local_result); } //#define FERMI -RegFU::RegFU(ParseXML* XML_interface, int ithCore_, - InputParameter* interface_ip_, const CoreDynParam& dyn_p_, - double exClockRate, bool exist_) - : XML(XML_interface), - ithCore(ithCore_), - interface_ip(*interface_ip_), - coredynp(dyn_p_), - IRF(0), - FRF(0), - RFWIN(0), - exist(exist_) { - /* - * processors have separate architectural register files for each thread. - * therefore, the bypass buses need to travel across all the register files. - */ - if (!exist) return; - int data; - clockRate = exClockRate; // coredynp.clockRate; - executionTime = coredynp.executionTime; +RegFU::RegFU(ParseXML* XML_interface, int ithCore_, InputParameter* interface_ip_, const CoreDynParam & dyn_p_,double exClockRate,bool exist_) +:XML(XML_interface), + ithCore(ithCore_), + interface_ip(*interface_ip_), + coredynp(dyn_p_), + IRF (0), + FRF (0), + RFWIN (0), + exist(exist_) + { + /* + * processors have separate architectural register files for each thread. + * therefore, the bypass buses need to travel across all the register files. + */ + if (!exist) return; + int data; + clockRate = exClockRate;//coredynp.clockRate; + executionTime = coredynp.executionTime; /********************************************************************************* - * OC stage modelling (Syed Gilani) - *********************************************************************************/ - - // Crossbar - - if (XML->sys.architecture == 1) { - xbar_rfu = new Crossbar(XML->sys.core[ithCore].rf_banks / 2, - XML->sys.core[ithCore].collector_units / 2, (128), - &(g_tp.peri_global)); - } else { - xbar_rfu = new Crossbar(XML->sys.core[ithCore].rf_banks, - XML->sys.core[ithCore].collector_units, (128), - &(g_tp.peri_global)); - } + * OC stage modelling (Syed Gilani) + *********************************************************************************/ + + //Crossbar + + if(XML->sys.architecture==1){ + xbar_rfu = new Crossbar(XML->sys.core[ithCore].rf_banks/2,XML->sys.core[ithCore].collector_units/2 + ,(128),&(g_tp.peri_global)); + }else{ + xbar_rfu = new Crossbar(XML->sys.core[ithCore].rf_banks,XML->sys.core[ithCore].collector_units + ,(128),&(g_tp.peri_global)); + } - // new - // Crossbar(simd_width,shared_memory_banks,word_length*simd_width,&(g_tp.peri_global)); - - // Arbiter - arbiter_rfu = new MCPAT_Arbiter(XML->sys.core[ithCore].rf_banks, - XML->sys.core[ithCore].collector_units, 1, - &(g_tp.peri_global)); - - // RF banks modelled here for GPGPU-Sim (Syed Gilani) - // - //**********************************IRF*************************************** - data = coredynp.int_data_width; - // data *= 8; - interface_ip.is_cache = false; - interface_ip.pure_cam = false; - interface_ip.pure_ram = true; - - interface_ip.line_sz = 16; // int(ceil(data/32.0))*4 * - // XML->sys.core[ithCore].simd_width/4 ;//2 for - // Tesla as RF width half of SIMD width - - interface_ip.line_sz = 16; // int(ceil(data/32.0))*4 * - // XML->sys.core[ithCore].simd_width/2 ;//2 for - // Tesla as RF width half of SIMD width - - interface_ip.cache_sz = coredynp.num_IRF_entry * 4; - interface_ip.assoc = 1; - interface_ip.nbanks = XML->sys.core[ithCore].rf_banks; - - interface_ip.out_w = - interface_ip.line_sz * - 8; // interface_ip.line_sz*XML->sys.core[ithCore].simd_width/4; //2 for - // Tesla and 4 for Fermi - - interface_ip.out_w = - interface_ip.line_sz * - 8; // interface_ip.line_sz*XML->sys.core[ithCore].simd_width/2; //2 for - // Tesla and 4 for Fermi - - interface_ip.access_mode = 1; - interface_ip.throughput = 1 / (clockRate); - interface_ip.latency = 8.0 / (clockRate); - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 1; - interface_ip.obj_func_cycle_t = 0; - interface_ip.num_rw_ports = 0; // this is the transfer port for - // saving/restoring states when exceptions - // happen. - interface_ip.num_rd_ports = 1; // 2*coredynp.peak_issueW; - interface_ip.num_wr_ports = 1; // coredynp.peak_issueW; - interface_ip.num_se_rd_ports = 0; - IRF = new ArrayST(&interface_ip, "Integer Register File", Core_device, - coredynp.opt_local, coredynp.core_ty); - - IRF->area.set_area(IRF->area.get_area() + - IRF->local_result.area * coredynp.num_pipelines * - cdb_overhead); - - area.set_area(area.get_area() + IRF->local_result.area + - xbar_rfu->area.get_area() + arbiter_rfu->area.get_area()); - if (XML->sys.architecture == 1) { - IRF->local_result.power.readOp.dynamic *= .33; - IRF->local_result.power.writeOp.dynamic *= .33; - } else { - IRF->local_result.power.readOp.dynamic *= .55; - IRF->local_result.power.writeOp.dynamic *= .55; - } + //new Crossbar(simd_width,shared_memory_banks,word_length*simd_width,&(g_tp.peri_global)); - /** - * Operand collectors (32-bit wide, 8 entry banks ) - */ - data = 32; - // data *= 8; - interface_ip.is_cache = false; - interface_ip.pure_cam = false; - interface_ip.pure_ram = true; - - interface_ip.line_sz = 4; // int(ceil(data/32.0))*4 * - // XML->sys.core[ithCore].simd_width/4 ;//2 for - // Tesla as RF width half of SIMD width - - interface_ip.line_sz = 4; // int(ceil(data/32.0))*4 * - // XML->sys.core[ithCore].simd_width/2 ;//2 for - // Tesla as RF width half of SIMD width - - interface_ip.cache_sz = 8 * 4; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - - interface_ip.out_w = - interface_ip - .line_sz; // interface_ip.line_sz*XML->sys.core[ithCore].simd_width/4; - // //2 for Tesla and 4 for Fermi - - interface_ip.out_w = - interface_ip - .line_sz; // interface_ip.line_sz*XML->sys.core[ithCore].simd_width/2; - // //2 for Tesla and 4 for Fermi - - interface_ip.access_mode = 1; - interface_ip.throughput = 1.0 / (clockRate); - interface_ip.latency = 1.0 / (clockRate); - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 1; - interface_ip.obj_func_cycle_t = 0; - interface_ip.num_rw_ports = 0; // this is the transfer port for - // saving/restoring states when exceptions - // happen. - interface_ip.num_rd_ports = 1; // 2*coredynp.peak_issueW; - interface_ip.num_wr_ports = 1; // coredynp.peak_issueW; - interface_ip.num_se_rd_ports = 0; - OPC = new ArrayST(&interface_ip, "Operand collectors", Core_device, - coredynp.opt_local, coredynp.core_ty); - - OPC->area.set_area(OPC->area.get_area() + - OPC->local_result.area * coredynp.num_pipelines * - cdb_overhead); - - area.set_area(area.get_area() + OPC->local_result.area); - - /******** - * For GPGPUSim (Syed Gilani) - * Do not include FRF in final results for GPU. Only model the IRF - ********/ - - //**********************************FRF*************************************** - data = coredynp.fp_data_width; - // data *= 8; - interface_ip.is_cache = false; - interface_ip.pure_cam = false; - interface_ip.pure_ram = true; - interface_ip.line_sz = int(ceil(data / 32.0)) * 4; - interface_ip.cache_sz = coredynp.num_FRF_entry * interface_ip.line_sz; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 1; - interface_ip.throughput = 1.0 / clockRate; - interface_ip.latency = 1.0 / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; // this is the transfer port for - // saving/restoring states when exceptions - // happen. - interface_ip.num_rd_ports = 2 * XML->sys.core[ithCore].issue_width; - // interface_ip.num_rd_ports = 1; - interface_ip.num_wr_ports = XML->sys.core[ithCore].issue_width; - // interface_ip.num_wr_ports = 1; - interface_ip.num_se_rd_ports = 0; - FRF = new ArrayST(&interface_ip, "Floating point Register File", Core_device, - coredynp.opt_local, coredynp.core_ty); - // FRF->area.set_area(FRF->area.get_area()+ - // FRF->local_result.area*XML->sys.core[ithCore].number_hardware_threads*coredynp.num_fp_pipelines*cdb_overhead); - // area.set_area(area.get_area()+ - // FRF->local_result.area*XML->sys.core[ithCore].number_hardware_threads*coredynp.num_fp_pipelines*cdb_overhead); - // area.set_area(area.get_area()*cdb_overhead); - // output_data_csv(FRF.RF.local_result); - int_regfile_height = IRF->local_result.cache_ht * - XML->sys.core[ithCore].number_hardware_threads * - sqrt(cdb_overhead); - fp_regfile_height = 0; - // fp_regfile_height = - // FRF->local_result.cache_ht*XML->sys.core[ithCore].number_hardware_threads*sqrt(cdb_overhead); - // since a EXU is associated with each pipeline, the cdb should not have - // longer length. - if (coredynp.regWindowing) { - //*********************************REG_WIN************************************ - data = coredynp.int_data_width; // ECC, and usually 2 regs are transfered - // together during window shifting.Niagara - // Mega cell - interface_ip.is_cache = false; - interface_ip.pure_cam = false; - interface_ip.pure_ram = true; - interface_ip.line_sz = int(ceil(data / 8.0)); - interface_ip.cache_sz = XML->sys.core[ithCore].register_windows_size * - IRF->l_ip.cache_sz * - XML->sys.core[ithCore].number_hardware_threads; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 1; - interface_ip.throughput = 4.0 / clockRate; - interface_ip.latency = 4.0 / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; // this is the transfer port for - // saving/restoring states when exceptions - // happen. - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - RFWIN = new ArrayST(&interface_ip, "RegWindow", Core_device, - coredynp.opt_local, coredynp.core_ty); - RFWIN->area.set_area(RFWIN->area.get_area() + - RFWIN->local_result.area * coredynp.num_pipelines); - area.set_area(area.get_area() + - RFWIN->local_result.area * coredynp.num_pipelines); - // output_data_csv(RFWIN.RF.local_result); - } -} + //Arbiter + arbiter_rfu = new MCPAT_Arbiter(XML->sys.core[ithCore].rf_banks,XML->sys.core[ithCore].collector_units , 1,&(g_tp.peri_global)); -EXECU::EXECU(ParseXML* XML_interface, int ithCore_, - InputParameter* interface_ip_, double lsq_height_, - const CoreDynParam& dyn_p_, double exClockRate, bool exist_) - : XML(XML_interface), - ithCore(ithCore_), - interface_ip(*interface_ip_), - lsq_height(lsq_height_), - coredynp(dyn_p_), - rfu(0), - scheu(0), - fp_u(0), - exeu(0), - mul(0), - int_bypass(0), - intTagBypass(0), - int_mul_bypass(0), - intTag_mul_Bypass(0), - fp_bypass(0), - fpTagBypass(0), - exist(exist_), - rf_fu_clockRate(exClockRate) { - if (!exist) return; - double fu_height = 0.0; - clockRate = coredynp.clockRate; - // cout <<"EXECU exClockRate: "<area.get_area() + rfu->area.get_area() + - scheu->area.get_area()); - fu_height = exeu->FU_height; - if (coredynp.num_fpus > 0) { - fp_u = new FunctionalUnit(XML, ithCore, &interface_ip, coredynp, FPU, - exClockRate); - area.set_area(area.get_area() + fp_u->area.get_area()); - } - if (coredynp.num_muls > 0) { - mul = new FunctionalUnit(XML, ithCore, &interface_ip, coredynp, MUL, - exClockRate); - area.set_area(area.get_area() + mul->area.get_area()); - fu_height += mul->FU_height; - } - /* - * broadcast logic, including int-broadcast; int_tag-broadcast; fp-broadcast; - * fp_tag-broadcast - * integer by pass has two paths and fp has 3 paths. - * on the same bus there are multiple tri-state drivers and muxes that go to - * different components on the same bus - */ - if (XML->sys.Embedded) { - interface_ip.wt = Global_30; - interface_ip.wire_is_mat_type = 0; - interface_ip.wire_os_mat_type = 0; - interface_ip.throughput = 1.0 / clockRate; - interface_ip.latency = 1.0 / clockRate; - } else { - interface_ip.wt = Global; - interface_ip.wire_is_mat_type = - 2; // start from semi-global since local wires are already used - interface_ip.wire_os_mat_type = 2; - interface_ip.throughput = 10.0 / clockRate; // Do not care - interface_ip.latency = 10.0 / clockRate; - } - if (coredynp.core_ty == Inorder) { // - int_bypass = new interconnect( - "Int Bypass Data", Core_device, 1, 1, - int(ceil(XML->sys.machine_bits / 32.0) * 32), - rfu->int_regfile_height + exeu->FU_height + lsq_height, &interface_ip, - 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); - bypass.area.set_area(bypass.area.get_area() + int_bypass->area.get_area()); - intTagBypass = new interconnect( - "Int Bypass tag", Core_device, 1, 1, coredynp.perThreadState, - rfu->int_regfile_height + exeu->FU_height + lsq_height + - scheu->Iw_height, - &interface_ip, 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); - bypass.area.set_area(bypass.area.get_area() + - intTagBypass->area.get_area()); - - if (coredynp.num_muls > 0) { - int_mul_bypass = new interconnect( - "Mul Bypass Data", Core_device, 1, 1, - int(ceil(XML->sys.machine_bits / 32.0) * 32 * 1.5), - rfu->fp_regfile_height + exeu->FU_height + mul->FU_height + - lsq_height, - &interface_ip, 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); - bypass.area.set_area(bypass.area.get_area() + - int_mul_bypass->area.get_area()); - intTag_mul_Bypass = new interconnect( - "Mul Bypass tag", Core_device, 1, 1, coredynp.perThreadState, - rfu->fp_regfile_height + exeu->FU_height + mul->FU_height + - lsq_height + scheu->Iw_height, - &interface_ip, 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); - bypass.area.set_area(bypass.area.get_area() + - intTag_mul_Bypass->area.get_area()); - } - /* - if (coredynp.num_fpus>0) - { - fp_bypass = new interconnect("FP Bypass Data" , Core_device, 1, - 1, int(ceil(XML->sys.machine_bits/32.0)*32*1.5), - rfu->fp_regfile_height + fp_u->FU_height, - &interface_ip, 3, - false, 1.0, coredynp.opt_local, coredynp.core_ty); - bypass.area.set_area(bypass.area.get_area() - +fp_bypass->area.get_area()); - fpTagBypass = new interconnect("FP Bypass tag" , Core_device, 1, - 1, coredynp.perThreadState, - rfu->fp_regfile_height + fp_u->FU_height + - lsq_height + scheu->Iw_height, &interface_ip, 3, - false, 1.0, coredynp.opt_local, coredynp.core_ty); - bypass.area.set_area(bypass.area.get_area() - +fpTagBypass->area.get_area()); - }*/ - } /* if (coredynp.core_ty==Inorder) */ - else { // OOO - if (coredynp.scheu_ty == PhysicalRegFile) { - /* For physical register based OOO, - * data broadcast interconnects cover across functional units, lsq, inst - * windows and register files, - * while tag broadcast interconnects also cover across ROB - */ - int_bypass = new interconnect( - "Int Bypass Data", Core_device, 1, 1, - int(ceil(coredynp.int_data_width)), - rfu->int_regfile_height + exeu->FU_height + lsq_height, &interface_ip, - 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); - bypass.area.set_area(bypass.area.get_area() + - int_bypass->area.get_area()); - intTagBypass = new interconnect( - "Int Bypass tag", Core_device, 1, 1, coredynp.phy_ireg_width, - rfu->int_regfile_height + exeu->FU_height + lsq_height + - scheu->Iw_height + scheu->ROB_height, - &interface_ip, 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); - - if (coredynp.num_muls > 0) { - int_mul_bypass = new interconnect( - "Mul Bypass Data", Core_device, 1, 1, - int(ceil(coredynp.int_data_width)), - rfu->int_regfile_height + exeu->FU_height + mul->FU_height + - lsq_height, - &interface_ip, 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); - intTag_mul_Bypass = new interconnect( - "Mul Bypass tag", Core_device, 1, 1, coredynp.phy_ireg_width, - rfu->int_regfile_height + exeu->FU_height + mul->FU_height + - lsq_height + scheu->Iw_height + scheu->ROB_height, - &interface_ip, 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); - bypass.area.set_area(bypass.area.get_area() + - int_mul_bypass->area.get_area()); - bypass.area.set_area(bypass.area.get_area() + - intTag_mul_Bypass->area.get_area()); - } + // RF banks modelled here for GPGPU-Sim (Syed Gilani) + // + //**********************************IRF*************************************** + data = coredynp.int_data_width; + //data *= 8; + interface_ip.is_cache = false; + interface_ip.pure_cam = false; + interface_ip.pure_ram = true; - if (coredynp.num_fpus > 0) { - fp_bypass = new interconnect("FP Bypass Data", Core_device, 1, 1, - int(ceil(coredynp.fp_data_width)), - rfu->fp_regfile_height + fp_u->FU_height, - &interface_ip, 3, false, 1.0, - coredynp.opt_local, coredynp.core_ty); - fpTagBypass = new interconnect( - "FP Bypass tag", Core_device, 1, 1, coredynp.phy_freg_width, - rfu->fp_regfile_height + fp_u->FU_height + lsq_height + - scheu->fp_Iw_height + scheu->ROB_height, - &interface_ip, 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); - bypass.area.set_area(bypass.area.get_area() + - fp_bypass->area.get_area()); - bypass.area.set_area(bypass.area.get_area() + - fpTagBypass->area.get_area()); - } - } else { - /* - * In RS based processor both data and tag are broadcast together, - * covering functional units, lsq, nst windows, register files, and ROBs - */ - int_bypass = new interconnect( - "Int Bypass Data", Core_device, 1, 1, - int(ceil(coredynp.int_data_width)), - rfu->int_regfile_height + exeu->FU_height + lsq_height + - scheu->Iw_height + scheu->ROB_height, - &interface_ip, 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); - intTagBypass = new interconnect( - "Int Bypass tag", Core_device, 1, 1, coredynp.phy_ireg_width, - rfu->int_regfile_height + exeu->FU_height + lsq_height + - scheu->Iw_height + scheu->ROB_height, - &interface_ip, 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); - bypass.area.set_area(bypass.area.get_area() + - int_bypass->area.get_area()); - bypass.area.set_area(bypass.area.get_area() + - intTagBypass->area.get_area()); - if (coredynp.num_muls > 0) { - int_mul_bypass = new interconnect( - "Mul Bypass Data", Core_device, 1, 1, - int(ceil(coredynp.int_data_width)), - rfu->int_regfile_height + exeu->FU_height + mul->FU_height + - lsq_height + scheu->Iw_height + scheu->ROB_height, - &interface_ip, 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); - intTag_mul_Bypass = new interconnect( - "Mul Bypass tag", Core_device, 1, 1, coredynp.phy_ireg_width, - rfu->int_regfile_height + exeu->FU_height + mul->FU_height + - lsq_height + scheu->Iw_height + scheu->ROB_height, - &interface_ip, 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); - bypass.area.set_area(bypass.area.get_area() + - int_mul_bypass->area.get_area()); - bypass.area.set_area(bypass.area.get_area() + - intTag_mul_Bypass->area.get_area()); - } + interface_ip.line_sz = 16;//int(ceil(data/32.0))*4 * XML->sys.core[ithCore].simd_width/4 ;//2 for Tesla as RF width half of SIMD width - if (coredynp.num_fpus > 0) { - fp_bypass = new interconnect( - "FP Bypass Data", Core_device, 1, 1, - int(ceil(coredynp.fp_data_width)), - rfu->fp_regfile_height + fp_u->FU_height + lsq_height + - scheu->fp_Iw_height + scheu->ROB_height, - &interface_ip, 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); - fpTagBypass = new interconnect( - "FP Bypass tag", Core_device, 1, 1, coredynp.phy_freg_width, - rfu->fp_regfile_height + fp_u->FU_height + lsq_height + - scheu->fp_Iw_height + scheu->ROB_height, - &interface_ip, 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); - bypass.area.set_area(bypass.area.get_area() + - fp_bypass->area.get_area()); - bypass.area.set_area(bypass.area.get_area() + - fpTagBypass->area.get_area()); - } - } /* else */ + interface_ip.line_sz = 16;//int(ceil(data/32.0))*4 * XML->sys.core[ithCore].simd_width/2 ;//2 for Tesla as RF width half of SIMD width + + interface_ip.cache_sz = coredynp.num_IRF_entry*4; + interface_ip.assoc = 1; + interface_ip.nbanks = XML->sys.core[ithCore].rf_banks; + + interface_ip.out_w = interface_ip.line_sz*8;//interface_ip.line_sz*XML->sys.core[ithCore].simd_width/4; //2 for Tesla and 4 for Fermi - } /* else */ - area.set_area(area.get_area() /*+ bypass.area.get_area()*/); + interface_ip.out_w = interface_ip.line_sz*8;//interface_ip.line_sz*XML->sys.core[ithCore].simd_width/2; //2 for Tesla and 4 for Fermi + + + interface_ip.access_mode = 1; + interface_ip.throughput = 1/(clockRate); + interface_ip.latency = 8.0/(clockRate); + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 1; + interface_ip.obj_func_cycle_t = 0; + interface_ip.num_rw_ports = 0;//this is the transfer port for saving/restoring states when exceptions happen. + interface_ip.num_rd_ports = 1;//2*coredynp.peak_issueW; + interface_ip.num_wr_ports = 1;//coredynp.peak_issueW; + interface_ip.num_se_rd_ports = 0; + IRF = new ArrayST(&interface_ip, "Integer Register File", Core_device, coredynp.opt_local, coredynp.core_ty); + + IRF->area.set_area(IRF->area.get_area()+ IRF->local_result.area*coredynp.num_pipelines*cdb_overhead); + + + area.set_area(area.get_area()+ IRF->local_result.area + + xbar_rfu->area.get_area() + arbiter_rfu->area.get_area()); + if(XML->sys.architecture==1){ + IRF->local_result.power.readOp.dynamic *= .33; + IRF->local_result.power.writeOp.dynamic *= .33; + } + else { + IRF->local_result.power.readOp.dynamic *= .55; + IRF->local_result.power.writeOp.dynamic *= .55; + } + + + + + /** + * Operand collectors (32-bit wide, 8 entry banks ) + */ + data = 32; + //data *= 8; + interface_ip.is_cache = false; + interface_ip.pure_cam = false; + interface_ip.pure_ram = true; + + interface_ip.line_sz = 4;//int(ceil(data/32.0))*4 * XML->sys.core[ithCore].simd_width/4 ;//2 for Tesla as RF width half of SIMD width + + interface_ip.line_sz = 4;//int(ceil(data/32.0))*4 * XML->sys.core[ithCore].simd_width/2 ;//2 for Tesla as RF width half of SIMD width + + interface_ip.cache_sz = 8*4; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + + interface_ip.out_w = interface_ip.line_sz;//interface_ip.line_sz*XML->sys.core[ithCore].simd_width/4; //2 for Tesla and 4 for Fermi + + interface_ip.out_w = interface_ip.line_sz;//interface_ip.line_sz*XML->sys.core[ithCore].simd_width/2; //2 for Tesla and 4 for Fermi + + + interface_ip.access_mode = 1; + interface_ip.throughput = 1.0/(clockRate); + interface_ip.latency = 1.0/(clockRate); + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 1; + interface_ip.obj_func_cycle_t = 0; + interface_ip.num_rw_ports = 0;//this is the transfer port for saving/restoring states when exceptions happen. + interface_ip.num_rd_ports = 1;//2*coredynp.peak_issueW; + interface_ip.num_wr_ports = 1;//coredynp.peak_issueW; + interface_ip.num_se_rd_ports = 0; + OPC = new ArrayST(&interface_ip, "Operand collectors", Core_device, coredynp.opt_local, coredynp.core_ty); + + OPC->area.set_area(OPC->area.get_area()+ OPC->local_result.area*coredynp.num_pipelines*cdb_overhead); + + + area.set_area(area.get_area()+ OPC->local_result.area); + + + + + /******** + * For GPGPUSim (Syed Gilani) + * Do not include FRF in final results for GPU. Only model the IRF + ********/ + + //**********************************FRF*************************************** + data = coredynp.fp_data_width; + //data *= 8; + interface_ip.is_cache = false; + interface_ip.pure_cam = false; + interface_ip.pure_ram = true; + interface_ip.line_sz = int(ceil(data/32.0))*4; + interface_ip.cache_sz = coredynp.num_FRF_entry*interface_ip.line_sz; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 1; + interface_ip.throughput = 1.0/clockRate; + interface_ip.latency = 1.0/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1;//this is the transfer port for saving/restoring states when exceptions happen. + interface_ip.num_rd_ports = 2*XML->sys.core[ithCore].issue_width; + //interface_ip.num_rd_ports = 1; + interface_ip.num_wr_ports = XML->sys.core[ithCore].issue_width; + //interface_ip.num_wr_ports = 1; + interface_ip.num_se_rd_ports = 0; + FRF = new ArrayST(&interface_ip, "Floating point Register File", Core_device, coredynp.opt_local, coredynp.core_ty); + //FRF->area.set_area(FRF->area.get_area()+ FRF->local_result.area*XML->sys.core[ithCore].number_hardware_threads*coredynp.num_fp_pipelines*cdb_overhead); + //area.set_area(area.get_area()+ FRF->local_result.area*XML->sys.core[ithCore].number_hardware_threads*coredynp.num_fp_pipelines*cdb_overhead); + //area.set_area(area.get_area()*cdb_overhead); + //output_data_csv(FRF.RF.local_result); + int_regfile_height= IRF->local_result.cache_ht*XML->sys.core[ithCore].number_hardware_threads*sqrt(cdb_overhead); + fp_regfile_height=0; + //fp_regfile_height = FRF->local_result.cache_ht*XML->sys.core[ithCore].number_hardware_threads*sqrt(cdb_overhead); + //since a EXU is associated with each pipeline, the cdb should not have longer length. + if (coredynp.regWindowing) + { + //*********************************REG_WIN************************************ + data = coredynp.int_data_width; //ECC, and usually 2 regs are transfered together during window shifting.Niagara Mega cell + interface_ip.is_cache = false; + interface_ip.pure_cam = false; + interface_ip.pure_ram = true; + interface_ip.line_sz = int(ceil(data/8.0)); + interface_ip.cache_sz = XML->sys.core[ithCore].register_windows_size*IRF->l_ip.cache_sz*XML->sys.core[ithCore].number_hardware_threads; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 1; + interface_ip.throughput = 4.0/clockRate; + interface_ip.latency = 4.0/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1;//this is the transfer port for saving/restoring states when exceptions happen. + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + RFWIN = new ArrayST(&interface_ip, "RegWindow", Core_device, coredynp.opt_local, coredynp.core_ty); + RFWIN->area.set_area(RFWIN->area.get_area()+ RFWIN->local_result.area*coredynp.num_pipelines); + area.set_area(area.get_area()+ RFWIN->local_result.area*coredynp.num_pipelines); + //output_data_csv(RFWIN.RF.local_result); + } + + + } + +EXECU::EXECU(ParseXML* XML_interface, int ithCore_, InputParameter* interface_ip_, double lsq_height_, const CoreDynParam & dyn_p_, double exClockRate, bool exist_) +:XML(XML_interface), + ithCore(ithCore_), + interface_ip(*interface_ip_), + lsq_height(lsq_height_), + coredynp(dyn_p_), + rfu(0), + scheu(0), + fp_u(0), + exeu(0), + mul(0), + int_bypass(0), + intTagBypass(0), + int_mul_bypass(0), + intTag_mul_Bypass(0), + fp_bypass(0), + fpTagBypass(0), + exist(exist_), + rf_fu_clockRate(exClockRate) +{ + if (!exist) return; + double fu_height = 0.0; + clockRate = coredynp.clockRate; + //cout <<"EXECU exClockRate: "<area.get_area() + rfu->area.get_area() +scheu->area.get_area() ); + fu_height = exeu->FU_height; + if (coredynp.num_fpus >0) + { + fp_u = new FunctionalUnit(XML, ithCore,&interface_ip, coredynp, FPU, exClockRate); + area.set_area(area.get_area()+ fp_u->area.get_area()); + } + if (coredynp.num_muls >0) + { + mul = new FunctionalUnit(XML, ithCore,&interface_ip, coredynp, MUL, exClockRate); + area.set_area(area.get_area()+ mul->area.get_area()); + fu_height += mul->FU_height; + } + /* + * broadcast logic, including int-broadcast; int_tag-broadcast; fp-broadcast; fp_tag-broadcast + * integer by pass has two paths and fp has 3 paths. + * on the same bus there are multiple tri-state drivers and muxes that go to different components on the same bus + */ + if (XML->sys.Embedded) + { + interface_ip.wt =Global_30; + interface_ip.wire_is_mat_type = 0; + interface_ip.wire_os_mat_type = 0; + interface_ip.throughput = 1.0/clockRate; + interface_ip.latency = 1.0/clockRate; + } + else + { + interface_ip.wt =Global; + interface_ip.wire_is_mat_type = 2;//start from semi-global since local wires are already used + interface_ip.wire_os_mat_type = 2; + interface_ip.throughput = 10.0/clockRate; //Do not care + interface_ip.latency = 10.0/clockRate; + } + + if (coredynp.core_ty==Inorder) + {// + int_bypass = new interconnect("Int Bypass Data", Core_device, 1, 1, int(ceil(XML->sys.machine_bits/32.0)*32), + rfu->int_regfile_height + exeu->FU_height + lsq_height, &interface_ip, 3, + false, 1.0, coredynp.opt_local, coredynp.core_ty); + bypass.area.set_area(bypass.area.get_area() + int_bypass->area.get_area()); + intTagBypass = new interconnect("Int Bypass tag" , Core_device, 1, 1, coredynp.perThreadState, + rfu->int_regfile_height + exeu->FU_height + lsq_height + scheu->Iw_height, &interface_ip, 3, + false, 1.0, coredynp.opt_local, coredynp.core_ty); + bypass.area.set_area(bypass.area.get_area() +intTagBypass->area.get_area()); + + if (coredynp.num_muls>0) + { + int_mul_bypass = new interconnect("Mul Bypass Data" , Core_device, 1, 1, int(ceil(XML->sys.machine_bits/32.0)*32*1.5), + rfu->fp_regfile_height + exeu->FU_height + mul->FU_height + lsq_height, &interface_ip, 3, + false, 1.0, coredynp.opt_local, coredynp.core_ty); + bypass.area.set_area(bypass.area.get_area() +int_mul_bypass->area.get_area()); + intTag_mul_Bypass = new interconnect("Mul Bypass tag" , Core_device, 1, 1, coredynp.perThreadState, + rfu->fp_regfile_height + exeu->FU_height + mul->FU_height + lsq_height + scheu->Iw_height, &interface_ip, 3, + false, 1.0, coredynp.opt_local, coredynp.core_ty); + bypass.area.set_area(bypass.area.get_area() +intTag_mul_Bypass->area.get_area()); + } + + /* + if (coredynp.num_fpus>0) + { + fp_bypass = new interconnect("FP Bypass Data" , Core_device, 1, 1, int(ceil(XML->sys.machine_bits/32.0)*32*1.5), + rfu->fp_regfile_height + fp_u->FU_height, &interface_ip, 3, + false, 1.0, coredynp.opt_local, coredynp.core_ty); + bypass.area.set_area(bypass.area.get_area() +fp_bypass->area.get_area()); + fpTagBypass = new interconnect("FP Bypass tag" , Core_device, 1, 1, coredynp.perThreadState, + rfu->fp_regfile_height + fp_u->FU_height + lsq_height + scheu->Iw_height, &interface_ip, 3, + false, 1.0, coredynp.opt_local, coredynp.core_ty); + bypass.area.set_area(bypass.area.get_area() +fpTagBypass->area.get_area()); + }*/ + } /* if (coredynp.core_ty==Inorder) */ + else + {//OOO + if (coredynp.scheu_ty==PhysicalRegFile) + { + /* For physical register based OOO, + * data broadcast interconnects cover across functional units, lsq, inst windows and register files, + * while tag broadcast interconnects also cover across ROB + */ + int_bypass = new interconnect("Int Bypass Data", Core_device, 1, 1, int(ceil(coredynp.int_data_width)), + rfu->int_regfile_height + exeu->FU_height + lsq_height, &interface_ip, 3, + false, 1.0, coredynp.opt_local, coredynp.core_ty); + bypass.area.set_area(bypass.area.get_area() +int_bypass->area.get_area()); + intTagBypass = new interconnect("Int Bypass tag" , Core_device, 1, 1, coredynp.phy_ireg_width, + rfu->int_regfile_height + exeu->FU_height + lsq_height + scheu->Iw_height + scheu->ROB_height , &interface_ip, 3, + false, 1.0, coredynp.opt_local, coredynp.core_ty); + + if (coredynp.num_muls>0) + { + int_mul_bypass = new interconnect("Mul Bypass Data", Core_device, 1, 1, int(ceil(coredynp.int_data_width)), + rfu->int_regfile_height + exeu->FU_height + mul->FU_height + lsq_height, &interface_ip, 3, + false, 1.0, coredynp.opt_local, coredynp.core_ty); + intTag_mul_Bypass = new interconnect("Mul Bypass tag" , Core_device, 1, 1, coredynp.phy_ireg_width, + rfu->int_regfile_height + exeu->FU_height + mul->FU_height + lsq_height + scheu->Iw_height + scheu->ROB_height , &interface_ip, 3, + false, 1.0, coredynp.opt_local, coredynp.core_ty); + bypass.area.set_area(bypass.area.get_area() +int_mul_bypass->area.get_area()); + bypass.area.set_area(bypass.area.get_area() +intTag_mul_Bypass->area.get_area()); + } + + if (coredynp.num_fpus>0) + { + fp_bypass = new interconnect("FP Bypass Data" , Core_device, 1, 1, int(ceil(coredynp.fp_data_width)), + rfu->fp_regfile_height + fp_u->FU_height, &interface_ip, 3, + false, 1.0, coredynp.opt_local, coredynp.core_ty); + fpTagBypass = new interconnect("FP Bypass tag" , Core_device, 1, 1, coredynp.phy_freg_width, + rfu->fp_regfile_height + fp_u->FU_height + lsq_height + scheu->fp_Iw_height + scheu->ROB_height, &interface_ip, 3, + false, 1.0, coredynp.opt_local, coredynp.core_ty); + bypass.area.set_area(bypass.area.get_area() +fp_bypass->area.get_area()); + bypass.area.set_area(bypass.area.get_area() +fpTagBypass->area.get_area()); + } + } + else + { + /* + * In RS based processor both data and tag are broadcast together, + * covering functional units, lsq, nst windows, register files, and ROBs + */ + int_bypass = new interconnect("Int Bypass Data", Core_device, 1, 1, int(ceil(coredynp.int_data_width)), + rfu->int_regfile_height + exeu->FU_height + lsq_height + scheu->Iw_height + scheu->ROB_height, &interface_ip, 3, + false, 1.0, coredynp.opt_local, coredynp.core_ty); + intTagBypass = new interconnect("Int Bypass tag" , Core_device, 1, 1, coredynp.phy_ireg_width, + rfu->int_regfile_height + exeu->FU_height + lsq_height + scheu->Iw_height + scheu->ROB_height , &interface_ip, 3, + false, 1.0, coredynp.opt_local, coredynp.core_ty); + bypass.area.set_area(bypass.area.get_area() +int_bypass->area.get_area()); + bypass.area.set_area(bypass.area.get_area() +intTagBypass->area.get_area()); + if (coredynp.num_muls>0) + { + int_mul_bypass = new interconnect("Mul Bypass Data", Core_device, 1, 1, int(ceil(coredynp.int_data_width)), + rfu->int_regfile_height + exeu->FU_height + mul->FU_height + lsq_height + scheu->Iw_height + scheu->ROB_height, &interface_ip, 3, + false, 1.0, coredynp.opt_local, coredynp.core_ty); + intTag_mul_Bypass = new interconnect("Mul Bypass tag" , Core_device, 1, 1, coredynp.phy_ireg_width, + rfu->int_regfile_height + exeu->FU_height + mul->FU_height + lsq_height + scheu->Iw_height + scheu->ROB_height , &interface_ip, 3, + false, 1.0, coredynp.opt_local, coredynp.core_ty); + bypass.area.set_area(bypass.area.get_area() +int_mul_bypass->area.get_area()); + bypass.area.set_area(bypass.area.get_area() +intTag_mul_Bypass->area.get_area()); + } + + if (coredynp.num_fpus>0) + { + fp_bypass = new interconnect("FP Bypass Data" , Core_device, 1, 1, int(ceil(coredynp.fp_data_width)), + rfu->fp_regfile_height + fp_u->FU_height + lsq_height + scheu->fp_Iw_height + scheu->ROB_height, &interface_ip, 3, + false, 1.0, coredynp.opt_local, coredynp.core_ty); + fpTagBypass = new interconnect("FP Bypass tag" , Core_device, 1, 1, coredynp.phy_freg_width, + rfu->fp_regfile_height + fp_u->FU_height + lsq_height + scheu->fp_Iw_height + scheu->ROB_height, &interface_ip, 3, + false, 1.0, coredynp.opt_local, coredynp.core_ty); + bypass.area.set_area(bypass.area.get_area() +fp_bypass->area.get_area()); + bypass.area.set_area(bypass.area.get_area() +fpTagBypass->area.get_area()); + } + } /* else */ + + + } /* else */ + area.set_area(area.get_area()/*+ bypass.area.get_area()*/); } -RENAMINGU::RENAMINGU(ParseXML* XML_interface, int ithCore_, - InputParameter* interface_ip_, const CoreDynParam& dyn_p_, - bool exist_) - : XML(XML_interface), - ithCore(ithCore_), - interface_ip(*interface_ip_), - coredynp(dyn_p_), - iFRAT(0), - fFRAT(0), - iRRAT(0), - fRRAT(0), - ifreeL(0), - ffreeL(0), - idcl(0), - fdcl(0), - RAHT(0), - exist(exist_) { - /* - * Although renaming logic maybe be used in in-order processors, -*McPAT assumes no renaming logic is used since the performance gain is very -* limited and -*the only major inorder processor with renaming logic is Itainium -*that is a VLIW processor and different from current McPAT's model. - * physical register base OOO must have Dual-RAT architecture or equivalent -* structure.FRAT:FrontRAT, RRAT:RetireRAT; - * i,f prefix mean int and fp - * RAT for all Renaming logic, random accessible checkpointing is used, but -* only update when instruction retires. - * FRAT will be read twice and written once per instruction; - * RRAT will be write once per instruction when committing and reads out all -* when context switch - * checkpointing is implicit - * Renaming logic is duplicated for each different hardware threads - * - * No Dual-RAT is needed in RS-based OOO processors, - * however, RAT needs to do associative search in RAT, when instruction -* commits and ROB release the entry, - * to make sure all the renamings associated with the ROB to be released are -* updated at the same time. - * RAM scheme has # ARchi Reg entry with each entry hold phy reg tag, - * CAM scheme has # Phy Reg entry with each entry hold ARchi reg tag, - * - * Both RAM and CAM have same DCL - */ - if (!exist) return; - int tag, data, out_w; - // interface_ip.wire_is_mat_type = 0; - // interface_ip.wire_os_mat_type = 0; - // interface_ip.wt = Global_30; - clockRate = coredynp.clockRate; - executionTime = coredynp.executionTime; - if (coredynp.core_ty == OOO) { - // integer pipeline - if (coredynp.scheu_ty == PhysicalRegFile) { - if (coredynp.rm_ty == RAMbased) { // FRAT with global checkpointing (GCs) - // please see paper tech report for - // detailed explaintions - data = - 33; // int(ceil(coredynp.phy_ireg_width*(1+coredynp.globalCheckpoint)/8.0)); - // data = - //int(ceil(coredynp.phy_ireg_width/8.0)); - out_w = 1; // int(ceil(coredynp.phy_ireg_width/8.0)); - interface_ip.is_cache = false; - interface_ip.pure_cam = false; - interface_ip.pure_ram = true; - interface_ip.line_sz = data; - interface_ip.cache_sz = - data * XML->sys.core[ithCore].archi_Regs_IRF_size; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = out_w * 8; - interface_ip.access_mode = 2; - interface_ip.throughput = 1.0 / clockRate; - interface_ip.latency = 1.0 / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; // the extra one port is for GCs - interface_ip.num_rd_ports = 2 * coredynp.decodeW; - interface_ip.num_wr_ports = coredynp.decodeW; - interface_ip.num_se_rd_ports = 0; - iFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, - coredynp.opt_local, coredynp.core_ty); - iFRAT->area.set_area( - iFRAT->area.get_area() + - iFRAT->local_result.area * - XML->sys.core[ithCore].number_hardware_threads); - area.set_area(area.get_area() + iFRAT->area.get_area()); - - // //RAHT According to Intel, combine GC with FRAT is - //very costly. - // data = - //int(ceil(coredynp.phy_ireg_width/8.0)*coredynp.num_IRF_entry); - // out_w = data; - // interface_ip.is_cache = - //false; - // interface_ip.pure_cam = false; - // interface_ip.pure_ram = true; - // interface_ip.line_sz = data; - // interface_ip.cache_sz = - //data*coredynp.globalCheckpoint; - // interface_ip.assoc = 1; - // interface_ip.nbanks = 1; - // interface_ip.out_w = out_w*8; - // interface_ip.access_mode = 0; - // interface_ip.throughput = - //1.0/clockRate; - // interface_ip.latency = - //1.0/clockRate; - // interface_ip.obj_func_dyn_energy = 0; - // interface_ip.obj_func_dyn_power = 0; - // interface_ip.obj_func_leak_power = 0; - // interface_ip.obj_func_cycle_t = 1; - // interface_ip.num_rw_ports = 1;//the extra one - //port is for GCs - // interface_ip.num_rd_ports = - //2*coredynp.decodeW; - // interface_ip.num_wr_ports = coredynp.decodeW; - // interface_ip.num_se_rd_ports = 0; - // iFRAT = new ArrayST(&interface_ip, "Int - //FrontRAT"); - // iFRAT->area.set_area(iFRAT->area.get_area()+ - //iFRAT->local_result.area*XML->sys.core[ithCore].number_hardware_threads); - // area.set_area(area.get_area()+ - //iFRAT->area.get_area()); - - // FRAT floating point - data = int(ceil(coredynp.phy_freg_width * - (1 + coredynp.globalCheckpoint) / 8.0)); - out_w = int(ceil(coredynp.phy_freg_width / 8.0)); - interface_ip.is_cache = false; - interface_ip.pure_cam = false; - interface_ip.pure_ram = true; - interface_ip.line_sz = data; - interface_ip.cache_sz = - data * XML->sys.core[ithCore].archi_Regs_FRF_size; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = out_w * 8; - interface_ip.access_mode = 2; - interface_ip.throughput = 1.0 / clockRate; - interface_ip.latency = 1.0 / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; // the extra one port is for GCs - interface_ip.num_rd_ports = 2 * coredynp.fp_decodeW; - interface_ip.num_wr_ports = coredynp.fp_decodeW; - interface_ip.num_se_rd_ports = 0; - fFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, - coredynp.opt_local, coredynp.core_ty); - fFRAT->area.set_area( - fFRAT->area.get_area() + - fFRAT->local_result.area * - XML->sys.core[ithCore].number_hardware_threads); - area.set_area(area.get_area() + fFRAT->area.get_area()); - - } else if ((coredynp.rm_ty == CAMbased)) { - // FRAT - tag = coredynp.arch_ireg_width; - data = int( - ceil((coredynp.arch_ireg_width + 1 * coredynp.globalCheckpoint) / - 8.0)); // the address of CAM needed to be sent out - out_w = int(ceil(coredynp.arch_ireg_width / 8.0)); - interface_ip.is_cache = true; - interface_ip.pure_cam = false; - interface_ip.pure_ram = false; - interface_ip.line_sz = data; - interface_ip.cache_sz = data * XML->sys.core[ithCore].phy_Regs_IRF_size; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = out_w * 8; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.access_mode = 2; - interface_ip.throughput = 1.0 / clockRate; - interface_ip.latency = 1.0 / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; // for GCs - interface_ip.num_rd_ports = coredynp.decodeW; - interface_ip.num_wr_ports = coredynp.decodeW; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = 2 * coredynp.decodeW; - iFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, - coredynp.opt_local, coredynp.core_ty); - iFRAT->area.set_area( - iFRAT->area.get_area() + - iFRAT->local_result.area * - XML->sys.core[ithCore].number_hardware_threads); - area.set_area(area.get_area() + iFRAT->area.get_area()); - - // FRAT for FP - tag = coredynp.arch_freg_width; - data = int( - ceil((coredynp.arch_freg_width + 1 * coredynp.globalCheckpoint) / - 8.0)); // the address of CAM needed to be sent out - out_w = int(ceil(coredynp.arch_freg_width / 8.0)); - interface_ip.is_cache = true; - interface_ip.pure_cam = false; - interface_ip.pure_ram = false; - interface_ip.line_sz = data; - interface_ip.cache_sz = data * XML->sys.core[ithCore].phy_Regs_FRF_size; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = out_w * 8; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.access_mode = 2; - interface_ip.throughput = 1.0 / clockRate; - interface_ip.latency = 1.0 / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; // for GCs - interface_ip.num_rd_ports = coredynp.fp_decodeW; - interface_ip.num_wr_ports = coredynp.fp_decodeW; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = 2 * coredynp.fp_decodeW; - fFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, - coredynp.opt_local, coredynp.core_ty); - fFRAT->area.set_area( - fFRAT->area.get_area() + - fFRAT->local_result.area * - XML->sys.core[ithCore].number_hardware_threads); - area.set_area(area.get_area() + fFRAT->area.get_area()); - } +RENAMINGU::RENAMINGU(ParseXML* XML_interface, int ithCore_, InputParameter* interface_ip_, const CoreDynParam & dyn_p_,bool exist_) +:XML(XML_interface), + ithCore(ithCore_), + interface_ip(*interface_ip_), + coredynp(dyn_p_), + iFRAT(0), + fFRAT(0), + iRRAT(0), + fRRAT(0), + ifreeL(0), + ffreeL(0), + idcl(0), + fdcl(0), + RAHT(0), + exist(exist_) + { + /* + * Although renaming logic maybe be used in in-order processors, + * McPAT assumes no renaming logic is used since the performance gain is very limited and + * the only major inorder processor with renaming logic is Itainium + * that is a VLIW processor and different from current McPAT's model. + * physical register base OOO must have Dual-RAT architecture or equivalent structure.FRAT:FrontRAT, RRAT:RetireRAT; + * i,f prefix mean int and fp + * RAT for all Renaming logic, random accessible checkpointing is used, but only update when instruction retires. + * FRAT will be read twice and written once per instruction; + * RRAT will be write once per instruction when committing and reads out all when context switch + * checkpointing is implicit + * Renaming logic is duplicated for each different hardware threads + * + * No Dual-RAT is needed in RS-based OOO processors, + * however, RAT needs to do associative search in RAT, when instruction commits and ROB release the entry, + * to make sure all the renamings associated with the ROB to be released are updated at the same time. + * RAM scheme has # ARchi Reg entry with each entry hold phy reg tag, + * CAM scheme has # Phy Reg entry with each entry hold ARchi reg tag, + * + * Both RAM and CAM have same DCL + */ + if (!exist) return; + int tag, data, out_w; +// interface_ip.wire_is_mat_type = 0; +// interface_ip.wire_os_mat_type = 0; +// interface_ip.wt = Global_30; + clockRate = coredynp.clockRate; + executionTime = coredynp.executionTime; + if (coredynp.core_ty==OOO) + { + //integer pipeline + if (coredynp.scheu_ty==PhysicalRegFile) + { + if (coredynp.rm_ty ==RAMbased) + { //FRAT with global checkpointing (GCs) please see paper tech report for detailed explaintions + data = 33;//int(ceil(coredynp.phy_ireg_width*(1+coredynp.globalCheckpoint)/8.0)); +// data = int(ceil(coredynp.phy_ireg_width/8.0)); + out_w = 1;//int(ceil(coredynp.phy_ireg_width/8.0)); + interface_ip.is_cache = false; + interface_ip.pure_cam = false; + interface_ip.pure_ram = true; + interface_ip.line_sz = data; + interface_ip.cache_sz = data*XML->sys.core[ithCore].archi_Regs_IRF_size; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = out_w*8; + interface_ip.access_mode = 2; + interface_ip.throughput = 1.0/clockRate; + interface_ip.latency = 1.0/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1;//the extra one port is for GCs + interface_ip.num_rd_ports = 2*coredynp.decodeW; + interface_ip.num_wr_ports = coredynp.decodeW; + interface_ip.num_se_rd_ports = 0; + iFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, coredynp.opt_local, coredynp.core_ty); + iFRAT->area.set_area(iFRAT->area.get_area()+ iFRAT->local_result.area*XML->sys.core[ithCore].number_hardware_threads); + area.set_area(area.get_area()+ iFRAT->area.get_area()); + +// //RAHT According to Intel, combine GC with FRAT is very costly. +// data = int(ceil(coredynp.phy_ireg_width/8.0)*coredynp.num_IRF_entry); +// out_w = data; +// interface_ip.is_cache = false; +// interface_ip.pure_cam = false; +// interface_ip.pure_ram = true; +// interface_ip.line_sz = data; +// interface_ip.cache_sz = data*coredynp.globalCheckpoint; +// interface_ip.assoc = 1; +// interface_ip.nbanks = 1; +// interface_ip.out_w = out_w*8; +// interface_ip.access_mode = 0; +// interface_ip.throughput = 1.0/clockRate; +// interface_ip.latency = 1.0/clockRate; +// interface_ip.obj_func_dyn_energy = 0; +// interface_ip.obj_func_dyn_power = 0; +// interface_ip.obj_func_leak_power = 0; +// interface_ip.obj_func_cycle_t = 1; +// interface_ip.num_rw_ports = 1;//the extra one port is for GCs +// interface_ip.num_rd_ports = 2*coredynp.decodeW; +// interface_ip.num_wr_ports = coredynp.decodeW; +// interface_ip.num_se_rd_ports = 0; +// iFRAT = new ArrayST(&interface_ip, "Int FrontRAT"); +// iFRAT->area.set_area(iFRAT->area.get_area()+ iFRAT->local_result.area*XML->sys.core[ithCore].number_hardware_threads); +// area.set_area(area.get_area()+ iFRAT->area.get_area()); + + //FRAT floating point + data = int(ceil(coredynp.phy_freg_width*(1+coredynp.globalCheckpoint)/8.0)); + out_w = int(ceil(coredynp.phy_freg_width/8.0)); + interface_ip.is_cache = false; + interface_ip.pure_cam = false; + interface_ip.pure_ram = true; + interface_ip.line_sz = data; + interface_ip.cache_sz = data*XML->sys.core[ithCore].archi_Regs_FRF_size; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = out_w*8; + interface_ip.access_mode = 2; + interface_ip.throughput = 1.0/clockRate; + interface_ip.latency = 1.0/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1;//the extra one port is for GCs + interface_ip.num_rd_ports = 2*coredynp.fp_decodeW; + interface_ip.num_wr_ports = coredynp.fp_decodeW; + interface_ip.num_se_rd_ports = 0; + fFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, coredynp.opt_local, coredynp.core_ty); + fFRAT->area.set_area(fFRAT->area.get_area()+ fFRAT->local_result.area*XML->sys.core[ithCore].number_hardware_threads); + area.set_area(area.get_area()+ fFRAT->area.get_area()); + + } + else if ((coredynp.rm_ty ==CAMbased)) + { + //FRAT + tag = coredynp.arch_ireg_width; + data = int(ceil ((coredynp.arch_ireg_width+1*coredynp.globalCheckpoint)/8.0));//the address of CAM needed to be sent out + out_w = int(ceil (coredynp.arch_ireg_width/8.0)); + interface_ip.is_cache = true; + interface_ip.pure_cam = false; + interface_ip.pure_ram = false; + interface_ip.line_sz = data; + interface_ip.cache_sz = data*XML->sys.core[ithCore].phy_Regs_IRF_size; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = out_w*8; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.access_mode = 2; + interface_ip.throughput = 1.0/clockRate; + interface_ip.latency = 1.0/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1;//for GCs + interface_ip.num_rd_ports = coredynp.decodeW; + interface_ip.num_wr_ports = coredynp.decodeW; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports= 2*coredynp.decodeW; + iFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, coredynp.opt_local, coredynp.core_ty); + iFRAT->area.set_area(iFRAT->area.get_area()+ iFRAT->local_result.area*XML->sys.core[ithCore].number_hardware_threads); + area.set_area(area.get_area()+ iFRAT->area.get_area()); + + //FRAT for FP + tag = coredynp.arch_freg_width; + data = int(ceil ((coredynp.arch_freg_width+1*coredynp.globalCheckpoint)/8.0));//the address of CAM needed to be sent out + out_w = int(ceil (coredynp.arch_freg_width/8.0)); + interface_ip.is_cache = true; + interface_ip.pure_cam = false; + interface_ip.pure_ram = false; + interface_ip.line_sz = data; + interface_ip.cache_sz = data*XML->sys.core[ithCore].phy_Regs_FRF_size; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = out_w*8; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.access_mode = 2; + interface_ip.throughput = 1.0/clockRate; + interface_ip.latency = 1.0/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1;//for GCs + interface_ip.num_rd_ports = coredynp.fp_decodeW; + interface_ip.num_wr_ports = coredynp.fp_decodeW; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports= 2*coredynp.fp_decodeW; + fFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, coredynp.opt_local, coredynp.core_ty); + fFRAT->area.set_area(fFRAT->area.get_area()+ fFRAT->local_result.area*XML->sys.core[ithCore].number_hardware_threads); + area.set_area(area.get_area()+ fFRAT->area.get_area()); + + } + + //RRAT is always RAM based, does not have GCs, and is used only for record latest non-speculative mapping + data = int(ceil(coredynp.phy_ireg_width/8.0)); + interface_ip.is_cache = false; + interface_ip.pure_cam = false; + interface_ip.pure_ram = true; + interface_ip.line_sz = data; + interface_ip.cache_sz = data*XML->sys.core[ithCore].archi_Regs_IRF_size*2;//HACK to make it as least 64B + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 1; + interface_ip.throughput = 1.0/clockRate; + interface_ip.latency = 1.0/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = XML->sys.core[ithCore].commit_width; + interface_ip.num_wr_ports = XML->sys.core[ithCore].commit_width; + interface_ip.num_se_rd_ports = 0; + iRRAT = new ArrayST(&interface_ip, "Int RetireRAT", Core_device, coredynp.opt_local, coredynp.core_ty); + iRRAT->area.set_area(iRRAT->area.get_area()+ iRRAT->local_result.area*XML->sys.core[ithCore].number_hardware_threads); + area.set_area(area.get_area()+ iRRAT->area.get_area()); + + //RRAT for FP + data = int(ceil(coredynp.phy_freg_width/8.0)); + interface_ip.is_cache = false; + interface_ip.pure_cam = false; + interface_ip.pure_ram = true; + interface_ip.line_sz = data; + interface_ip.cache_sz = data*XML->sys.core[ithCore].archi_Regs_FRF_size*2;//HACK to make it as least 64B + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 1; + interface_ip.throughput = 1.0/clockRate; + interface_ip.latency = 1.0/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = coredynp.fp_decodeW; + interface_ip.num_wr_ports = coredynp.fp_decodeW; + interface_ip.num_se_rd_ports = 0; + fRRAT = new ArrayST(&interface_ip, "Int RetireRAT", Core_device, coredynp.opt_local, coredynp.core_ty); + fRRAT->area.set_area(fRRAT->area.get_area()+ fRRAT->local_result.area*XML->sys.core[ithCore].number_hardware_threads); + area.set_area(area.get_area()+ fRRAT->area.get_area()); + + //Freelist of renaming unit always RAM based + //Recycle happens at two places: 1)when DCL check there are WAW, the Phyregisters/ROB directly recycles into freelist + // 2)When instruction commits the Phyregisters/ROB needed to be recycled. + //therefore num_wr port = decode-1(-1 means at least one phy reg will be used for the current renaming group) + commit width + data = int(ceil(coredynp.phy_ireg_width/8.0)); + interface_ip.is_cache = false; + interface_ip.pure_cam = false; + interface_ip.pure_ram = true; + interface_ip.line_sz = data; + interface_ip.cache_sz = data*coredynp.num_ifreelist_entries; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 1; + interface_ip.throughput = 1.0/clockRate; + interface_ip.latency = 1.0/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1;//TODO + interface_ip.num_rd_ports = coredynp.decodeW; + interface_ip.num_wr_ports = coredynp.decodeW -1 + XML->sys.core[ithCore].commit_width; + //every cycle, (coredynp.decodeW -1) inst may need to send back it dest tags, committW insts needs to update freelist buffers + interface_ip.num_se_rd_ports = 0; + ifreeL = new ArrayST(&interface_ip, "Int Free List", Core_device, coredynp.opt_local, coredynp.core_ty); + ifreeL->area.set_area(ifreeL->area.get_area()+ ifreeL->local_result.area*XML->sys.core[ithCore].number_hardware_threads); + area.set_area(area.get_area()+ ifreeL->area.get_area()); + + //freelist for FP + data = int(ceil(coredynp.phy_freg_width/8.0)); + interface_ip.is_cache = false; + interface_ip.pure_cam = false; + interface_ip.pure_ram = true; + interface_ip.line_sz = data; + interface_ip.cache_sz = data*coredynp.num_ffreelist_entries; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 1; + interface_ip.throughput = 1.0/clockRate; + interface_ip.latency = 1.0/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1; + interface_ip.num_rd_ports = coredynp.fp_decodeW; + interface_ip.num_wr_ports = coredynp.fp_decodeW -1 + XML->sys.core[ithCore].commit_width; + interface_ip.num_se_rd_ports = 0; + ffreeL = new ArrayST(&interface_ip, "Int Free List", Core_device, coredynp.opt_local, coredynp.core_ty); + ffreeL->area.set_area(ffreeL->area.get_area()+ ffreeL->local_result.area*XML->sys.core[ithCore].number_hardware_threads); + area.set_area(area.get_area()+ ffreeL->area.get_area()); + + idcl = new dep_resource_conflict_check(&interface_ip,coredynp,coredynp.phy_ireg_width);//TODO:Separate 2 sections See TR + fdcl = new dep_resource_conflict_check(&interface_ip,coredynp,coredynp.phy_freg_width); + + } + else if (coredynp.scheu_ty==ReservationStation){ + if (coredynp.rm_ty ==RAMbased){ + /* + * however, RAT needs to do associative search in RAT, when instruction commits and ROB release the entry, + * to make sure all the renamings associated with the ROB to be released are updated to ARF at the same time. + * RAM based RAT for RS base OOO does not save the search operations. Its advantage is to have less entries than + * CAM based RAT so that it is more scalable as number of ROB/physical regs increases. + */ + tag = coredynp.phy_ireg_width; + data = int(ceil(coredynp.phy_ireg_width*(1+coredynp.globalCheckpoint)/8.0)); + out_w = int(ceil(coredynp.phy_ireg_width/8.0)); + interface_ip.is_cache = true; + interface_ip.pure_cam = false; + interface_ip.pure_ram = false; + interface_ip.line_sz = data; + interface_ip.cache_sz = data*XML->sys.core[ithCore].archi_Regs_IRF_size; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = out_w*8; + interface_ip.access_mode = 2; + interface_ip.throughput = 1.0/clockRate; + interface_ip.latency = 1.0/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1;//the extra one port is for GCs + interface_ip.num_rd_ports = 2*coredynp.decodeW; + interface_ip.num_wr_ports = coredynp.decodeW; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports= coredynp.commitW;//TODO + iFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, coredynp.opt_local, coredynp.core_ty); + iFRAT->local_result.adjust_area(); + iFRAT->area.set_area(iFRAT->area.get_area()+ iFRAT->local_result.area*XML->sys.core[ithCore].number_hardware_threads); + area.set_area(area.get_area()+ iFRAT->area.get_area()); + + //FP + tag = coredynp.phy_freg_width; + data = int(ceil(coredynp.phy_freg_width*(1+coredynp.globalCheckpoint)/8.0)); + out_w = int(ceil(coredynp.phy_freg_width/8.0)); + interface_ip.is_cache = true; + interface_ip.pure_cam = false; + interface_ip.pure_ram = false; + interface_ip.line_sz = data; + interface_ip.cache_sz = data*XML->sys.core[ithCore].archi_Regs_FRF_size; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = out_w*8; + interface_ip.access_mode = 2; + interface_ip.throughput = 1.0/clockRate; + interface_ip.latency = 1.0/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1;//the extra one port is for GCs + interface_ip.num_rd_ports = 2*coredynp.fp_decodeW; + interface_ip.num_wr_ports = coredynp.fp_decodeW; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports= coredynp.fp_decodeW;//actually is fp commit width + fFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, coredynp.opt_local, coredynp.core_ty); + fFRAT->local_result.adjust_area(); + fFRAT->area.set_area(fFRAT->area.get_area()+ fFRAT->local_result.area*XML->sys.core[ithCore].number_hardware_threads); + area.set_area(area.get_area()+ fFRAT->area.get_area()); + + } + else if ((coredynp.rm_ty ==CAMbased)) + { + //FRAT + tag = coredynp.arch_ireg_width; + data = int(ceil (coredynp.arch_ireg_width+1*coredynp.globalCheckpoint/8.0));//the address of CAM needed to be sent out + out_w = int(ceil (coredynp.arch_ireg_width/8.0)); + interface_ip.is_cache = true; + interface_ip.pure_cam = false; + interface_ip.pure_ram = false; + interface_ip.line_sz = data; + interface_ip.cache_sz = data*XML->sys.core[ithCore].phy_Regs_IRF_size; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = out_w*8; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.access_mode = 2; + interface_ip.throughput = 1.0/clockRate; + interface_ip.latency = 1.0/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1;//for GCs + interface_ip.num_rd_ports = XML->sys.core[ithCore].decode_width;//0;TODO + interface_ip.num_wr_ports = XML->sys.core[ithCore].decode_width; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports= 2*XML->sys.core[ithCore].decode_width; + iFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, coredynp.opt_local, coredynp.core_ty); + iFRAT->area.set_area(iFRAT->area.get_area()+ iFRAT->local_result.area*XML->sys.core[ithCore].number_hardware_threads); + area.set_area(area.get_area()+ iFRAT->area.get_area()); + + //FRAT + tag = coredynp.arch_freg_width; + data = int(ceil (coredynp.arch_freg_width+1*coredynp.globalCheckpoint/8.0));//the address of CAM needed to be sent out + out_w = int(ceil (coredynp.arch_freg_width/8.0)); + interface_ip.is_cache = true; + interface_ip.pure_cam = false; + interface_ip.pure_ram = false; + interface_ip.line_sz = data; + interface_ip.cache_sz = data*XML->sys.core[ithCore].phy_Regs_FRF_size; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = out_w*8; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.access_mode = 2; + interface_ip.throughput = 1.0/clockRate; + interface_ip.latency = 1.0/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1;//for GCs + interface_ip.num_rd_ports = XML->sys.core[ithCore].decode_width;//0;TODO; + interface_ip.num_wr_ports = coredynp.fp_decodeW; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports= 2*coredynp.fp_decodeW; + fFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, coredynp.opt_local, coredynp.core_ty); + fFRAT->area.set_area(fFRAT->area.get_area()+ fFRAT->local_result.area*XML->sys.core[ithCore].number_hardware_threads); + area.set_area(area.get_area()+ fFRAT->area.get_area()); + + } + //No RRAT for RS based OOO + //Freelist of renaming unit of RS based OOO is unifed for both int and fp renaming unit since the ROB is unified + data = int(ceil(coredynp.phy_ireg_width/8.0)); + interface_ip.is_cache = false; + interface_ip.pure_cam = false; + interface_ip.pure_ram = true; + interface_ip.line_sz = data; + interface_ip.cache_sz = data*coredynp.num_ifreelist_entries; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 1; + interface_ip.throughput = 1.0/clockRate; + interface_ip.latency = 1.0/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1;//TODO + interface_ip.num_rd_ports = XML->sys.core[ithCore].decode_width; + interface_ip.num_wr_ports = XML->sys.core[ithCore].decode_width -1 + XML->sys.core[ithCore].commit_width; + interface_ip.num_se_rd_ports = 0; + ifreeL = new ArrayST(&interface_ip, "Unified Free List", Core_device, coredynp.opt_local, coredynp.core_ty); + ifreeL->area.set_area(ifreeL->area.get_area()+ ifreeL->local_result.area*XML->sys.core[ithCore].number_hardware_threads); + area.set_area(area.get_area()+ ifreeL->area.get_area()); + + idcl = new dep_resource_conflict_check(&interface_ip,coredynp,coredynp.phy_ireg_width);//TODO:Separate 2 sections See TR + fdcl = new dep_resource_conflict_check(&interface_ip,coredynp,coredynp.phy_freg_width); + } - // RRAT is always RAM based, does not have GCs, and is used only for - // record latest non-speculative mapping - data = int(ceil(coredynp.phy_ireg_width / 8.0)); - interface_ip.is_cache = false; - interface_ip.pure_cam = false; - interface_ip.pure_ram = true; - interface_ip.line_sz = data; - interface_ip.cache_sz = data * - XML->sys.core[ithCore].archi_Regs_IRF_size * - 2; // HACK to make it as least 64B - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 1; - interface_ip.throughput = 1.0 / clockRate; - interface_ip.latency = 1.0 / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = XML->sys.core[ithCore].commit_width; - interface_ip.num_wr_ports = XML->sys.core[ithCore].commit_width; - interface_ip.num_se_rd_ports = 0; - iRRAT = new ArrayST(&interface_ip, "Int RetireRAT", Core_device, - coredynp.opt_local, coredynp.core_ty); - iRRAT->area.set_area(iRRAT->area.get_area() + - iRRAT->local_result.area * - XML->sys.core[ithCore].number_hardware_threads); - area.set_area(area.get_area() + iRRAT->area.get_area()); - - // RRAT for FP - data = int(ceil(coredynp.phy_freg_width / 8.0)); - interface_ip.is_cache = false; - interface_ip.pure_cam = false; - interface_ip.pure_ram = true; - interface_ip.line_sz = data; - interface_ip.cache_sz = data * - XML->sys.core[ithCore].archi_Regs_FRF_size * - 2; // HACK to make it as least 64B - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 1; - interface_ip.throughput = 1.0 / clockRate; - interface_ip.latency = 1.0 / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = coredynp.fp_decodeW; - interface_ip.num_wr_ports = coredynp.fp_decodeW; - interface_ip.num_se_rd_ports = 0; - fRRAT = new ArrayST(&interface_ip, "Int RetireRAT", Core_device, - coredynp.opt_local, coredynp.core_ty); - fRRAT->area.set_area(fRRAT->area.get_area() + - fRRAT->local_result.area * - XML->sys.core[ithCore].number_hardware_threads); - area.set_area(area.get_area() + fRRAT->area.get_area()); - - // Freelist of renaming unit always RAM based - // Recycle happens at two places: 1)when DCL check there are WAW, the - // Phyregisters/ROB directly recycles into freelist - // 2)When instruction commits the Phyregisters/ROB needed to be recycled. - // therefore num_wr port = decode-1(-1 means at least one phy reg will be - // used for the current renaming group) + commit width - data = int(ceil(coredynp.phy_ireg_width / 8.0)); - interface_ip.is_cache = false; - interface_ip.pure_cam = false; - interface_ip.pure_ram = true; - interface_ip.line_sz = data; - interface_ip.cache_sz = data * coredynp.num_ifreelist_entries; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 1; - interface_ip.throughput = 1.0 / clockRate; - interface_ip.latency = 1.0 / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; // TODO - interface_ip.num_rd_ports = coredynp.decodeW; - interface_ip.num_wr_ports = - coredynp.decodeW - 1 + XML->sys.core[ithCore].commit_width; - // every cycle, (coredynp.decodeW -1) inst may need to send back it dest - // tags, committW insts needs to update freelist buffers - interface_ip.num_se_rd_ports = 0; - ifreeL = new ArrayST(&interface_ip, "Int Free List", Core_device, - coredynp.opt_local, coredynp.core_ty); - ifreeL->area.set_area(ifreeL->area.get_area() + - ifreeL->local_result.area * - XML->sys.core[ithCore].number_hardware_threads); - area.set_area(area.get_area() + ifreeL->area.get_area()); - - // freelist for FP - data = int(ceil(coredynp.phy_freg_width / 8.0)); - interface_ip.is_cache = false; - interface_ip.pure_cam = false; - interface_ip.pure_ram = true; - interface_ip.line_sz = data; - interface_ip.cache_sz = data * coredynp.num_ffreelist_entries; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 1; - interface_ip.throughput = 1.0 / clockRate; - interface_ip.latency = 1.0 / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; - interface_ip.num_rd_ports = coredynp.fp_decodeW; - interface_ip.num_wr_ports = - coredynp.fp_decodeW - 1 + XML->sys.core[ithCore].commit_width; - interface_ip.num_se_rd_ports = 0; - ffreeL = new ArrayST(&interface_ip, "Int Free List", Core_device, - coredynp.opt_local, coredynp.core_ty); - ffreeL->area.set_area(ffreeL->area.get_area() + - ffreeL->local_result.area * - XML->sys.core[ithCore].number_hardware_threads); - area.set_area(area.get_area() + ffreeL->area.get_area()); - - idcl = new dep_resource_conflict_check( - &interface_ip, coredynp, - coredynp.phy_ireg_width); // TODO:Separate 2 sections See TR - fdcl = new dep_resource_conflict_check(&interface_ip, coredynp, - coredynp.phy_freg_width); - - } else if (coredynp.scheu_ty == ReservationStation) { - if (coredynp.rm_ty == RAMbased) { - /* - * however, RAT needs to do associative search in RAT, when instruction - * commits and ROB release the entry, - * to make sure all the renamings associated with the ROB to be released - * are updated to ARF at the same time. - * RAM based RAT for RS base OOO does not save the search operations. - * Its advantage is to have less entries than - * CAM based RAT so that it is more scalable as number of ROB/physical - * regs increases. - */ - tag = coredynp.phy_ireg_width; - data = int(ceil(coredynp.phy_ireg_width * - (1 + coredynp.globalCheckpoint) / 8.0)); - out_w = int(ceil(coredynp.phy_ireg_width / 8.0)); - interface_ip.is_cache = true; - interface_ip.pure_cam = false; - interface_ip.pure_ram = false; - interface_ip.line_sz = data; - interface_ip.cache_sz = - data * XML->sys.core[ithCore].archi_Regs_IRF_size; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = out_w * 8; - interface_ip.access_mode = 2; - interface_ip.throughput = 1.0 / clockRate; - interface_ip.latency = 1.0 / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; // the extra one port is for GCs - interface_ip.num_rd_ports = 2 * coredynp.decodeW; - interface_ip.num_wr_ports = coredynp.decodeW; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = coredynp.commitW; // TODO - iFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, - coredynp.opt_local, coredynp.core_ty); - iFRAT->local_result.adjust_area(); - iFRAT->area.set_area( - iFRAT->area.get_area() + - iFRAT->local_result.area * - XML->sys.core[ithCore].number_hardware_threads); - area.set_area(area.get_area() + iFRAT->area.get_area()); - - // FP - tag = coredynp.phy_freg_width; - data = int(ceil(coredynp.phy_freg_width * - (1 + coredynp.globalCheckpoint) / 8.0)); - out_w = int(ceil(coredynp.phy_freg_width / 8.0)); - interface_ip.is_cache = true; - interface_ip.pure_cam = false; - interface_ip.pure_ram = false; - interface_ip.line_sz = data; - interface_ip.cache_sz = - data * XML->sys.core[ithCore].archi_Regs_FRF_size; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = out_w * 8; - interface_ip.access_mode = 2; - interface_ip.throughput = 1.0 / clockRate; - interface_ip.latency = 1.0 / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; // the extra one port is for GCs - interface_ip.num_rd_ports = 2 * coredynp.fp_decodeW; - interface_ip.num_wr_ports = coredynp.fp_decodeW; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = - coredynp.fp_decodeW; // actually is fp commit width - fFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, - coredynp.opt_local, coredynp.core_ty); - fFRAT->local_result.adjust_area(); - fFRAT->area.set_area( - fFRAT->area.get_area() + - fFRAT->local_result.area * - XML->sys.core[ithCore].number_hardware_threads); - area.set_area(area.get_area() + fFRAT->area.get_area()); - - } else if ((coredynp.rm_ty == CAMbased)) { - // FRAT - tag = coredynp.arch_ireg_width; - data = int(ceil(coredynp.arch_ireg_width + - 1 * coredynp.globalCheckpoint / - 8.0)); // the address of CAM needed to be sent out - out_w = int(ceil(coredynp.arch_ireg_width / 8.0)); - interface_ip.is_cache = true; - interface_ip.pure_cam = false; - interface_ip.pure_ram = false; - interface_ip.line_sz = data; - interface_ip.cache_sz = data * XML->sys.core[ithCore].phy_Regs_IRF_size; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = out_w * 8; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.access_mode = 2; - interface_ip.throughput = 1.0 / clockRate; - interface_ip.latency = 1.0 / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; // for GCs - interface_ip.num_rd_ports = - XML->sys.core[ithCore].decode_width; // 0;TODO - interface_ip.num_wr_ports = XML->sys.core[ithCore].decode_width; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = 2 * XML->sys.core[ithCore].decode_width; - iFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, - coredynp.opt_local, coredynp.core_ty); - iFRAT->area.set_area( - iFRAT->area.get_area() + - iFRAT->local_result.area * - XML->sys.core[ithCore].number_hardware_threads); - area.set_area(area.get_area() + iFRAT->area.get_area()); - - // FRAT - tag = coredynp.arch_freg_width; - data = int(ceil(coredynp.arch_freg_width + - 1 * coredynp.globalCheckpoint / - 8.0)); // the address of CAM needed to be sent out - out_w = int(ceil(coredynp.arch_freg_width / 8.0)); - interface_ip.is_cache = true; - interface_ip.pure_cam = false; - interface_ip.pure_ram = false; - interface_ip.line_sz = data; - interface_ip.cache_sz = data * XML->sys.core[ithCore].phy_Regs_FRF_size; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = out_w * 8; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.access_mode = 2; - interface_ip.throughput = 1.0 / clockRate; - interface_ip.latency = 1.0 / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; // for GCs - interface_ip.num_rd_ports = - XML->sys.core[ithCore].decode_width; // 0;TODO; - interface_ip.num_wr_ports = coredynp.fp_decodeW; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = 2 * coredynp.fp_decodeW; - fFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, - coredynp.opt_local, coredynp.core_ty); - fFRAT->area.set_area( - fFRAT->area.get_area() + - fFRAT->local_result.area * - XML->sys.core[ithCore].number_hardware_threads); - area.set_area(area.get_area() + fFRAT->area.get_area()); - } - // No RRAT for RS based OOO - // Freelist of renaming unit of RS based OOO is unifed for both int and fp - // renaming unit since the ROB is unified - data = int(ceil(coredynp.phy_ireg_width / 8.0)); - interface_ip.is_cache = false; - interface_ip.pure_cam = false; - interface_ip.pure_ram = true; - interface_ip.line_sz = data; - interface_ip.cache_sz = data * coredynp.num_ifreelist_entries; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 1; - interface_ip.throughput = 1.0 / clockRate; - interface_ip.latency = 1.0 / clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; // TODO - interface_ip.num_rd_ports = XML->sys.core[ithCore].decode_width; - interface_ip.num_wr_ports = XML->sys.core[ithCore].decode_width - 1 + - XML->sys.core[ithCore].commit_width; - interface_ip.num_se_rd_ports = 0; - ifreeL = new ArrayST(&interface_ip, "Unified Free List", Core_device, - coredynp.opt_local, coredynp.core_ty); - ifreeL->area.set_area(ifreeL->area.get_area() + - ifreeL->local_result.area * - XML->sys.core[ithCore].number_hardware_threads); - area.set_area(area.get_area() + ifreeL->area.get_area()); - - idcl = new dep_resource_conflict_check( - &interface_ip, coredynp, - coredynp.phy_ireg_width); // TODO:Separate 2 sections See TR - fdcl = new dep_resource_conflict_check(&interface_ip, coredynp, - coredynp.phy_freg_width); +} + if (coredynp.core_ty==Inorder&& coredynp.issueW>1) + { + /* Dependency check logic will only present when decode(issue) width>1. + * Multiple issue in order processor can do without renaming, but dcl is a must. + */ + idcl = new dep_resource_conflict_check(&interface_ip,coredynp,coredynp.phy_ireg_width);//TODO:Separate 2 sections See TR + fdcl = new dep_resource_conflict_check(&interface_ip,coredynp,coredynp.phy_freg_width); } - } - if (coredynp.core_ty == Inorder && coredynp.issueW > 1) { - /* Dependency check logic will only present when decode(issue) width>1. - * Multiple issue in order processor can do without renaming, but dcl is a - * must. - */ - idcl = new dep_resource_conflict_check( - &interface_ip, coredynp, - coredynp.phy_ireg_width); // TODO:Separate 2 sections See TR - fdcl = new dep_resource_conflict_check(&interface_ip, coredynp, - coredynp.phy_freg_width); - } } Core::Core(ParseXML* XML_interface, int ithCore_, InputParameter* interface_ip_) - : XML(XML_interface), - ithCore(ithCore_), - interface_ip(*interface_ip_), - ifu(0), - lsu(0), - mmu(0), - exu(0), - rnu(0), - corepipe(0), - undiffCore(0), - l2cache(0) { - /** - * Testing: (to be removed) added by syed - */ - // XML->sys.core[ithCore].simd_width=8;// (8) - // XML->sys.core[ithCore].collector_units=4;// (4) - // XML->sys.core[ithCore].core_clock_ratio=2.0;// (2.0) - // XML->sys.core[ithCore].warp_size=32;// (32) - +:XML(XML_interface), + ithCore(ithCore_), + interface_ip(*interface_ip_), + ifu (0), + lsu (0), + mmu (0), + exu (0), + rnu (0), + corepipe (0), + undiffCore (0), + l2cache (0) +{ + /** + * Testing: (to be removed) added by syed + */ + //XML->sys.core[ithCore].simd_width=8;// (8) + //XML->sys.core[ithCore].collector_units=4;// (4) + //XML->sys.core[ithCore].core_clock_ratio=2.0;// (2.0) + //XML->sys.core[ithCore].warp_size=32;// (32) + /* * initialize, compute and optimize individual components. */ - IdleCoreEnergy = 0; - IdlePower_PerCore = 0; + IdleCoreEnergy=0; + IdlePower_PerCore = 0; double pipeline_area_per_unit; - if (XML->sys.Private_L2) { - l2cache = new SharedCache(XML, ithCore, &interface_ip); + if (XML->sys.Private_L2) + { + l2cache = new SharedCache(XML,ithCore, &interface_ip); + } - // interface_ip.wire_is_mat_type = 2; - // interface_ip.wire_os_mat_type = 2; - // interface_ip.wt =Global_30; +// interface_ip.wire_is_mat_type = 2; +// interface_ip.wire_os_mat_type = 2; +// interface_ip.wt =Global_30; set_core_param(); clockRate = coredynp.clockRate; - exClockRate = clockRate * XML->sys.core[ithCore].core_clock_ratio; + exClockRate = clockRate*XML->sys.core[ithCore].core_clock_ratio; executionTime = coredynp.executionTime; - ifu = new InstFetchU(XML, ithCore, &interface_ip, coredynp); - lsu = new LoadStoreU(XML, ithCore, &interface_ip, coredynp); - mmu = new MemManU(XML, ithCore, &interface_ip, coredynp); - exu = new EXECU(XML, ithCore, &interface_ip, lsu->lsq_height, coredynp, - exClockRate, true); - - undiffCore = new UndiffCore(XML, ithCore, &interface_ip, coredynp); - if (coredynp.core_ty == OOO) { - rnu = new RENAMINGU(XML, ithCore, &interface_ip, coredynp); - } - corepipe = new Pipeline(&interface_ip, coredynp); + ifu = new InstFetchU(XML, ithCore, &interface_ip,coredynp); + lsu = new LoadStoreU(XML, ithCore, &interface_ip,coredynp); + mmu = new MemManU (XML, ithCore, &interface_ip,coredynp); + exu = new EXECU (XML, ithCore, &interface_ip,lsu->lsq_height, coredynp, exClockRate,true); + - if (coredynp.core_ty == OOO) { - pipeline_area_per_unit = - (corepipe->area.get_area() * coredynp.num_pipelines) / 5.0; - if (rnu->exist) { - rnu->area.set_area(rnu->area.get_area() + pipeline_area_per_unit); - } - } else { - pipeline_area_per_unit = - (corepipe->area.get_area() * coredynp.num_pipelines) / 4.0; - } - // area.set_area(area.get_area()+ corepipe->area.get_area()); - if (ifu->exist) { - ifu->area.set_area(ifu->area.get_area() + pipeline_area_per_unit); - area.set_area(area.get_area() + ifu->area.get_area()); - } - if (lsu->exist) { - lsu->area.set_area(lsu->area.get_area() + pipeline_area_per_unit); - area.set_area(area.get_area() + lsu->area.get_area()); + + + undiffCore = new UndiffCore(XML, ithCore, &interface_ip,coredynp); + if (coredynp.core_ty==OOO) + { + rnu = new RENAMINGU(XML, ithCore, &interface_ip,coredynp); } - if (exu->exist) { - exu->area.set_area(exu->area.get_area() + pipeline_area_per_unit); - area.set_area(area.get_area() + exu->area.get_area()); + corepipe = new Pipeline(&interface_ip,coredynp); + + if (coredynp.core_ty==OOO) + { + pipeline_area_per_unit = (corepipe->area.get_area()*coredynp.num_pipelines)/5.0; + if (rnu->exist) + { + rnu->area.set_area(rnu->area.get_area() + pipeline_area_per_unit); + } } - if (mmu->exist) { - mmu->area.set_area(mmu->area.get_area() + pipeline_area_per_unit); - area.set_area(area.get_area() + mmu->area.get_area()); + else { + pipeline_area_per_unit = (corepipe->area.get_area()*coredynp.num_pipelines)/4.0; } - if (coredynp.core_ty == OOO) { - if (rnu->exist) { - area.set_area(area.get_area() + rnu->area.get_area()); - } + //area.set_area(area.get_area()+ corepipe->area.get_area()); + if (ifu->exist) + { + ifu->area.set_area(ifu->area.get_area() + pipeline_area_per_unit); + area.set_area(area.get_area() + ifu->area.get_area()); } - - if (undiffCore->exist) { - area.set_area(area.get_area() + undiffCore->area.get_area()); + if (lsu->exist) + { + lsu->area.set_area(lsu->area.get_area() + pipeline_area_per_unit); + area.set_area(area.get_area() + lsu->area.get_area()); } - - if (XML->sys.Private_L2) { - area.set_area(area.get_area() + l2cache->area.get_area()); + if (exu->exist) + { + exu->area.set_area(exu->area.get_area() + pipeline_area_per_unit); + area.set_area(area.get_area()+exu->area.get_area()); } - // //clock power - // clockNetwork.init_wire_external(is_default, &interface_ip); - // clockNetwork.clk_area =area*1.1;//10% of placement overhead. - // rule of thumb - // clockNetwork.end_wiring_level =5;//toplevel metal - // clockNetwork.start_wiring_level =5;//toplevel metal - // clockNetwork.num_regs = corepipe.tot_stage_vector; - // clockNetwork.optimize_wire(); -} - -void BranchPredictor::computeEnergy(bool is_tdp) { - if (!exist) return; - double r_access; - double w_access; - if (is_tdp) { - r_access = coredynp.predictionW * coredynp.BR_duty_cycle; - w_access = 0 * coredynp.BR_duty_cycle; - globalBPT->stats_t.readAc.access = r_access; - globalBPT->stats_t.writeAc.access = w_access; - globalBPT->tdp_stats = globalBPT->stats_t; - - L1_localBPT->stats_t.readAc.access = r_access; - L1_localBPT->stats_t.writeAc.access = w_access; - L1_localBPT->tdp_stats = L1_localBPT->stats_t; - - L2_localBPT->stats_t.readAc.access = r_access; - L2_localBPT->stats_t.writeAc.access = w_access; - L2_localBPT->tdp_stats = L2_localBPT->stats_t; - - chooser->stats_t.readAc.access = r_access; - chooser->stats_t.writeAc.access = w_access; - chooser->tdp_stats = chooser->stats_t; - - RAS->stats_t.readAc.access = r_access; - RAS->stats_t.writeAc.access = w_access; - RAS->tdp_stats = RAS->stats_t; - } else { - // The resolution of BPT accesses is coarse, but this is - // because most simulators cannot track finer grained details - r_access = XML->sys.core[ithCore].branch_instructions; - w_access = - XML->sys.core[ithCore].branch_mispredictions + - 0.1 * - XML->sys.core[ithCore] - .branch_instructions; // 10% of BR will flip internal bits//0 - globalBPT->stats_t.readAc.access = r_access; - globalBPT->stats_t.writeAc.access = w_access; - globalBPT->rtp_stats = globalBPT->stats_t; - - L1_localBPT->stats_t.readAc.access = r_access; - L1_localBPT->stats_t.writeAc.access = w_access; - L1_localBPT->rtp_stats = L1_localBPT->stats_t; - - L2_localBPT->stats_t.readAc.access = r_access; - L2_localBPT->stats_t.writeAc.access = w_access; - L2_localBPT->rtp_stats = L2_localBPT->stats_t; - - chooser->stats_t.readAc.access = r_access; - chooser->stats_t.writeAc.access = w_access; - chooser->rtp_stats = chooser->stats_t; - - RAS->stats_t.readAc.access = XML->sys.core[ithCore].function_calls; - RAS->stats_t.writeAc.access = XML->sys.core[ithCore].function_calls; - RAS->rtp_stats = RAS->stats_t; + if (mmu->exist) + { + mmu->area.set_area(mmu->area.get_area() + pipeline_area_per_unit); + area.set_area(area.get_area()+mmu->area.get_area()); } - globalBPT->power_t.reset(); - L1_localBPT->power_t.reset(); - L2_localBPT->power_t.reset(); - chooser->power_t.reset(); - RAS->power_t.reset(); - - globalBPT->power_t.readOp.dynamic += - globalBPT->local_result.power.readOp.dynamic * - globalBPT->stats_t.readAc.access + - globalBPT->stats_t.writeAc.access * - globalBPT->local_result.power.writeOp.dynamic; - L1_localBPT->power_t.readOp.dynamic += - L1_localBPT->local_result.power.readOp.dynamic * - L1_localBPT->stats_t.readAc.access + - L1_localBPT->stats_t.writeAc.access * - L1_localBPT->local_result.power.writeOp.dynamic; - - L2_localBPT->power_t.readOp.dynamic += - L2_localBPT->local_result.power.readOp.dynamic * - L2_localBPT->stats_t.readAc.access + - L2_localBPT->stats_t.writeAc.access * - L2_localBPT->local_result.power.writeOp.dynamic; - - chooser->power_t.readOp.dynamic += - chooser->local_result.power.readOp.dynamic * - chooser->stats_t.readAc.access + - chooser->stats_t.writeAc.access * - chooser->local_result.power.writeOp.dynamic; - RAS->power_t.readOp.dynamic += - RAS->local_result.power.readOp.dynamic * RAS->stats_t.readAc.access + - RAS->stats_t.writeAc.access * RAS->local_result.power.writeOp.dynamic; - - if (is_tdp) { - globalBPT->power = - globalBPT->power_t + globalBPT->local_result.power * pppm_lkg; - L1_localBPT->power = - L1_localBPT->power_t + L1_localBPT->local_result.power * pppm_lkg; - L2_localBPT->power = - L2_localBPT->power_t + L2_localBPT->local_result.power * pppm_lkg; - chooser->power = chooser->power_t + chooser->local_result.power * pppm_lkg; - RAS->power = - RAS->power_t + RAS->local_result.power * coredynp.pppm_lkg_multhread; - - power = power + globalBPT->power + L1_localBPT->power + chooser->power + - RAS->power; - } else { - globalBPT->rt_power = - globalBPT->power_t + globalBPT->local_result.power * pppm_lkg; - L1_localBPT->rt_power = - L1_localBPT->power_t + L1_localBPT->local_result.power * pppm_lkg; - L2_localBPT->rt_power = - L2_localBPT->power_t + L2_localBPT->local_result.power * pppm_lkg; - chooser->rt_power = - chooser->power_t + chooser->local_result.power * pppm_lkg; - RAS->rt_power = - RAS->power_t + RAS->local_result.power * coredynp.pppm_lkg_multhread; - rt_power = rt_power + globalBPT->rt_power + L1_localBPT->rt_power + - chooser->rt_power + RAS->rt_power; - } -} + if (coredynp.core_ty==OOO) + { + if (rnu->exist) + { -void BranchPredictor::displayEnergy(uint32_t indent, int plevel, bool is_tdp) { - if (!exist) return; - string indent_str(indent, ' '); - string indent_str_next(indent + 2, ' '); - bool long_channel = XML->sys.longer_channel_device; - if (is_tdp) { - cout << indent_str << "Global Predictor:" << endl; - cout << indent_str_next << "Area = " << globalBPT->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << globalBPT->power.readOp.dynamic * clockRate - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? globalBPT->power.readOp.longer_channel_leakage - : globalBPT->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << globalBPT->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << globalBPT->rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << endl; - cout << indent_str << "Local Predictor:" << endl; - cout << indent_str << "L1_Local Predictor:" << endl; - cout << indent_str_next << "Area = " << L1_localBPT->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << L1_localBPT->power.readOp.dynamic * clockRate - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? L1_localBPT->power.readOp.longer_channel_leakage - : L1_localBPT->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << L1_localBPT->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << L1_localBPT->rt_power.readOp.dynamic / executionTime << " W" - << endl; - cout << endl; - cout << indent_str << "L2_Local Predictor:" << endl; - cout << indent_str_next << "Area = " << L2_localBPT->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << L2_localBPT->power.readOp.dynamic * clockRate - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? L2_localBPT->power.readOp.longer_channel_leakage - : L2_localBPT->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << L2_localBPT->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << L2_localBPT->rt_power.readOp.dynamic / executionTime << " W" - << endl; - cout << endl; - - cout << indent_str << "Chooser:" << endl; - cout << indent_str_next << "Area = " << chooser->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << chooser->power.readOp.dynamic * clockRate - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? chooser->power.readOp.longer_channel_leakage - : chooser->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << chooser->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << chooser->rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << endl; - cout << indent_str << "RAS:" << endl; - cout << indent_str_next << "Area = " << RAS->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << RAS->power.readOp.dynamic * clockRate << " W" - << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? RAS->power.readOp.longer_channel_leakage - : RAS->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << RAS->power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next - << "Runtime Dynamic = " << RAS->rt_power.readOp.dynamic / executionTime - << " W" << endl; - cout << endl; - } else { - // cout << indent_str_next << "Global Predictor Peak Dynamic = " << - //globalBPT->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Global Predictor Subthreshold Leakage = - //" << globalBPT->rt_power.readOp.leakage <<" W" << endl; - // cout << indent_str_next << "Global Predictor Gate Leakage = " << - //globalBPT->rt_power.readOp.gate_leakage << " W" << endl; - // cout << indent_str_next << "Local Predictor Peak Dynamic = " << - //L1_localBPT->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Local Predictor Subthreshold Leakage = " - //<< L1_localBPT->rt_power.readOp.leakage << " W" << endl; - // cout << indent_str_next << "Local Predictor Gate Leakage = " << - //L1_localBPT->rt_power.readOp.gate_leakage << " W" << endl; - // cout << indent_str_next << "Chooser Peak Dynamic = " << - //chooser->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Chooser Subthreshold Leakage = " << - //chooser->rt_power.readOp.leakage << " W" << endl; - // cout << indent_str_next << "Chooser Gate Leakage = " << - //chooser->rt_power.readOp.gate_leakage << " W" << endl; - // cout << indent_str_next << "RAS Peak Dynamic = " << - //RAS->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "RAS Subthreshold Leakage = " << - //RAS->rt_power.readOp.leakage << " W" << endl; - // cout << indent_str_next << "RAS Gate Leakage = " << - //RAS->rt_power.readOp.gate_leakage << " W" << endl; + area.set_area(area.get_area() + rnu->area.get_area()); + } } -} -void InstFetchU::computeEnergy(bool is_tdp) { - executionTime = - XML->sys.total_cycles / (XML->sys.target_core_clockrate * 1e6); // Syed - // cout <<"IFU: execution time: - // "<sys.total_cycles/(XML->sys.target_core_clockrate*1e6)<sys.total_cycles<stats_t.readAc.access = - icache.caches->l_ip.num_rw_ports * coredynp.IFU_duty_cycle; - icache.caches->stats_t.readAc.miss = 0; - icache.caches->stats_t.readAc.hit = icache.caches->stats_t.readAc.access - - icache.caches->stats_t.readAc.miss; - icache.caches->tdp_stats = icache.caches->stats_t; - - icache.missb->stats_t.readAc.access = icache.missb->stats_t.readAc.hit = - icache.missb->l_ip.num_search_ports; - icache.missb->stats_t.writeAc.access = icache.missb->stats_t.writeAc.hit = - icache.missb->l_ip.num_search_ports; - icache.missb->tdp_stats = icache.missb->stats_t; - - icache.ifb->stats_t.readAc.access = icache.ifb->stats_t.readAc.hit = - icache.ifb->l_ip.num_search_ports; - icache.ifb->stats_t.writeAc.access = icache.ifb->stats_t.writeAc.hit = - icache.ifb->l_ip.num_search_ports; - icache.ifb->tdp_stats = icache.ifb->stats_t; - - icache.prefetchb->stats_t.readAc.access = - icache.prefetchb->stats_t.readAc.hit = - icache.prefetchb->l_ip.num_search_ports; - icache.prefetchb->stats_t.writeAc.access = icache.ifb->stats_t.writeAc.hit = - icache.ifb->l_ip.num_search_ports; - icache.prefetchb->tdp_stats = icache.prefetchb->stats_t; - - IB->stats_t.readAc.access = IB->stats_t.writeAc.access = - XML->sys.core[ithCore].peak_issue_width; - IB->tdp_stats = IB->stats_t; - - if (coredynp.predictionW > 0) { - BTB->stats_t.readAc.access = - coredynp.predictionW; // XML->sys.core[ithCore].BTB.read_accesses; - BTB->stats_t.writeAc.access = - 0; // XML->sys.core[ithCore].BTB.write_accesses; - } - - ID_inst->stats_t.readAc.access = coredynp.decodeW; - ID_operand->stats_t.readAc.access = coredynp.decodeW; - ID_misc->stats_t.readAc.access = coredynp.decodeW; - ID_inst->tdp_stats = ID_inst->stats_t; - ID_operand->tdp_stats = ID_operand->stats_t; - ID_misc->tdp_stats = ID_misc->stats_t; - - } /* if (is_tdp) */ - else { - rt_power.reset(); - icache.rt_power.reset(); // Jingwen - // init stats for Runtime Dynamic (RTP) - // cout<< "****>>>>Icache stats:"<sys.core[ithCore].icache.read_accesses << - // " Read misses: "<sys.core[ithCore].icache.read_misses<stats_t.readAc.access = - XML->sys.core[ithCore].icache.read_accesses; - icache.caches->stats_t.readAc.miss = - XML->sys.core[ithCore].icache.read_misses; - // cout<sys.core[ithCore].icache.read_accesses; - // cout<sys.core[ithCore].icache.read_misses; - - icache.caches->stats_t.readAc.hit = icache.caches->stats_t.readAc.access - - icache.caches->stats_t.readAc.miss; - icache.caches->rtp_stats = icache.caches->stats_t; - // cout<stats_t.readAc.hit<stats_t.readAc.access = icache.caches->stats_t.readAc.miss; - icache.missb->stats_t.writeAc.access = icache.caches->stats_t.readAc.miss; - icache.missb->rtp_stats = icache.missb->stats_t; - - icache.ifb->stats_t.readAc.access = icache.caches->stats_t.readAc.miss; - icache.ifb->stats_t.writeAc.access = icache.caches->stats_t.readAc.miss; - icache.ifb->rtp_stats = icache.ifb->stats_t; - - icache.prefetchb->stats_t.readAc.access = - icache.caches->stats_t.readAc.miss; - icache.prefetchb->stats_t.writeAc.access = - icache.caches->stats_t.readAc.miss; - icache.prefetchb->rtp_stats = icache.prefetchb->stats_t; - - IB->stats_t.readAc.access = IB->stats_t.writeAc.access = - XML->sys.core[ithCore].total_instructions; - IB->rtp_stats = IB->stats_t; - // cout<<"IB: total instructions: "<stats_t.readAc.access < 0) { - BTB->stats_t.readAc.access = - XML->sys.core[ithCore] - .BTB - .read_accesses; // XML->sys.core[ithCore].branch_instructions; - BTB->stats_t.writeAc.access = - XML->sys.core[ithCore] - .BTB - .write_accesses; // XML->sys.core[ithCore].branch_mispredictions; - BTB->rtp_stats = BTB->stats_t; - } - // cout<<"ID: total instructions: "<< - // XML->sys.core[ithCore].total_instructions<stats_t.readAc.access = XML->sys.core[ithCore].total_instructions; - ID_operand->stats_t.readAc.access = - XML->sys.core[ithCore].total_instructions; - ID_misc->stats_t.readAc.access = XML->sys.core[ithCore].total_instructions; - ID_inst->rtp_stats = ID_inst->stats_t; - ID_operand->rtp_stats = ID_operand->stats_t; - ID_misc->rtp_stats = ID_misc->stats_t; + if (undiffCore->exist) + { + area.set_area(area.get_area() + undiffCore->area.get_area()); } - icache.power_t.reset(); - IB->power_t.reset(); - // ID_inst->power_t.reset(); - // ID_operand->power_t.reset(); - // ID_misc->power_t.reset(); - if (coredynp.predictionW > 0) { - BTB->power_t.reset(); - } + if (XML->sys.Private_L2) + { + area.set_area(area.get_area() + l2cache->area.get_area()); - icache.power_t.readOp.dynamic += - (icache.caches->stats_t.readAc.hit * - icache.caches->local_result.power.readOp.dynamic + - // icache.caches->stats_t.readAc.miss*icache.caches->local_result.tag_array2->power.readOp.dynamic+ - icache.caches->stats_t.readAc.miss * - icache.caches->local_result.power.readOp - .dynamic + // assume tag data accessed in parallel - icache.caches->stats_t.readAc.miss * - icache.caches->local_result.power.writeOp - .dynamic); // read miss in Icache cause a write to Icache - icache.power_t.readOp.dynamic += - icache.missb->stats_t.readAc.access * - icache.missb->local_result.power.searchOp.dynamic + - icache.missb->stats_t.writeAc.access * - icache.missb->local_result.power.writeOp - .dynamic; // each access to missb involves a CAM and a write - icache.power_t.readOp.dynamic += - icache.ifb->stats_t.readAc.access * - icache.ifb->local_result.power.searchOp.dynamic + - icache.ifb->stats_t.writeAc.access * - icache.ifb->local_result.power.writeOp.dynamic; - icache.power_t.readOp.dynamic += - icache.prefetchb->stats_t.readAc.access * - icache.prefetchb->local_result.power.searchOp.dynamic + - icache.prefetchb->stats_t.writeAc.access * - icache.prefetchb->local_result.power.writeOp.dynamic; - // cout<<"Icache power: "<power_t.readOp.dynamic += - IB->local_result.power.readOp.dynamic * IB->stats_t.readAc.access + - IB->stats_t.writeAc.access * IB->local_result.power.writeOp.dynamic; - // cout << "IB power: "<power_t.readOp.dynamic< 0) { - BTB->power_t.readOp.dynamic += - BTB->local_result.power.readOp.dynamic * BTB->stats_t.readAc.access + - BTB->stats_t.writeAc.access * BTB->local_result.power.writeOp.dynamic; - - BPT->computeEnergy(is_tdp); } +// //clock power +// clockNetwork.init_wire_external(is_default, &interface_ip); +// clockNetwork.clk_area =area*1.1;//10% of placement overhead. rule of thumb +// clockNetwork.end_wiring_level =5;//toplevel metal +// clockNetwork.start_wiring_level =5;//toplevel metal +// clockNetwork.num_regs = corepipe.tot_stage_vector; +// clockNetwork.optimize_wire(); +} - if (is_tdp) { - // icache.power = icache.power_t + - // (icache.caches->local_result.power)*pppm_lkg + - // (icache.missb->local_result.power + - // icache.ifb->local_result.power + - // icache.prefetchb->local_result.power)*pppm_Isub; - icache.power = - icache.power_t + - (icache.caches->local_result.power + icache.missb->local_result.power + - icache.ifb->local_result.power + - icache.prefetchb->local_result.power) * - pppm_lkg; - - IB->power = IB->power_t + IB->local_result.power * pppm_lkg; - power = power + icache.power + IB->power; - if (coredynp.predictionW > 0) { - BTB->power = BTB->power_t + BTB->local_result.power * pppm_lkg; - power = power + BTB->power + BPT->power; - } - - ID_inst->power_t.readOp.dynamic = ID_inst->power.readOp.dynamic; - ID_operand->power_t.readOp.dynamic = ID_operand->power.readOp.dynamic; - ID_misc->power_t.readOp.dynamic = ID_misc->power.readOp.dynamic; - - ID_inst->power.readOp.dynamic *= ID_inst->tdp_stats.readAc.access; - ID_operand->power.readOp.dynamic *= ID_operand->tdp_stats.readAc.access; - ID_misc->power.readOp.dynamic *= ID_misc->tdp_stats.readAc.access; - power = power + (ID_inst->power + ID_operand->power + ID_misc->power); - } /* if (is_tdp) */ - else { - // icache.rt_power = icache.power_t + - // (icache.caches->local_result.power)*pppm_lkg + - // (icache.missb->local_result.power + - // icache.ifb->local_result.power + - // icache.prefetchb->local_result.power)*pppm_Isub; - - icache.rt_power = - icache.power_t + - (icache.caches->local_result.power + icache.missb->local_result.power + - icache.ifb->local_result.power + - icache.prefetchb->local_result.power) * - pppm_lkg; - - // IB->rt_power = IB->power_t + IB->local_result.power*pppm_lkg; - IB->rt_power.readOp.dynamic = - IB->local_result.power.readOp.dynamic * IB->rtp_stats.readAc.access; - IB->rt_power.readOp.dynamic += - IB->local_result.power.writeOp.dynamic * IB->rtp_stats.writeAc.access; - rt_power = rt_power + icache.rt_power + IB->rt_power; - if (coredynp.predictionW > 0) { - BTB->rt_power = BTB->power_t + BTB->local_result.power * pppm_lkg; - rt_power = rt_power + BTB->rt_power + BPT->rt_power; +void BranchPredictor::computeEnergy(bool is_tdp) +{ + if (!exist) return; + double r_access; + double w_access; + if (is_tdp) + { + r_access = coredynp.predictionW*coredynp.BR_duty_cycle; + w_access = 0*coredynp.BR_duty_cycle; + globalBPT->stats_t.readAc.access = r_access; + globalBPT->stats_t.writeAc.access = w_access; + globalBPT->tdp_stats = globalBPT->stats_t; + + L1_localBPT->stats_t.readAc.access = r_access; + L1_localBPT->stats_t.writeAc.access = w_access; + L1_localBPT->tdp_stats = L1_localBPT->stats_t; + + L2_localBPT->stats_t.readAc.access = r_access; + L2_localBPT->stats_t.writeAc.access = w_access; + L2_localBPT->tdp_stats = L2_localBPT->stats_t; + + chooser->stats_t.readAc.access = r_access; + chooser->stats_t.writeAc.access = w_access; + chooser->tdp_stats = chooser->stats_t; + + RAS->stats_t.readAc.access = r_access; + RAS->stats_t.writeAc.access = w_access; + RAS->tdp_stats = RAS->stats_t; } + else + { + //The resolution of BPT accesses is coarse, but this is + //because most simulators cannot track finer grained details + r_access = XML->sys.core[ithCore].branch_instructions; + w_access = XML->sys.core[ithCore].branch_mispredictions + 0.1*XML->sys.core[ithCore].branch_instructions;//10% of BR will flip internal bits//0 + globalBPT->stats_t.readAc.access = r_access; + globalBPT->stats_t.writeAc.access = w_access; + globalBPT->rtp_stats = globalBPT->stats_t; + + L1_localBPT->stats_t.readAc.access = r_access; + L1_localBPT->stats_t.writeAc.access = w_access; + L1_localBPT->rtp_stats = L1_localBPT->stats_t; + + L2_localBPT->stats_t.readAc.access = r_access; + L2_localBPT->stats_t.writeAc.access = w_access; + L2_localBPT->rtp_stats = L2_localBPT->stats_t; + + chooser->stats_t.readAc.access = r_access; + chooser->stats_t.writeAc.access = w_access; + chooser->rtp_stats = chooser->stats_t; + + RAS->stats_t.readAc.access = XML->sys.core[ithCore].function_calls; + RAS->stats_t.writeAc.access = XML->sys.core[ithCore].function_calls; + RAS->rtp_stats = RAS->stats_t; + } + + globalBPT->power_t.reset(); + L1_localBPT->power_t.reset(); + L2_localBPT->power_t.reset(); + chooser->power_t.reset(); + RAS->power_t.reset(); + + globalBPT->power_t.readOp.dynamic += globalBPT->local_result.power.readOp.dynamic*globalBPT->stats_t.readAc.access + + globalBPT->stats_t.writeAc.access*globalBPT->local_result.power.writeOp.dynamic; + L1_localBPT->power_t.readOp.dynamic += L1_localBPT->local_result.power.readOp.dynamic*L1_localBPT->stats_t.readAc.access + + L1_localBPT->stats_t.writeAc.access*L1_localBPT->local_result.power.writeOp.dynamic; + + L2_localBPT->power_t.readOp.dynamic += L2_localBPT->local_result.power.readOp.dynamic*L2_localBPT->stats_t.readAc.access + + L2_localBPT->stats_t.writeAc.access*L2_localBPT->local_result.power.writeOp.dynamic; + + chooser->power_t.readOp.dynamic += chooser->local_result.power.readOp.dynamic*chooser->stats_t.readAc.access + + chooser->stats_t.writeAc.access*chooser->local_result.power.writeOp.dynamic; + RAS->power_t.readOp.dynamic += RAS->local_result.power.readOp.dynamic*RAS->stats_t.readAc.access + + RAS->stats_t.writeAc.access*RAS->local_result.power.writeOp.dynamic; + + if (is_tdp) + { + globalBPT->power = globalBPT->power_t + globalBPT->local_result.power*pppm_lkg; + L1_localBPT->power = L1_localBPT->power_t + L1_localBPT->local_result.power*pppm_lkg; + L2_localBPT->power = L2_localBPT->power_t + L2_localBPT->local_result.power*pppm_lkg; + chooser->power = chooser->power_t + chooser->local_result.power*pppm_lkg; + RAS->power = RAS->power_t + RAS->local_result.power*coredynp.pppm_lkg_multhread; - ID_inst->rt_power.readOp.dynamic = - ID_inst->power_t.readOp.dynamic * ID_inst->rtp_stats.readAc.access; - ID_operand->rt_power.readOp.dynamic = ID_operand->power_t.readOp.dynamic * - ID_operand->rtp_stats.readAc.access; - ID_misc->rt_power.readOp.dynamic = - ID_misc->power_t.readOp.dynamic * ID_misc->rtp_stats.readAc.access; - - rt_power = rt_power + - (ID_inst->rt_power + ID_operand->rt_power + ID_misc->rt_power); - // cout<<"ID inst: "<rt_power.readOp.dynamic << " ID operand: - // "<rt_power.readOp.dynamic<<" ID misc: - // "<rt_power.readOp.dynamic<sys.longer_channel_device; - - if (is_tdp) { - cout << indent_str << "Instruction Cache:" << endl; - cout << indent_str_next << "Area = " << icache.area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << icache.power.readOp.dynamic * clockRate << " W" - << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? icache.power.readOp.longer_channel_leakage - : icache.power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << icache.power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << icache.rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << endl; - if (coredynp.predictionW > 0) { - cout << indent_str << "Branch Target Buffer:" << endl; - cout << indent_str_next << "Area = " << BTB->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << BTB->power.readOp.dynamic * clockRate << " W" - << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? BTB->power.readOp.longer_channel_leakage - : BTB->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << BTB->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << BTB->rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << endl; - if (BPT->exist) { - cout << indent_str << "Branch Predictor:" << endl; - cout << indent_str_next << "Area = " << BPT->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << BPT->power.readOp.dynamic * clockRate - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? BPT->power.readOp.longer_channel_leakage - : BPT->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << BPT->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << BPT->rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << endl; - if (plevel > 3) { - BPT->displayEnergy(indent + 4, plevel, is_tdp); - } - } + power = power + globalBPT->power + L1_localBPT->power + chooser->power + RAS->power; + } + else + { + globalBPT->rt_power = globalBPT->power_t + globalBPT->local_result.power*pppm_lkg; + L1_localBPT->rt_power = L1_localBPT->power_t + L1_localBPT->local_result.power*pppm_lkg; + L2_localBPT->rt_power = L2_localBPT->power_t + L2_localBPT->local_result.power*pppm_lkg; + chooser->rt_power = chooser->power_t + chooser->local_result.power*pppm_lkg; + RAS->rt_power = RAS->power_t + RAS->local_result.power*coredynp.pppm_lkg_multhread; + rt_power = rt_power + globalBPT->rt_power + L1_localBPT->rt_power + chooser->rt_power + RAS->rt_power; } - cout << indent_str << "Instruction Buffer:" << endl; - cout << indent_str_next << "Area = " << IB->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << IB->power.readOp.dynamic * clockRate << " W" - << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? IB->power.readOp.longer_channel_leakage - : IB->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << IB->power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next - << "Runtime Dynamic = " << IB->rt_power.readOp.dynamic / executionTime - << " W" << endl; - cout << endl; - cout << indent_str << "Instruction Decoder:" << endl; - cout << indent_str_next << "Area = " - << (ID_inst->area.get_area() + ID_operand->area.get_area() + - ID_misc->area.get_area()) * - coredynp.decodeW * 1e-6 - << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " - << (ID_inst->power.readOp.dynamic + ID_operand->power.readOp.dynamic + - ID_misc->power.readOp.dynamic) * - clockRate - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? (ID_inst->power.readOp.longer_channel_leakage + - ID_operand->power.readOp.longer_channel_leakage + - ID_misc->power.readOp.longer_channel_leakage) - : (ID_inst->power.readOp.leakage + - ID_operand->power.readOp.leakage + - ID_misc->power.readOp.leakage)) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << (ID_inst->power.readOp.gate_leakage + - ID_operand->power.readOp.gate_leakage + - ID_misc->power.readOp.gate_leakage) - << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " - << (ID_inst->rt_power.readOp.dynamic + - ID_operand->rt_power.readOp.dynamic + - ID_misc->rt_power.readOp.dynamic) / - executionTime - << " W" << endl; - cout << endl; - } else { - // cout << indent_str_next << "Instruction Cache Peak Dynamic = " << - //icache.rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Instruction Cache Subthreshold Leakage - //= " << icache.rt_power.readOp.leakage <<" W" << endl; - // cout << indent_str_next << "Instruction Cache Gate Leakage = " << - //icache.rt_power.readOp.gate_leakage << " W" << endl; - // cout << indent_str_next << "Instruction Buffer Peak Dynamic = " << - //IB->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Instruction Buffer Subthreshold Leakage - //= " << IB->rt_power.readOp.leakage << " W" << endl; - // cout << indent_str_next << "Instruction Buffer Gate Leakage = " << - //IB->rt_power.readOp.gate_leakage << " W" << endl; - // cout << indent_str_next << "Branch Target Buffer Peak Dynamic = " << - //BTB->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Branch Target Buffer Subthreshold - //Leakage = " << BTB->rt_power.readOp.leakage << " W" << endl; - // cout << indent_str_next << "Branch Target Buffer Gate Leakage = " << - //BTB->rt_power.readOp.gate_leakage << " W" << endl; - // cout << indent_str_next << "Branch Predictor Peak Dynamic = " << - //BPT->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Branch Predictor Subthreshold Leakage = - //" << BPT->rt_power.readOp.leakage << " W" << endl; - // cout << indent_str_next << "Branch Predictor Gate Leakage = " << - //BPT->rt_power.readOp.gate_leakage << " W" << endl; - } } -void RENAMINGU::computeEnergy(bool is_tdp) { - if (!exist) return; - double pppm_t[4] = {1, 1, 1, 1}; - if (is_tdp) { // init stats for Peak - if (coredynp.core_ty == OOO) { - if (coredynp.scheu_ty == PhysicalRegFile) { - if (coredynp.rm_ty == RAMbased) { - iFRAT->stats_t.readAc.access = iFRAT->l_ip.num_rd_ports; - iFRAT->stats_t.writeAc.access = iFRAT->l_ip.num_wr_ports; - iFRAT->tdp_stats = iFRAT->stats_t; - - fFRAT->stats_t.readAc.access = fFRAT->l_ip.num_rd_ports; - fFRAT->stats_t.writeAc.access = fFRAT->l_ip.num_wr_ports; - fFRAT->tdp_stats = fFRAT->stats_t; - - } else if ((coredynp.rm_ty == CAMbased)) { - iFRAT->stats_t.readAc.access = iFRAT->l_ip.num_search_ports; - iFRAT->stats_t.writeAc.access = iFRAT->l_ip.num_wr_ports; - iFRAT->tdp_stats = iFRAT->stats_t; - - fFRAT->stats_t.readAc.access = fFRAT->l_ip.num_search_ports; - fFRAT->stats_t.writeAc.access = fFRAT->l_ip.num_wr_ports; - fFRAT->tdp_stats = fFRAT->stats_t; - } - - iRRAT->stats_t.readAc.access = iRRAT->l_ip.num_rd_ports; - iRRAT->stats_t.writeAc.access = iRRAT->l_ip.num_wr_ports; - iRRAT->tdp_stats = iRRAT->stats_t; - - fRRAT->stats_t.readAc.access = fRRAT->l_ip.num_rd_ports; - fRRAT->stats_t.writeAc.access = fRRAT->l_ip.num_wr_ports; - fRRAT->tdp_stats = fRRAT->stats_t; - - ifreeL->stats_t.readAc.access = - coredynp.decodeW; // ifreeL->l_ip.num_rd_ports;; - ifreeL->stats_t.writeAc.access = - coredynp.decodeW; // ifreeL->l_ip.num_wr_ports; - ifreeL->tdp_stats = ifreeL->stats_t; - - ffreeL->stats_t.readAc.access = - coredynp.decodeW; // ffreeL->l_ip.num_rd_ports; - ffreeL->stats_t.writeAc.access = - coredynp.decodeW; // ffreeL->l_ip.num_wr_ports; - ffreeL->tdp_stats = ffreeL->stats_t; - } else if (coredynp.scheu_ty == ReservationStation) { - if (coredynp.rm_ty == RAMbased) { - iFRAT->stats_t.readAc.access = iFRAT->l_ip.num_rd_ports; - iFRAT->stats_t.writeAc.access = iFRAT->l_ip.num_wr_ports; - iFRAT->stats_t.searchAc.access = iFRAT->l_ip.num_search_ports; - iFRAT->tdp_stats = iFRAT->stats_t; - - fFRAT->stats_t.readAc.access = fFRAT->l_ip.num_rd_ports; - fFRAT->stats_t.writeAc.access = fFRAT->l_ip.num_wr_ports; - fFRAT->stats_t.searchAc.access = fFRAT->l_ip.num_search_ports; - fFRAT->tdp_stats = fFRAT->stats_t; - - } else if ((coredynp.rm_ty == CAMbased)) { - iFRAT->stats_t.readAc.access = iFRAT->l_ip.num_search_ports; - iFRAT->stats_t.writeAc.access = iFRAT->l_ip.num_wr_ports; - iFRAT->tdp_stats = iFRAT->stats_t; - - fFRAT->stats_t.readAc.access = fFRAT->l_ip.num_search_ports; - fFRAT->stats_t.writeAc.access = fFRAT->l_ip.num_wr_ports; - fFRAT->tdp_stats = fFRAT->stats_t; - } - // Unified free list for both int and fp - ifreeL->stats_t.readAc.access = - coredynp.decodeW; // ifreeL->l_ip.num_rd_ports; - ifreeL->stats_t.writeAc.access = - coredynp.decodeW; // ifreeL->l_ip.num_wr_ports; - ifreeL->tdp_stats = ifreeL->stats_t; - } - idcl->stats_t.readAc.access = coredynp.decodeW; - fdcl->stats_t.readAc.access = coredynp.decodeW; - idcl->tdp_stats = idcl->stats_t; - fdcl->tdp_stats = fdcl->stats_t; - } else { - if (coredynp.issueW > 1) { - idcl->stats_t.readAc.access = coredynp.decodeW; - fdcl->stats_t.readAc.access = coredynp.decodeW; - idcl->tdp_stats = idcl->stats_t; - fdcl->tdp_stats = fdcl->stats_t; - } - } +void BranchPredictor::displayEnergy(uint32_t indent,int plevel,bool is_tdp) +{ + if (!exist) return; + string indent_str(indent, ' '); + string indent_str_next(indent+2, ' '); + bool long_channel = XML->sys.longer_channel_device; + if (is_tdp) + { + cout << indent_str<< "Global Predictor:" << endl; + cout << indent_str_next << "Area = " << globalBPT->area.get_area()*1e-6<< " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << globalBPT->power.readOp.dynamic*clockRate << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? globalBPT->power.readOp.longer_channel_leakage:globalBPT->power.readOp.leakage) <<" W" << endl; + cout << indent_str_next << "Gate Leakage = " << globalBPT->power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << globalBPT->rt_power.readOp.dynamic/executionTime << " W" << endl; + cout <stats_t.readAc.access = XML->sys.core[ithCore].rename_reads; - iFRAT->stats_t.writeAc.access = XML->sys.core[ithCore].rename_writes; - iFRAT->rtp_stats = iFRAT->stats_t; - - fFRAT->stats_t.readAc.access = XML->sys.core[ithCore].fp_rename_reads; - fFRAT->stats_t.writeAc.access = - XML->sys.core[ithCore].fp_rename_writes; - fFRAT->rtp_stats = fFRAT->stats_t; - } else if ((coredynp.rm_ty == CAMbased)) { - iFRAT->stats_t.readAc.access = XML->sys.core[ithCore].rename_reads; - iFRAT->stats_t.writeAc.access = XML->sys.core[ithCore].rename_writes; - iFRAT->rtp_stats = iFRAT->stats_t; - - fFRAT->stats_t.readAc.access = XML->sys.core[ithCore].fp_rename_reads; - fFRAT->stats_t.writeAc.access = - XML->sys.core[ithCore].fp_rename_writes; - fFRAT->rtp_stats = fFRAT->stats_t; - } - - iRRAT->stats_t.readAc.access = - XML->sys.core[ithCore].rename_writes; // Hack, should be (context - // switch + branch - // mispredictions)*16 - iRRAT->stats_t.writeAc.access = XML->sys.core[ithCore].rename_writes; - iRRAT->rtp_stats = iRRAT->stats_t; - - fRRAT->stats_t.readAc.access = - XML->sys.core[ithCore].fp_rename_writes; // Hack, should be - // (context switch + - // branch - // mispredictions)*16 - fRRAT->stats_t.writeAc.access = XML->sys.core[ithCore].fp_rename_writes; - fRRAT->rtp_stats = fRRAT->stats_t; - - ifreeL->stats_t.readAc.access = XML->sys.core[ithCore].rename_reads; - ifreeL->stats_t.writeAc.access = - 2 * XML->sys.core[ithCore].rename_writes; - ifreeL->rtp_stats = ifreeL->stats_t; - - ffreeL->stats_t.readAc.access = XML->sys.core[ithCore].fp_rename_reads; - ffreeL->stats_t.writeAc.access = - 2 * XML->sys.core[ithCore].fp_rename_writes; - ffreeL->rtp_stats = ffreeL->stats_t; - } else if (coredynp.scheu_ty == ReservationStation) { - if (coredynp.rm_ty == RAMbased) { - iFRAT->stats_t.readAc.access = XML->sys.core[ithCore].rename_reads; - iFRAT->stats_t.writeAc.access = XML->sys.core[ithCore].rename_writes; - iFRAT->stats_t.searchAc.access = - XML->sys.core[ithCore] - .committed_int_instructions; // hack: not all committed - // instructions use regs. - iFRAT->rtp_stats = iFRAT->stats_t; - - fFRAT->stats_t.readAc.access = XML->sys.core[ithCore].fp_rename_reads; - fFRAT->stats_t.writeAc.access = - XML->sys.core[ithCore].fp_rename_writes; - fFRAT->stats_t.searchAc.access = - XML->sys.core[ithCore].committed_fp_instructions; - fFRAT->rtp_stats = fFRAT->stats_t; - } else if ((coredynp.rm_ty == CAMbased)) { - iFRAT->stats_t.readAc.access = XML->sys.core[ithCore].rename_reads; - iFRAT->stats_t.writeAc.access = XML->sys.core[ithCore].rename_writes; - iFRAT->rtp_stats = iFRAT->stats_t; - - fFRAT->stats_t.readAc.access = XML->sys.core[ithCore].fp_rename_reads; - fFRAT->stats_t.writeAc.access = - XML->sys.core[ithCore].fp_rename_writes; - fFRAT->rtp_stats = fFRAT->stats_t; - } - // Unified free list for both int and fp since the ROB act as physcial - // registers - ifreeL->stats_t.readAc.access = XML->sys.core[ithCore].rename_reads + - XML->sys.core[ithCore].fp_rename_reads; - ifreeL->stats_t.writeAc.access = - 2 * (XML->sys.core[ithCore].rename_writes + - XML->sys.core[ithCore].fp_rename_writes); // HACK: 2-> since - // some of renaming - // in the same group - // are terminated early - ifreeL->rtp_stats = ifreeL->stats_t; - } - idcl->stats_t.readAc.access = 3 * coredynp.decodeW * coredynp.decodeW * - XML->sys.core[ithCore].rename_reads; - fdcl->stats_t.readAc.access = 3 * coredynp.fp_issueW * - coredynp.fp_issueW * - XML->sys.core[ithCore].fp_rename_writes; - idcl->rtp_stats = idcl->stats_t; - fdcl->rtp_stats = fdcl->stats_t; - } else { - if (coredynp.issueW > 1) { - idcl->stats_t.readAc.access = - 2 * XML->sys.core[ithCore].int_instructions; - fdcl->stats_t.readAc.access = XML->sys.core[ithCore].fp_instructions; - idcl->rtp_stats = idcl->stats_t; - fdcl->rtp_stats = fdcl->stats_t; - } - } - } - /* Compute engine */ - if (coredynp.core_ty == OOO) { - if (coredynp.scheu_ty == PhysicalRegFile) { - if (coredynp.rm_ty == RAMbased) { - iFRAT->power_t.reset(); - fFRAT->power_t.reset(); - - iFRAT->power_t.readOp.dynamic += - (iFRAT->stats_t.readAc.access * - (iFRAT->local_result.power.readOp.dynamic + - idcl->power.readOp.dynamic) + - iFRAT->stats_t.writeAc.access * - iFRAT->local_result.power.writeOp.dynamic); - fFRAT->power_t.readOp.dynamic += - (fFRAT->stats_t.readAc.access * - (fFRAT->local_result.power.readOp.dynamic + - fdcl->power.readOp.dynamic) + - fFRAT->stats_t.writeAc.access * - fFRAT->local_result.power.writeOp.dynamic); - } else if ((coredynp.rm_ty == CAMbased)) { - iFRAT->power_t.reset(); - fFRAT->power_t.reset(); - iFRAT->power_t.readOp.dynamic += - (iFRAT->stats_t.readAc.access * - (iFRAT->local_result.power.searchOp.dynamic + - idcl->power.readOp.dynamic) + - iFRAT->stats_t.writeAc.access * - iFRAT->local_result.power.writeOp.dynamic); - fFRAT->power_t.readOp.dynamic += - (fFRAT->stats_t.readAc.access * - (fFRAT->local_result.power.searchOp.dynamic + - fdcl->power.readOp.dynamic) + - fFRAT->stats_t.writeAc.access * - fFRAT->local_result.power.writeOp.dynamic); - } +} - iRRAT->power_t.reset(); - fRRAT->power_t.reset(); - ifreeL->power_t.reset(); - ffreeL->power_t.reset(); - - iRRAT->power_t.readOp.dynamic += - (iRRAT->stats_t.readAc.access * - iRRAT->local_result.power.readOp.dynamic + - iRRAT->stats_t.writeAc.access * - iRRAT->local_result.power.writeOp.dynamic); - fRRAT->power_t.readOp.dynamic += - (fRRAT->stats_t.readAc.access * - fRRAT->local_result.power.readOp.dynamic + - fRRAT->stats_t.writeAc.access * - fRRAT->local_result.power.writeOp.dynamic); - ifreeL->power_t.readOp.dynamic += - (ifreeL->stats_t.readAc.access * - ifreeL->local_result.power.readOp.dynamic + - ifreeL->stats_t.writeAc.access * - ifreeL->local_result.power.writeOp.dynamic); - ffreeL->power_t.readOp.dynamic += - (ffreeL->stats_t.readAc.access * - ffreeL->local_result.power.readOp.dynamic + - ffreeL->stats_t.writeAc.access * - ffreeL->local_result.power.writeOp.dynamic); - - } else if (coredynp.scheu_ty == ReservationStation) { - if (coredynp.rm_ty == RAMbased) { - iFRAT->power_t.reset(); - fFRAT->power_t.reset(); - - iFRAT->power_t.readOp.dynamic += - (iFRAT->stats_t.readAc.access * - (iFRAT->local_result.power.readOp.dynamic + - idcl->power.readOp.dynamic) + - iFRAT->stats_t.writeAc.access * - iFRAT->local_result.power.writeOp.dynamic + - iFRAT->stats_t.searchAc.access * - iFRAT->local_result.power.searchOp.dynamic); - fFRAT->power_t.readOp.dynamic += - (fFRAT->stats_t.readAc.access * - (fFRAT->local_result.power.readOp.dynamic + - fdcl->power.readOp.dynamic) + - fFRAT->stats_t.writeAc.access * - fFRAT->local_result.power.writeOp.dynamic + - fFRAT->stats_t.searchAc.access * - fFRAT->local_result.power.searchOp.dynamic); - } else if ((coredynp.rm_ty == CAMbased)) { - iFRAT->power_t.reset(); - fFRAT->power_t.reset(); - iFRAT->power_t.readOp.dynamic += - (iFRAT->stats_t.readAc.access * - (iFRAT->local_result.power.searchOp.dynamic + - idcl->power.readOp.dynamic) + - iFRAT->stats_t.writeAc.access * - iFRAT->local_result.power.writeOp.dynamic); - fFRAT->power_t.readOp.dynamic += - (fFRAT->stats_t.readAc.access * - (fFRAT->local_result.power.searchOp.dynamic + - fdcl->power.readOp.dynamic) + - fFRAT->stats_t.writeAc.access * - fFRAT->local_result.power.writeOp.dynamic); - } - ifreeL->power_t.reset(); - ifreeL->power_t.readOp.dynamic += - (ifreeL->stats_t.readAc.access * - ifreeL->local_result.power.readOp.dynamic + - ifreeL->stats_t.writeAc.access * - ifreeL->local_result.power.writeOp.dynamic); - } +void InstFetchU::computeEnergy(bool is_tdp) +{ + executionTime=XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6);//Syed + //cout <<"IFU: execution time: "<sys.total_cycles/(XML->sys.target_core_clockrate*1e6)<sys.total_cycles<stats_t.readAc.access = icache.caches->l_ip.num_rw_ports*coredynp.IFU_duty_cycle; + icache.caches->stats_t.readAc.miss = 0; + icache.caches->stats_t.readAc.hit = icache.caches->stats_t.readAc.access - icache.caches->stats_t.readAc.miss; + icache.caches->tdp_stats = icache.caches->stats_t; + + icache.missb->stats_t.readAc.access = icache.missb->stats_t.readAc.hit= icache.missb->l_ip.num_search_ports; + icache.missb->stats_t.writeAc.access = icache.missb->stats_t.writeAc.hit= icache.missb->l_ip.num_search_ports; + icache.missb->tdp_stats = icache.missb->stats_t; + + icache.ifb->stats_t.readAc.access = icache.ifb->stats_t.readAc.hit= icache.ifb->l_ip.num_search_ports; + icache.ifb->stats_t.writeAc.access = icache.ifb->stats_t.writeAc.hit= icache.ifb->l_ip.num_search_ports; + icache.ifb->tdp_stats = icache.ifb->stats_t; + + icache.prefetchb->stats_t.readAc.access = icache.prefetchb->stats_t.readAc.hit= icache.prefetchb->l_ip.num_search_ports; + icache.prefetchb->stats_t.writeAc.access = icache.ifb->stats_t.writeAc.hit= icache.ifb->l_ip.num_search_ports; + icache.prefetchb->tdp_stats = icache.prefetchb->stats_t; + + IB->stats_t.readAc.access = IB->stats_t.writeAc.access = XML->sys.core[ithCore].peak_issue_width; + IB->tdp_stats = IB->stats_t; + + if (coredynp.predictionW>0) + { + BTB->stats_t.readAc.access = coredynp.predictionW;//XML->sys.core[ithCore].BTB.read_accesses; + BTB->stats_t.writeAc.access = 0;//XML->sys.core[ithCore].BTB.write_accesses; + } + + ID_inst->stats_t.readAc.access = coredynp.decodeW; + ID_operand->stats_t.readAc.access = coredynp.decodeW; + ID_misc->stats_t.readAc.access = coredynp.decodeW; + ID_inst->tdp_stats = ID_inst->stats_t; + ID_operand->tdp_stats = ID_operand->stats_t; + ID_misc->tdp_stats = ID_misc->stats_t; + + + + } /* if (is_tdp) */ + else + { + rt_power.reset(); + icache.rt_power.reset(); //Jingwen + //init stats for Runtime Dynamic (RTP) + //cout<< "****>>>>Icache stats:"<sys.core[ithCore].icache.read_accesses << " Read misses: "<sys.core[ithCore].icache.read_misses<stats_t.readAc.access = XML->sys.core[ithCore].icache.read_accesses; + icache.caches->stats_t.readAc.miss = XML->sys.core[ithCore].icache.read_misses; + //cout<stats_t.readAc.access <0) + { + BTB->stats_t.readAc.access = XML->sys.core[ithCore].BTB.read_accesses;//XML->sys.core[ithCore].branch_instructions; + BTB->stats_t.writeAc.access = XML->sys.core[ithCore].BTB.write_accesses;//XML->sys.core[ithCore].branch_mispredictions; + BTB->rtp_stats = BTB->stats_t; + } + //cout<<"ID: total instructions: "<< XML->sys.core[ithCore].total_instructions<stats_t.readAc.access = XML->sys.core[ithCore].total_instructions; + ID_operand->stats_t.readAc.access = XML->sys.core[ithCore].total_instructions; + ID_misc->stats_t.readAc.access = XML->sys.core[ithCore].total_instructions; + ID_inst->rtp_stats = ID_inst->stats_t; + ID_operand->rtp_stats = ID_operand->stats_t; + ID_misc->rtp_stats = ID_misc->stats_t; - } else { - if (coredynp.issueW > 1) { - idcl->power_t.reset(); - fdcl->power_t.reset(); - set_pppm(pppm_t, idcl->stats_t.readAc.access, coredynp.num_hthreads, - coredynp.num_hthreads, idcl->stats_t.readAc.access); - idcl->power_t = idcl->power * pppm_t; - set_pppm(pppm_t, fdcl->stats_t.readAc.access, coredynp.num_hthreads, - coredynp.num_hthreads, idcl->stats_t.readAc.access); - fdcl->power_t = fdcl->power * pppm_t; } - } - // assign value to tpd and rtp - if (is_tdp) { - if (coredynp.core_ty == OOO) { - if (coredynp.scheu_ty == PhysicalRegFile) { - iFRAT->power = - iFRAT->power_t + - (iFRAT->local_result.power) * coredynp.pppm_lkg_multhread + - idcl->power_t; - fFRAT->power = - fFRAT->power_t + - (fFRAT->local_result.power) * coredynp.pppm_lkg_multhread + - fdcl->power_t; - iRRAT->power = iRRAT->power_t + - iRRAT->local_result.power * coredynp.pppm_lkg_multhread; - fRRAT->power = fRRAT->power_t + - fRRAT->local_result.power * coredynp.pppm_lkg_multhread; - ifreeL->power = - ifreeL->power_t + - ifreeL->local_result.power * coredynp.pppm_lkg_multhread; - ffreeL->power = - ffreeL->power_t + - ffreeL->local_result.power * coredynp.pppm_lkg_multhread; - power = power + (iFRAT->power + fFRAT->power) + - (iRRAT->power + fRRAT->power) + (ifreeL->power + ffreeL->power); - } else if (coredynp.scheu_ty == ReservationStation) { - iFRAT->power = - iFRAT->power_t + - (iFRAT->local_result.power) * coredynp.pppm_lkg_multhread + - idcl->power_t; - fFRAT->power = - fFRAT->power_t + - (fFRAT->local_result.power) * coredynp.pppm_lkg_multhread + - fdcl->power_t; - ifreeL->power = - ifreeL->power_t + - ifreeL->local_result.power * coredynp.pppm_lkg_multhread; - power = power + (iFRAT->power + fFRAT->power) + ifreeL->power; - } - } else { - power = power + idcl->power_t + fdcl->power_t; + icache.power_t.reset(); + IB->power_t.reset(); +// ID_inst->power_t.reset(); +// ID_operand->power_t.reset(); +// ID_misc->power_t.reset(); + if (coredynp.predictionW>0) + { + BTB->power_t.reset(); } - } else { - if (coredynp.core_ty == OOO) { - if (coredynp.scheu_ty == PhysicalRegFile) { - iFRAT->rt_power = - iFRAT->power_t + - (iFRAT->local_result.power) * coredynp.pppm_lkg_multhread + - idcl->power_t; - fFRAT->rt_power = - fFRAT->power_t + - (fFRAT->local_result.power) * coredynp.pppm_lkg_multhread + - fdcl->power_t; - iRRAT->rt_power = - iRRAT->power_t + - iRRAT->local_result.power * coredynp.pppm_lkg_multhread; - fRRAT->rt_power = - fRRAT->power_t + - fRRAT->local_result.power * coredynp.pppm_lkg_multhread; - ifreeL->rt_power = - ifreeL->power_t + - ifreeL->local_result.power * coredynp.pppm_lkg_multhread; - ffreeL->rt_power = - ffreeL->power_t + - ffreeL->local_result.power * coredynp.pppm_lkg_multhread; - rt_power = rt_power + (iFRAT->rt_power + fFRAT->rt_power) + - (iRRAT->rt_power + fRRAT->rt_power) + - (ifreeL->rt_power + ffreeL->rt_power); - } else if (coredynp.scheu_ty == ReservationStation) { - iFRAT->rt_power = - iFRAT->power_t + - (iFRAT->local_result.power) * coredynp.pppm_lkg_multhread + - idcl->power_t; - fFRAT->rt_power = - fFRAT->power_t + - (fFRAT->local_result.power) * coredynp.pppm_lkg_multhread + - fdcl->power_t; - ifreeL->rt_power = - ifreeL->power_t + - ifreeL->local_result.power * coredynp.pppm_lkg_multhread; - rt_power = - rt_power + (iFRAT->rt_power + fFRAT->rt_power) + ifreeL->rt_power; - } - } else { - rt_power = rt_power + idcl->power_t + fdcl->power_t; + icache.power_t.readOp.dynamic += (icache.caches->stats_t.readAc.hit*icache.caches->local_result.power.readOp.dynamic+ + //icache.caches->stats_t.readAc.miss*icache.caches->local_result.tag_array2->power.readOp.dynamic+ + icache.caches->stats_t.readAc.miss*icache.caches->local_result.power.readOp.dynamic+ //assume tag data accessed in parallel + icache.caches->stats_t.readAc.miss*icache.caches->local_result.power.writeOp.dynamic); //read miss in Icache cause a write to Icache + icache.power_t.readOp.dynamic += icache.missb->stats_t.readAc.access*icache.missb->local_result.power.searchOp.dynamic + + icache.missb->stats_t.writeAc.access*icache.missb->local_result.power.writeOp.dynamic;//each access to missb involves a CAM and a write + icache.power_t.readOp.dynamic += icache.ifb->stats_t.readAc.access*icache.ifb->local_result.power.searchOp.dynamic + + icache.ifb->stats_t.writeAc.access*icache.ifb->local_result.power.writeOp.dynamic; + icache.power_t.readOp.dynamic += icache.prefetchb->stats_t.readAc.access*icache.prefetchb->local_result.power.searchOp.dynamic + + icache.prefetchb->stats_t.writeAc.access*icache.prefetchb->local_result.power.writeOp.dynamic; + //cout<<"Icache power: "<power_t.readOp.dynamic += IB->local_result.power.readOp.dynamic*IB->stats_t.readAc.access + + IB->stats_t.writeAc.access*IB->local_result.power.writeOp.dynamic; + //cout << "IB power: "<power_t.readOp.dynamic<0) + { + BTB->power_t.readOp.dynamic += BTB->local_result.power.readOp.dynamic*BTB->stats_t.readAc.access + + BTB->stats_t.writeAc.access*BTB->local_result.power.writeOp.dynamic; + + BPT->computeEnergy(is_tdp); + } + + if (is_tdp) + { +// icache.power = icache.power_t + +// (icache.caches->local_result.power)*pppm_lkg + +// (icache.missb->local_result.power + +// icache.ifb->local_result.power + +// icache.prefetchb->local_result.power)*pppm_Isub; + icache.power = icache.power_t + + (icache.caches->local_result.power + + icache.missb->local_result.power + + icache.ifb->local_result.power + + icache.prefetchb->local_result.power)*pppm_lkg; + + IB->power = IB->power_t + IB->local_result.power*pppm_lkg; + power = power + icache.power + IB->power; + if (coredynp.predictionW>0) + { + BTB->power = BTB->power_t + BTB->local_result.power*pppm_lkg; + power = power + BTB->power + BPT->power; + } + + ID_inst->power_t.readOp.dynamic = ID_inst->power.readOp.dynamic; + ID_operand->power_t.readOp.dynamic = ID_operand->power.readOp.dynamic; + ID_misc->power_t.readOp.dynamic = ID_misc->power.readOp.dynamic; + + ID_inst->power.readOp.dynamic *= ID_inst->tdp_stats.readAc.access; + ID_operand->power.readOp.dynamic *= ID_operand->tdp_stats.readAc.access; + ID_misc->power.readOp.dynamic *= ID_misc->tdp_stats.readAc.access; + + power = power + (ID_inst->power + + ID_operand->power + + ID_misc->power); + } /* if (is_tdp) */ + else + { +// icache.rt_power = icache.power_t + +// (icache.caches->local_result.power)*pppm_lkg + +// (icache.missb->local_result.power + +// icache.ifb->local_result.power + +// icache.prefetchb->local_result.power)*pppm_Isub; + + icache.rt_power = icache.power_t + + (icache.caches->local_result.power + + icache.missb->local_result.power + + icache.ifb->local_result.power + + icache.prefetchb->local_result.power)*pppm_lkg; + + //IB->rt_power = IB->power_t + IB->local_result.power*pppm_lkg; + IB->rt_power.readOp.dynamic = IB->local_result.power.readOp.dynamic * IB->rtp_stats.readAc.access; + IB->rt_power.readOp.dynamic += IB->local_result.power.writeOp.dynamic * IB->rtp_stats.writeAc.access; + rt_power = rt_power + icache.rt_power + IB->rt_power; + if (coredynp.predictionW>0) + { + BTB->rt_power = BTB->power_t + BTB->local_result.power*pppm_lkg; + rt_power = rt_power + BTB->rt_power + BPT->rt_power; + } + + ID_inst->rt_power.readOp.dynamic = ID_inst->power_t.readOp.dynamic*ID_inst->rtp_stats.readAc.access; + ID_operand->rt_power.readOp.dynamic = ID_operand->power_t.readOp.dynamic * ID_operand->rtp_stats.readAc.access; + ID_misc->rt_power.readOp.dynamic = ID_misc->power_t.readOp.dynamic * ID_misc->rtp_stats.readAc.access; + + rt_power = rt_power + (ID_inst->rt_power + + ID_operand->rt_power + + ID_misc->rt_power); + //cout<<"ID inst: "<rt_power.readOp.dynamic << " ID operand: "<rt_power.readOp.dynamic<<" ID misc: "<rt_power.readOp.dynamic<sys.longer_channel_device; - - if (is_tdp) { - if (coredynp.core_ty == OOO) { - cout << indent_str << "Int Front End RAT:" << endl; - cout << indent_str_next << "Area = " << iFRAT->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << iFRAT->power.readOp.dynamic * clockRate - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? iFRAT->power.readOp.longer_channel_leakage - : iFRAT->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << iFRAT->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << iFRAT->rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << endl; - cout << indent_str << "FP Front End RAT:" << endl; - cout << indent_str_next << "Area = " << fFRAT->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << fFRAT->power.readOp.dynamic * clockRate - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? fFRAT->power.readOp.longer_channel_leakage - : fFRAT->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << fFRAT->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << fFRAT->rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << endl; - cout << indent_str << "Free List:" << endl; - cout << indent_str_next << "Area = " << ifreeL->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << ifreeL->power.readOp.dynamic * clockRate - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? ifreeL->power.readOp.longer_channel_leakage - : ifreeL->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << ifreeL->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << ifreeL->rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << endl; - - if (coredynp.scheu_ty == PhysicalRegFile) { - cout << indent_str << "Int Retire RAT: " << endl; - cout << indent_str_next << "Area = " << iRRAT->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << iRRAT->power.readOp.dynamic * clockRate - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? iRRAT->power.readOp.longer_channel_leakage - : iRRAT->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << iRRAT->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << iRRAT->rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << endl; - cout << indent_str << "FP Retire RAT:" << endl; - cout << indent_str_next << "Area = " << fRRAT->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << fRRAT->power.readOp.dynamic * clockRate - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? fRRAT->power.readOp.longer_channel_leakage - : fRRAT->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << fRRAT->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << fRRAT->rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << endl; - cout << indent_str << "FP Free List:" << endl; - cout << indent_str_next << "Area = " << ffreeL->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << ffreeL->power.readOp.dynamic * clockRate - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? ffreeL->power.readOp.longer_channel_leakage - : ffreeL->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << ffreeL->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << ffreeL->rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << endl; - } - } else { - cout << indent_str << "Int DCL:" << endl; - cout << indent_str_next - << "Peak Dynamic = " << idcl->power.readOp.dynamic * clockRate - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? idcl->power.readOp.longer_channel_leakage - : idcl->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << idcl->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << idcl->rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << indent_str << "FP DCL:" << endl; - cout << indent_str_next - << "Peak Dynamic = " << fdcl->power.readOp.dynamic * clockRate - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? fdcl->power.readOp.longer_channel_leakage - : fdcl->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << fdcl->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << fdcl->rt_power.readOp.dynamic / executionTime << " W" << endl; - } - } else { - if (coredynp.core_ty == OOO) { - cout << indent_str_next << "Int Front End RAT Peak Dynamic = " - << iFRAT->rt_power.readOp.dynamic * clockRate << " W" << endl; - cout << indent_str_next << "Int Front End RAT Subthreshold Leakage = " - << iFRAT->rt_power.readOp.leakage << " W" << endl; - cout << indent_str_next << "Int Front End RAT Gate Leakage = " - << iFRAT->rt_power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "FP Front End RAT Peak Dynamic = " - << fFRAT->rt_power.readOp.dynamic * clockRate << " W" << endl; - cout << indent_str_next << "FP Front End RAT Subthreshold Leakage = " - << fFRAT->rt_power.readOp.leakage << " W" << endl; - cout << indent_str_next << "FP Front End RAT Gate Leakage = " - << fFRAT->rt_power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Free List Peak Dynamic = " - << ifreeL->rt_power.readOp.dynamic * clockRate << " W" << endl; - cout << indent_str_next << "Free List Subthreshold Leakage = " - << ifreeL->rt_power.readOp.leakage << " W" << endl; - cout << indent_str_next << "Free List Gate Leakage = " - << fFRAT->rt_power.readOp.gate_leakage << " W" << endl; - if (coredynp.scheu_ty == PhysicalRegFile) { - cout << indent_str_next << "Int Retire RAT Peak Dynamic = " - << iRRAT->rt_power.readOp.dynamic * clockRate << " W" << endl; - cout << indent_str_next << "Int Retire RAT Subthreshold Leakage = " - << iRRAT->rt_power.readOp.leakage << " W" << endl; - cout << indent_str_next << "Int Retire RAT Gate Leakage = " - << iRRAT->rt_power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "FP Retire RAT Peak Dynamic = " - << fRRAT->rt_power.readOp.dynamic * clockRate << " W" << endl; - cout << indent_str_next << "FP Retire RAT Subthreshold Leakage = " - << fRRAT->rt_power.readOp.leakage << " W" << endl; - cout << indent_str_next << "FP Retire RAT Gate Leakage = " - << fRRAT->rt_power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "FP Free List Peak Dynamic = " - << ffreeL->rt_power.readOp.dynamic * clockRate << " W" << endl; - cout << indent_str_next << "FP Free List Subthreshold Leakage = " - << ffreeL->rt_power.readOp.leakage << " W" << endl; - cout << indent_str_next << "FP Free List Gate Leakage = " - << fFRAT->rt_power.readOp.gate_leakage << " W" << endl; - } - } else { - cout << indent_str_next << "Int DCL Peak Dynamic = " - << idcl->rt_power.readOp.dynamic * clockRate << " W" << endl; - cout << indent_str_next << "Int DCL Subthreshold Leakage = " - << idcl->rt_power.readOp.leakage << " W" << endl; - cout << indent_str_next - << "Int DCL Gate Leakage = " << idcl->rt_power.readOp.gate_leakage - << " W" << endl; - cout << indent_str_next << "FP DCL Peak Dynamic = " - << fdcl->rt_power.readOp.dynamic * clockRate << " W" << endl; - cout << indent_str_next << "FP DCL Subthreshold Leakage = " - << fdcl->rt_power.readOp.leakage << " W" << endl; - cout << indent_str_next - << "FP DCL Gate Leakage = " << fdcl->rt_power.readOp.gate_leakage - << " W" << endl; - } - } +void InstFetchU::displayEnergy(uint32_t indent,int plevel,bool is_tdp) +{ + if (!exist) return; + string indent_str(indent, ' '); + string indent_str_next(indent+2, ' '); + bool long_channel = XML->sys.longer_channel_device; + + + if (is_tdp) + { + + cout << indent_str<< "Instruction Cache:" << endl; + cout << indent_str_next << "Area = " << icache.area.get_area()*1e-6<< " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << icache.power.readOp.dynamic*clockRate << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? icache.power.readOp.longer_channel_leakage:icache.power.readOp.leakage) <<" W" << endl; + cout << indent_str_next << "Gate Leakage = " << icache.power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << icache.rt_power.readOp.dynamic/executionTime << " W" << endl; + cout <0) + { + cout << indent_str<< "Branch Target Buffer:" << endl; + cout << indent_str_next << "Area = " << BTB->area.get_area() *1e-6 << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << BTB->power.readOp.dynamic*clockRate << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? BTB->power.readOp.longer_channel_leakage:BTB->power.readOp.leakage) << " W" << endl; + cout << indent_str_next << "Gate Leakage = " << BTB->power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << BTB->rt_power.readOp.dynamic/executionTime << " W" << endl; + cout <exist) + { + cout << indent_str<< "Branch Predictor:" << endl; + cout << indent_str_next << "Area = " << BPT->area.get_area() *1e-6<< " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << BPT->power.readOp.dynamic*clockRate << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? BPT->power.readOp.longer_channel_leakage:BPT->power.readOp.leakage) << " W" << endl; + cout << indent_str_next << "Gate Leakage = " << BPT->power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << BPT->rt_power.readOp.dynamic/executionTime << " W" << endl; + cout <3) + { + BPT->displayEnergy(indent+4, plevel, is_tdp); + } + } + } + cout << indent_str<< "Instruction Buffer:" << endl; + cout << indent_str_next << "Area = " << IB->area.get_area()*1e-6 << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << IB->power.readOp.dynamic*clockRate << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? IB->power.readOp.longer_channel_leakage:IB->power.readOp.leakage) << " W" << endl; + cout << indent_str_next << "Gate Leakage = " << IB->power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << IB->rt_power.readOp.dynamic/executionTime << " W" << endl; + cout <0?coredynp.MUL_duty_cycle:0 - // + coredynp.num_fpus>0?coredynp.FPU_duty_cycle:0))*1.1<1 ? - //(coredynp.ALU_duty_cycle + coredynp.num_muls>0?coredynp.MUL_duty_cycle:0 - // + - //coredynp.num_fpus>0?coredynp.FPU_duty_cycle:0)*1.1:1; - ROB_duty_cycle = 1; - // init stats - if (is_tdp) { - if (coredynp.core_ty == OOO) { - int_inst_window->stats_t.readAc.access = - coredynp.issueW * - coredynp.num_pipelines; // int_inst_window->l_ip.num_search_ports; - int_inst_window->stats_t.writeAc.access = - coredynp.issueW * - coredynp.num_pipelines; // int_inst_window->l_ip.num_wr_ports; - int_inst_window->stats_t.searchAc.access = - coredynp.issueW * coredynp.num_pipelines; - int_inst_window->tdp_stats = int_inst_window->stats_t; - fp_inst_window->stats_t.readAc.access = - fp_inst_window->l_ip.num_rd_ports * coredynp.num_fp_pipelines; - fp_inst_window->stats_t.writeAc.access = - fp_inst_window->l_ip.num_wr_ports * coredynp.num_fp_pipelines; - fp_inst_window->stats_t.searchAc.access = - fp_inst_window->l_ip.num_search_ports * coredynp.num_fp_pipelines; - fp_inst_window->tdp_stats = fp_inst_window->stats_t; - - if (XML->sys.core[ithCore].ROB_size > 0) { - ROB->stats_t.readAc.access = - coredynp.commitW * coredynp.num_pipelines * ROB_duty_cycle; - ROB->stats_t.writeAc.access = - coredynp.issueW * coredynp.num_pipelines * ROB_duty_cycle; - ROB->tdp_stats = ROB->stats_t; - - /* - * When inst commits, ROB must be read. - * Because for Physcial register based cores, physical register tag in - * ROB - * need to be read out and write into RRAT/CAM based RAT. - * For RS based cores, register content that stored in ROB must be - * read out and stored in architectural registers. - * - * if no-register is involved, the ROB read out operation when - * instruction commits can be ignored. - * assuming 20% insts. belong this type. - * TODO: ROB duty_cycle need to be revisited - */ - } +void RENAMINGU::computeEnergy(bool is_tdp) +{ + if (!exist) return; + double pppm_t[4] = {1,1,1,1}; + if (is_tdp) + {//init stats for Peak + if (coredynp.core_ty==OOO){ + if (coredynp.scheu_ty==PhysicalRegFile) + { + if (coredynp.rm_ty ==RAMbased) + { + iFRAT->stats_t.readAc.access = iFRAT->l_ip.num_rd_ports; + iFRAT->stats_t.writeAc.access = iFRAT->l_ip.num_wr_ports; + iFRAT->tdp_stats = iFRAT->stats_t; + + fFRAT->stats_t.readAc.access = fFRAT->l_ip.num_rd_ports; + fFRAT->stats_t.writeAc.access = fFRAT->l_ip.num_wr_ports; + fFRAT->tdp_stats = fFRAT->stats_t; + + } + else if ((coredynp.rm_ty ==CAMbased)) + { + iFRAT->stats_t.readAc.access = iFRAT->l_ip.num_search_ports; + iFRAT->stats_t.writeAc.access = iFRAT->l_ip.num_wr_ports; + iFRAT->tdp_stats = iFRAT->stats_t; + + fFRAT->stats_t.readAc.access = fFRAT->l_ip.num_search_ports; + fFRAT->stats_t.writeAc.access = fFRAT->l_ip.num_wr_ports; + fFRAT->tdp_stats = fFRAT->stats_t; + } + + iRRAT->stats_t.readAc.access = iRRAT->l_ip.num_rd_ports; + iRRAT->stats_t.writeAc.access = iRRAT->l_ip.num_wr_ports; + iRRAT->tdp_stats = iRRAT->stats_t; + + fRRAT->stats_t.readAc.access = fRRAT->l_ip.num_rd_ports; + fRRAT->stats_t.writeAc.access = fRRAT->l_ip.num_wr_ports; + fRRAT->tdp_stats = fRRAT->stats_t; + + ifreeL->stats_t.readAc.access = coredynp.decodeW;//ifreeL->l_ip.num_rd_ports;; + ifreeL->stats_t.writeAc.access = coredynp.decodeW;//ifreeL->l_ip.num_wr_ports; + ifreeL->tdp_stats = ifreeL->stats_t; + + ffreeL->stats_t.readAc.access = coredynp.decodeW;//ffreeL->l_ip.num_rd_ports; + ffreeL->stats_t.writeAc.access = coredynp.decodeW;//ffreeL->l_ip.num_wr_ports; + ffreeL->tdp_stats = ffreeL->stats_t; + } + else if (coredynp.scheu_ty==ReservationStation){ + if (coredynp.rm_ty ==RAMbased) + { + iFRAT->stats_t.readAc.access = iFRAT->l_ip.num_rd_ports; + iFRAT->stats_t.writeAc.access = iFRAT->l_ip.num_wr_ports; + iFRAT->stats_t.searchAc.access = iFRAT->l_ip.num_search_ports; + iFRAT->tdp_stats = iFRAT->stats_t; + + fFRAT->stats_t.readAc.access = fFRAT->l_ip.num_rd_ports; + fFRAT->stats_t.writeAc.access = fFRAT->l_ip.num_wr_ports; + fFRAT->stats_t.searchAc.access = fFRAT->l_ip.num_search_ports; + fFRAT->tdp_stats = fFRAT->stats_t; + + } + else if ((coredynp.rm_ty ==CAMbased)) + { + iFRAT->stats_t.readAc.access = iFRAT->l_ip.num_search_ports; + iFRAT->stats_t.writeAc.access = iFRAT->l_ip.num_wr_ports; + iFRAT->tdp_stats = iFRAT->stats_t; + + fFRAT->stats_t.readAc.access = fFRAT->l_ip.num_search_ports; + fFRAT->stats_t.writeAc.access = fFRAT->l_ip.num_wr_ports; + fFRAT->tdp_stats = fFRAT->stats_t; + } + //Unified free list for both int and fp + ifreeL->stats_t.readAc.access = coredynp.decodeW;//ifreeL->l_ip.num_rd_ports; + ifreeL->stats_t.writeAc.access = coredynp.decodeW;//ifreeL->l_ip.num_wr_ports; + ifreeL->tdp_stats = ifreeL->stats_t; + } + idcl->stats_t.readAc.access = coredynp.decodeW; + fdcl->stats_t.readAc.access = coredynp.decodeW; + idcl->tdp_stats = idcl->stats_t; + fdcl->tdp_stats = fdcl->stats_t; + } + else + { + if (coredynp.issueW>1) + { + idcl->stats_t.readAc.access = coredynp.decodeW; + fdcl->stats_t.readAc.access = coredynp.decodeW; + idcl->tdp_stats = idcl->stats_t; + fdcl->tdp_stats = fdcl->stats_t; + } + } + + } + else + {//init stats for Runtime Dynamic (RTP) + if (coredynp.core_ty==OOO){ + if (coredynp.scheu_ty==PhysicalRegFile) + { + if (coredynp.rm_ty ==RAMbased) + { + iFRAT->stats_t.readAc.access = XML->sys.core[ithCore].rename_reads; + iFRAT->stats_t.writeAc.access = XML->sys.core[ithCore].rename_writes; + iFRAT->rtp_stats = iFRAT->stats_t; + + fFRAT->stats_t.readAc.access = XML->sys.core[ithCore].fp_rename_reads; + fFRAT->stats_t.writeAc.access = XML->sys.core[ithCore].fp_rename_writes; + fFRAT->rtp_stats = fFRAT->stats_t; + } + else if ((coredynp.rm_ty ==CAMbased)) + { + iFRAT->stats_t.readAc.access = XML->sys.core[ithCore].rename_reads; + iFRAT->stats_t.writeAc.access = XML->sys.core[ithCore].rename_writes; + iFRAT->rtp_stats = iFRAT->stats_t; + + fFRAT->stats_t.readAc.access = XML->sys.core[ithCore].fp_rename_reads; + fFRAT->stats_t.writeAc.access = XML->sys.core[ithCore].fp_rename_writes; + fFRAT->rtp_stats = fFRAT->stats_t; + } + + iRRAT->stats_t.readAc.access = XML->sys.core[ithCore].rename_writes;//Hack, should be (context switch + branch mispredictions)*16 + iRRAT->stats_t.writeAc.access = XML->sys.core[ithCore].rename_writes; + iRRAT->rtp_stats = iRRAT->stats_t; + + fRRAT->stats_t.readAc.access = XML->sys.core[ithCore].fp_rename_writes;//Hack, should be (context switch + branch mispredictions)*16 + fRRAT->stats_t.writeAc.access = XML->sys.core[ithCore].fp_rename_writes; + fRRAT->rtp_stats = fRRAT->stats_t; + + ifreeL->stats_t.readAc.access = XML->sys.core[ithCore].rename_reads; + ifreeL->stats_t.writeAc.access = 2*XML->sys.core[ithCore].rename_writes; + ifreeL->rtp_stats = ifreeL->stats_t; + + ffreeL->stats_t.readAc.access = XML->sys.core[ithCore].fp_rename_reads; + ffreeL->stats_t.writeAc.access = 2*XML->sys.core[ithCore].fp_rename_writes; + ffreeL->rtp_stats = ffreeL->stats_t; + } + else if (coredynp.scheu_ty==ReservationStation){ + if (coredynp.rm_ty ==RAMbased) + { + iFRAT->stats_t.readAc.access = XML->sys.core[ithCore].rename_reads; + iFRAT->stats_t.writeAc.access = XML->sys.core[ithCore].rename_writes; + iFRAT->stats_t.searchAc.access = XML->sys.core[ithCore].committed_int_instructions;//hack: not all committed instructions use regs. + iFRAT->rtp_stats = iFRAT->stats_t; + + fFRAT->stats_t.readAc.access = XML->sys.core[ithCore].fp_rename_reads; + fFRAT->stats_t.writeAc.access = XML->sys.core[ithCore].fp_rename_writes; + fFRAT->stats_t.searchAc.access = XML->sys.core[ithCore].committed_fp_instructions; + fFRAT->rtp_stats = fFRAT->stats_t; + } + else if ((coredynp.rm_ty ==CAMbased)) + { + iFRAT->stats_t.readAc.access = XML->sys.core[ithCore].rename_reads; + iFRAT->stats_t.writeAc.access = XML->sys.core[ithCore].rename_writes; + iFRAT->rtp_stats = iFRAT->stats_t; + + fFRAT->stats_t.readAc.access = XML->sys.core[ithCore].fp_rename_reads; + fFRAT->stats_t.writeAc.access = XML->sys.core[ithCore].fp_rename_writes; + fFRAT->rtp_stats = fFRAT->stats_t; + } + //Unified free list for both int and fp since the ROB act as physcial registers + ifreeL->stats_t.readAc.access = XML->sys.core[ithCore].rename_reads + + XML->sys.core[ithCore].fp_rename_reads; + ifreeL->stats_t.writeAc.access = 2*(XML->sys.core[ithCore].rename_writes + + XML->sys.core[ithCore].fp_rename_writes);//HACK: 2-> since some of renaming in the same group + //are terminated early + ifreeL->rtp_stats = ifreeL->stats_t; + } + idcl->stats_t.readAc.access = 3*coredynp.decodeW*coredynp.decodeW*XML->sys.core[ithCore].rename_reads; + fdcl->stats_t.readAc.access = 3*coredynp.fp_issueW*coredynp.fp_issueW*XML->sys.core[ithCore].fp_rename_writes; + idcl->rtp_stats = idcl->stats_t; + fdcl->rtp_stats = fdcl->stats_t; + } + else + { + if (coredynp.issueW>1) + { + idcl->stats_t.readAc.access = 2*XML->sys.core[ithCore].int_instructions; + fdcl->stats_t.readAc.access = XML->sys.core[ithCore].fp_instructions; + idcl->rtp_stats = idcl->stats_t; + fdcl->rtp_stats = fdcl->stats_t; + } + } + + } + /* Compute engine */ + if (coredynp.core_ty==OOO) + { + if (coredynp.scheu_ty==PhysicalRegFile) + { + if (coredynp.rm_ty ==RAMbased) + { + iFRAT->power_t.reset(); + fFRAT->power_t.reset(); + + iFRAT->power_t.readOp.dynamic += (iFRAT->stats_t.readAc.access + *(iFRAT->local_result.power.readOp.dynamic + idcl->power.readOp.dynamic) + +iFRAT->stats_t.writeAc.access*iFRAT->local_result.power.writeOp.dynamic); + fFRAT->power_t.readOp.dynamic += (fFRAT->stats_t.readAc.access + *(fFRAT->local_result.power.readOp.dynamic + fdcl->power.readOp.dynamic) + +fFRAT->stats_t.writeAc.access*fFRAT->local_result.power.writeOp.dynamic); + } + else if ((coredynp.rm_ty ==CAMbased)) + { + iFRAT->power_t.reset(); + fFRAT->power_t.reset(); + iFRAT->power_t.readOp.dynamic += (iFRAT->stats_t.readAc.access + *(iFRAT->local_result.power.searchOp.dynamic + idcl->power.readOp.dynamic) + +iFRAT->stats_t.writeAc.access*iFRAT->local_result.power.writeOp.dynamic); + fFRAT->power_t.readOp.dynamic += (fFRAT->stats_t.readAc.access + *(fFRAT->local_result.power.searchOp.dynamic + fdcl->power.readOp.dynamic) + +fFRAT->stats_t.writeAc.access*fFRAT->local_result.power.writeOp.dynamic); + } + + iRRAT->power_t.reset(); + fRRAT->power_t.reset(); + ifreeL->power_t.reset(); + ffreeL->power_t.reset(); + + iRRAT->power_t.readOp.dynamic += (iRRAT->stats_t.readAc.access*iRRAT->local_result.power.readOp.dynamic + +iRRAT->stats_t.writeAc.access*iRRAT->local_result.power.writeOp.dynamic); + fRRAT->power_t.readOp.dynamic += (fRRAT->stats_t.readAc.access*fRRAT->local_result.power.readOp.dynamic + +fRRAT->stats_t.writeAc.access*fRRAT->local_result.power.writeOp.dynamic); + ifreeL->power_t.readOp.dynamic += (ifreeL->stats_t.readAc.access*ifreeL->local_result.power.readOp.dynamic + +ifreeL->stats_t.writeAc.access*ifreeL->local_result.power.writeOp.dynamic); + ffreeL->power_t.readOp.dynamic += (ffreeL->stats_t.readAc.access*ffreeL->local_result.power.readOp.dynamic + +ffreeL->stats_t.writeAc.access*ffreeL->local_result.power.writeOp.dynamic); + + } + else if (coredynp.scheu_ty==ReservationStation) + { + if (coredynp.rm_ty ==RAMbased) + { + iFRAT->power_t.reset(); + fFRAT->power_t.reset(); + + iFRAT->power_t.readOp.dynamic += (iFRAT->stats_t.readAc.access + *(iFRAT->local_result.power.readOp.dynamic + idcl->power.readOp.dynamic) + +iFRAT->stats_t.writeAc.access*iFRAT->local_result.power.writeOp.dynamic + +iFRAT->stats_t.searchAc.access*iFRAT->local_result.power.searchOp.dynamic); + fFRAT->power_t.readOp.dynamic += (fFRAT->stats_t.readAc.access + *(fFRAT->local_result.power.readOp.dynamic + fdcl->power.readOp.dynamic) + +fFRAT->stats_t.writeAc.access*fFRAT->local_result.power.writeOp.dynamic + +fFRAT->stats_t.searchAc.access*fFRAT->local_result.power.searchOp.dynamic); + } + else if ((coredynp.rm_ty ==CAMbased)) + { + iFRAT->power_t.reset(); + fFRAT->power_t.reset(); + iFRAT->power_t.readOp.dynamic += (iFRAT->stats_t.readAc.access + *(iFRAT->local_result.power.searchOp.dynamic + idcl->power.readOp.dynamic) + +iFRAT->stats_t.writeAc.access*iFRAT->local_result.power.writeOp.dynamic); + fFRAT->power_t.readOp.dynamic += (fFRAT->stats_t.readAc.access + *(fFRAT->local_result.power.searchOp.dynamic + fdcl->power.readOp.dynamic) + +fFRAT->stats_t.writeAc.access*fFRAT->local_result.power.writeOp.dynamic); + } + ifreeL->power_t.reset(); + ifreeL->power_t.readOp.dynamic += (ifreeL->stats_t.readAc.access*ifreeL->local_result.power.readOp.dynamic + +ifreeL->stats_t.writeAc.access*ifreeL->local_result.power.writeOp.dynamic); + } + + } + else + { + if (coredynp.issueW>1) + { + idcl->power_t.reset(); + fdcl->power_t.reset(); + set_pppm(pppm_t, idcl->stats_t.readAc.access, coredynp.num_hthreads, coredynp.num_hthreads, idcl->stats_t.readAc.access); + idcl->power_t = idcl->power * pppm_t; + set_pppm(pppm_t, fdcl->stats_t.readAc.access, coredynp.num_hthreads, coredynp.num_hthreads, idcl->stats_t.readAc.access); + fdcl->power_t = fdcl->power * pppm_t; + } + + } + + //assign value to tpd and rtp + if (is_tdp) + { + if (coredynp.core_ty==OOO) + { + if (coredynp.scheu_ty==PhysicalRegFile) + { + iFRAT->power = iFRAT->power_t + (iFRAT->local_result.power ) * coredynp.pppm_lkg_multhread + idcl->power_t; + fFRAT->power = fFRAT->power_t + (fFRAT->local_result.power ) * coredynp.pppm_lkg_multhread + fdcl->power_t; + iRRAT->power = iRRAT->power_t + iRRAT->local_result.power * coredynp.pppm_lkg_multhread; + fRRAT->power = fRRAT->power_t + fRRAT->local_result.power * coredynp.pppm_lkg_multhread; + ifreeL->power = ifreeL->power_t + ifreeL->local_result.power * coredynp.pppm_lkg_multhread; + ffreeL->power = ffreeL->power_t + ffreeL->local_result.power * coredynp.pppm_lkg_multhread; + power = power + (iFRAT->power + fFRAT->power) + + (iRRAT->power + fRRAT->power) + + (ifreeL->power + ffreeL->power); + } + else if (coredynp.scheu_ty==ReservationStation) + { + iFRAT->power = iFRAT->power_t + (iFRAT->local_result.power ) * coredynp.pppm_lkg_multhread + idcl->power_t; + fFRAT->power = fFRAT->power_t + (fFRAT->local_result.power ) * coredynp.pppm_lkg_multhread + fdcl->power_t; + ifreeL->power = ifreeL->power_t + ifreeL->local_result.power * coredynp.pppm_lkg_multhread; + power = power + (iFRAT->power + fFRAT->power) + + ifreeL->power; + } + } + else + { + power = power + idcl->power_t + fdcl->power_t; + } + + } + else + { + if (coredynp.core_ty==OOO) + { + if (coredynp.scheu_ty==PhysicalRegFile) + { + iFRAT->rt_power = iFRAT->power_t + (iFRAT->local_result.power ) * coredynp.pppm_lkg_multhread + idcl->power_t; + fFRAT->rt_power = fFRAT->power_t + (fFRAT->local_result.power ) * coredynp.pppm_lkg_multhread + fdcl->power_t; + iRRAT->rt_power = iRRAT->power_t + iRRAT->local_result.power * coredynp.pppm_lkg_multhread; + fRRAT->rt_power = fRRAT->power_t + fRRAT->local_result.power * coredynp.pppm_lkg_multhread; + ifreeL->rt_power = ifreeL->power_t + ifreeL->local_result.power * coredynp.pppm_lkg_multhread; + ffreeL->rt_power = ffreeL->power_t + ffreeL->local_result.power * coredynp.pppm_lkg_multhread; + rt_power = rt_power + (iFRAT->rt_power + fFRAT->rt_power) + + (iRRAT->rt_power + fRRAT->rt_power) + + (ifreeL->rt_power + ffreeL->rt_power); + } + else if (coredynp.scheu_ty==ReservationStation) + { + iFRAT->rt_power = iFRAT->power_t + (iFRAT->local_result.power ) * coredynp.pppm_lkg_multhread + idcl->power_t; + fFRAT->rt_power = fFRAT->power_t + (fFRAT->local_result.power ) * coredynp.pppm_lkg_multhread + fdcl->power_t; + ifreeL->rt_power = ifreeL->power_t + ifreeL->local_result.power * coredynp.pppm_lkg_multhread; + rt_power = rt_power + (iFRAT->rt_power + fFRAT->rt_power) + + ifreeL->rt_power; + } + } + else + { + rt_power = rt_power + idcl->power_t + fdcl->power_t; + } + + } +} - } else if (coredynp.multithreaded) { - int_inst_window->stats_t.readAc.access = - coredynp.issueW * - coredynp.num_pipelines; // int_inst_window->l_ip.num_search_ports; - int_inst_window->stats_t.writeAc.access = - coredynp.issueW * - coredynp.num_pipelines; // int_inst_window->l_ip.num_wr_ports; - int_inst_window->stats_t.searchAc.access = - coredynp.issueW * coredynp.num_pipelines; - int_inst_window->tdp_stats = int_inst_window->stats_t; - } +void RENAMINGU::displayEnergy(uint32_t indent,int plevel,bool is_tdp) +{ + if (!exist) return; + string indent_str(indent, ' '); + string indent_str_next(indent+2, ' '); + bool long_channel = XML->sys.longer_channel_device; + + + if (is_tdp) + { + + if (coredynp.core_ty==OOO) + { + cout << indent_str<< "Int Front End RAT:" << endl; + cout << indent_str_next << "Area = " << iFRAT->area.get_area()*1e-6<< " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << iFRAT->power.readOp.dynamic*clockRate << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? iFRAT->power.readOp.longer_channel_leakage:iFRAT->power.readOp.leakage) <<" W" << endl; + cout << indent_str_next << "Gate Leakage = " << iFRAT->power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << iFRAT->rt_power.readOp.dynamic/executionTime << " W" << endl; + cout <stats_t.readAc.access = - XML->sys.core[ithCore].inst_window_reads; - int_inst_window->stats_t.writeAc.access = - XML->sys.core[ithCore].inst_window_writes; - int_inst_window->stats_t.searchAc.access = - XML->sys.core[ithCore].inst_window_wakeup_accesses; - int_inst_window->rtp_stats = int_inst_window->stats_t; - fp_inst_window->stats_t.readAc.access = - XML->sys.core[ithCore].fp_inst_window_reads; - fp_inst_window->stats_t.writeAc.access = - XML->sys.core[ithCore].fp_inst_window_writes; - fp_inst_window->stats_t.searchAc.access = - XML->sys.core[ithCore].fp_inst_window_wakeup_accesses; - fp_inst_window->rtp_stats = fp_inst_window->stats_t; - - if (XML->sys.core[ithCore].ROB_size > 0) { - ROB->stats_t.readAc.access = XML->sys.core[ithCore].ROB_reads; - ROB->stats_t.writeAc.access = XML->sys.core[ithCore].ROB_writes; - /* ROB need to be updated in RS based OOO when new values are produced, - * this update may happen before the commit stage when ROB entry is - * released - * 1. ROB write at instruction inserted in - * 2. ROB write as results produced (for RS based OOO only) - * 3. ROB read as instruction committed. For RS based OOO, data values - * are read out and sent to ARF - * For Physical reg based OOO, no data stored in ROB, but register tags - * need to be - * read out and used to set the RRAT and to recycle the register tag to - * free list buffer - */ - ROB->rtp_stats = ROB->stats_t; - } +} - } else if (coredynp.multithreaded) { - int_inst_window->stats_t.readAc.access = - XML->sys.core[ithCore].int_instructions + - XML->sys.core[ithCore].fp_instructions; - int_inst_window->stats_t.writeAc.access = - XML->sys.core[ithCore].int_instructions + - XML->sys.core[ithCore].fp_instructions; - int_inst_window->stats_t.searchAc.access = - 2 * (XML->sys.core[ithCore].int_instructions + - XML->sys.core[ithCore].fp_instructions); - int_inst_window->rtp_stats = int_inst_window->stats_t; - } - } - // computation engine - if (coredynp.core_ty == OOO) { - int_inst_window->power_t.reset(); - fp_inst_window->power_t.reset(); - - /* each instruction needs to write to scheduler, read out when all resources - * and source operands are ready - * two search ops with one for each source operand - * - */ - int_inst_window->power_t.readOp.dynamic += - int_inst_window->local_result.power.readOp.dynamic * - int_inst_window->stats_t.readAc.access + - int_inst_window->local_result.power.searchOp.dynamic * - int_inst_window->stats_t.searchAc.access + - int_inst_window->local_result.power.writeOp.dynamic * - int_inst_window->stats_t.writeAc.access + - int_inst_window->stats_t.readAc.access * - instruction_selection->power.readOp.dynamic; - - fp_inst_window->power_t.readOp.dynamic += - fp_inst_window->local_result.power.readOp.dynamic * - fp_inst_window->stats_t.readAc.access + - fp_inst_window->local_result.power.searchOp.dynamic * - fp_inst_window->stats_t.searchAc.access + - fp_inst_window->local_result.power.writeOp.dynamic * - fp_inst_window->stats_t.writeAc.access + - fp_inst_window->stats_t.writeAc.access * - instruction_selection->power.readOp.dynamic; - - if (XML->sys.core[ithCore].ROB_size > 0) { - ROB->power_t.reset(); - ROB->power_t.readOp.dynamic += - ROB->local_result.power.readOp.dynamic * ROB->stats_t.readAc.access + - ROB->stats_t.writeAc.access * ROB->local_result.power.writeOp.dynamic; +void SchedulerU::computeEnergy(bool is_tdp) +{ + if (!exist) return; + double ROB_duty_cycle; +// ROB_duty_cycle = ((coredynp.ALU_duty_cycle + coredynp.num_muls>0?coredynp.MUL_duty_cycle:0 +// + coredynp.num_fpus>0?coredynp.FPU_duty_cycle:0))*1.1<1 ? (coredynp.ALU_duty_cycle + coredynp.num_muls>0?coredynp.MUL_duty_cycle:0 +// + coredynp.num_fpus>0?coredynp.FPU_duty_cycle:0)*1.1:1; + ROB_duty_cycle = 1; + //init stats + if (is_tdp) + { + if (coredynp.core_ty==OOO) + { + int_inst_window->stats_t.readAc.access = coredynp.issueW*coredynp.num_pipelines;//int_inst_window->l_ip.num_search_ports; + int_inst_window->stats_t.writeAc.access = coredynp.issueW*coredynp.num_pipelines;//int_inst_window->l_ip.num_wr_ports; + int_inst_window->stats_t.searchAc.access = coredynp.issueW*coredynp.num_pipelines; + int_inst_window->tdp_stats = int_inst_window->stats_t; + fp_inst_window->stats_t.readAc.access = fp_inst_window->l_ip.num_rd_ports*coredynp.num_fp_pipelines; + fp_inst_window->stats_t.writeAc.access = fp_inst_window->l_ip.num_wr_ports*coredynp.num_fp_pipelines; + fp_inst_window->stats_t.searchAc.access = fp_inst_window->l_ip.num_search_ports*coredynp.num_fp_pipelines; + fp_inst_window->tdp_stats = fp_inst_window->stats_t; + + if (XML->sys.core[ithCore].ROB_size >0) + { + ROB->stats_t.readAc.access = coredynp.commitW*coredynp.num_pipelines*ROB_duty_cycle; + ROB->stats_t.writeAc.access = coredynp.issueW*coredynp.num_pipelines*ROB_duty_cycle; + ROB->tdp_stats = ROB->stats_t; + + /* + * When inst commits, ROB must be read. + * Because for Physcial register based cores, physical register tag in ROB + * need to be read out and write into RRAT/CAM based RAT. + * For RS based cores, register content that stored in ROB must be + * read out and stored in architectural registers. + * + * if no-register is involved, the ROB read out operation when instruction commits can be ignored. + * assuming 20% insts. belong this type. + * TODO: ROB duty_cycle need to be revisited + */ + } + + } + else if (coredynp.multithreaded) + { + int_inst_window->stats_t.readAc.access = coredynp.issueW*coredynp.num_pipelines;//int_inst_window->l_ip.num_search_ports; + int_inst_window->stats_t.writeAc.access = coredynp.issueW*coredynp.num_pipelines;//int_inst_window->l_ip.num_wr_ports; + int_inst_window->stats_t.searchAc.access = coredynp.issueW*coredynp.num_pipelines; + int_inst_window->tdp_stats = int_inst_window->stats_t; + } + + } + else + {//rtp + if (coredynp.core_ty==OOO) + { + int_inst_window->stats_t.readAc.access = XML->sys.core[ithCore].inst_window_reads; + int_inst_window->stats_t.writeAc.access = XML->sys.core[ithCore].inst_window_writes; + int_inst_window->stats_t.searchAc.access = XML->sys.core[ithCore].inst_window_wakeup_accesses; + int_inst_window->rtp_stats = int_inst_window->stats_t; + fp_inst_window->stats_t.readAc.access = XML->sys.core[ithCore].fp_inst_window_reads; + fp_inst_window->stats_t.writeAc.access = XML->sys.core[ithCore].fp_inst_window_writes; + fp_inst_window->stats_t.searchAc.access = XML->sys.core[ithCore].fp_inst_window_wakeup_accesses; + fp_inst_window->rtp_stats = fp_inst_window->stats_t; + + if (XML->sys.core[ithCore].ROB_size >0) + { + + ROB->stats_t.readAc.access = XML->sys.core[ithCore].ROB_reads; + ROB->stats_t.writeAc.access = XML->sys.core[ithCore].ROB_writes; + /* ROB need to be updated in RS based OOO when new values are produced, + * this update may happen before the commit stage when ROB entry is released + * 1. ROB write at instruction inserted in + * 2. ROB write as results produced (for RS based OOO only) + * 3. ROB read as instruction committed. For RS based OOO, data values are read out and sent to ARF + * For Physical reg based OOO, no data stored in ROB, but register tags need to be + * read out and used to set the RRAT and to recycle the register tag to free list buffer + */ + ROB->rtp_stats = ROB->stats_t; + } + + } + else if (coredynp.multithreaded) + { + int_inst_window->stats_t.readAc.access = XML->sys.core[ithCore].int_instructions + XML->sys.core[ithCore].fp_instructions; + int_inst_window->stats_t.writeAc.access = XML->sys.core[ithCore].int_instructions + XML->sys.core[ithCore].fp_instructions; + int_inst_window->stats_t.searchAc.access = 2*(XML->sys.core[ithCore].int_instructions + XML->sys.core[ithCore].fp_instructions); + int_inst_window->rtp_stats = int_inst_window->stats_t; + } } - } else if (coredynp.multithreaded) { - int_inst_window->power_t.reset(); - int_inst_window->power_t.readOp.dynamic += - int_inst_window->local_result.power.readOp.dynamic * - int_inst_window->stats_t.readAc.access + - int_inst_window->local_result.power.searchOp.dynamic * - int_inst_window->stats_t.searchAc.access + - int_inst_window->local_result.power.writeOp.dynamic * - int_inst_window->stats_t.writeAc.access + - int_inst_window->stats_t.writeAc.access * - instruction_selection->power.readOp.dynamic; - } - - // assign values - if (is_tdp) { - if (coredynp.core_ty == OOO) { - int_inst_window->power = - int_inst_window->power_t + - (int_inst_window->local_result.power + instruction_selection->power) * - pppm_lkg; - fp_inst_window->power = - fp_inst_window->power_t + - (fp_inst_window->local_result.power + instruction_selection->power) * - pppm_lkg; - power = power + int_inst_window->power + fp_inst_window->power; - if (XML->sys.core[ithCore].ROB_size > 0) { - ROB->power = ROB->power_t + ROB->local_result.power * pppm_lkg; - power = power + ROB->power; - } - - } else if (coredynp.multithreaded) { - // set_pppm(pppm_t, - //XML->sys.core[ithCore].issue_width,1, 1, 1); - int_inst_window->power = - int_inst_window->power_t + - (int_inst_window->local_result.power + instruction_selection->power) * - pppm_lkg; - power = power + int_inst_window->power; + //computation engine + if (coredynp.core_ty==OOO) + { + int_inst_window->power_t.reset(); + fp_inst_window->power_t.reset(); + + /* each instruction needs to write to scheduler, read out when all resources and source operands are ready + * two search ops with one for each source operand + * + */ + int_inst_window->power_t.readOp.dynamic += int_inst_window->local_result.power.readOp.dynamic * int_inst_window->stats_t.readAc.access + + int_inst_window->local_result.power.searchOp.dynamic * int_inst_window->stats_t.searchAc.access + + int_inst_window->local_result.power.writeOp.dynamic * int_inst_window->stats_t.writeAc.access + + int_inst_window->stats_t.readAc.access * instruction_selection->power.readOp.dynamic; + + fp_inst_window->power_t.readOp.dynamic += fp_inst_window->local_result.power.readOp.dynamic * fp_inst_window->stats_t.readAc.access + + fp_inst_window->local_result.power.searchOp.dynamic * fp_inst_window->stats_t.searchAc.access + + fp_inst_window->local_result.power.writeOp.dynamic * fp_inst_window->stats_t.writeAc.access + + fp_inst_window->stats_t.writeAc.access * instruction_selection->power.readOp.dynamic; + + if (XML->sys.core[ithCore].ROB_size >0) + { + ROB->power_t.reset(); + ROB->power_t.readOp.dynamic += ROB->local_result.power.readOp.dynamic*ROB->stats_t.readAc.access + + ROB->stats_t.writeAc.access*ROB->local_result.power.writeOp.dynamic; + } + + + + + } + else if (coredynp.multithreaded) + { + int_inst_window->power_t.reset(); + int_inst_window->power_t.readOp.dynamic += int_inst_window->local_result.power.readOp.dynamic * int_inst_window->stats_t.readAc.access + + int_inst_window->local_result.power.searchOp.dynamic * int_inst_window->stats_t.searchAc.access + + int_inst_window->local_result.power.writeOp.dynamic * int_inst_window->stats_t.writeAc.access + + int_inst_window->stats_t.writeAc.access * instruction_selection->power.readOp.dynamic; + } + + //assign values + if (is_tdp) + { + if (coredynp.core_ty==OOO) + { + int_inst_window->power = int_inst_window->power_t + (int_inst_window->local_result.power +instruction_selection->power) *pppm_lkg; + fp_inst_window->power = fp_inst_window->power_t + (fp_inst_window->local_result.power +instruction_selection->power) *pppm_lkg; + power = power + int_inst_window->power + fp_inst_window->power; + if (XML->sys.core[ithCore].ROB_size >0) + { + ROB->power = ROB->power_t + ROB->local_result.power*pppm_lkg; + power = power + ROB->power; + } + + } + else if (coredynp.multithreaded) + { + // set_pppm(pppm_t, XML->sys.core[ithCore].issue_width,1, 1, 1); + int_inst_window->power = int_inst_window->power_t + (int_inst_window->local_result.power +instruction_selection->power) *pppm_lkg; + power = power + int_inst_window->power; + } + + } + else + {//rtp + if (coredynp.core_ty==OOO) + { + int_inst_window->rt_power = int_inst_window->power_t + (int_inst_window->local_result.power +instruction_selection->power) *pppm_lkg; + fp_inst_window->rt_power = fp_inst_window->power_t + (fp_inst_window->local_result.power +instruction_selection->power) *pppm_lkg; + rt_power = rt_power + int_inst_window->rt_power + fp_inst_window->rt_power; + if (XML->sys.core[ithCore].ROB_size >0) + { + ROB->rt_power = ROB->power_t + ROB->local_result.power*pppm_lkg; + rt_power = rt_power + ROB->rt_power; + } + + } + else if (coredynp.multithreaded) + { + // set_pppm(pppm_t, XML->sys.core[ithCore].issue_width,1, 1, 1); + int_inst_window->rt_power = int_inst_window->power_t + (int_inst_window->local_result.power +instruction_selection->power) *pppm_lkg; + rt_power = rt_power + int_inst_window->rt_power; + } } +// set_pppm(pppm_t, XML->sys.core[ithCore].issue_width,1, 1, 1); +// cout<<"Scheduler power="<power.readOp.dynamic<<"leakage"<power.readOp.leakage<rt_power = - int_inst_window->power_t + - (int_inst_window->local_result.power + instruction_selection->power) * - pppm_lkg; - fp_inst_window->rt_power = - fp_inst_window->power_t + - (fp_inst_window->local_result.power + instruction_selection->power) * - pppm_lkg; - rt_power = - rt_power + int_inst_window->rt_power + fp_inst_window->rt_power; - if (XML->sys.core[ithCore].ROB_size > 0) { - ROB->rt_power = ROB->power_t + ROB->local_result.power * pppm_lkg; - rt_power = rt_power + ROB->rt_power; - } +void SchedulerU::displayEnergy(uint32_t indent,int plevel,bool is_tdp) +{ + if (!exist) return; + string indent_str(indent, ' '); + string indent_str_next(indent+2, ' '); + bool long_channel = XML->sys.longer_channel_device; + + + if (is_tdp) + { + if (coredynp.core_ty==OOO) + { + cout << indent_str << "Instruction Window:" << endl; + cout << indent_str_next << "Area = " << int_inst_window->area.get_area()*1e-6<< " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << int_inst_window->power.readOp.dynamic*clockRate << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? int_inst_window->power.readOp.longer_channel_leakage:int_inst_window->power.readOp.leakage) <<" W" << endl; + cout << indent_str_next << "Gate Leakage = " << int_inst_window->power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << int_inst_window->rt_power.readOp.dynamic/executionTime << " W" << endl; + cout <sys.core[ithCore].ROB_size >0) + { + cout << indent_str<<"ROB:" << endl; + cout << indent_str_next << "Area = " << ROB->area.get_area() *1e-6 << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << ROB->power.readOp.dynamic*clockRate << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? ROB->power.readOp.longer_channel_leakage:ROB->power.readOp.leakage) << " W" << endl; + cout << indent_str_next << "Gate Leakage = " << ROB->power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << ROB->rt_power.readOp.dynamic/executionTime << " W" << endl; + cout <sys.core[ithCore].ROB_size >0) + { + cout << indent_str_next << "ROB Peak Dynamic = " << ROB->rt_power.readOp.dynamic*clockRate << " W" << endl; + cout << indent_str_next << "ROB Subthreshold Leakage = " << ROB->rt_power.readOp.leakage << " W" << endl; + cout << indent_str_next << "ROB Gate Leakage = " << ROB->rt_power.readOp.gate_leakage << " W" << endl; + } + } + else if (coredynp.multithreaded) + { + cout << indent_str_next << "Instruction Window Peak Dynamic = " << int_inst_window->rt_power.readOp.dynamic*clockRate << " W" << endl; + cout << indent_str_next << "Instruction Window Subthreshold Leakage = " << int_inst_window->rt_power.readOp.leakage <<" W" << endl; + cout << indent_str_next << "Instruction Window Gate Leakage = " << int_inst_window->rt_power.readOp.gate_leakage << " W" << endl; + } + } - } else if (coredynp.multithreaded) { - // set_pppm(pppm_t, - //XML->sys.core[ithCore].issue_width,1, 1, 1); - int_inst_window->rt_power = - int_inst_window->power_t + - (int_inst_window->local_result.power + instruction_selection->power) * - pppm_lkg; - rt_power = rt_power + int_inst_window->rt_power; - } - } - // set_pppm(pppm_t, XML->sys.core[ithCore].issue_width,1, 1, 1); - // cout<<"Scheduler - //power="<power.readOp.dynamic<<"leakage"<power.readOp.leakage<sys.longer_channel_device; - - if (is_tdp) { - if (coredynp.core_ty == OOO) { - cout << indent_str << "Instruction Window:" << endl; - cout << indent_str_next - << "Area = " << int_inst_window->area.get_area() * 1e-6 << " mm^2" - << endl; - cout << indent_str_next << "Peak Dynamic = " - << int_inst_window->power.readOp.dynamic * clockRate << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel - ? int_inst_window->power.readOp.longer_channel_leakage - : int_inst_window->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << int_inst_window->power.readOp.gate_leakage - << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " - << int_inst_window->rt_power.readOp.dynamic / executionTime << " W" - << endl; - cout << endl; - cout << indent_str << "FP Instruction Window:" << endl; - cout << indent_str_next - << "Area = " << fp_inst_window->area.get_area() * 1e-6 << " mm^2" - << endl; - cout << indent_str_next << "Peak Dynamic = " - << fp_inst_window->power.readOp.dynamic * clockRate << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel - ? fp_inst_window->power.readOp.longer_channel_leakage - : fp_inst_window->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << fp_inst_window->power.readOp.gate_leakage - << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " - << fp_inst_window->rt_power.readOp.dynamic / executionTime << " W" - << endl; - cout << endl; - if (XML->sys.core[ithCore].ROB_size > 0) { - cout << indent_str << "ROB:" << endl; - cout << indent_str_next << "Area = " << ROB->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << ROB->power.readOp.dynamic * clockRate - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? ROB->power.readOp.longer_channel_leakage - : ROB->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << ROB->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << ROB->rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << endl; - } - } else if (coredynp.multithreaded) { - cout << indent_str << "Instruction Window:" << endl; - cout << indent_str_next - << "Area = " << int_inst_window->area.get_area() * 1e-6 << " mm^2" - << endl; - cout << indent_str_next << "Peak Dynamic = " - << int_inst_window->power.readOp.dynamic * clockRate << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel - ? int_inst_window->power.readOp.longer_channel_leakage - : int_inst_window->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << int_inst_window->power.readOp.gate_leakage - << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " - << int_inst_window->rt_power.readOp.dynamic / executionTime << " W" - << endl; - cout << endl; +void LoadStoreU::computeEnergy(bool is_tdp) +{ + if (!exist) return; + + executionTime=XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6);//Syed + + //RF crossbar power (Syed) + xbar_shared->compute_power(); + + if (is_tdp) + { + + //init stats for Peak + // added by Jingwen + sharedmemory.caches->stats_t.readAc.access = 0.67*sharedmemory.caches->l_ip.num_rw_ports*coredynp.LSU_duty_cycle; + sharedmemory.caches->stats_t.readAc.miss = 0; + sharedmemory.caches->stats_t.readAc.hit = sharedmemory.caches->stats_t.readAc.access - sharedmemory.caches->stats_t.readAc.miss; + sharedmemory.caches->stats_t.writeAc.access = 0.33*sharedmemory.caches->l_ip.num_rw_ports*coredynp.LSU_duty_cycle; + sharedmemory.caches->stats_t.writeAc.miss = 0; + sharedmemory.caches->stats_t.writeAc.hit = sharedmemory.caches->stats_t.writeAc.access - sharedmemory.caches->stats_t.writeAc.miss; + sharedmemory.caches->tdp_stats = sharedmemory.caches->stats_t; + + sharedmemory.missb->stats_t.readAc.access = sharedmemory.missb->l_ip.num_search_ports; + sharedmemory.missb->stats_t.writeAc.access = sharedmemory.missb->l_ip.num_search_ports; + sharedmemory.missb->tdp_stats = sharedmemory.missb->stats_t; + + sharedmemory.ifb->stats_t.readAc.access = sharedmemory.ifb->l_ip.num_search_ports; + sharedmemory.ifb->stats_t.writeAc.access = sharedmemory.ifb->l_ip.num_search_ports; + sharedmemory.ifb->tdp_stats = sharedmemory.ifb->stats_t; + + sharedmemory.prefetchb->stats_t.readAc.access = sharedmemory.prefetchb->l_ip.num_search_ports; + sharedmemory.prefetchb->stats_t.writeAc.access = sharedmemory.ifb->l_ip.num_search_ports; + sharedmemory.prefetchb->tdp_stats = sharedmemory.prefetchb->stats_t; + if (cache_p==Write_back) + { + sharedmemory.wbb->stats_t.readAc.access = sharedmemory.wbb->l_ip.num_search_ports; + sharedmemory.wbb->stats_t.writeAc.access = sharedmemory.wbb->l_ip.num_search_ports; + sharedmemory.wbb->tdp_stats = sharedmemory.wbb->stats_t; + } + + + + //init stats for Peak + dcache.caches->stats_t.readAc.access = 0.67*dcache.caches->l_ip.num_rw_ports*coredynp.LSU_duty_cycle; + dcache.caches->stats_t.readAc.miss = 0; + dcache.caches->stats_t.readAc.hit = dcache.caches->stats_t.readAc.access - dcache.caches->stats_t.readAc.miss; + dcache.caches->stats_t.writeAc.access = 0.33*dcache.caches->l_ip.num_rw_ports*coredynp.LSU_duty_cycle; + dcache.caches->stats_t.writeAc.miss = 0; + dcache.caches->stats_t.writeAc.hit = dcache.caches->stats_t.writeAc.access - dcache.caches->stats_t.writeAc.miss; + dcache.caches->tdp_stats = dcache.caches->stats_t; + + dcache.missb->stats_t.readAc.access = dcache.missb->l_ip.num_search_ports; + dcache.missb->stats_t.writeAc.access = dcache.missb->l_ip.num_search_ports; + dcache.missb->tdp_stats = dcache.missb->stats_t; + + dcache.ifb->stats_t.readAc.access = dcache.ifb->l_ip.num_search_ports; + dcache.ifb->stats_t.writeAc.access = dcache.ifb->l_ip.num_search_ports; + dcache.ifb->tdp_stats = dcache.ifb->stats_t; + + dcache.prefetchb->stats_t.readAc.access = dcache.prefetchb->l_ip.num_search_ports; + dcache.prefetchb->stats_t.writeAc.access = dcache.ifb->l_ip.num_search_ports; + dcache.prefetchb->tdp_stats = dcache.prefetchb->stats_t; + if (cache_p==Write_back) + { + dcache.wbb->stats_t.readAc.access = dcache.wbb->l_ip.num_search_ports; + dcache.wbb->stats_t.writeAc.access = dcache.wbb->l_ip.num_search_ports; + dcache.wbb->tdp_stats = dcache.wbb->stats_t; + } + + + //init stats for Peak - ccache + ccache.caches->stats_t.readAc.access = 0.67*ccache.caches->l_ip.num_rw_ports*coredynp.LSU_duty_cycle; + ccache.caches->stats_t.readAc.miss = 0; + ccache.caches->stats_t.readAc.hit = ccache.caches->stats_t.readAc.access - ccache.caches->stats_t.readAc.miss; + ccache.caches->stats_t.writeAc.access = 0.33*ccache.caches->l_ip.num_rw_ports*coredynp.LSU_duty_cycle; + ccache.caches->stats_t.writeAc.miss = 0; + ccache.caches->stats_t.writeAc.hit = ccache.caches->stats_t.writeAc.access - ccache.caches->stats_t.writeAc.miss; + ccache.caches->tdp_stats = ccache.caches->stats_t; + + ccache.missb->stats_t.readAc.access = ccache.missb->l_ip.num_search_ports; + ccache.missb->stats_t.writeAc.access = ccache.missb->l_ip.num_search_ports; + ccache.missb->tdp_stats = ccache.missb->stats_t; + + ccache.ifb->stats_t.readAc.access = ccache.ifb->l_ip.num_search_ports; + ccache.ifb->stats_t.writeAc.access = ccache.ifb->l_ip.num_search_ports; + ccache.ifb->tdp_stats = ccache.ifb->stats_t; + + ccache.prefetchb->stats_t.readAc.access = ccache.prefetchb->l_ip.num_search_ports; + ccache.prefetchb->stats_t.writeAc.access = ccache.ifb->l_ip.num_search_ports; + ccache.prefetchb->tdp_stats = ccache.prefetchb->stats_t; + if (cache_p==Write_back) + { + ccache.wbb->stats_t.readAc.access = ccache.wbb->l_ip.num_search_ports; + ccache.wbb->stats_t.writeAc.access = ccache.wbb->l_ip.num_search_ports; + ccache.wbb->tdp_stats = ccache.wbb->stats_t; + } + + + //init stats for Peak - tcache + tcache.caches->stats_t.readAc.access = 0.67*tcache.caches->l_ip.num_rw_ports*coredynp.LSU_duty_cycle; + tcache.caches->stats_t.readAc.miss = 0; + tcache.caches->stats_t.readAc.hit = tcache.caches->stats_t.readAc.access - tcache.caches->stats_t.readAc.miss; + tcache.caches->stats_t.writeAc.access = 0.33*tcache.caches->l_ip.num_rw_ports*coredynp.LSU_duty_cycle; + tcache.caches->stats_t.writeAc.miss = 0; + tcache.caches->stats_t.writeAc.hit = tcache.caches->stats_t.writeAc.access - tcache.caches->stats_t.writeAc.miss; + tcache.caches->tdp_stats = tcache.caches->stats_t; + + tcache.missb->stats_t.readAc.access = tcache.missb->l_ip.num_search_ports; + tcache.missb->stats_t.writeAc.access = tcache.missb->l_ip.num_search_ports; + tcache.missb->tdp_stats = tcache.missb->stats_t; + + tcache.ifb->stats_t.readAc.access = tcache.ifb->l_ip.num_search_ports; + tcache.ifb->stats_t.writeAc.access = tcache.ifb->l_ip.num_search_ports; + tcache.ifb->tdp_stats = tcache.ifb->stats_t; + + tcache.prefetchb->stats_t.readAc.access = tcache.prefetchb->l_ip.num_search_ports; + tcache.prefetchb->stats_t.writeAc.access = tcache.ifb->l_ip.num_search_ports; + tcache.prefetchb->tdp_stats = tcache.prefetchb->stats_t; + if (cache_p==Write_back) + { + tcache.wbb->stats_t.readAc.access = tcache.wbb->l_ip.num_search_ports; + tcache.wbb->stats_t.writeAc.access = tcache.wbb->l_ip.num_search_ports; + tcache.wbb->tdp_stats = tcache.wbb->stats_t; + } + + + + LSQ->stats_t.readAc.access = LSQ->stats_t.writeAc.access = LSQ->l_ip.num_search_ports*coredynp.LSU_duty_cycle; + LSQ->tdp_stats = LSQ->stats_t; + if ((coredynp.core_ty==OOO) && (XML->sys.core[ithCore].load_buffer_size >0)) + { + LoadQ->stats_t.readAc.access = LoadQ->stats_t.writeAc.access = LoadQ->l_ip.num_search_ports*coredynp.LSU_duty_cycle; + LoadQ->tdp_stats = LoadQ->stats_t; + } + } + else + { + //init stats for Runtime Dynamic (RTP) + + sharedmemory.caches->stats_t.readAc.access = XML->sys.core[ithCore].sharedmemory.read_accesses; + sharedmemory.caches->stats_t.readAc.miss = XML->sys.core[ithCore].sharedmemory.read_misses; + sharedmemory.caches->stats_t.readAc.hit = sharedmemory.caches->stats_t.readAc.access - sharedmemory.caches->stats_t.readAc.miss; + sharedmemory.caches->stats_t.writeAc.access = XML->sys.core[ithCore].sharedmemory.write_accesses; + sharedmemory.caches->stats_t.writeAc.miss = XML->sys.core[ithCore].sharedmemory.write_misses; + sharedmemory.caches->stats_t.writeAc.hit = sharedmemory.caches->stats_t.writeAc.access - sharedmemory.caches->stats_t.writeAc.miss; + sharedmemory.caches->rtp_stats = sharedmemory.caches->stats_t; + + + + dcache.caches->stats_t.readAc.access = XML->sys.core[ithCore].dcache.read_accesses; + dcache.caches->stats_t.readAc.miss = XML->sys.core[ithCore].dcache.read_misses; + dcache.caches->stats_t.readAc.hit = dcache.caches->stats_t.readAc.access - dcache.caches->stats_t.readAc.miss; + dcache.caches->stats_t.writeAc.access = XML->sys.core[ithCore].dcache.write_accesses; + dcache.caches->stats_t.writeAc.miss = XML->sys.core[ithCore].dcache.write_misses; + dcache.caches->stats_t.writeAc.hit = dcache.caches->stats_t.writeAc.access - dcache.caches->stats_t.writeAc.miss; + dcache.caches->rtp_stats = dcache.caches->stats_t; + + ccache.caches->stats_t.readAc.access = XML->sys.core[ithCore].ccache.read_accesses; + ccache.caches->stats_t.readAc.miss = XML->sys.core[ithCore].ccache.read_misses; + ccache.caches->stats_t.readAc.hit = ccache.caches->stats_t.readAc.access - ccache.caches->stats_t.readAc.miss; + ccache.caches->stats_t.writeAc.access = XML->sys.core[ithCore].ccache.write_accesses; + ccache.caches->stats_t.writeAc.miss = XML->sys.core[ithCore].ccache.write_misses; + ccache.caches->stats_t.writeAc.hit = ccache.caches->stats_t.writeAc.access - ccache.caches->stats_t.writeAc.miss; + ccache.caches->rtp_stats = ccache.caches->stats_t; + + tcache.caches->stats_t.readAc.access = XML->sys.core[ithCore].tcache.read_accesses; + tcache.caches->stats_t.readAc.miss = XML->sys.core[ithCore].tcache.read_misses; + tcache.caches->stats_t.readAc.hit = tcache.caches->stats_t.readAc.access - tcache.caches->stats_t.readAc.miss; + tcache.caches->stats_t.writeAc.access = XML->sys.core[ithCore].tcache.write_accesses; + tcache.caches->stats_t.writeAc.miss = XML->sys.core[ithCore].tcache.write_misses; + tcache.caches->stats_t.writeAc.hit = tcache.caches->stats_t.writeAc.access - tcache.caches->stats_t.writeAc.miss; + tcache.caches->rtp_stats = tcache.caches->stats_t; + + if (cache_p==Write_back) + { + + sharedmemory.missb->stats_t.readAc.access = sharedmemory.caches->stats_t.writeAc.miss; + sharedmemory.missb->stats_t.writeAc.access = sharedmemory.caches->stats_t.writeAc.miss; + sharedmemory.missb->rtp_stats = sharedmemory.missb->stats_t; + sharedmemory.ifb->stats_t.readAc.access = sharedmemory.caches->stats_t.writeAc.miss; + sharedmemory.ifb->stats_t.writeAc.access = sharedmemory.caches->stats_t.writeAc.miss; + sharedmemory.ifb->rtp_stats = sharedmemory.ifb->stats_t; + sharedmemory.prefetchb->stats_t.readAc.access = sharedmemory.caches->stats_t.writeAc.miss; + sharedmemory.prefetchb->stats_t.writeAc.access = sharedmemory.caches->stats_t.writeAc.miss; + sharedmemory.prefetchb->rtp_stats = sharedmemory.prefetchb->stats_t; + sharedmemory.wbb->stats_t.readAc.access = sharedmemory.caches->stats_t.writeAc.miss; + sharedmemory.wbb->stats_t.writeAc.access = sharedmemory.caches->stats_t.writeAc.miss; + sharedmemory.wbb->rtp_stats = sharedmemory.wbb->stats_t; + + + dcache.missb->stats_t.readAc.access = dcache.caches->stats_t.writeAc.miss; + dcache.missb->stats_t.writeAc.access = dcache.caches->stats_t.writeAc.miss; + dcache.missb->rtp_stats = dcache.missb->stats_t; + dcache.ifb->stats_t.readAc.access = dcache.caches->stats_t.writeAc.miss; + dcache.ifb->stats_t.writeAc.access = dcache.caches->stats_t.writeAc.miss; + dcache.ifb->rtp_stats = dcache.ifb->stats_t; + dcache.prefetchb->stats_t.readAc.access = dcache.caches->stats_t.writeAc.miss; + dcache.prefetchb->stats_t.writeAc.access = dcache.caches->stats_t.writeAc.miss; + dcache.prefetchb->rtp_stats = dcache.prefetchb->stats_t; + dcache.wbb->stats_t.readAc.access = dcache.caches->stats_t.writeAc.miss; + dcache.wbb->stats_t.writeAc.access = dcache.caches->stats_t.writeAc.miss; + dcache.wbb->rtp_stats = dcache.wbb->stats_t; + + ccache.missb->stats_t.readAc.access = ccache.caches->stats_t.writeAc.miss; + ccache.missb->stats_t.writeAc.access = ccache.caches->stats_t.writeAc.miss; + ccache.missb->rtp_stats = ccache.missb->stats_t; + ccache.ifb->stats_t.readAc.access = ccache.caches->stats_t.writeAc.miss; + ccache.ifb->stats_t.writeAc.access = ccache.caches->stats_t.writeAc.miss; + ccache.ifb->rtp_stats = ccache.ifb->stats_t; + ccache.prefetchb->stats_t.readAc.access = ccache.caches->stats_t.writeAc.miss; + ccache.prefetchb->stats_t.writeAc.access = ccache.caches->stats_t.writeAc.miss; + ccache.prefetchb->rtp_stats = ccache.prefetchb->stats_t; + ccache.wbb->stats_t.readAc.access = ccache.caches->stats_t.writeAc.miss; + ccache.wbb->stats_t.writeAc.access = ccache.caches->stats_t.writeAc.miss; + ccache.wbb->rtp_stats = ccache.wbb->stats_t; + + tcache.missb->stats_t.readAc.access = tcache.caches->stats_t.writeAc.miss; + tcache.missb->stats_t.writeAc.access = tcache.caches->stats_t.writeAc.miss; + tcache.missb->rtp_stats = tcache.missb->stats_t; + tcache.ifb->stats_t.readAc.access = tcache.caches->stats_t.writeAc.miss; + tcache.ifb->stats_t.writeAc.access = tcache.caches->stats_t.writeAc.miss; + tcache.ifb->rtp_stats = tcache.ifb->stats_t; + tcache.prefetchb->stats_t.readAc.access = tcache.caches->stats_t.writeAc.miss; + tcache.prefetchb->stats_t.writeAc.access = tcache.caches->stats_t.writeAc.miss; + tcache.prefetchb->rtp_stats = tcache.prefetchb->stats_t; + tcache.wbb->stats_t.readAc.access = tcache.caches->stats_t.writeAc.miss; + tcache.wbb->stats_t.writeAc.access = tcache.caches->stats_t.writeAc.miss; + tcache.wbb->rtp_stats = tcache.wbb->stats_t; + } + else + { + sharedmemory.missb->stats_t.readAc.access = sharedmemory.caches->stats_t.readAc.miss; + sharedmemory.missb->stats_t.writeAc.access = sharedmemory.caches->stats_t.readAc.miss; + sharedmemory.missb->rtp_stats = sharedmemory.missb->stats_t; + sharedmemory.ifb->stats_t.readAc.access = sharedmemory.caches->stats_t.readAc.miss; + sharedmemory.ifb->stats_t.writeAc.access = sharedmemory.caches->stats_t.readAc.miss; + sharedmemory.ifb->rtp_stats = sharedmemory.ifb->stats_t; + sharedmemory.prefetchb->stats_t.readAc.access = sharedmemory.caches->stats_t.readAc.miss; + sharedmemory.prefetchb->stats_t.writeAc.access = sharedmemory.caches->stats_t.readAc.miss; + sharedmemory.prefetchb->rtp_stats = sharedmemory.prefetchb->stats_t; + + + dcache.missb->stats_t.readAc.access = dcache.caches->stats_t.readAc.miss; + dcache.missb->stats_t.writeAc.access = dcache.caches->stats_t.readAc.miss; + dcache.missb->rtp_stats = dcache.missb->stats_t; + dcache.ifb->stats_t.readAc.access = dcache.caches->stats_t.readAc.miss; + dcache.ifb->stats_t.writeAc.access = dcache.caches->stats_t.readAc.miss; + dcache.ifb->rtp_stats = dcache.ifb->stats_t; + dcache.prefetchb->stats_t.readAc.access = dcache.caches->stats_t.readAc.miss; + dcache.prefetchb->stats_t.writeAc.access = dcache.caches->stats_t.readAc.miss; + dcache.prefetchb->rtp_stats = dcache.prefetchb->stats_t; + + + ccache.missb->stats_t.readAc.access = ccache.caches->stats_t.readAc.miss; + ccache.missb->stats_t.writeAc.access = ccache.caches->stats_t.readAc.miss; + ccache.missb->rtp_stats = ccache.missb->stats_t; + ccache.ifb->stats_t.readAc.access = ccache.caches->stats_t.readAc.miss; + ccache.ifb->stats_t.writeAc.access = ccache.caches->stats_t.readAc.miss; + ccache.ifb->rtp_stats = ccache.ifb->stats_t; + ccache.prefetchb->stats_t.readAc.access = ccache.caches->stats_t.readAc.miss; + ccache.prefetchb->stats_t.writeAc.access = ccache.caches->stats_t.readAc.miss; + ccache.prefetchb->rtp_stats = ccache.prefetchb->stats_t; + + tcache.missb->stats_t.readAc.access = tcache.caches->stats_t.readAc.miss; + tcache.missb->stats_t.writeAc.access = tcache.caches->stats_t.readAc.miss; + tcache.missb->rtp_stats = tcache.missb->stats_t; + tcache.ifb->stats_t.readAc.access = tcache.caches->stats_t.readAc.miss; + tcache.ifb->stats_t.writeAc.access = tcache.caches->stats_t.readAc.miss; + tcache.ifb->rtp_stats = tcache.ifb->stats_t; + tcache.prefetchb->stats_t.readAc.access = tcache.caches->stats_t.readAc.miss; + tcache.prefetchb->stats_t.writeAc.access = tcache.caches->stats_t.readAc.miss; + tcache.prefetchb->rtp_stats = tcache.prefetchb->stats_t; + + } + + LSQ->stats_t.readAc.access = (XML->sys.core[ithCore].load_instructions + XML->sys.core[ithCore].store_instructions)*2;//flush overhead considered + LSQ->stats_t.writeAc.access = (XML->sys.core[ithCore].load_instructions + XML->sys.core[ithCore].store_instructions)*2; + LSQ->rtp_stats = LSQ->stats_t; + + if ((coredynp.core_ty==OOO) && (XML->sys.core[ithCore].load_buffer_size >0)) + { + LoadQ->stats_t.readAc.access = XML->sys.core[ithCore].load_instructions + XML->sys.core[ithCore].store_instructions; + LoadQ->stats_t.writeAc.access = XML->sys.core[ithCore].load_instructions + XML->sys.core[ithCore].store_instructions; + LoadQ->rtp_stats = LoadQ->stats_t; + } + + } + + sharedmemory.power_t.reset(); + dcache.power_t.reset(); + ccache.power_t.reset(); + tcache.power_t.reset(); + LSQ->power_t.reset(); + + sharedmemory.power_t.readOp.dynamic += (sharedmemory.caches->stats_t.readAc.hit*sharedmemory.caches->local_result.power.readOp.dynamic+ + sharedmemory.caches->stats_t.readAc.miss*sharedmemory.caches->local_result.power.readOp.dynamic+ + sharedmemory.caches->stats_t.writeAc.miss*sharedmemory.caches->local_result.tag_array2->power.readOp.dynamic+ + sharedmemory.caches->stats_t.writeAc.access*sharedmemory.caches->local_result.power.writeOp.dynamic + + xbar_shared->power.readOp.dynamic*(sharedmemory.caches->stats_t.readAc.hit+ sharedmemory.caches->stats_t.writeAc.hit)); + + + dcache.power_t.readOp.dynamic += (dcache.caches->stats_t.readAc.hit*dcache.caches->local_result.power.readOp.dynamic+ + dcache.caches->stats_t.readAc.miss*dcache.caches->local_result.power.readOp.dynamic+ + dcache.caches->stats_t.writeAc.miss*dcache.caches->local_result.tag_array2->power.readOp.dynamic+ + dcache.caches->stats_t.writeAc.access*dcache.caches->local_result.power.writeOp.dynamic + + xbar_shared->power.readOp.dynamic*(dcache.caches->stats_t.readAc.hit+ dcache.caches->stats_t.writeAc.hit)); + ccache.power_t.readOp.dynamic += (ccache.caches->stats_t.readAc.hit*ccache.caches->local_result.power.readOp.dynamic+ + ccache.caches->stats_t.readAc.miss*ccache.caches->local_result.power.readOp.dynamic+ + ccache.caches->stats_t.writeAc.miss*ccache.caches->local_result.tag_array2->power.readOp.dynamic+ + ccache.caches->stats_t.writeAc.access*ccache.caches->local_result.power.writeOp.dynamic + + xbar_shared->power.readOp.dynamic*(ccache.caches->stats_t.readAc.hit)); + + tcache.power_t.readOp.dynamic += (tcache.caches->stats_t.readAc.hit*tcache.caches->local_result.power.readOp.dynamic+ + tcache.caches->stats_t.readAc.miss*tcache.caches->local_result.power.readOp.dynamic+ + tcache.caches->stats_t.writeAc.miss*tcache.caches->local_result.tag_array2->power.readOp.dynamic+ + tcache.caches->stats_t.writeAc.access*tcache.caches->local_result.power.writeOp.dynamic+ + xbar_shared->power.readOp.dynamic*(tcache.caches->stats_t.readAc.hit+ tcache.caches->stats_t.writeAc.hit)); + + if (cache_p==Write_back) + {//write miss will generate a write later + dcache.power_t.readOp.dynamic += dcache.caches->stats_t.writeAc.miss*dcache.caches->local_result.power.writeOp.dynamic; + ccache.power_t.readOp.dynamic += ccache.caches->stats_t.writeAc.miss*ccache.caches->local_result.power.writeOp.dynamic; + tcache.power_t.readOp.dynamic += tcache.caches->stats_t.writeAc.miss*tcache.caches->local_result.power.writeOp.dynamic; + sharedmemory.power_t.readOp.dynamic += sharedmemory.caches->stats_t.writeAc.miss*sharedmemory.caches->local_result.power.writeOp.dynamic; } - } else { - if (coredynp.core_ty == OOO) { - cout << indent_str_next << "Instruction Window Peak Dynamic = " - << int_inst_window->rt_power.readOp.dynamic * clockRate << " W" - << endl; - cout << indent_str_next << "Instruction Window Subthreshold Leakage = " - << int_inst_window->rt_power.readOp.leakage << " W" << endl; - cout << indent_str_next << "Instruction Window Gate Leakage = " - << int_inst_window->rt_power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "FP Instruction Window Peak Dynamic = " - << fp_inst_window->rt_power.readOp.dynamic * clockRate << " W" - << endl; - cout << indent_str_next - << "FP Instruction Window Subthreshold Leakage = " - << fp_inst_window->rt_power.readOp.leakage << " W" << endl; - cout << indent_str_next << "FP Instruction Window Gate Leakage = " - << fp_inst_window->rt_power.readOp.gate_leakage << " W" << endl; - if (XML->sys.core[ithCore].ROB_size > 0) { - cout << indent_str_next << "ROB Peak Dynamic = " - << ROB->rt_power.readOp.dynamic * clockRate << " W" << endl; - cout << indent_str_next - << "ROB Subthreshold Leakage = " << ROB->rt_power.readOp.leakage - << " W" << endl; - cout << indent_str_next - << "ROB Gate Leakage = " << ROB->rt_power.readOp.gate_leakage - << " W" << endl; - } - } else if (coredynp.multithreaded) { - cout << indent_str_next << "Instruction Window Peak Dynamic = " - << int_inst_window->rt_power.readOp.dynamic * clockRate << " W" - << endl; - cout << indent_str_next << "Instruction Window Subthreshold Leakage = " - << int_inst_window->rt_power.readOp.leakage << " W" << endl; - cout << indent_str_next << "Instruction Window Gate Leakage = " - << int_inst_window->rt_power.readOp.gate_leakage << " W" << endl; - } - } -} -void LoadStoreU::computeEnergy(bool is_tdp) { - if (!exist) return; - - executionTime = - XML->sys.total_cycles / (XML->sys.target_core_clockrate * 1e6); // Syed - - // RF crossbar power (Syed) - xbar_shared->compute_power(); - - if (is_tdp) { - // init stats for Peak - // added by Jingwen - sharedmemory.caches->stats_t.readAc.access = - 0.67 * sharedmemory.caches->l_ip.num_rw_ports * coredynp.LSU_duty_cycle; - sharedmemory.caches->stats_t.readAc.miss = 0; - sharedmemory.caches->stats_t.readAc.hit = - sharedmemory.caches->stats_t.readAc.access - - sharedmemory.caches->stats_t.readAc.miss; - sharedmemory.caches->stats_t.writeAc.access = - 0.33 * sharedmemory.caches->l_ip.num_rw_ports * coredynp.LSU_duty_cycle; - sharedmemory.caches->stats_t.writeAc.miss = 0; - sharedmemory.caches->stats_t.writeAc.hit = - sharedmemory.caches->stats_t.writeAc.access - - sharedmemory.caches->stats_t.writeAc.miss; - sharedmemory.caches->tdp_stats = sharedmemory.caches->stats_t; - - sharedmemory.missb->stats_t.readAc.access = - sharedmemory.missb->l_ip.num_search_ports; - sharedmemory.missb->stats_t.writeAc.access = - sharedmemory.missb->l_ip.num_search_ports; - sharedmemory.missb->tdp_stats = sharedmemory.missb->stats_t; - - sharedmemory.ifb->stats_t.readAc.access = - sharedmemory.ifb->l_ip.num_search_ports; - sharedmemory.ifb->stats_t.writeAc.access = - sharedmemory.ifb->l_ip.num_search_ports; - sharedmemory.ifb->tdp_stats = sharedmemory.ifb->stats_t; - - sharedmemory.prefetchb->stats_t.readAc.access = - sharedmemory.prefetchb->l_ip.num_search_ports; - sharedmemory.prefetchb->stats_t.writeAc.access = - sharedmemory.ifb->l_ip.num_search_ports; - sharedmemory.prefetchb->tdp_stats = sharedmemory.prefetchb->stats_t; - if (cache_p == Write_back) { - sharedmemory.wbb->stats_t.readAc.access = - sharedmemory.wbb->l_ip.num_search_ports; - sharedmemory.wbb->stats_t.writeAc.access = - sharedmemory.wbb->l_ip.num_search_ports; - sharedmemory.wbb->tdp_stats = sharedmemory.wbb->stats_t; - } - // init stats for Peak - dcache.caches->stats_t.readAc.access = - 0.67 * dcache.caches->l_ip.num_rw_ports * coredynp.LSU_duty_cycle; - dcache.caches->stats_t.readAc.miss = 0; - dcache.caches->stats_t.readAc.hit = dcache.caches->stats_t.readAc.access - - dcache.caches->stats_t.readAc.miss; - dcache.caches->stats_t.writeAc.access = - 0.33 * dcache.caches->l_ip.num_rw_ports * coredynp.LSU_duty_cycle; - dcache.caches->stats_t.writeAc.miss = 0; - dcache.caches->stats_t.writeAc.hit = dcache.caches->stats_t.writeAc.access - - dcache.caches->stats_t.writeAc.miss; - dcache.caches->tdp_stats = dcache.caches->stats_t; - - dcache.missb->stats_t.readAc.access = dcache.missb->l_ip.num_search_ports; - dcache.missb->stats_t.writeAc.access = dcache.missb->l_ip.num_search_ports; - dcache.missb->tdp_stats = dcache.missb->stats_t; - - dcache.ifb->stats_t.readAc.access = dcache.ifb->l_ip.num_search_ports; - dcache.ifb->stats_t.writeAc.access = dcache.ifb->l_ip.num_search_ports; - dcache.ifb->tdp_stats = dcache.ifb->stats_t; - - dcache.prefetchb->stats_t.readAc.access = - dcache.prefetchb->l_ip.num_search_ports; - dcache.prefetchb->stats_t.writeAc.access = - dcache.ifb->l_ip.num_search_ports; - dcache.prefetchb->tdp_stats = dcache.prefetchb->stats_t; - if (cache_p == Write_back) { - dcache.wbb->stats_t.readAc.access = dcache.wbb->l_ip.num_search_ports; - dcache.wbb->stats_t.writeAc.access = dcache.wbb->l_ip.num_search_ports; - dcache.wbb->tdp_stats = dcache.wbb->stats_t; + sharedmemory.power_t.readOp.dynamic += sharedmemory.missb->stats_t.readAc.access*sharedmemory.missb->local_result.power.searchOp.dynamic + + sharedmemory.missb->stats_t.writeAc.access*sharedmemory.missb->local_result.power.writeOp.dynamic;//each access to missb involves a CAM and a write + sharedmemory.power_t.readOp.dynamic += sharedmemory.ifb->stats_t.readAc.access*sharedmemory.ifb->local_result.power.searchOp.dynamic + + sharedmemory.ifb->stats_t.writeAc.access*sharedmemory.ifb->local_result.power.writeOp.dynamic; + sharedmemory.power_t.readOp.dynamic += sharedmemory.prefetchb->stats_t.readAc.access*sharedmemory.prefetchb->local_result.power.searchOp.dynamic + + sharedmemory.prefetchb->stats_t.writeAc.access*sharedmemory.prefetchb->local_result.power.writeOp.dynamic; + if (cache_p==Write_back) + { + sharedmemory.power_t.readOp.dynamic += sharedmemory.wbb->stats_t.readAc.access*sharedmemory.wbb->local_result.power.searchOp.dynamic + + sharedmemory.wbb->stats_t.writeAc.access*sharedmemory.wbb->local_result.power.writeOp.dynamic; } - // init stats for Peak - ccache - ccache.caches->stats_t.readAc.access = - 0.67 * ccache.caches->l_ip.num_rw_ports * coredynp.LSU_duty_cycle; - ccache.caches->stats_t.readAc.miss = 0; - ccache.caches->stats_t.readAc.hit = ccache.caches->stats_t.readAc.access - - ccache.caches->stats_t.readAc.miss; - ccache.caches->stats_t.writeAc.access = - 0.33 * ccache.caches->l_ip.num_rw_ports * coredynp.LSU_duty_cycle; - ccache.caches->stats_t.writeAc.miss = 0; - ccache.caches->stats_t.writeAc.hit = ccache.caches->stats_t.writeAc.access - - ccache.caches->stats_t.writeAc.miss; - ccache.caches->tdp_stats = ccache.caches->stats_t; - - ccache.missb->stats_t.readAc.access = ccache.missb->l_ip.num_search_ports; - ccache.missb->stats_t.writeAc.access = ccache.missb->l_ip.num_search_ports; - ccache.missb->tdp_stats = ccache.missb->stats_t; - - ccache.ifb->stats_t.readAc.access = ccache.ifb->l_ip.num_search_ports; - ccache.ifb->stats_t.writeAc.access = ccache.ifb->l_ip.num_search_ports; - ccache.ifb->tdp_stats = ccache.ifb->stats_t; - - ccache.prefetchb->stats_t.readAc.access = - ccache.prefetchb->l_ip.num_search_ports; - ccache.prefetchb->stats_t.writeAc.access = - ccache.ifb->l_ip.num_search_ports; - ccache.prefetchb->tdp_stats = ccache.prefetchb->stats_t; - if (cache_p == Write_back) { - ccache.wbb->stats_t.readAc.access = ccache.wbb->l_ip.num_search_ports; - ccache.wbb->stats_t.writeAc.access = ccache.wbb->l_ip.num_search_ports; - ccache.wbb->tdp_stats = ccache.wbb->stats_t; - } - // init stats for Peak - tcache - tcache.caches->stats_t.readAc.access = - 0.67 * tcache.caches->l_ip.num_rw_ports * coredynp.LSU_duty_cycle; - tcache.caches->stats_t.readAc.miss = 0; - tcache.caches->stats_t.readAc.hit = tcache.caches->stats_t.readAc.access - - tcache.caches->stats_t.readAc.miss; - tcache.caches->stats_t.writeAc.access = - 0.33 * tcache.caches->l_ip.num_rw_ports * coredynp.LSU_duty_cycle; - tcache.caches->stats_t.writeAc.miss = 0; - tcache.caches->stats_t.writeAc.hit = tcache.caches->stats_t.writeAc.access - - tcache.caches->stats_t.writeAc.miss; - tcache.caches->tdp_stats = tcache.caches->stats_t; - - tcache.missb->stats_t.readAc.access = tcache.missb->l_ip.num_search_ports; - tcache.missb->stats_t.writeAc.access = tcache.missb->l_ip.num_search_ports; - tcache.missb->tdp_stats = tcache.missb->stats_t; - - tcache.ifb->stats_t.readAc.access = tcache.ifb->l_ip.num_search_ports; - tcache.ifb->stats_t.writeAc.access = tcache.ifb->l_ip.num_search_ports; - tcache.ifb->tdp_stats = tcache.ifb->stats_t; - - tcache.prefetchb->stats_t.readAc.access = - tcache.prefetchb->l_ip.num_search_ports; - tcache.prefetchb->stats_t.writeAc.access = - tcache.ifb->l_ip.num_search_ports; - tcache.prefetchb->tdp_stats = tcache.prefetchb->stats_t; - if (cache_p == Write_back) { - tcache.wbb->stats_t.readAc.access = tcache.wbb->l_ip.num_search_ports; - tcache.wbb->stats_t.writeAc.access = tcache.wbb->l_ip.num_search_ports; - tcache.wbb->tdp_stats = tcache.wbb->stats_t; + dcache.power_t.readOp.dynamic += dcache.missb->stats_t.readAc.access*dcache.missb->local_result.power.searchOp.dynamic + + dcache.missb->stats_t.writeAc.access*dcache.missb->local_result.power.writeOp.dynamic;//each access to missb involves a CAM and a write + dcache.power_t.readOp.dynamic += dcache.ifb->stats_t.readAc.access*dcache.ifb->local_result.power.searchOp.dynamic + + dcache.ifb->stats_t.writeAc.access*dcache.ifb->local_result.power.writeOp.dynamic; + dcache.power_t.readOp.dynamic += dcache.prefetchb->stats_t.readAc.access*dcache.prefetchb->local_result.power.searchOp.dynamic + + dcache.prefetchb->stats_t.writeAc.access*dcache.prefetchb->local_result.power.writeOp.dynamic; + if (cache_p==Write_back) + { + dcache.power_t.readOp.dynamic += dcache.wbb->stats_t.readAc.access*dcache.wbb->local_result.power.searchOp.dynamic + + dcache.wbb->stats_t.writeAc.access*dcache.wbb->local_result.power.writeOp.dynamic; } - LSQ->stats_t.readAc.access = LSQ->stats_t.writeAc.access = - LSQ->l_ip.num_search_ports * coredynp.LSU_duty_cycle; - LSQ->tdp_stats = LSQ->stats_t; - if ((coredynp.core_ty == OOO) && - (XML->sys.core[ithCore].load_buffer_size > 0)) { - LoadQ->stats_t.readAc.access = LoadQ->stats_t.writeAc.access = - LoadQ->l_ip.num_search_ports * coredynp.LSU_duty_cycle; - LoadQ->tdp_stats = LoadQ->stats_t; - } - } else { - // init stats for Runtime Dynamic (RTP) - - sharedmemory.caches->stats_t.readAc.access = - XML->sys.core[ithCore].sharedmemory.read_accesses; - sharedmemory.caches->stats_t.readAc.miss = - XML->sys.core[ithCore].sharedmemory.read_misses; - sharedmemory.caches->stats_t.readAc.hit = - sharedmemory.caches->stats_t.readAc.access - - sharedmemory.caches->stats_t.readAc.miss; - sharedmemory.caches->stats_t.writeAc.access = - XML->sys.core[ithCore].sharedmemory.write_accesses; - sharedmemory.caches->stats_t.writeAc.miss = - XML->sys.core[ithCore].sharedmemory.write_misses; - sharedmemory.caches->stats_t.writeAc.hit = - sharedmemory.caches->stats_t.writeAc.access - - sharedmemory.caches->stats_t.writeAc.miss; - sharedmemory.caches->rtp_stats = sharedmemory.caches->stats_t; - - dcache.caches->stats_t.readAc.access = - XML->sys.core[ithCore].dcache.read_accesses; - dcache.caches->stats_t.readAc.miss = - XML->sys.core[ithCore].dcache.read_misses; - dcache.caches->stats_t.readAc.hit = dcache.caches->stats_t.readAc.access - - dcache.caches->stats_t.readAc.miss; - dcache.caches->stats_t.writeAc.access = - XML->sys.core[ithCore].dcache.write_accesses; - dcache.caches->stats_t.writeAc.miss = - XML->sys.core[ithCore].dcache.write_misses; - dcache.caches->stats_t.writeAc.hit = dcache.caches->stats_t.writeAc.access - - dcache.caches->stats_t.writeAc.miss; - dcache.caches->rtp_stats = dcache.caches->stats_t; - - ccache.caches->stats_t.readAc.access = - XML->sys.core[ithCore].ccache.read_accesses; - ccache.caches->stats_t.readAc.miss = - XML->sys.core[ithCore].ccache.read_misses; - ccache.caches->stats_t.readAc.hit = ccache.caches->stats_t.readAc.access - - ccache.caches->stats_t.readAc.miss; - ccache.caches->stats_t.writeAc.access = - XML->sys.core[ithCore].ccache.write_accesses; - ccache.caches->stats_t.writeAc.miss = - XML->sys.core[ithCore].ccache.write_misses; - ccache.caches->stats_t.writeAc.hit = ccache.caches->stats_t.writeAc.access - - ccache.caches->stats_t.writeAc.miss; - ccache.caches->rtp_stats = ccache.caches->stats_t; - - tcache.caches->stats_t.readAc.access = - XML->sys.core[ithCore].tcache.read_accesses; - tcache.caches->stats_t.readAc.miss = - XML->sys.core[ithCore].tcache.read_misses; - tcache.caches->stats_t.readAc.hit = tcache.caches->stats_t.readAc.access - - tcache.caches->stats_t.readAc.miss; - tcache.caches->stats_t.writeAc.access = - XML->sys.core[ithCore].tcache.write_accesses; - tcache.caches->stats_t.writeAc.miss = - XML->sys.core[ithCore].tcache.write_misses; - tcache.caches->stats_t.writeAc.hit = tcache.caches->stats_t.writeAc.access - - tcache.caches->stats_t.writeAc.miss; - tcache.caches->rtp_stats = tcache.caches->stats_t; - - if (cache_p == Write_back) { - sharedmemory.missb->stats_t.readAc.access = - sharedmemory.caches->stats_t.writeAc.miss; - sharedmemory.missb->stats_t.writeAc.access = - sharedmemory.caches->stats_t.writeAc.miss; - sharedmemory.missb->rtp_stats = sharedmemory.missb->stats_t; - sharedmemory.ifb->stats_t.readAc.access = - sharedmemory.caches->stats_t.writeAc.miss; - sharedmemory.ifb->stats_t.writeAc.access = - sharedmemory.caches->stats_t.writeAc.miss; - sharedmemory.ifb->rtp_stats = sharedmemory.ifb->stats_t; - sharedmemory.prefetchb->stats_t.readAc.access = - sharedmemory.caches->stats_t.writeAc.miss; - sharedmemory.prefetchb->stats_t.writeAc.access = - sharedmemory.caches->stats_t.writeAc.miss; - sharedmemory.prefetchb->rtp_stats = sharedmemory.prefetchb->stats_t; - sharedmemory.wbb->stats_t.readAc.access = - sharedmemory.caches->stats_t.writeAc.miss; - sharedmemory.wbb->stats_t.writeAc.access = - sharedmemory.caches->stats_t.writeAc.miss; - sharedmemory.wbb->rtp_stats = sharedmemory.wbb->stats_t; - - dcache.missb->stats_t.readAc.access = dcache.caches->stats_t.writeAc.miss; - dcache.missb->stats_t.writeAc.access = - dcache.caches->stats_t.writeAc.miss; - dcache.missb->rtp_stats = dcache.missb->stats_t; - dcache.ifb->stats_t.readAc.access = dcache.caches->stats_t.writeAc.miss; - dcache.ifb->stats_t.writeAc.access = dcache.caches->stats_t.writeAc.miss; - dcache.ifb->rtp_stats = dcache.ifb->stats_t; - dcache.prefetchb->stats_t.readAc.access = - dcache.caches->stats_t.writeAc.miss; - dcache.prefetchb->stats_t.writeAc.access = - dcache.caches->stats_t.writeAc.miss; - dcache.prefetchb->rtp_stats = dcache.prefetchb->stats_t; - dcache.wbb->stats_t.readAc.access = dcache.caches->stats_t.writeAc.miss; - dcache.wbb->stats_t.writeAc.access = dcache.caches->stats_t.writeAc.miss; - dcache.wbb->rtp_stats = dcache.wbb->stats_t; - - ccache.missb->stats_t.readAc.access = ccache.caches->stats_t.writeAc.miss; - ccache.missb->stats_t.writeAc.access = - ccache.caches->stats_t.writeAc.miss; - ccache.missb->rtp_stats = ccache.missb->stats_t; - ccache.ifb->stats_t.readAc.access = ccache.caches->stats_t.writeAc.miss; - ccache.ifb->stats_t.writeAc.access = ccache.caches->stats_t.writeAc.miss; - ccache.ifb->rtp_stats = ccache.ifb->stats_t; - ccache.prefetchb->stats_t.readAc.access = - ccache.caches->stats_t.writeAc.miss; - ccache.prefetchb->stats_t.writeAc.access = - ccache.caches->stats_t.writeAc.miss; - ccache.prefetchb->rtp_stats = ccache.prefetchb->stats_t; - ccache.wbb->stats_t.readAc.access = ccache.caches->stats_t.writeAc.miss; - ccache.wbb->stats_t.writeAc.access = ccache.caches->stats_t.writeAc.miss; - ccache.wbb->rtp_stats = ccache.wbb->stats_t; - - tcache.missb->stats_t.readAc.access = tcache.caches->stats_t.writeAc.miss; - tcache.missb->stats_t.writeAc.access = - tcache.caches->stats_t.writeAc.miss; - tcache.missb->rtp_stats = tcache.missb->stats_t; - tcache.ifb->stats_t.readAc.access = tcache.caches->stats_t.writeAc.miss; - tcache.ifb->stats_t.writeAc.access = tcache.caches->stats_t.writeAc.miss; - tcache.ifb->rtp_stats = tcache.ifb->stats_t; - tcache.prefetchb->stats_t.readAc.access = - tcache.caches->stats_t.writeAc.miss; - tcache.prefetchb->stats_t.writeAc.access = - tcache.caches->stats_t.writeAc.miss; - tcache.prefetchb->rtp_stats = tcache.prefetchb->stats_t; - tcache.wbb->stats_t.readAc.access = tcache.caches->stats_t.writeAc.miss; - tcache.wbb->stats_t.writeAc.access = tcache.caches->stats_t.writeAc.miss; - tcache.wbb->rtp_stats = tcache.wbb->stats_t; - } else { - sharedmemory.missb->stats_t.readAc.access = - sharedmemory.caches->stats_t.readAc.miss; - sharedmemory.missb->stats_t.writeAc.access = - sharedmemory.caches->stats_t.readAc.miss; - sharedmemory.missb->rtp_stats = sharedmemory.missb->stats_t; - sharedmemory.ifb->stats_t.readAc.access = - sharedmemory.caches->stats_t.readAc.miss; - sharedmemory.ifb->stats_t.writeAc.access = - sharedmemory.caches->stats_t.readAc.miss; - sharedmemory.ifb->rtp_stats = sharedmemory.ifb->stats_t; - sharedmemory.prefetchb->stats_t.readAc.access = - sharedmemory.caches->stats_t.readAc.miss; - sharedmemory.prefetchb->stats_t.writeAc.access = - sharedmemory.caches->stats_t.readAc.miss; - sharedmemory.prefetchb->rtp_stats = sharedmemory.prefetchb->stats_t; - - dcache.missb->stats_t.readAc.access = dcache.caches->stats_t.readAc.miss; - dcache.missb->stats_t.writeAc.access = dcache.caches->stats_t.readAc.miss; - dcache.missb->rtp_stats = dcache.missb->stats_t; - dcache.ifb->stats_t.readAc.access = dcache.caches->stats_t.readAc.miss; - dcache.ifb->stats_t.writeAc.access = dcache.caches->stats_t.readAc.miss; - dcache.ifb->rtp_stats = dcache.ifb->stats_t; - dcache.prefetchb->stats_t.readAc.access = - dcache.caches->stats_t.readAc.miss; - dcache.prefetchb->stats_t.writeAc.access = - dcache.caches->stats_t.readAc.miss; - dcache.prefetchb->rtp_stats = dcache.prefetchb->stats_t; - - ccache.missb->stats_t.readAc.access = ccache.caches->stats_t.readAc.miss; - ccache.missb->stats_t.writeAc.access = ccache.caches->stats_t.readAc.miss; - ccache.missb->rtp_stats = ccache.missb->stats_t; - ccache.ifb->stats_t.readAc.access = ccache.caches->stats_t.readAc.miss; - ccache.ifb->stats_t.writeAc.access = ccache.caches->stats_t.readAc.miss; - ccache.ifb->rtp_stats = ccache.ifb->stats_t; - ccache.prefetchb->stats_t.readAc.access = - ccache.caches->stats_t.readAc.miss; - ccache.prefetchb->stats_t.writeAc.access = - ccache.caches->stats_t.readAc.miss; - ccache.prefetchb->rtp_stats = ccache.prefetchb->stats_t; - - tcache.missb->stats_t.readAc.access = tcache.caches->stats_t.readAc.miss; - tcache.missb->stats_t.writeAc.access = tcache.caches->stats_t.readAc.miss; - tcache.missb->rtp_stats = tcache.missb->stats_t; - tcache.ifb->stats_t.readAc.access = tcache.caches->stats_t.readAc.miss; - tcache.ifb->stats_t.writeAc.access = tcache.caches->stats_t.readAc.miss; - tcache.ifb->rtp_stats = tcache.ifb->stats_t; - tcache.prefetchb->stats_t.readAc.access = - tcache.caches->stats_t.readAc.miss; - tcache.prefetchb->stats_t.writeAc.access = - tcache.caches->stats_t.readAc.miss; - tcache.prefetchb->rtp_stats = tcache.prefetchb->stats_t; + ccache.power_t.readOp.dynamic += ccache.missb->stats_t.readAc.access*ccache.missb->local_result.power.searchOp.dynamic + + ccache.missb->stats_t.writeAc.access*ccache.missb->local_result.power.writeOp.dynamic;//each access to missb involves a CAM and a write + ccache.power_t.readOp.dynamic += ccache.ifb->stats_t.readAc.access*ccache.ifb->local_result.power.searchOp.dynamic + + ccache.ifb->stats_t.writeAc.access*ccache.ifb->local_result.power.writeOp.dynamic; + ccache.power_t.readOp.dynamic += ccache.prefetchb->stats_t.readAc.access*ccache.prefetchb->local_result.power.searchOp.dynamic + + ccache.prefetchb->stats_t.writeAc.access*ccache.prefetchb->local_result.power.writeOp.dynamic; + if (cache_p==Write_back) + { + ccache.power_t.readOp.dynamic += ccache.wbb->stats_t.readAc.access*ccache.wbb->local_result.power.searchOp.dynamic + + ccache.wbb->stats_t.writeAc.access*ccache.wbb->local_result.power.writeOp.dynamic; } - LSQ->stats_t.readAc.access = (XML->sys.core[ithCore].load_instructions + - XML->sys.core[ithCore].store_instructions) * - 2; // flush overhead considered - LSQ->stats_t.writeAc.access = (XML->sys.core[ithCore].load_instructions + - XML->sys.core[ithCore].store_instructions) * - 2; - LSQ->rtp_stats = LSQ->stats_t; - - if ((coredynp.core_ty == OOO) && - (XML->sys.core[ithCore].load_buffer_size > 0)) { - LoadQ->stats_t.readAc.access = XML->sys.core[ithCore].load_instructions + - XML->sys.core[ithCore].store_instructions; - LoadQ->stats_t.writeAc.access = XML->sys.core[ithCore].load_instructions + - XML->sys.core[ithCore].store_instructions; - LoadQ->rtp_stats = LoadQ->stats_t; + tcache.power_t.readOp.dynamic += tcache.missb->stats_t.readAc.access*tcache.missb->local_result.power.searchOp.dynamic + + tcache.missb->stats_t.writeAc.access*tcache.missb->local_result.power.writeOp.dynamic;//each access to missb involves a CAM and a write + tcache.power_t.readOp.dynamic += tcache.ifb->stats_t.readAc.access*tcache.ifb->local_result.power.searchOp.dynamic + + tcache.ifb->stats_t.writeAc.access*tcache.ifb->local_result.power.writeOp.dynamic; + tcache.power_t.readOp.dynamic += tcache.prefetchb->stats_t.readAc.access*tcache.prefetchb->local_result.power.searchOp.dynamic + + tcache.prefetchb->stats_t.writeAc.access*tcache.prefetchb->local_result.power.writeOp.dynamic; + if (cache_p==Write_back) + { + tcache.power_t.readOp.dynamic += tcache.wbb->stats_t.readAc.access*tcache.wbb->local_result.power.searchOp.dynamic + + tcache.wbb->stats_t.writeAc.access*tcache.wbb->local_result.power.writeOp.dynamic; } - } - - sharedmemory.power_t.reset(); - dcache.power_t.reset(); - ccache.power_t.reset(); - tcache.power_t.reset(); - LSQ->power_t.reset(); - - sharedmemory.power_t.readOp.dynamic += - (sharedmemory.caches->stats_t.readAc.hit * - sharedmemory.caches->local_result.power.readOp.dynamic + - sharedmemory.caches->stats_t.readAc.miss * - sharedmemory.caches->local_result.power.readOp.dynamic + - sharedmemory.caches->stats_t.writeAc.miss * - sharedmemory.caches->local_result.tag_array2->power.readOp.dynamic + - sharedmemory.caches->stats_t.writeAc.access * - sharedmemory.caches->local_result.power.writeOp.dynamic + - xbar_shared->power.readOp.dynamic * - (sharedmemory.caches->stats_t.readAc.hit + - sharedmemory.caches->stats_t.writeAc.hit)); - - dcache.power_t.readOp.dynamic += - (dcache.caches->stats_t.readAc.hit * - dcache.caches->local_result.power.readOp.dynamic + - dcache.caches->stats_t.readAc.miss * - dcache.caches->local_result.power.readOp.dynamic + - dcache.caches->stats_t.writeAc.miss * - dcache.caches->local_result.tag_array2->power.readOp.dynamic + - dcache.caches->stats_t.writeAc.access * - dcache.caches->local_result.power.writeOp.dynamic + - xbar_shared->power.readOp.dynamic * - (dcache.caches->stats_t.readAc.hit + - dcache.caches->stats_t.writeAc.hit)); - ccache.power_t.readOp.dynamic += - (ccache.caches->stats_t.readAc.hit * - ccache.caches->local_result.power.readOp.dynamic + - ccache.caches->stats_t.readAc.miss * - ccache.caches->local_result.power.readOp.dynamic + - ccache.caches->stats_t.writeAc.miss * - ccache.caches->local_result.tag_array2->power.readOp.dynamic + - ccache.caches->stats_t.writeAc.access * - ccache.caches->local_result.power.writeOp.dynamic + - xbar_shared->power.readOp.dynamic * (ccache.caches->stats_t.readAc.hit)); - - tcache.power_t.readOp.dynamic += - (tcache.caches->stats_t.readAc.hit * - tcache.caches->local_result.power.readOp.dynamic + - tcache.caches->stats_t.readAc.miss * - tcache.caches->local_result.power.readOp.dynamic + - tcache.caches->stats_t.writeAc.miss * - tcache.caches->local_result.tag_array2->power.readOp.dynamic + - tcache.caches->stats_t.writeAc.access * - tcache.caches->local_result.power.writeOp.dynamic + - xbar_shared->power.readOp.dynamic * - (tcache.caches->stats_t.readAc.hit + - tcache.caches->stats_t.writeAc.hit)); - - if (cache_p == Write_back) { // write miss will generate a write later - dcache.power_t.readOp.dynamic += - dcache.caches->stats_t.writeAc.miss * - dcache.caches->local_result.power.writeOp.dynamic; - ccache.power_t.readOp.dynamic += - ccache.caches->stats_t.writeAc.miss * - ccache.caches->local_result.power.writeOp.dynamic; - tcache.power_t.readOp.dynamic += - tcache.caches->stats_t.writeAc.miss * - tcache.caches->local_result.power.writeOp.dynamic; - sharedmemory.power_t.readOp.dynamic += - sharedmemory.caches->stats_t.writeAc.miss * - sharedmemory.caches->local_result.power.writeOp.dynamic; - } - - sharedmemory.power_t.readOp.dynamic += - sharedmemory.missb->stats_t.readAc.access * - sharedmemory.missb->local_result.power.searchOp.dynamic + - sharedmemory.missb->stats_t.writeAc.access * - sharedmemory.missb->local_result.power.writeOp - .dynamic; // each access to missb involves a CAM and a write - sharedmemory.power_t.readOp.dynamic += - sharedmemory.ifb->stats_t.readAc.access * - sharedmemory.ifb->local_result.power.searchOp.dynamic + - sharedmemory.ifb->stats_t.writeAc.access * - sharedmemory.ifb->local_result.power.writeOp.dynamic; - sharedmemory.power_t.readOp.dynamic += - sharedmemory.prefetchb->stats_t.readAc.access * - sharedmemory.prefetchb->local_result.power.searchOp.dynamic + - sharedmemory.prefetchb->stats_t.writeAc.access * - sharedmemory.prefetchb->local_result.power.writeOp.dynamic; - if (cache_p == Write_back) { - sharedmemory.power_t.readOp.dynamic += - sharedmemory.wbb->stats_t.readAc.access * - sharedmemory.wbb->local_result.power.searchOp.dynamic + - sharedmemory.wbb->stats_t.writeAc.access * - sharedmemory.wbb->local_result.power.writeOp.dynamic; - } - - dcache.power_t.readOp.dynamic += - dcache.missb->stats_t.readAc.access * - dcache.missb->local_result.power.searchOp.dynamic + - dcache.missb->stats_t.writeAc.access * - dcache.missb->local_result.power.writeOp - .dynamic; // each access to missb involves a CAM and a write - dcache.power_t.readOp.dynamic += - dcache.ifb->stats_t.readAc.access * - dcache.ifb->local_result.power.searchOp.dynamic + - dcache.ifb->stats_t.writeAc.access * - dcache.ifb->local_result.power.writeOp.dynamic; - dcache.power_t.readOp.dynamic += - dcache.prefetchb->stats_t.readAc.access * - dcache.prefetchb->local_result.power.searchOp.dynamic + - dcache.prefetchb->stats_t.writeAc.access * - dcache.prefetchb->local_result.power.writeOp.dynamic; - if (cache_p == Write_back) { - dcache.power_t.readOp.dynamic += - dcache.wbb->stats_t.readAc.access * - dcache.wbb->local_result.power.searchOp.dynamic + - dcache.wbb->stats_t.writeAc.access * - dcache.wbb->local_result.power.writeOp.dynamic; - } - ccache.power_t.readOp.dynamic += - ccache.missb->stats_t.readAc.access * - ccache.missb->local_result.power.searchOp.dynamic + - ccache.missb->stats_t.writeAc.access * - ccache.missb->local_result.power.writeOp - .dynamic; // each access to missb involves a CAM and a write - ccache.power_t.readOp.dynamic += - ccache.ifb->stats_t.readAc.access * - ccache.ifb->local_result.power.searchOp.dynamic + - ccache.ifb->stats_t.writeAc.access * - ccache.ifb->local_result.power.writeOp.dynamic; - ccache.power_t.readOp.dynamic += - ccache.prefetchb->stats_t.readAc.access * - ccache.prefetchb->local_result.power.searchOp.dynamic + - ccache.prefetchb->stats_t.writeAc.access * - ccache.prefetchb->local_result.power.writeOp.dynamic; - if (cache_p == Write_back) { - ccache.power_t.readOp.dynamic += - ccache.wbb->stats_t.readAc.access * - ccache.wbb->local_result.power.searchOp.dynamic + - ccache.wbb->stats_t.writeAc.access * - ccache.wbb->local_result.power.writeOp.dynamic; - } - tcache.power_t.readOp.dynamic += - tcache.missb->stats_t.readAc.access * - tcache.missb->local_result.power.searchOp.dynamic + - tcache.missb->stats_t.writeAc.access * - tcache.missb->local_result.power.writeOp - .dynamic; // each access to missb involves a CAM and a write - tcache.power_t.readOp.dynamic += - tcache.ifb->stats_t.readAc.access * - tcache.ifb->local_result.power.searchOp.dynamic + - tcache.ifb->stats_t.writeAc.access * - tcache.ifb->local_result.power.writeOp.dynamic; - tcache.power_t.readOp.dynamic += - tcache.prefetchb->stats_t.readAc.access * - tcache.prefetchb->local_result.power.searchOp.dynamic + - tcache.prefetchb->stats_t.writeAc.access * - tcache.prefetchb->local_result.power.writeOp.dynamic; - if (cache_p == Write_back) { - tcache.power_t.readOp.dynamic += - tcache.wbb->stats_t.readAc.access * - tcache.wbb->local_result.power.searchOp.dynamic + - tcache.wbb->stats_t.writeAc.access * - tcache.wbb->local_result.power.writeOp.dynamic; - } + if ((coredynp.core_ty==OOO) && (XML->sys.core[ithCore].load_buffer_size >0)) + { + LoadQ->power_t.reset(); + LoadQ->power_t.readOp.dynamic += LoadQ->stats_t.readAc.access*(LoadQ->local_result.power.searchOp.dynamic+ LoadQ->local_result.power.readOp.dynamic)+ + LoadQ->stats_t.writeAc.access*LoadQ->local_result.power.writeOp.dynamic;//every memory access invloves at least two operations on LoadQ - if ((coredynp.core_ty == OOO) && - (XML->sys.core[ithCore].load_buffer_size > 0)) { - LoadQ->power_t.reset(); - LoadQ->power_t.readOp.dynamic += - LoadQ->stats_t.readAc.access * - (LoadQ->local_result.power.searchOp.dynamic + - LoadQ->local_result.power.readOp.dynamic) + - LoadQ->stats_t.writeAc.access * - LoadQ->local_result.power.writeOp.dynamic; // every memory access - // invloves at least two - // operations on LoadQ - - LSQ->power_t.readOp.dynamic += - LSQ->stats_t.readAc.access * (LSQ->local_result.power.searchOp.dynamic + - LSQ->local_result.power.readOp.dynamic) + - LSQ->stats_t.writeAc.access * - LSQ->local_result.power.writeOp.dynamic; // every memory access - // invloves at least two - // operations on LSQ - - } else { - // LSQ->power_t.readOp.dynamic += - //LSQ->stats_t.readAc.access*(LSQ->local_result.power.searchOp.dynamic + - //LSQ->local_result.power.readOp.dynamic) - // + - //LSQ->stats_t.writeAc.access*LSQ->local_result.power.writeOp.dynamic;//every - //memory access invloves at least two operations on LSQ - // No LSQ in GPUs (Syed) - } + LSQ->power_t.readOp.dynamic += LSQ->stats_t.readAc.access*(LSQ->local_result.power.searchOp.dynamic + LSQ->local_result.power.readOp.dynamic) + + LSQ->stats_t.writeAc.access*LSQ->local_result.power.writeOp.dynamic;//every memory access invloves at least two operations on LSQ - if (is_tdp) { - // dcache.power = dcache.power_t + - // (dcache.caches->local_result.power)*pppm_lkg + - // (dcache.missb->local_result.power + - // dcache.ifb->local_result.power + - // dcache.prefetchb->local_result.power + - // dcache.wbb->local_result.power)*pppm_Isub; - - sharedmemory.power = - sharedmemory.power_t + - (sharedmemory.caches->local_result.power + - sharedmemory.missb->local_result.power + - sharedmemory.ifb->local_result.power + - sharedmemory.prefetchb->local_result.power + xbar_shared->power) * - pppm_lkg; - if (cache_p == Write_back) { - sharedmemory.power = - sharedmemory.power + sharedmemory.wbb->local_result.power * pppm_lkg; } + else + { + // LSQ->power_t.readOp.dynamic += LSQ->stats_t.readAc.access*(LSQ->local_result.power.searchOp.dynamic + LSQ->local_result.power.readOp.dynamic) + // + LSQ->stats_t.writeAc.access*LSQ->local_result.power.writeOp.dynamic;//every memory access invloves at least two operations on LSQ + // No LSQ in GPUs (Syed) - dcache.power = - dcache.power_t + - (dcache.caches->local_result.power + dcache.missb->local_result.power + - dcache.ifb->local_result.power + - dcache.prefetchb->local_result.power) * - pppm_lkg; - if (cache_p == Write_back) { - dcache.power = dcache.power + dcache.wbb->local_result.power * pppm_lkg; } - ccache.power = - ccache.power_t + - (ccache.caches->local_result.power + ccache.missb->local_result.power + - ccache.ifb->local_result.power + - ccache.prefetchb->local_result.power) * - pppm_lkg; - if (cache_p == Write_back) { - ccache.power = ccache.power + ccache.wbb->local_result.power * pppm_lkg; + if (is_tdp) + { +// dcache.power = dcache.power_t + (dcache.caches->local_result.power)*pppm_lkg + +// (dcache.missb->local_result.power + +// dcache.ifb->local_result.power + +// dcache.prefetchb->local_result.power + +// dcache.wbb->local_result.power)*pppm_Isub; + + + sharedmemory.power = sharedmemory.power_t + (sharedmemory.caches->local_result.power + + sharedmemory.missb->local_result.power + + sharedmemory.ifb->local_result.power + + sharedmemory.prefetchb->local_result.power + xbar_shared->power) *pppm_lkg; + if (cache_p==Write_back) + { + sharedmemory.power = sharedmemory.power + sharedmemory.wbb->local_result.power*pppm_lkg; + } + + + dcache.power = dcache.power_t + (dcache.caches->local_result.power + + dcache.missb->local_result.power + + dcache.ifb->local_result.power + + dcache.prefetchb->local_result.power) *pppm_lkg; + if (cache_p==Write_back) + { + dcache.power = dcache.power + dcache.wbb->local_result.power*pppm_lkg; + } + + ccache.power = ccache.power_t + (ccache.caches->local_result.power + + ccache.missb->local_result.power + + ccache.ifb->local_result.power + + ccache.prefetchb->local_result.power) *pppm_lkg; + if (cache_p==Write_back) + { + ccache.power = ccache.power + ccache.wbb->local_result.power*pppm_lkg; + } + + tcache.power = tcache.power_t + (tcache.caches->local_result.power + + tcache.missb->local_result.power + + tcache.ifb->local_result.power + + tcache.prefetchb->local_result.power) *pppm_lkg; + if (cache_p==Write_back) + { + tcache.power = tcache.power + tcache.wbb->local_result.power*pppm_lkg; + } + + + LSQ->power = LSQ->power_t + LSQ->local_result.power *pppm_lkg; + //No LSQ in GPUs (Syed) + LSQ->power.reset(); + power = power + dcache.power + LSQ->power +sharedmemory.power + ccache.power + tcache.power; + + if ((coredynp.core_ty==OOO) && (XML->sys.core[ithCore].load_buffer_size >0)) + { + LoadQ->power = LoadQ->power_t + LoadQ->local_result.power *pppm_lkg; + power = power + LoadQ->power; + } } - - tcache.power = - tcache.power_t + - (tcache.caches->local_result.power + tcache.missb->local_result.power + - tcache.ifb->local_result.power + - tcache.prefetchb->local_result.power) * - pppm_lkg; - if (cache_p == Write_back) { - tcache.power = tcache.power + tcache.wbb->local_result.power * pppm_lkg; + else + { +// dcache.rt_power = dcache.power_t + (dcache.caches->local_result.power + +// dcache.missb->local_result.power + +// dcache.ifb->local_result.power + +// dcache.prefetchb->local_result.power + +// dcache.wbb->local_result.power)*pppm_lkg; + rt_power.reset(); + sharedmemory.rt_power.reset(); //Jingwen + tcache.rt_power.reset(); + ccache.rt_power.reset(); + dcache.rt_power.reset(); + LSQ->rt_power.reset(); + + + sharedmemory.rt_power = sharedmemory.power_t + (sharedmemory.caches->local_result.power + + sharedmemory.missb->local_result.power + + sharedmemory.ifb->local_result.power + + sharedmemory.prefetchb->local_result.power )*pppm_lkg; + + if (cache_p==Write_back) + { + sharedmemory.rt_power = sharedmemory.rt_power + sharedmemory.wbb->local_result.power*pppm_lkg; + } + + dcache.rt_power = dcache.power_t + (dcache.caches->local_result.power + + dcache.missb->local_result.power + + dcache.ifb->local_result.power + + dcache.prefetchb->local_result.power )*pppm_lkg; + if (cache_p==Write_back) + { + dcache.rt_power = dcache.rt_power + dcache.wbb->local_result.power*pppm_lkg; + } + + ccache.rt_power = ccache.power_t + (ccache.caches->local_result.power + + ccache.missb->local_result.power + + ccache.ifb->local_result.power + + ccache.prefetchb->local_result.power )*pppm_lkg; + if (cache_p==Write_back) + { + ccache.rt_power = ccache.rt_power + ccache.wbb->local_result.power*pppm_lkg; + } + + tcache.rt_power = tcache.power_t + (tcache.caches->local_result.power + + tcache.missb->local_result.power + + tcache.ifb->local_result.power + + tcache.prefetchb->local_result.power )*pppm_lkg; + if (cache_p==Write_back) + { + tcache.rt_power = tcache.rt_power + tcache.wbb->local_result.power*pppm_lkg; + } + + + + LSQ->rt_power = LSQ->power_t + LSQ->local_result.power *pppm_lkg; + LSQ->rt_power.reset(); + rt_power = rt_power + dcache.rt_power + LSQ->rt_power + sharedmemory.rt_power + ccache.rt_power + tcache.rt_power; + + if ((coredynp.core_ty==OOO) && (XML->sys.core[ithCore].load_buffer_size >0)) + { + LoadQ->rt_power = LoadQ->power_t + LoadQ->local_result.power *pppm_lkg; + rt_power = rt_power + LoadQ->rt_power; + } } +} - LSQ->power = LSQ->power_t + LSQ->local_result.power * pppm_lkg; - // No LSQ in GPUs (Syed) - LSQ->power.reset(); - power = power + dcache.power + LSQ->power + sharedmemory.power + - ccache.power + tcache.power; - if ((coredynp.core_ty == OOO) && - (XML->sys.core[ithCore].load_buffer_size > 0)) { - LoadQ->power = LoadQ->power_t + LoadQ->local_result.power * pppm_lkg; - power = power + LoadQ->power; - } - } else { - // dcache.rt_power = dcache.power_t + - // (dcache.caches->local_result.power + - // dcache.missb->local_result.power + - // dcache.ifb->local_result.power + - // dcache.prefetchb->local_result.power + - // dcache.wbb->local_result.power)*pppm_lkg; - rt_power.reset(); - sharedmemory.rt_power.reset(); // Jingwen - tcache.rt_power.reset(); - ccache.rt_power.reset(); - dcache.rt_power.reset(); - LSQ->rt_power.reset(); - - sharedmemory.rt_power = sharedmemory.power_t + - (sharedmemory.caches->local_result.power + - sharedmemory.missb->local_result.power + - sharedmemory.ifb->local_result.power + - sharedmemory.prefetchb->local_result.power) * - pppm_lkg; - - if (cache_p == Write_back) { - sharedmemory.rt_power = sharedmemory.rt_power + - sharedmemory.wbb->local_result.power * pppm_lkg; - } +void LoadStoreU::displayEnergy(uint32_t indent,int plevel,bool is_tdp) +{ + if (!exist) return; + string indent_str(indent, ' '); + string indent_str_next(indent+2, ' '); + bool long_channel = XML->sys.longer_channel_device; + + + if (is_tdp) + { + + cout << indent_str << "Shared Memory:" << endl; + cout << indent_str_next << "Area = " << sharedmemory.area.get_area()*1e-6<< " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << sharedmemory.power.readOp.dynamic*clockRate << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? sharedmemory.power.readOp.longer_channel_leakage:sharedmemory.power.readOp.leakage )<<" W" << endl; + cout << indent_str_next << "Gate Leakage = " << sharedmemory.power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << sharedmemory.rt_power.readOp.dynamic/executionTime << " W" << endl; + cout <sys.core[ithCore].load_buffer_size >0) + { + cout << indent_str << "LoadQ:" << endl; + cout << indent_str_next << "Area = " << LoadQ->area.get_area() *1e-6 << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << LoadQ->power.readOp.dynamic*clockRate << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? LoadQ->power.readOp.longer_channel_leakage:LoadQ->power.readOp.leakage) << " W" << endl; + cout << indent_str_next << "Gate Leakage = " << LoadQ->power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << LoadQ->rt_power.readOp.dynamic/executionTime << " W" << endl; + cout <local_result.power + dcache.missb->local_result.power + - dcache.ifb->local_result.power + - dcache.prefetchb->local_result.power) * - pppm_lkg; - if (cache_p == Write_back) { - dcache.rt_power = - dcache.rt_power + dcache.wbb->local_result.power * pppm_lkg; - } +} - ccache.rt_power = - ccache.power_t + - (ccache.caches->local_result.power + ccache.missb->local_result.power + - ccache.ifb->local_result.power + - ccache.prefetchb->local_result.power) * - pppm_lkg; - if (cache_p == Write_back) { - ccache.rt_power = - ccache.rt_power + ccache.wbb->local_result.power * pppm_lkg; - } +void MemManU::computeEnergy(bool is_tdp) +{ - tcache.rt_power = - tcache.power_t + - (tcache.caches->local_result.power + tcache.missb->local_result.power + - tcache.ifb->local_result.power + - tcache.prefetchb->local_result.power) * - pppm_lkg; - if (cache_p == Write_back) { - tcache.rt_power = - tcache.rt_power + tcache.wbb->local_result.power * pppm_lkg; + if (!exist) return; + if (is_tdp) + { + //init stats for Peak + itlb->stats_t.readAc.access = itlb->l_ip.num_search_ports; + itlb->stats_t.readAc.miss = 0; + itlb->stats_t.readAc.hit = itlb->stats_t.readAc.access - itlb->stats_t.readAc.miss; + itlb->tdp_stats = itlb->stats_t; + + dtlb->stats_t.readAc.access = dtlb->l_ip.num_search_ports*coredynp.LSU_duty_cycle; + dtlb->stats_t.readAc.miss = 0; + dtlb->stats_t.readAc.hit = dtlb->stats_t.readAc.access - dtlb->stats_t.readAc.miss; + dtlb->tdp_stats = dtlb->stats_t; + } + else + { + //init stats for Runtime Dynamic (RTP) + itlb->stats_t.readAc.access = XML->sys.core[ithCore].itlb.total_accesses; + itlb->stats_t.readAc.miss = XML->sys.core[ithCore].itlb.total_misses; + itlb->stats_t.readAc.hit = itlb->stats_t.readAc.access - itlb->stats_t.readAc.miss; + itlb->rtp_stats = itlb->stats_t; + + dtlb->stats_t.readAc.access = XML->sys.core[ithCore].dtlb.total_accesses; + dtlb->stats_t.readAc.miss = XML->sys.core[ithCore].dtlb.total_misses; + dtlb->stats_t.readAc.hit = dtlb->stats_t.readAc.access - dtlb->stats_t.readAc.miss; + dtlb->rtp_stats = dtlb->stats_t; } - LSQ->rt_power = LSQ->power_t + LSQ->local_result.power * pppm_lkg; - LSQ->rt_power.reset(); - rt_power = rt_power + dcache.rt_power + LSQ->rt_power + - sharedmemory.rt_power + ccache.rt_power + tcache.rt_power; + itlb->power_t.reset(); + dtlb->power_t.reset(); + itlb->power_t.readOp.dynamic += itlb->stats_t.readAc.access*itlb->local_result.power.searchOp.dynamic//FA spent most power in tag, so use total access not hits + +itlb->stats_t.readAc.miss*itlb->local_result.power.writeOp.dynamic; + dtlb->power_t.readOp.dynamic += dtlb->stats_t.readAc.access*dtlb->local_result.power.searchOp.dynamic//FA spent most power in tag, so use total access not hits + +dtlb->stats_t.readAc.miss*dtlb->local_result.power.writeOp.dynamic; + + if (is_tdp) + { + itlb->power = itlb->power_t + itlb->local_result.power *pppm_lkg; + dtlb->power = dtlb->power_t + dtlb->local_result.power *pppm_lkg; + power = power + itlb->power + dtlb->power; + } + else + { + itlb->rt_power = itlb->power_t + itlb->local_result.power *pppm_lkg; + dtlb->rt_power = dtlb->power_t + dtlb->local_result.power *pppm_lkg; + rt_power = rt_power + itlb->rt_power + dtlb->rt_power; + } - if ((coredynp.core_ty == OOO) && - (XML->sys.core[ithCore].load_buffer_size > 0)) { - LoadQ->rt_power = LoadQ->power_t + LoadQ->local_result.power * pppm_lkg; - rt_power = rt_power + LoadQ->rt_power; - } - } } -void LoadStoreU::displayEnergy(uint32_t indent, int plevel, bool is_tdp) { - if (!exist) return; - string indent_str(indent, ' '); - string indent_str_next(indent + 2, ' '); - bool long_channel = XML->sys.longer_channel_device; - - if (is_tdp) { - cout << indent_str << "Shared Memory:" << endl; - cout << indent_str_next << "Area = " << sharedmemory.area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << sharedmemory.power.readOp.dynamic * clockRate - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? sharedmemory.power.readOp.longer_channel_leakage - : sharedmemory.power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << sharedmemory.power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << sharedmemory.rt_power.readOp.dynamic / executionTime << " W" - << endl; - cout << endl; - - cout << indent_str << "Data Cache:" << endl; - cout << indent_str_next << "Area = " << dcache.area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << dcache.power.readOp.dynamic * clockRate << " W" - << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? dcache.power.readOp.longer_channel_leakage - : dcache.power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << dcache.power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << dcache.rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << endl; - - cout << indent_str << "Constant Cache:" << endl; - cout << indent_str_next << "Area = " << ccache.area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << ccache.power.readOp.dynamic * clockRate << " W" - << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? dcache.power.readOp.longer_channel_leakage - : dcache.power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << ccache.power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << ccache.rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << indent_str_next - << "Runtime Dynamic Energy = " << ccache.rt_power.readOp.dynamic - << " J" << endl; - cout << indent_str_next << "Execution Time = " << executionTime << " s" - << endl; - cout << endl; - - cout << indent_str << "Texture Cache:" << endl; - cout << indent_str_next << "Area = " << tcache.area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << tcache.power.readOp.dynamic * clockRate << " W" - << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? dcache.power.readOp.longer_channel_leakage - : dcache.power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << tcache.power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << tcache.rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << endl; - - if (coredynp.core_ty == Inorder) { - cout << indent_str << "Load/Store Queue:" << endl; - cout << indent_str_next << "Area = " << LSQ->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << LSQ->power.readOp.dynamic * clockRate << " W" - << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? LSQ->power.readOp.longer_channel_leakage - : LSQ->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << LSQ->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << LSQ->rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << endl; - } else +void MemManU::displayEnergy(uint32_t indent,int plevel,bool is_tdp) +{ + if (!exist) return; + string indent_str(indent, ' '); + string indent_str_next(indent+2, ' '); + bool long_channel = XML->sys.longer_channel_device; + + + + + if (is_tdp) + { + cout << indent_str << "Itlb:" << endl; + cout << indent_str_next << "Area = " << itlb->area.get_area()*1e-6<< " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << itlb->power.readOp.dynamic*clockRate << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? itlb->power.readOp.longer_channel_leakage:itlb->power.readOp.leakage) <<" W" << endl; + cout << indent_str_next << "Gate Leakage = " << itlb->power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << itlb->rt_power.readOp.dynamic/executionTime << " W" << endl; + cout <sys.core[ithCore].load_buffer_size > 0) { - cout << indent_str << "LoadQ:" << endl; - cout << indent_str_next << "Area = " << LoadQ->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << LoadQ->power.readOp.dynamic * clockRate - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? LoadQ->power.readOp.longer_channel_leakage - : LoadQ->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << LoadQ->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << LoadQ->rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << endl; - } - cout << indent_str << "StoreQ:" << endl; - cout << indent_str_next << "Area = " << LSQ->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << LSQ->power.readOp.dynamic * clockRate << " W" - << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? LSQ->power.readOp.longer_channel_leakage - : LSQ->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << LSQ->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << LSQ->rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << endl; - } - } else { - cout << indent_str_next << "Shared Memory Peak Dynamic = " - << sharedmemory.rt_power.readOp.dynamic * clockRate << " W" << endl; - cout << indent_str_next << "Shared Memory Subthreshold Leakage = " - << sharedmemory.rt_power.readOp.leakage << " W" << endl; - cout << indent_str_next << "Shared Memory Gate Leakage = " - << sharedmemory.rt_power.readOp.gate_leakage << " W" << endl; - - cout << indent_str_next << "Data Cache Peak Dynamic = " - << dcache.rt_power.readOp.dynamic * clockRate << " W" << endl; - cout << indent_str_next << "Data Cache Subthreshold Leakage = " - << dcache.rt_power.readOp.leakage << " W" << endl; - cout << indent_str_next << "Data Cache Gate Leakage = " - << dcache.rt_power.readOp.gate_leakage << " W" << endl; - - cout << indent_str_next << "Constant Cache Peak Dynamic = " - << ccache.rt_power.readOp.dynamic * clockRate << " W" << endl; - cout << indent_str_next << "Constant Cache Subthreshold Leakage = " - << ccache.rt_power.readOp.leakage << " W" << endl; - cout << indent_str_next << "Constant Cache Gate Leakage = " - << ccache.rt_power.readOp.gate_leakage << " W" << endl; - - cout << indent_str_next << "Texture Cache Peak Dynamic = " - << tcache.rt_power.readOp.dynamic * clockRate << " W" << endl; - cout << indent_str_next << "Texture Cache Subthreshold Leakage = " - << tcache.rt_power.readOp.leakage << " W" << endl; - cout << indent_str_next << "Texture Cache Gate Leakage = " - << tcache.rt_power.readOp.gate_leakage << " W" << endl; - - if (coredynp.core_ty == Inorder) { - cout << indent_str_next << "Load/Store Queue Peak Dynamic = " - << LSQ->rt_power.readOp.dynamic * clockRate << " W" << endl; - cout << indent_str_next << "Load/Store Queue Subthreshold Leakage = " - << LSQ->rt_power.readOp.leakage << " W" << endl; - cout << indent_str_next << "Load/Store Queue Gate Leakage = " - << LSQ->rt_power.readOp.gate_leakage << " W" << endl; - } else { - cout << indent_str_next << "LoadQ Peak Dynamic = " - << LoadQ->rt_power.readOp.dynamic * clockRate << " W" << endl; - cout << indent_str_next << "LoadQ Subthreshold Leakage = " - << LoadQ->rt_power.readOp.leakage << " W" << endl; - cout << indent_str_next - << "LoadQ Gate Leakage = " << LoadQ->rt_power.readOp.gate_leakage - << " W" << endl; - cout << indent_str_next << "StoreQ Peak Dynamic = " - << LSQ->rt_power.readOp.dynamic * clockRate << " W" << endl; - cout << indent_str_next - << "StoreQ Subthreshold Leakage = " << LSQ->rt_power.readOp.leakage - << " W" << endl; - cout << indent_str_next - << "StoreQ Gate Leakage = " << LSQ->rt_power.readOp.gate_leakage - << " W" << endl; - } - } } -void MemManU::computeEnergy(bool is_tdp) { - if (!exist) return; - if (is_tdp) { - // init stats for Peak - itlb->stats_t.readAc.access = itlb->l_ip.num_search_ports; - itlb->stats_t.readAc.miss = 0; - itlb->stats_t.readAc.hit = - itlb->stats_t.readAc.access - itlb->stats_t.readAc.miss; - itlb->tdp_stats = itlb->stats_t; - - dtlb->stats_t.readAc.access = - dtlb->l_ip.num_search_ports * coredynp.LSU_duty_cycle; - dtlb->stats_t.readAc.miss = 0; - dtlb->stats_t.readAc.hit = - dtlb->stats_t.readAc.access - dtlb->stats_t.readAc.miss; - dtlb->tdp_stats = dtlb->stats_t; - } else { - // init stats for Runtime Dynamic (RTP) - itlb->stats_t.readAc.access = XML->sys.core[ithCore].itlb.total_accesses; - itlb->stats_t.readAc.miss = XML->sys.core[ithCore].itlb.total_misses; - itlb->stats_t.readAc.hit = - itlb->stats_t.readAc.access - itlb->stats_t.readAc.miss; - itlb->rtp_stats = itlb->stats_t; - - dtlb->stats_t.readAc.access = XML->sys.core[ithCore].dtlb.total_accesses; - dtlb->stats_t.readAc.miss = XML->sys.core[ithCore].dtlb.total_misses; - dtlb->stats_t.readAc.hit = - dtlb->stats_t.readAc.access - dtlb->stats_t.readAc.miss; - dtlb->rtp_stats = dtlb->stats_t; - } +void RegFU::computeEnergy(bool is_tdp) +{ +/* + * Architecture RF and physical RF cannot be present at the same time. + * Therefore, the RF stats can only refer to either ARF or PRF; + * And the same stats can be used for both. + */ + if (!exist) return; - itlb->power_t.reset(); - dtlb->power_t.reset(); - itlb->power_t.readOp.dynamic += - itlb->stats_t.readAc.access * - itlb->local_result.power.searchOp.dynamic // FA spent most power in - // tag, so use total access - // not hits - + itlb->stats_t.readAc.miss * itlb->local_result.power.writeOp.dynamic; - dtlb->power_t.readOp.dynamic += - dtlb->stats_t.readAc.access * - dtlb->local_result.power.searchOp.dynamic // FA spent most power in - // tag, so use total access - // not hits - + dtlb->stats_t.readAc.miss * dtlb->local_result.power.writeOp.dynamic; - - if (is_tdp) { - itlb->power = itlb->power_t + itlb->local_result.power * pppm_lkg; - dtlb->power = dtlb->power_t + dtlb->local_result.power * pppm_lkg; - power = power + itlb->power + dtlb->power; - } else { - itlb->rt_power = itlb->power_t + itlb->local_result.power * pppm_lkg; - dtlb->rt_power = dtlb->power_t + dtlb->local_result.power * pppm_lkg; - rt_power = rt_power + itlb->rt_power + dtlb->rt_power; - } -} + executionTime=XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6);//Syed + //RF crossbar power (Syed Gilani) + xbar_rfu->compute_power(); -void MemManU::displayEnergy(uint32_t indent, int plevel, bool is_tdp) { - if (!exist) return; - string indent_str(indent, ' '); - string indent_str_next(indent + 2, ' '); - bool long_channel = XML->sys.longer_channel_device; - - if (is_tdp) { - cout << indent_str << "Itlb:" << endl; - cout << indent_str_next << "Area = " << itlb->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << itlb->power.readOp.dynamic * clockRate << " W" - << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? itlb->power.readOp.longer_channel_leakage - : itlb->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << itlb->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << itlb->rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << endl; - cout << indent_str << "Dtlb:" << endl; - cout << indent_str_next << "Area = " << dtlb->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << dtlb->power.readOp.dynamic * clockRate << " W" - << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? dtlb->power.readOp.longer_channel_leakage - : dtlb->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << dtlb->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << dtlb->rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << endl; - } else { - cout << indent_str_next << "Itlb Peak Dynamic = " - << itlb->rt_power.readOp.dynamic * clockRate << " W" << endl; - cout << indent_str_next - << "Itlb Subthreshold Leakage = " << itlb->rt_power.readOp.leakage - << " W" << endl; - cout << indent_str_next - << "Itlb Gate Leakage = " << itlb->rt_power.readOp.gate_leakage - << " W" << endl; - cout << indent_str_next << "Dtlb Peak Dynamic = " - << dtlb->rt_power.readOp.dynamic * clockRate << " W" << endl; - cout << indent_str_next - << "Dtlb Subthreshold Leakage = " << dtlb->rt_power.readOp.leakage - << " W" << endl; - cout << indent_str_next - << "Dtlb Gate Leakage = " << dtlb->rt_power.readOp.gate_leakage - << " W" << endl; - } -} -void RegFU::computeEnergy(bool is_tdp) { - /* - * Architecture RF and physical RF cannot be present at the same time. - * Therefore, the RF stats can only refer to either ARF or PRF; - * And the same stats can be used for both. - */ - if (!exist) return; - - executionTime = - XML->sys.total_cycles / (XML->sys.target_core_clockrate * 1e6); // Syed - // RF crossbar power (Syed Gilani) - xbar_rfu->compute_power(); - - // Arbiter power - arbiter_rfu->compute_power(); - - if (is_tdp) { - // RF power -- modified by Syed - // init stats for Peak - - IRF->stats_t.readAc.access = 4; - IRF->stats_t.writeAc.access = 4; - IRF->tdp_stats = IRF->stats_t; - - IRF->stats_t.readAc.access = 2; - IRF->stats_t.writeAc.access = 1; - IRF->tdp_stats = IRF->stats_t; - - OPC->stats_t.readAc.access = 32; - OPC->stats_t.writeAc.access = 32; - OPC->tdp_stats = OPC->stats_t; - - // Commented by Syed (GPUs have a single RF which we model by IRF) - // FRF->stats_t.readAc.access = - // FRF->l_ip.num_rd_ports*coredynp.FPU_duty_cycle*1.05*coredynp.num_fp_pipelines; - // FRF->stats_t.writeAc.access = - // FRF->l_ip.num_wr_ports*coredynp.FPU_duty_cycle*1.05*coredynp.num_fp_pipelines; - // FRF->tdp_stats = FRF->stats_t; - if (coredynp.regWindowing) { - RFWIN->stats_t.readAc.access = 0; // 0.5*RFWIN->l_ip.num_rw_ports; - RFWIN->stats_t.writeAc.access = 0; // 0.5*RFWIN->l_ip.num_rw_ports; - RFWIN->tdp_stats = RFWIN->stats_t; - } - } /* if (is_tdp) */ - else { - // init stats for Runtime Dynamic (RTP) - // in Tesla each RF operand accesses 2 banks, so multiply acceses by 2 - // (read and write energies of reg_file are per bank)(Tesla) : Syed - // Also, for a SIMD width of 8 and warp size of 32 threads, 4 accesses - // (each accessing 2 banks) need to be performed per operand - if (XML->sys.architecture == 1) { - IRF->stats_t.readAc.access = - (XML->sys.core[ithCore].int_regfile_reads / 32) * (4 * 2); /// 1.5; - IRF->stats_t.writeAc.access = - (XML->sys.core[ithCore].int_regfile_writes / 32) * (4 * 2); /// 1.5; - } else { - IRF->stats_t.readAc.access = - (XML->sys.core[ithCore].int_regfile_reads / 32) * - (2 * 4); /// 1.5;//TODO: no diff on archi and phy - IRF->stats_t.writeAc.access = - (XML->sys.core[ithCore].int_regfile_writes / 32) * (2 * 4); /// 1.5; - } - IRF->rtp_stats = IRF->stats_t; - - OPC->stats_t.readAc.access = - (XML->sys.core[ithCore].int_regfile_reads) /*/1.5*/ + - XML->sys.core[ithCore] - .non_rf_operands; /// 1.5;//TODO: no diff on archi and phy - OPC->stats_t.writeAc.access = 0; - OPC->rtp_stats = OPC->stats_t; - - // cout<< "IRF read energy: "<< - // IRF->local_result.power.readOp.dynamic<local_result.power.writeOp.dynamic<stats_t.readAc.access = XML->sys.core[ithCore].float_regfile_reads; - // FRF->stats_t.writeAc.access = - // XML->sys.core[ithCore].float_regfile_writes; - // FRF->rtp_stats = FRF->stats_t; - if (coredynp.regWindowing) { - RFWIN->stats_t.readAc.access = XML->sys.core[ithCore].function_calls * 16; - RFWIN->stats_t.writeAc.access = - XML->sys.core[ithCore].function_calls * 16; - RFWIN->rtp_stats = RFWIN->stats_t; - - IRF->stats_t.readAc.access = XML->sys.core[ithCore].int_regfile_reads + - XML->sys.core[ithCore].function_calls * 16; - IRF->stats_t.writeAc.access = XML->sys.core[ithCore].int_regfile_writes + - XML->sys.core[ithCore].function_calls * 16; - IRF->rtp_stats = IRF->stats_t; - } - } - IRF->power_t.reset(); - FRF->power_t.reset(); - OPC->power_t.reset(); - // IRF->power_t = IRF->power_t + IRF->local_result.power;// + - // xbar_rfu->power + arbiter_rfu->power; - - IRF->power_t.readOp.dynamic = - (IRF->stats_t.readAc.access * IRF->local_result.power.readOp.dynamic + - IRF->stats_t.writeAc.access * IRF->local_result.power.writeOp.dynamic); - OPC->power_t.readOp.dynamic = - (OPC->stats_t.readAc.access * OPC->local_result.power.readOp.dynamic); - - if (coredynp.regWindowing) { - RFWIN->power_t.reset(); - RFWIN->power_t.readOp.dynamic += - (RFWIN->stats_t.readAc.access * - RFWIN->local_result.power.readOp.dynamic + - RFWIN->stats_t.writeAc.access * - RFWIN->local_result.power.writeOp.dynamic); - } + //Arbiter power + arbiter_rfu->compute_power(); - if (is_tdp) { - // cout<<"pre: IRF_power_t: "<power.readOp.dynamic<<" - // ("<power.readOp.dynamic*clockRate<<") "<<" IRF_localresult: "<< - // IRF->local_result.power.readOp.dynamic<power = FRF->power_t + FRF->local_result.power - // *coredynp.pppm_lkg_multhread; - - double pppm_lkg_banks[4]; - set_pppm(pppm_lkg_banks, 0, XML->sys.core[ithCore].collector_units, - XML->sys.core[ithCore].collector_units); - IRF->power = (IRF->power_t) + IRF->local_result.power * pppm_lkg; - IRF->power.readOp.dynamic = IRF->power_t.readOp.dynamic * 1; - OPC->power = (OPC->power_t) + OPC->local_result.power * pppm_lkg_banks; - OPC->power.readOp.dynamic = OPC->power_t.readOp.dynamic * 1; - - power = power + (IRF->power + OPC->power); - - if (coredynp.regWindowing) { - RFWIN->power = RFWIN->power_t + RFWIN->local_result.power * pppm_lkg; - power = power + RFWIN->power; - } - } /* if (is_tdp) */ - else { - // Removed *coredynp.pppm_lkg_multhread since all hardware threads shared - // the same IRF - IRF->rt_power = - IRF->power_t + - IRF->local_result.power * pppm_lkg; /* *coredynp.pppm_lkg_multhread;*/ - OPC->rt_power = OPC->power_t + OPC->local_result.power * pppm_lkg; - if (XML->sys.architecture == 1) { - // Each warp operand accesses the crossbar - xbar_rfu->rt_power.readOp.dynamic = - ((XML->sys.core[ithCore].int_regfile_reads / (32 /**1.5*/)) + - (XML->sys.core[ithCore].non_rf_operands / (32 /**1.5*/))) * - xbar_rfu->power.readOp.dynamic; - } else { - xbar_rfu->rt_power.readOp.dynamic = - ((XML->sys.core[ithCore].int_regfile_reads / (32 /**1.5*/)) + - (XML->sys.core[ithCore].non_rf_operands / (32 /**1.5*/))) * - xbar_rfu->power.readOp.dynamic; - } - arbiter_rfu->rt_power.readOp.dynamic = - ((XML->sys.core[ithCore].int_regfile_reads / (32 /**1.5*/)) + - (XML->sys.core[ithCore].non_rf_operands / (32 /**1.5*/))) * - arbiter_rfu->power.readOp.dynamic; - - rt_power = - rt_power + (IRF->power_t /*+ FRF->power_t*/ + xbar_rfu->rt_power + - arbiter_rfu->rt_power + OPC->power_t); - if (coredynp.regWindowing) { - RFWIN->rt_power = RFWIN->power_t + RFWIN->local_result.power * pppm_lkg; - rt_power = rt_power + RFWIN->rt_power; + if (is_tdp) + { + //RF power -- modified by Syed + //init stats for Peak + + IRF->stats_t.readAc.access = 4; + IRF->stats_t.writeAc.access = 4; + IRF->tdp_stats = IRF->stats_t; + + IRF->stats_t.readAc.access = 2; + IRF->stats_t.writeAc.access = 1; + IRF->tdp_stats = IRF->stats_t; + + + OPC->stats_t.readAc.access = 32; + OPC->stats_t.writeAc.access = 32; + OPC->tdp_stats = OPC->stats_t; + + //Commented by Syed (GPUs have a single RF which we model by IRF) + //FRF->stats_t.readAc.access = FRF->l_ip.num_rd_ports*coredynp.FPU_duty_cycle*1.05*coredynp.num_fp_pipelines; + //FRF->stats_t.writeAc.access = FRF->l_ip.num_wr_ports*coredynp.FPU_duty_cycle*1.05*coredynp.num_fp_pipelines; + //FRF->tdp_stats = FRF->stats_t; + if (coredynp.regWindowing) + { + RFWIN->stats_t.readAc.access = 0;//0.5*RFWIN->l_ip.num_rw_ports; + RFWIN->stats_t.writeAc.access = 0;//0.5*RFWIN->l_ip.num_rw_ports; + RFWIN->tdp_stats = RFWIN->stats_t; + } + } /* if (is_tdp) */ + else + { + //init stats for Runtime Dynamic (RTP) + //in Tesla each RF operand accesses 2 banks, so multiply acceses by 2 + // (read and write energies of reg_file are per bank)(Tesla) : Syed + // Also, for a SIMD width of 8 and warp size of 32 threads, 4 accesses + // (each accessing 2 banks) need to be performed per operand +if (XML->sys.architecture==1){ + IRF->stats_t.readAc.access = (XML->sys.core[ithCore].int_regfile_reads/32)*(4*2);///1.5; + IRF->stats_t.writeAc.access = (XML->sys.core[ithCore].int_regfile_writes/32)*(4*2);///1.5; +} else { + IRF->stats_t.readAc.access = (XML->sys.core[ithCore].int_regfile_reads/32)*(2*4);///1.5;//TODO: no diff on archi and phy + IRF->stats_t.writeAc.access = (XML->sys.core[ithCore].int_regfile_writes/32)*(2*4);///1.5; +} + IRF->rtp_stats = IRF->stats_t; + + OPC->stats_t.readAc.access = (XML->sys.core[ithCore].int_regfile_reads)/*/1.5*/+XML->sys.core[ithCore].non_rf_operands;///1.5;//TODO: no diff on archi and phy + OPC->stats_t.writeAc.access = 0; + OPC->rtp_stats = OPC->stats_t; + + //cout<< "IRF read energy: "<< IRF->local_result.power.readOp.dynamic<local_result.power.writeOp.dynamic<stats_t.readAc.access = XML->sys.core[ithCore].float_regfile_reads; + //FRF->stats_t.writeAc.access = XML->sys.core[ithCore].float_regfile_writes; + //FRF->rtp_stats = FRF->stats_t; + if (coredynp.regWindowing) + { + RFWIN->stats_t.readAc.access = XML->sys.core[ithCore].function_calls*16; + RFWIN->stats_t.writeAc.access = XML->sys.core[ithCore].function_calls*16; + RFWIN->rtp_stats = RFWIN->stats_t; + + IRF->stats_t.readAc.access = XML->sys.core[ithCore].int_regfile_reads + + XML->sys.core[ithCore].function_calls*16; + IRF->stats_t.writeAc.access = XML->sys.core[ithCore].int_regfile_writes + + XML->sys.core[ithCore].function_calls*16; + IRF->rtp_stats = IRF->stats_t; + + } } - } + IRF->power_t.reset(); + FRF->power_t.reset(); + OPC->power_t.reset(); + //IRF->power_t = IRF->power_t + IRF->local_result.power;// + xbar_rfu->power + arbiter_rfu->power; + + + + IRF->power_t.readOp.dynamic = (IRF->stats_t.readAc.access*IRF->local_result.power.readOp.dynamic + +IRF->stats_t.writeAc.access*IRF->local_result.power.writeOp.dynamic); + OPC->power_t.readOp.dynamic = (OPC->stats_t.readAc.access*OPC->local_result.power.readOp.dynamic); + + if (coredynp.regWindowing) + { + RFWIN->power_t.reset(); + RFWIN->power_t.readOp.dynamic += (RFWIN->stats_t.readAc.access*RFWIN->local_result.power.readOp.dynamic + + RFWIN->stats_t.writeAc.access*RFWIN->local_result.power.writeOp.dynamic); + } + + if (is_tdp) + { + + //cout<<"pre: IRF_power_t: "<power.readOp.dynamic<<" ("<power.readOp.dynamic*clockRate<<") "<<" IRF_localresult: "<< + // IRF->local_result.power.readOp.dynamic<power = FRF->power_t + FRF->local_result.power *coredynp.pppm_lkg_multhread; + + double pppm_lkg_banks[4]; + set_pppm(pppm_lkg_banks, 0,XML->sys.core[ithCore].collector_units,XML->sys.core[ithCore].collector_units ); + IRF->power = (IRF->power_t) + IRF->local_result.power*pppm_lkg; + IRF->power.readOp.dynamic=IRF->power_t.readOp.dynamic*1; + OPC->power = (OPC->power_t) + OPC->local_result.power *pppm_lkg_banks; + OPC->power.readOp.dynamic=OPC->power_t.readOp.dynamic*1; + + + power = power + (IRF->power+OPC->power); + + + if (coredynp.regWindowing) + { + RFWIN->power = RFWIN->power_t + RFWIN->local_result.power *pppm_lkg; + power = power + RFWIN->power; + } + } /* if (is_tdp) */ + else + { + //Removed *coredynp.pppm_lkg_multhread since all hardware threads shared the same IRF + IRF->rt_power = IRF->power_t + IRF->local_result.power*pppm_lkg;/* *coredynp.pppm_lkg_multhread;*/ + OPC->rt_power = OPC->power_t + OPC->local_result.power*pppm_lkg; +if(XML->sys.architecture==1){ + //Each warp operand accesses the crossbar + xbar_rfu->rt_power.readOp.dynamic=((XML->sys.core[ithCore].int_regfile_reads/(32/**1.5*/))+(XML->sys.core[ithCore].non_rf_operands/(32/**1.5*/)))*xbar_rfu->power.readOp.dynamic; +} else { + xbar_rfu->rt_power.readOp.dynamic=((XML->sys.core[ithCore].int_regfile_reads/(32/**1.5*/))+(XML->sys.core[ithCore].non_rf_operands/(32/**1.5*/)))*xbar_rfu->power.readOp.dynamic; } + arbiter_rfu->rt_power.readOp.dynamic=((XML->sys.core[ithCore].int_regfile_reads/(32/**1.5*/))+(XML->sys.core[ithCore].non_rf_operands/(32/**1.5*/)))*arbiter_rfu->power.readOp.dynamic; -void RegFU::displayEnergy(uint32_t indent, int plevel, bool is_tdp) { - if (!exist) return; - string indent_str(indent, ' '); - string indent_str_next(indent + 2, ' '); - bool long_channel = XML->sys.longer_channel_device; - - if (is_tdp) { - cout << indent_str << "Register file banks: " << endl; - cout << indent_str_next << "Area = " << IRF->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << IRF->power.readOp.dynamic * clockRate << " W" - << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? IRF->power.readOp.longer_channel_leakage - : IRF->power.readOp.leakage) - << " W" << endl; - - cout << indent_str_next - << "Gate Leakage = " << IRF->power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next - << "Runtime Dynamic = " << IRF->rt_power.readOp.dynamic / executionTime - << " W" << endl; - cout << endl; - cout << indent_str << "Crossbar (Integer RF):" << endl; - cout << indent_str_next << "Area = " << xbar_rfu->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << xbar_rfu->power.readOp.dynamic * clockRate - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? xbar_rfu->power.readOp.longer_channel_leakage - : xbar_rfu->power.readOp.leakage) - << " W" << endl; - - cout << indent_str_next - << "Gate Leakage = " << xbar_rfu->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << xbar_rfu->rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << endl; - - cout << indent_str << "Arbiter (Integer RF):" << endl; - cout << indent_str_next << "Area = " << arbiter_rfu->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << arbiter_rfu->power.readOp.dynamic * clockRate - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? arbiter_rfu->power.readOp.longer_channel_leakage - : arbiter_rfu->power.readOp.leakage) - << " W" << endl; - - cout << indent_str_next - << "Gate Leakage = " << arbiter_rfu->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << arbiter_rfu->rt_power.readOp.dynamic / executionTime << " W" - << endl; - cout << endl; - - /* - cout << indent_str<< "Floating Point RF:" << endl; - cout << indent_str_next << "Area = " << FRF->area.get_area()*1e-6 << " - mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << - FRF->power.readOp.dynamic*clockRate << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? - FRF->power.readOp.longer_channel_leakage:FRF->power.readOp.leakage) << " W" - << endl; - cout << indent_str_next << "Gate Leakage = " << - FRF->power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << - FRF->rt_power.readOp.dynamic/executionTime << " W" << endl; - cout <power_t /*+ FRF->power_t*/+xbar_rfu->rt_power+arbiter_rfu->rt_power+OPC->power_t); + if (coredynp.regWindowing) + { + RFWIN->rt_power = RFWIN->power_t + RFWIN->local_result.power *pppm_lkg; + rt_power = rt_power + RFWIN->rt_power; + } + } +} + + +void RegFU::displayEnergy(uint32_t indent,int plevel,bool is_tdp) +{ + if (!exist) return; + string indent_str(indent, ' '); + string indent_str_next(indent+2, ' '); + bool long_channel = XML->sys.longer_channel_device; + + if (is_tdp) + { cout << indent_str << "Register file banks: " << endl; + cout << indent_str_next << "Area = " << IRF->area.get_area()*1e-6<< " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << IRF->power.readOp.dynamic*clockRate << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? IRF->power.readOp.longer_channel_leakage:IRF->power.readOp.leakage) <<" W" << endl; + + cout << indent_str_next << "Gate Leakage = " << IRF->power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << IRF->rt_power.readOp.dynamic/executionTime << " W" << endl; + cout <sys.total_cycles / (XML->sys.target_core_clockrate * 1e6); // Syed - // rfu->power.reset(); +void EXECU::computeEnergy(bool is_tdp) +{ + if (!exist) return; + //Syed + double pppm_t[4] = {1,1,1,1}; + double pppm_freqScaling[4] = {rf_fu_clockRate/clockRate,1,1,1}; + executionTime=XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6);//Syed + + +// rfu->power.reset(); rfu->rt_power.reset(); - // scheu->power.reset(); - scheu->rt_power.reset(); - // exeu->power.reset(); - exeu->rt_power.reset(); - - rfu->computeEnergy(is_tdp); - scheu->computeEnergy(is_tdp); - exeu->computeEnergy(is_tdp); - if (coredynp.num_fpus > 0) { +// scheu->power.reset(); + scheu->rt_power.reset(); +// exeu->power.reset(); + exeu->rt_power.reset(); + + rfu->computeEnergy(is_tdp); + scheu->computeEnergy(is_tdp); + exeu->computeEnergy(is_tdp); + if (coredynp.num_fpus >0) + { fp_u->rt_power.reset(); - fp_u->computeEnergy(is_tdp); - } - if (coredynp.num_muls > 0) { + fp_u->computeEnergy(is_tdp); + } + if (coredynp.num_muls >0) + { mul->rt_power.reset(); - mul->computeEnergy(is_tdp); - } + mul->computeEnergy(is_tdp); + } bypass.rt_power.reset(); - if (is_tdp) { - set_pppm(pppm_t, 2 * coredynp.ALU_cdb_duty_cycle, 2, 2, - 2 * coredynp.ALU_cdb_duty_cycle); // 2 means two source operands - // needs to be passed for each - // int instruction. - // bypass.power = bypass.power + intTagBypass->power*pppm_t + - // int_bypass->power*pppm_t; - if (coredynp.num_muls > 0) { - set_pppm(pppm_t, 2 * coredynp.MUL_cdb_duty_cycle, 2, 2, - 2 * coredynp.MUL_cdb_duty_cycle); // 2 means two source operands - // needs to be passed for each - // int instruction. - // No conventional bypassing in GPU (Syed) - // bypass.power = bypass.power + intTag_mul_Bypass->power*pppm_t + - // int_mul_bypass->power*pppm_t; - power = power + mul->power * pppm_freqScaling; - } - - if (coredynp.num_fpus > 0) { - set_pppm(pppm_t, 3 * coredynp.FPU_cdb_duty_cycle, 3, 3, - 3 * coredynp.FPU_cdb_duty_cycle); // 3 means three source - // operands needs to be passed - // for each fp instruction. - // No conventional bypassing in GPU (Syed) - // bypass.power = bypass.power + fp_bypass->power*pppm_t + - // fpTagBypass->power*pppm_t ; - power = power + fp_u->power * pppm_freqScaling; - } - // No conventional bypassing in GPU (Syed) - - power = power + rfu->power * pppm_freqScaling + - exeu->power * pppm_freqScaling /*+ bypass.power*/ + scheu->power; - - } else { - set_pppm(pppm_t, XML->sys.core[ithCore].cdb_alu_accesses, 2, 2, - XML->sys.core[ithCore].cdb_alu_accesses); - // bypass.rt_power = bypass.rt_power + intTagBypass->power*pppm_t; - // bypass.rt_power = bypass.rt_power + int_bypass->power*pppm_t; - - if (coredynp.num_muls > 0) { - set_pppm(pppm_t, XML->sys.core[ithCore].cdb_mul_accesses, 2, 2, - XML->sys.core[ithCore].cdb_mul_accesses); // 2 means two source - // operands needs to - // be passed for each - // int instruction. - // bypass.rt_power = bypass.rt_power + intTag_mul_Bypass->power*pppm_t + - // int_mul_bypass->power*pppm_t; - rt_power = rt_power + mul->rt_power; - } - - if (coredynp.num_fpus > 0) { - set_pppm(pppm_t, XML->sys.core[ithCore].cdb_fpu_accesses, 3, 3, - XML->sys.core[ithCore].cdb_fpu_accesses); - // bypass.rt_power = bypass.rt_power + fp_bypass->power*pppm_t; - // bypass.rt_power = bypass.rt_power + fpTagBypass->power*pppm_t; - rt_power = rt_power + fp_u->rt_power; - } - // No conventional bypassing in GPU (Syed) - rt_power = rt_power + rfu->rt_power * pppm_freqScaling + - exeu->rt_power * pppm_freqScaling + - /*bypass.rt_power +*/ scheu->rt_power; - } + if (is_tdp) + { + set_pppm(pppm_t, 2*coredynp.ALU_cdb_duty_cycle, 2, 2, 2*coredynp.ALU_cdb_duty_cycle);//2 means two source operands needs to be passed for each int instruction. + //bypass.power = bypass.power + intTagBypass->power*pppm_t + int_bypass->power*pppm_t; + if (coredynp.num_muls >0) + { + set_pppm(pppm_t, 2*coredynp.MUL_cdb_duty_cycle, 2, 2, 2*coredynp.MUL_cdb_duty_cycle);//2 means two source operands needs to be passed for each int instruction. + //No conventional bypassing in GPU (Syed) + //bypass.power = bypass.power + intTag_mul_Bypass->power*pppm_t + int_mul_bypass->power*pppm_t; + power = power + mul->power*pppm_freqScaling; + } + + if (coredynp.num_fpus>0) + { + set_pppm(pppm_t, 3*coredynp.FPU_cdb_duty_cycle, 3, 3, 3*coredynp.FPU_cdb_duty_cycle);//3 means three source operands needs to be passed for each fp instruction. + //No conventional bypassing in GPU (Syed) + //bypass.power = bypass.power + fp_bypass->power*pppm_t + fpTagBypass->power*pppm_t ; + power = power + fp_u->power*pppm_freqScaling; + + } + //No conventional bypassing in GPU (Syed) + + power = power + rfu->power*pppm_freqScaling + exeu->power*pppm_freqScaling /*+ bypass.power*/ + scheu->power + ; + + + } + else + { + set_pppm(pppm_t, XML->sys.core[ithCore].cdb_alu_accesses, 2, 2, XML->sys.core[ithCore].cdb_alu_accesses); + //bypass.rt_power = bypass.rt_power + intTagBypass->power*pppm_t; + //bypass.rt_power = bypass.rt_power + int_bypass->power*pppm_t; + + if (coredynp.num_muls >0) + { + set_pppm(pppm_t, XML->sys.core[ithCore].cdb_mul_accesses, 2, 2, XML->sys.core[ithCore].cdb_mul_accesses);//2 means two source operands needs to be passed for each int instruction. + //bypass.rt_power = bypass.rt_power + intTag_mul_Bypass->power*pppm_t + int_mul_bypass->power*pppm_t; + rt_power = rt_power + mul->rt_power; + } + + if (coredynp.num_fpus>0) + { + set_pppm(pppm_t, XML->sys.core[ithCore].cdb_fpu_accesses, 3, 3, XML->sys.core[ithCore].cdb_fpu_accesses); + //bypass.rt_power = bypass.rt_power + fp_bypass->power*pppm_t; + //bypass.rt_power = bypass.rt_power + fpTagBypass->power*pppm_t; + rt_power = rt_power + fp_u->rt_power; + } + //No conventional bypassing in GPU (Syed) + rt_power = rt_power + rfu->rt_power*pppm_freqScaling + exeu->rt_power*pppm_freqScaling + /*bypass.rt_power +*/ scheu->rt_power; + } } -void EXECU::displayEnergy(uint32_t indent, int plevel, bool is_tdp) { - if (!exist) return; - 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) { - cout << indent_str << "Register Files:" << endl; - cout << indent_str_next << "Area = " << rfu->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << rfu->power.readOp.dynamic * rf_fu_clockRate - << " W" << endl; - // cout << "rf_fu Clock rate: "<< rf_fu_clockRate< 3) { - rfu->displayEnergy(indent + 4, is_tdp); - } - cout << indent_str << "Instruction Scheduler:" << endl; - cout << indent_str_next << "Area = " << scheu->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << scheu->power.readOp.dynamic * clockRate << " W" - << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? scheu->power.readOp.longer_channel_leakage - : scheu->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << scheu->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << scheu->rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << endl; - if (plevel > 3) { - scheu->displayEnergy(indent + 4, is_tdp); - } - exeu->displayEnergy(indent, is_tdp); - if (coredynp.num_fpus > 0) { - fp_u->displayEnergy(indent, is_tdp); - } - if (coredynp.num_muls > 0) { - mul->displayEnergy(indent, is_tdp); - } - cout << indent_str << "Results Broadcast Bus:" << endl; - cout << indent_str_next - << "Area Overhead = " << bypass.area.get_area() * 1e-6 << " mm^2" - << endl; - cout << indent_str_next - << "Peak Dynamic = " << bypass.power.readOp.dynamic * clockRate << " W" - << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? bypass.power.readOp.longer_channel_leakage - : bypass.power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << bypass.power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << bypass.rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << endl; - } else { - cout << indent_str_next << "Register Files Peak Dynamic = " - << rfu->rt_power.readOp.dynamic * clockRate << " W" << endl; - cout << indent_str_next << "Register Files Subthreshold Leakage = " - << rfu->rt_power.readOp.leakage << " W" << endl; - cout << indent_str_next << "Register Files Gate Leakage = " - << rfu->rt_power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Instruction Sheduler Peak Dynamic = " - << scheu->rt_power.readOp.dynamic * clockRate << " W" << endl; - cout << indent_str_next << "Instruction Sheduler Subthreshold Leakage = " - << scheu->rt_power.readOp.leakage << " W" << endl; - cout << indent_str_next << "Instruction Sheduler Gate Leakage = " - << scheu->rt_power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Results Broadcast Bus Peak Dynamic = " - << bypass.rt_power.readOp.dynamic * clockRate << " W" << endl; - cout << indent_str_next << "Results Broadcast Bus Subthreshold Leakage = " - << bypass.rt_power.readOp.leakage << " W" << endl; - cout << indent_str_next << "Results Broadcast Bus Gate Leakage = " - << bypass.rt_power.readOp.gate_leakage << " W" << endl; - } +void EXECU::displayEnergy(uint32_t indent,int plevel,bool is_tdp) +{ + if (!exist) return; + 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) + { + cout << indent_str << "Register Files:" << endl; + cout << indent_str_next << "Area = " << rfu->area.get_area()*1e-6<< " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << rfu->power.readOp.dynamic*rf_fu_clockRate << " W" << endl; + //cout << "rf_fu Clock rate: "<< rf_fu_clockRate<3){ + rfu->displayEnergy(indent+4,is_tdp); + } + cout << indent_str << "Instruction Scheduler:" << endl; + cout << indent_str_next << "Area = " << scheu->area.get_area()*1e-6 << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << scheu->power.readOp.dynamic*clockRate << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? scheu->power.readOp.longer_channel_leakage:scheu->power.readOp.leakage) << " W" << endl; + cout << indent_str_next << "Gate Leakage = " << scheu->power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << scheu->rt_power.readOp.dynamic/executionTime << " W" << endl; + cout <3){ + scheu->displayEnergy(indent+4,is_tdp); + } + exeu->displayEnergy(indent,is_tdp); + if (coredynp.num_fpus>0) + { + fp_u->displayEnergy(indent,is_tdp); + } + if (coredynp.num_muls >0) + { + mul->displayEnergy(indent,is_tdp); + } + cout << indent_str << "Results Broadcast Bus:" << endl; + cout << indent_str_next << "Area Overhead = " << bypass.area.get_area()*1e-6 << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << bypass.power.readOp.dynamic*clockRate << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? bypass.power.readOp.longer_channel_leakage:bypass.power.readOp.leakage ) << " W" << endl; + cout << indent_str_next << "Gate Leakage = " << bypass.power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << bypass.rt_power.readOp.dynamic/executionTime << " W" << endl; + cout <sys.core[ithCore].pipeline_duty_cycle; - rt_power.reset(); - ifu->rt_power.reset(); - lsu->rt_power.reset(); - mmu->rt_power.reset(); - exu->rt_power.reset(); - - ifu->computeEnergy(false); - lsu->computeEnergy(false); - mmu->computeEnergy(false); - exu->computeEnergy(false); - - if (XML->sys.homogeneous_cores == 1) { - rtp_pipeline_coe = coredynp.pipeline_duty_cycle * XML->sys.total_cycles * - XML->sys.number_of_cores; - } else { - rtp_pipeline_coe = coredynp.pipeline_duty_cycle * coredynp.total_cycles; - // Jingwen - if (coredynp.total_cycles != XML->sys.total_cycles) { - cout << "total cycle not match!" << endl; - exit(1); - } - } - set_pppm(pppm_t, coredynp.num_pipelines * rtp_pipeline_coe / num_units, - coredynp.num_pipelines / num_units, - coredynp.num_pipelines / num_units, - coredynp.num_pipelines / num_units); - if (ifu->exist) { - Pipeline_energy += corepipe->power.readOp.dynamic * - (coredynp.num_pipelines * rtp_pipeline_coe / num_units); - ifu->rt_power = ifu->rt_power + corepipe->power * pppm_t; - rt_power = rt_power + ifu->rt_power; - } - if (lsu->exist) { - Pipeline_energy += corepipe->power.readOp.dynamic * - (coredynp.num_pipelines * rtp_pipeline_coe / num_units); - lsu->rt_power = lsu->rt_power + corepipe->power * pppm_t; - rt_power = rt_power + lsu->rt_power; - } - if (exu->exist) { - Pipeline_energy += corepipe->power.readOp.dynamic * - (coredynp.num_pipelines * rtp_pipeline_coe / num_units); - exu->rt_power = exu->rt_power + corepipe->power * pppm_t; - rt_power = rt_power + exu->rt_power; - } - if (mmu->exist) { - Pipeline_energy += corepipe->power.readOp.dynamic * - (coredynp.num_pipelines * rtp_pipeline_coe / num_units); - mmu->rt_power = mmu->rt_power + corepipe->power * pppm_t; - rt_power = rt_power + mmu->rt_power; - } - rt_power = rt_power + undiffCore->power; - if (XML->sys.Private_L2) { - l2cache->computeEnergy(false); - rt_power = rt_power + l2cache->rt_power; - } +//Jingwen +void Core::compute() +{ + //power_point_product_masks + double pppm_t[4] = {1,1,1,1}; + double rtp_pipeline_coe; + double num_units = 4.0; + Pipeline_energy=0; - IdleCoreEnergy = - XML->sys.num_idle_cores * XML->sys.idle_core_power * executionTime; + //Set pipeline duty cycle for this inteval + coredynp.pipeline_duty_cycle=XML->sys.core[ithCore].pipeline_duty_cycle; + rt_power.reset(); + ifu->rt_power.reset(); + lsu->rt_power.reset(); + mmu->rt_power.reset(); + exu->rt_power.reset(); + + + ifu->computeEnergy(false); + lsu->computeEnergy(false); + mmu->computeEnergy(false); + exu->computeEnergy(false); + + + if (XML->sys.homogeneous_cores==1) + { + rtp_pipeline_coe = coredynp.pipeline_duty_cycle * XML->sys.total_cycles * XML->sys.number_of_cores; + } + else + { + + rtp_pipeline_coe = coredynp.pipeline_duty_cycle * coredynp.total_cycles; + //Jingwen + if (coredynp.total_cycles != XML->sys.total_cycles) + { + cout << "total cycle not match!" << endl; + exit(1); + } + } + + set_pppm(pppm_t, coredynp.num_pipelines*rtp_pipeline_coe/num_units, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units); + + if (ifu->exist) + { + Pipeline_energy+=corepipe->power.readOp.dynamic* (coredynp.num_pipelines*rtp_pipeline_coe/num_units); + ifu->rt_power = ifu->rt_power + corepipe->power*pppm_t; + rt_power = rt_power + ifu->rt_power ; + } + + if (lsu->exist) + { + Pipeline_energy+=corepipe->power.readOp.dynamic* (coredynp.num_pipelines*rtp_pipeline_coe/num_units); + lsu->rt_power = lsu->rt_power + corepipe->power*pppm_t; + rt_power = rt_power + lsu->rt_power; + } + if (exu->exist) + { + Pipeline_energy+=corepipe->power.readOp.dynamic* (coredynp.num_pipelines*rtp_pipeline_coe/num_units); + exu->rt_power = exu->rt_power + corepipe->power*pppm_t; + rt_power = rt_power + exu->rt_power; + } + if (mmu->exist) + { + Pipeline_energy+=corepipe->power.readOp.dynamic* (coredynp.num_pipelines*rtp_pipeline_coe/num_units); + mmu->rt_power = mmu->rt_power + corepipe->power*pppm_t; + rt_power = rt_power + mmu->rt_power ; + } + + rt_power = rt_power + undiffCore->power; + + + if (XML->sys.Private_L2) + { + + l2cache->computeEnergy(false); + rt_power = rt_power + l2cache->rt_power; + } + + IdleCoreEnergy=XML->sys.num_idle_cores * XML->sys.idle_core_power* executionTime; + + rt_power.readOp.dynamic += IdleCoreEnergy; - rt_power.readOp.dynamic += IdleCoreEnergy; } -void Core::computeEnergy(bool is_tdp) { - // power_point_product_masks - double pppm_t[4] = {1, 1, 1, 1}; - double rtp_pipeline_coe; - double num_units = 4.0; - Pipeline_energy = 0; - - if (XML->sys.homogeneous_cores == 1) { - rtp_pipeline_coe = coredynp.pipeline_duty_cycle * XML->sys.total_cycles * - XML->sys.number_of_cores; - } else { - rtp_pipeline_coe = coredynp.pipeline_duty_cycle * coredynp.total_cycles; - } - - if (is_tdp) { - ifu->computeEnergy(is_tdp); - lsu->computeEnergy(is_tdp); - mmu->computeEnergy(is_tdp); - exu->computeEnergy(is_tdp); - - if (coredynp.core_ty == OOO) { - num_units = 5.0; - rnu->computeEnergy(is_tdp); - set_pppm(pppm_t, coredynp.num_pipelines / num_units, - coredynp.num_pipelines / num_units, - coredynp.num_pipelines / num_units, - coredynp.num_pipelines / num_units); - if (rnu->exist) { - rnu->power = rnu->power + corepipe->power * pppm_t; - power = power + rnu->power; - } - } - - if (ifu->exist) { - Pipeline_energy += - corepipe->power.readOp.dynamic * - (coredynp.num_pipelines * rtp_pipeline_coe / num_units); - set_pppm(pppm_t, - coredynp.num_pipelines / num_units * coredynp.IFU_duty_cycle, - coredynp.num_pipelines / num_units, - coredynp.num_pipelines / num_units, - coredynp.num_pipelines / num_units); - // cout << "IFU = " << - //ifu->power.readOp.dynamic*clockRate << " W" << endl; - ifu->power = ifu->power + corepipe->power * pppm_t; - // cout << "IFU = " << - //ifu->power.readOp.dynamic*clockRate << " W" << endl; - // cout << "1/4 pipe = " << - //corepipe->power.readOp.dynamic*clockRate/num_units << " W" << endl; - power = power + ifu->power; - // cout << "core = " << - //power.readOp.dynamic*clockRate << " W" << endl; - } - if (lsu->exist) { - Pipeline_energy += - corepipe->power.readOp.dynamic * - (coredynp.num_pipelines * rtp_pipeline_coe / num_units); - set_pppm(pppm_t, - coredynp.num_pipelines / num_units * coredynp.LSU_duty_cycle, - coredynp.num_pipelines / num_units, - coredynp.num_pipelines / num_units, - coredynp.num_pipelines / num_units); - lsu->power = lsu->power + corepipe->power * pppm_t; - // cout << "LSU = " << - //lsu->power.readOp.dynamic*clockRate << " W" << endl; - power = power + lsu->power; - // cout << "core = " << - //power.readOp.dynamic*clockRate << " W" << endl; - } - if (exu->exist) { - Pipeline_energy += - corepipe->power.readOp.dynamic * - (coredynp.num_pipelines * rtp_pipeline_coe / num_units); - set_pppm(pppm_t, - coredynp.num_pipelines / num_units * coredynp.ALU_duty_cycle, - coredynp.num_pipelines / num_units, - coredynp.num_pipelines / num_units, - coredynp.num_pipelines / num_units); - // cout<<"ExPowerScalingFactor:"<power = exu->power + corepipe->power * pppm_t; - // cout << "EXE = " << - //exu->power.readOp.dynamic*clockRate << " W" << endl; - power = power + exu->power; - // cout << "core = " << - //power.readOp.dynamic*clockRate << " W" << endl; - } - if (mmu->exist) { - Pipeline_energy += - corepipe->power.readOp.dynamic * - (coredynp.num_pipelines * rtp_pipeline_coe / num_units); - set_pppm(pppm_t, coredynp.num_pipelines / num_units * - (0.5 + 0.5 * coredynp.LSU_duty_cycle), - coredynp.num_pipelines / num_units, - coredynp.num_pipelines / num_units, - coredynp.num_pipelines / num_units); - mmu->power = mmu->power + corepipe->power * pppm_t; - // cout << "MMU = " << - //mmu->power.readOp.dynamic*clockRate << " W" << endl; - power = power + mmu->power; - // cout << "core = " << - //power.readOp.dynamic*clockRate << " W" << endl; - } - - power = power + undiffCore->power; - if (XML->sys.Private_L2) { - l2cache->computeEnergy(is_tdp); - set_pppm(pppm_t, l2cache->cachep.clockRate / clockRate, 1, 1, 1); - // l2cache->power = l2cache->power*pppm_t; - power = power + l2cache->power * pppm_t; - } - - } else { - rt_power.reset(); - ifu->computeEnergy(is_tdp); - lsu->computeEnergy(is_tdp); - mmu->computeEnergy(is_tdp); - exu->computeEnergy(is_tdp); - if (coredynp.core_ty == OOO) { - num_units = 5.0; - rnu->computeEnergy(is_tdp); - set_pppm(pppm_t, coredynp.num_pipelines / num_units, - coredynp.num_pipelines / num_units, - coredynp.num_pipelines / num_units, - coredynp.num_pipelines / num_units); - if (rnu->exist) { - rnu->rt_power = rnu->rt_power + corepipe->power * pppm_t; - - rt_power = rt_power + rnu->rt_power; - } - } else { - set_pppm(pppm_t, coredynp.num_pipelines * rtp_pipeline_coe / num_units, - coredynp.num_pipelines / num_units, - coredynp.num_pipelines / num_units, - coredynp.num_pipelines / num_units); - } - if (ifu->exist) { - Pipeline_energy += - corepipe->power.readOp.dynamic * - (coredynp.num_pipelines * rtp_pipeline_coe / num_units); - ifu->rt_power = ifu->rt_power + corepipe->power * pppm_t; - rt_power = rt_power + ifu->rt_power; - } - if (lsu->exist) { - Pipeline_energy += - corepipe->power.readOp.dynamic * - (coredynp.num_pipelines * rtp_pipeline_coe / num_units); - lsu->rt_power = lsu->rt_power + corepipe->power * pppm_t; - rt_power = rt_power + lsu->rt_power; - } - if (exu->exist) { - Pipeline_energy += - corepipe->power.readOp.dynamic * - (coredynp.num_pipelines * rtp_pipeline_coe / num_units); - exu->rt_power = exu->rt_power + corepipe->power * pppm_t; - rt_power = rt_power + exu->rt_power; - } - if (mmu->exist) { - Pipeline_energy += - corepipe->power.readOp.dynamic * - (coredynp.num_pipelines * rtp_pipeline_coe / num_units); - mmu->rt_power = mmu->rt_power + corepipe->power * pppm_t; - rt_power = rt_power + mmu->rt_power; - } +void Core::computeEnergy(bool is_tdp) +{ + //power_point_product_masks + double pppm_t[4] = {1,1,1,1}; + double rtp_pipeline_coe; + double num_units = 4.0; + Pipeline_energy=0; - rt_power = rt_power + undiffCore->power; - // cout << "EXE = " << exu->power.readOp.dynamic*clockRate << " W" << - //endl; - if (XML->sys.Private_L2) { - l2cache->computeEnergy(is_tdp); - // set_pppm(pppm_t,1/l2cache->cachep.executionTime, 1,1,1); - // l2cache->rt_power = l2cache->rt_power*pppm_t; - rt_power = rt_power + l2cache->rt_power; - } - } -} - -void Core::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 << "Core:" << endl; - cout << indent_str << "Area = " << area.get_area() * 1e-6 << " mm^2" - << endl; - cout << indent_str << "Peak Dynamic = " << power.readOp.dynamic * clockRate - << " W" << endl; - cout << indent_str << "Subthreshold Leakage = " - << (long_channel ? power.readOp.longer_channel_leakage - : power.readOp.leakage) - << " W" << endl; - // cout << indent_str << "Subthreshold Leakage = " << - // power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str << "Gate Leakage = " << power.readOp.gate_leakage << " W" - << endl; - cout << indent_str - << "Runtime Dynamic = " << rt_power.readOp.dynamic / executionTime - << " W" << endl; - cout << endl; - if (ifu->exist) { - cout << indent_str << "Instruction Fetch Unit:" << endl; - cout << indent_str_next << "Area = " << ifu->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << ifu->power.readOp.dynamic * clockRate << " W" - << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? ifu->power.readOp.longer_channel_leakage - : ifu->power.readOp.leakage) - << " W" << endl; - // cout << indent_str_next << "Subthreshold Leakage = " << - // ifu->power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str_next - << "Gate Leakage = " << ifu->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << ifu->rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << endl; - if (plevel > 2) { - ifu->displayEnergy(indent + 4, plevel, is_tdp); - } - } - if (coredynp.core_ty == OOO) { - if (rnu->exist) { - cout << indent_str << "Renaming Unit:" << endl; - cout << indent_str_next << "Area = " << rnu->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << rnu->power.readOp.dynamic * clockRate - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? rnu->power.readOp.longer_channel_leakage - : rnu->power.readOp.leakage) - << " W" << endl; - // cout << indent_str_next << "Subthreshold Leakage = " << - // rnu->power.readOp.longer_channel_leakage << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << rnu->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << rnu->rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << endl; - if (plevel > 2) { - rnu->displayEnergy(indent + 4, plevel, is_tdp); - } - } - } - if (lsu->exist) { - cout << indent_str << "Load Store Unit:" << endl; - cout << indent_str_next << "Area = " << lsu->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << lsu->power.readOp.dynamic * clockRate << " W" - << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? lsu->power.readOp.longer_channel_leakage - : lsu->power.readOp.leakage) - << " W" << endl; - // cout << indent_str_next << "Subthreshold Leakage = " << - // lsu->power.readOp.longer_channel_leakage << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << lsu->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << lsu->rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << endl; - if (plevel > 2) { - lsu->displayEnergy(indent + 4, plevel, is_tdp); - } - } - if (mmu->exist) { - cout << indent_str << "Memory Management Unit:" << endl; - cout << indent_str_next << "Area = " << mmu->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << mmu->power.readOp.dynamic * clockRate << " W" - << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? mmu->power.readOp.longer_channel_leakage - : mmu->power.readOp.leakage) - << " W" << endl; - // cout << indent_str_next << "Subthreshold Leakage = " << - // mmu->power.readOp.longer_channel_leakage << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << mmu->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << mmu->rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << endl; - if (plevel > 2) { - mmu->displayEnergy(indent + 4, plevel, is_tdp); - } - } - if (exu->exist) { - cout << indent_str << "Execution Unit:" << endl; - cout << indent_str_next << "Area = " << exu->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << exu->power.readOp.dynamic * clockRate << " W" - << endl; - cout << indent_str_next - << "Peak Dynamic Energy = " << exu->power.readOp.dynamic << " W" - << endl; - cout << indent_str_next << "clock Rate = " << clockRate << " W" << endl; - - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? exu->power.readOp.longer_channel_leakage - : exu->power.readOp.leakage) - << " W" << endl; - // cout << indent_str_next << "Subthreshold Leakage = " << - // exu->power.readOp.longer_channel_leakage << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << exu->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << exu->rt_power.readOp.dynamic / executionTime << " W" << endl; - cout << endl; - if (plevel > 2) { - exu->displayEnergy(indent + 4, plevel, is_tdp); - } + if (XML->sys.homogeneous_cores==1) + { + rtp_pipeline_coe = coredynp.pipeline_duty_cycle * XML->sys.total_cycles * XML->sys.number_of_cores; } - // if (plevel >2) - // { - // if (undiffCore->exist) - // { - // cout << indent_str << "Undifferentiated Core" << - //endl; - // cout << indent_str_next << "Area = " << - //undiffCore->area.get_area()*1e-6<< " mm^2" << endl; - // cout << indent_str_next << "Peak Dynamic = " << - //undiffCore->power.readOp.dynamic*clockRate << " W" << endl; - //// cout << indent_str_next << "Subthreshold Leakage = " << - ///undiffCore->power.readOp.leakage <<" W" << endl; - // cout << indent_str_next << "Subthreshold Leakage = - //" - // << (long_channel? - //undiffCore->power.readOp.longer_channel_leakage:undiffCore->power.readOp.leakage) - //<< " W" << endl; - // cout << indent_str_next << "Gate Leakage = " << - //undiffCore->power.readOp.gate_leakage << " W" << endl; - // // cout << indent_str_next << "Runtime Dynamic = " << - //undiffCore->rt_power.readOp.dynamic/executionTime << " W" << endl; - // cout <sys.Private_L2) { - l2cache->displayEnergy(4, is_tdp); + else + { + rtp_pipeline_coe = coredynp.pipeline_duty_cycle * coredynp.total_cycles; } + + + if (is_tdp) + { + ifu->computeEnergy(is_tdp); + lsu->computeEnergy(is_tdp); + mmu->computeEnergy(is_tdp); + exu->computeEnergy(is_tdp); + + if (coredynp.core_ty==OOO) + { + num_units = 5.0; + rnu->computeEnergy(is_tdp); + set_pppm(pppm_t, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units); + if (rnu->exist) + { + rnu->power = rnu->power + corepipe->power*pppm_t; + power = power + rnu->power; + } + } + + if (ifu->exist) + { + Pipeline_energy+=corepipe->power.readOp.dynamic* (coredynp.num_pipelines*rtp_pipeline_coe/num_units); + set_pppm(pppm_t, coredynp.num_pipelines/num_units*coredynp.IFU_duty_cycle, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units); +// cout << "IFU = " << ifu->power.readOp.dynamic*clockRate << " W" << endl; + ifu->power = ifu->power + corepipe->power*pppm_t; +// cout << "IFU = " << ifu->power.readOp.dynamic*clockRate << " W" << endl; +// cout << "1/4 pipe = " << corepipe->power.readOp.dynamic*clockRate/num_units << " W" << endl; + power = power + ifu->power; +// cout << "core = " << power.readOp.dynamic*clockRate << " W" << endl; + } + if (lsu->exist) + { + Pipeline_energy+=corepipe->power.readOp.dynamic* (coredynp.num_pipelines*rtp_pipeline_coe/num_units); + set_pppm(pppm_t, coredynp.num_pipelines/num_units*coredynp.LSU_duty_cycle, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units); + lsu->power = lsu->power + corepipe->power*pppm_t; +// cout << "LSU = " << lsu->power.readOp.dynamic*clockRate << " W" << endl; + power = power + lsu->power; +// cout << "core = " << power.readOp.dynamic*clockRate << " W" << endl; + } + if (exu->exist) + { + Pipeline_energy+=corepipe->power.readOp.dynamic* (coredynp.num_pipelines*rtp_pipeline_coe/num_units); + set_pppm(pppm_t, coredynp.num_pipelines/num_units*coredynp.ALU_duty_cycle, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units); + //cout<<"ExPowerScalingFactor:"<power = exu->power + corepipe->power*pppm_t; +// cout << "EXE = " << exu->power.readOp.dynamic*clockRate << " W" << endl; + power = power + exu->power; +// cout << "core = " << power.readOp.dynamic*clockRate << " W" << endl; + } + if (mmu->exist) + { + Pipeline_energy+=corepipe->power.readOp.dynamic* (coredynp.num_pipelines*rtp_pipeline_coe/num_units); + set_pppm(pppm_t, coredynp.num_pipelines/num_units*(0.5+0.5*coredynp.LSU_duty_cycle), coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units); + mmu->power = mmu->power + corepipe->power*pppm_t; +// cout << "MMU = " << mmu->power.readOp.dynamic*clockRate << " W" << endl; + power = power + mmu->power; +// cout << "core = " << power.readOp.dynamic*clockRate << " W" << endl; + } + + power = power + undiffCore->power; + + if (XML->sys.Private_L2) + { + + l2cache->computeEnergy(is_tdp); + set_pppm(pppm_t,l2cache->cachep.clockRate/clockRate, 1,1,1); + //l2cache->power = l2cache->power*pppm_t; + power = power + l2cache->power*pppm_t; + } + + } + else + { + rt_power.reset(); - cout << indent_str << "Idle Core: " << endl; - cout << indent_str_next - << "Runtime Dynamic = " << IdleCoreEnergy / executionTime << " W\n" - << endl; - - } else { - // cout << indent_str_next << "Instruction Fetch Unit Peak Dynamic = " - //<< ifu->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Instruction Fetch Unit Subthreshold - //Leakage = " << ifu->rt_power.readOp.leakage <<" W" << endl; - // cout << indent_str_next << "Instruction Fetch Unit Gate Leakage = " - //<< ifu->rt_power.readOp.gate_leakage << " W" << endl; - // cout << indent_str_next << "Load Store Unit Peak Dynamic = " << - //lsu->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Load Store Unit Subthreshold Leakage = " - //<< lsu->rt_power.readOp.leakage << " W" << endl; - // cout << indent_str_next << "Load Store Unit Gate Leakage = " << - //lsu->rt_power.readOp.gate_leakage << " W" << endl; - // cout << indent_str_next << "Memory Management Unit Peak Dynamic = " - //<< mmu->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Memory Management Unit Subthreshold - //Leakage = " << mmu->rt_power.readOp.leakage << " W" << endl; - // cout << indent_str_next << "Memory Management Unit Gate Leakage = " - //<< mmu->rt_power.readOp.gate_leakage << " W" << endl; - // cout << indent_str_next << "Execution Unit Peak Dynamic = " << - //exu->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Execution Unit Subthreshold Leakage = " - //<< exu->rt_power.readOp.leakage << " W" << endl; - // cout << indent_str_next << "Execution Unit Gate Leakage = " << - //exu->rt_power.readOp.gate_leakage << " W" << endl; - } -} -InstFetchU::~InstFetchU() { - if (!exist) return; - if (IB) { - delete IB; - IB = 0; - } - if (ID_inst) { - delete ID_inst; - ID_inst = 0; - } - if (ID_operand) { - delete ID_operand; - ID_operand = 0; - } - if (ID_misc) { - delete ID_misc; - ID_misc = 0; - } - if (coredynp.predictionW > 0) { - if (BTB) { - delete BTB; - BTB = 0; - } - if (BPT) { - delete BPT; - BPT = 0; - } - } -} -BranchPredictor::~BranchPredictor() { - if (!exist) return; - if (globalBPT) { - delete globalBPT; - globalBPT = 0; - } - if (localBPT) { - delete localBPT; - localBPT = 0; - } - if (L1_localBPT) { - delete L1_localBPT; - L1_localBPT = 0; - } - if (L2_localBPT) { - delete L2_localBPT; - L2_localBPT = 0; - } - if (chooser) { - delete chooser; - chooser = 0; - } - if (RAS) { - delete RAS; - RAS = 0; - } -} -RENAMINGU::~RENAMINGU() { - if (!exist) return; - if (iFRAT) { - delete iFRAT; - iFRAT = 0; - } - if (fFRAT) { - delete fFRAT; - fFRAT = 0; - } - if (iRRAT) { - delete iRRAT; - iRRAT = 0; - } - if (iFRAT) { - delete iFRAT; - iFRAT = 0; - } - if (ifreeL) { - delete ifreeL; - ifreeL = 0; - } - if (ffreeL) { - delete ffreeL; - ffreeL = 0; - } - if (idcl) { - delete idcl; - idcl = 0; - } - if (fdcl) { - delete fdcl; - fdcl = 0; - } - if (RAHT) { - delete RAHT; - RAHT = 0; - } -} -LoadStoreU::~LoadStoreU() { - if (!exist) return; - if (LSQ) { - delete LSQ; - LSQ = 0; - } -} + ifu->computeEnergy(is_tdp); + lsu->computeEnergy(is_tdp); + mmu->computeEnergy(is_tdp); + exu->computeEnergy(is_tdp); + if (coredynp.core_ty==OOO) + { + num_units = 5.0; + rnu->computeEnergy(is_tdp); + set_pppm(pppm_t, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units); + if (rnu->exist) + { + rnu->rt_power = rnu->rt_power + corepipe->power*pppm_t; + + rt_power = rt_power + rnu->rt_power; + } + } + else + { + + set_pppm(pppm_t, coredynp.num_pipelines*rtp_pipeline_coe/num_units, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units); + } + + if (ifu->exist) + { + Pipeline_energy+=corepipe->power.readOp.dynamic* (coredynp.num_pipelines*rtp_pipeline_coe/num_units); + ifu->rt_power = ifu->rt_power + corepipe->power*pppm_t; + rt_power = rt_power + ifu->rt_power ; + } + if (lsu->exist) + { + Pipeline_energy+=corepipe->power.readOp.dynamic* (coredynp.num_pipelines*rtp_pipeline_coe/num_units); + lsu->rt_power = lsu->rt_power + corepipe->power*pppm_t; + rt_power = rt_power + lsu->rt_power; + } + if (exu->exist) + { + Pipeline_energy+=corepipe->power.readOp.dynamic* (coredynp.num_pipelines*rtp_pipeline_coe/num_units); + exu->rt_power = exu->rt_power + corepipe->power*pppm_t; + rt_power = rt_power + exu->rt_power; + } + if (mmu->exist) + { + Pipeline_energy+=corepipe->power.readOp.dynamic* (coredynp.num_pipelines*rtp_pipeline_coe/num_units); + mmu->rt_power = mmu->rt_power + corepipe->power*pppm_t; + rt_power = rt_power + mmu->rt_power ; + } + + rt_power = rt_power + undiffCore->power; +// cout << "EXE = " << exu->power.readOp.dynamic*clockRate << " W" << endl; + if (XML->sys.Private_L2) + { + l2cache->computeEnergy(is_tdp); + //set_pppm(pppm_t,1/l2cache->cachep.executionTime, 1,1,1); + //l2cache->rt_power = l2cache->rt_power*pppm_t; + rt_power = rt_power + l2cache->rt_power; + } + + } -MemManU::~MemManU() { - if (!exist) return; - if (itlb) { - delete itlb; - itlb = 0; - } - if (dtlb) { - delete dtlb; - dtlb = 0; - } } -RegFU::~RegFU() { - if (!exist) return; - if (IRF) { - delete IRF; - IRF = 0; - } - if (FRF) { - delete FRF; - FRF = 0; - } - if (RFWIN) { - delete RFWIN; - RFWIN = 0; - } +void Core::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 << "Core:" << endl; + cout << indent_str << "Area = " << area.get_area()*1e-6<< " mm^2" << endl; + cout << indent_str << "Peak Dynamic = " << power.readOp.dynamic*clockRate << " W" << endl; + cout << indent_str << "Subthreshold Leakage = " + << (long_channel? power.readOp.longer_channel_leakage:power.readOp.leakage) <<" W" << endl; + //cout << indent_str << "Subthreshold Leakage = " << power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str << "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl; + cout << indent_str << "Runtime Dynamic = " << rt_power.readOp.dynamic/executionTime << " W" << endl; + cout<exist) + { + cout << indent_str << "Instruction Fetch Unit:" << endl; + cout << indent_str_next << "Area = " << ifu->area.get_area()*1e-6<< " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << ifu->power.readOp.dynamic*clockRate << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? ifu->power.readOp.longer_channel_leakage:ifu->power.readOp.leakage) <<" W" << endl; + //cout << indent_str_next << "Subthreshold Leakage = " << ifu->power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str_next << "Gate Leakage = " << ifu->power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << ifu->rt_power.readOp.dynamic/executionTime << " W" << endl; + cout <2){ + ifu->displayEnergy(indent+4,plevel,is_tdp); + } + } + if (coredynp.core_ty==OOO) + { + if (rnu->exist) + { + cout << indent_str<< "Renaming Unit:" << endl; + cout << indent_str_next << "Area = " << rnu->area.get_area()*1e-6 << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << rnu->power.readOp.dynamic*clockRate << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? rnu->power.readOp.longer_channel_leakage:rnu->power.readOp.leakage) << " W" << endl; + //cout << indent_str_next << "Subthreshold Leakage = " << rnu->power.readOp.longer_channel_leakage << " W" << endl; + cout << indent_str_next << "Gate Leakage = " << rnu->power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << rnu->rt_power.readOp.dynamic/executionTime << " W" << endl; + cout <2){ + rnu->displayEnergy(indent+4,plevel,is_tdp); + } + } + + } + if (lsu->exist) + { + cout << indent_str<< "Load Store Unit:" << endl; + cout << indent_str_next << "Area = " << lsu->area.get_area()*1e-6 << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << lsu->power.readOp.dynamic*clockRate << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? lsu->power.readOp.longer_channel_leakage:lsu->power.readOp.leakage ) << " W" << endl; + //cout << indent_str_next << "Subthreshold Leakage = " << lsu->power.readOp.longer_channel_leakage << " W" << endl; + cout << indent_str_next << "Gate Leakage = " << lsu->power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << lsu->rt_power.readOp.dynamic/executionTime << " W" << endl; + cout <2){ + lsu->displayEnergy(indent+4,plevel,is_tdp); + } + } + if (mmu->exist) + { + cout << indent_str<< "Memory Management Unit:" << endl; + cout << indent_str_next << "Area = " << mmu->area.get_area() *1e-6 << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << mmu->power.readOp.dynamic*clockRate << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? mmu->power.readOp.longer_channel_leakage:mmu->power.readOp.leakage) << " W" << endl; + //cout << indent_str_next << "Subthreshold Leakage = " << mmu->power.readOp.longer_channel_leakage << " W" << endl; + cout << indent_str_next << "Gate Leakage = " << mmu->power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << mmu->rt_power.readOp.dynamic/executionTime << " W" << endl; + cout <2){ + mmu->displayEnergy(indent+4,plevel,is_tdp); + } + } + if (exu->exist) + { + cout << indent_str<< "Execution Unit:" << endl; + cout << indent_str_next << "Area = " << exu->area.get_area() *1e-6<< " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << exu->power.readOp.dynamic*clockRate << " W" << endl; + cout << indent_str_next << "Peak Dynamic Energy = " << exu->power.readOp.dynamic << " W" << endl; + cout << indent_str_next << "clock Rate = " << clockRate << " W" << endl; + + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? exu->power.readOp.longer_channel_leakage:exu->power.readOp.leakage) << " W" << endl; + //cout << indent_str_next << "Subthreshold Leakage = " << exu->power.readOp.longer_channel_leakage << " W" << endl; + cout << indent_str_next << "Gate Leakage = " << exu->power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << exu->rt_power.readOp.dynamic/executionTime << " W" << endl; + cout <2){ + exu->displayEnergy(indent+4,plevel,is_tdp); + } + } +// if (plevel >2) +// { +// if (undiffCore->exist) +// { +// cout << indent_str << "Undifferentiated Core" << endl; +// cout << indent_str_next << "Area = " << undiffCore->area.get_area()*1e-6<< " mm^2" << endl; +// cout << indent_str_next << "Peak Dynamic = " << undiffCore->power.readOp.dynamic*clockRate << " W" << endl; +//// cout << indent_str_next << "Subthreshold Leakage = " << undiffCore->power.readOp.leakage <<" W" << endl; +// cout << indent_str_next << "Subthreshold Leakage = " +// << (long_channel? undiffCore->power.readOp.longer_channel_leakage:undiffCore->power.readOp.leakage) << " W" << endl; +// cout << indent_str_next << "Gate Leakage = " << undiffCore->power.readOp.gate_leakage << " W" << endl; +// // cout << indent_str_next << "Runtime Dynamic = " << undiffCore->rt_power.readOp.dynamic/executionTime << " W" << endl; +// cout <sys.Private_L2) + { + + l2cache->displayEnergy(4,is_tdp); + } + + cout << indent_str<< "Idle Core: " << endl; + cout << indent_str_next << "Runtime Dynamic = " << IdleCoreEnergy/executionTime << " W\n" << endl; + + } + else + { +// cout << indent_str_next << "Instruction Fetch Unit Peak Dynamic = " << ifu->rt_power.readOp.dynamic*clockRate << " W" << endl; +// cout << indent_str_next << "Instruction Fetch Unit Subthreshold Leakage = " << ifu->rt_power.readOp.leakage <<" W" << endl; +// cout << indent_str_next << "Instruction Fetch Unit Gate Leakage = " << ifu->rt_power.readOp.gate_leakage << " W" << endl; +// cout << indent_str_next << "Load Store Unit Peak Dynamic = " << lsu->rt_power.readOp.dynamic*clockRate << " W" << endl; +// cout << indent_str_next << "Load Store Unit Subthreshold Leakage = " << lsu->rt_power.readOp.leakage << " W" << endl; +// cout << indent_str_next << "Load Store Unit Gate Leakage = " << lsu->rt_power.readOp.gate_leakage << " W" << endl; +// cout << indent_str_next << "Memory Management Unit Peak Dynamic = " << mmu->rt_power.readOp.dynamic*clockRate << " W" << endl; +// cout << indent_str_next << "Memory Management Unit Subthreshold Leakage = " << mmu->rt_power.readOp.leakage << " W" << endl; +// cout << indent_str_next << "Memory Management Unit Gate Leakage = " << mmu->rt_power.readOp.gate_leakage << " W" << endl; +// cout << indent_str_next << "Execution Unit Peak Dynamic = " << exu->rt_power.readOp.dynamic*clockRate << " W" << endl; +// cout << indent_str_next << "Execution Unit Subthreshold Leakage = " << exu->rt_power.readOp.leakage << " W" << endl; +// cout << indent_str_next << "Execution Unit Gate Leakage = " << exu->rt_power.readOp.gate_leakage << " W" << endl; + } } - -SchedulerU::~SchedulerU() { - if (!exist) return; - if (int_inst_window) { - delete int_inst_window; - int_inst_window = 0; - } - if (fp_inst_window) { - delete int_inst_window; - int_inst_window = 0; - } - if (ROB) { - delete ROB; - ROB = 0; - } - if (instruction_selection) { - delete instruction_selection; - instruction_selection = 0; - } +InstFetchU ::~InstFetchU(){ + + if (!exist) return; + if(IB) {delete IB; IB = 0;} + if(ID_inst) {delete ID_inst; ID_inst = 0;} + if(ID_operand) {delete ID_operand; ID_operand = 0;} + if(ID_misc) {delete ID_misc; ID_misc = 0;} + if (coredynp.predictionW>0) + { + if(BTB) {delete BTB; BTB = 0;} + if(BPT) {delete BPT; BPT = 0;} + } } -EXECU::~EXECU() { - if (!exist) return; - if (int_bypass) { - delete int_bypass; - int_bypass = 0; - } - if (intTagBypass) { - delete intTagBypass; - intTagBypass = 0; - } - if (int_mul_bypass) { - delete int_mul_bypass; - int_mul_bypass = 0; - } - if (intTag_mul_Bypass) { - delete intTag_mul_Bypass; - intTag_mul_Bypass = 0; - } - if (fp_bypass) { - delete fp_bypass; - fp_bypass = 0; - } - if (fpTagBypass) { - delete fpTagBypass; - fpTagBypass = 0; - } - if (fp_u) { - delete fp_u; - fp_u = 0; - } - if (exeu) { - delete exeu; - exeu = 0; - } - if (mul) { - delete mul; - mul = 0; - } - if (rfu) { - delete rfu; - rfu = 0; - } - if (scheu) { - delete scheu; - scheu = 0; - } -} +BranchPredictor ::~BranchPredictor(){ + + if (!exist) return; + if(globalBPT) {delete globalBPT; globalBPT = 0;} + if(localBPT) {delete localBPT; localBPT = 0;} + if(L1_localBPT) {delete L1_localBPT; L1_localBPT = 0;} + if(L2_localBPT) {delete L2_localBPT; L2_localBPT = 0;} + if(chooser) {delete chooser; chooser = 0;} + if(RAS) {delete RAS; RAS = 0;} + } + +RENAMINGU ::~RENAMINGU(){ + + if (!exist) return; + if(iFRAT ) {delete iFRAT; iFRAT = 0;} + if(fFRAT ) {delete fFRAT; fFRAT =0;} + if(iRRAT) {delete iRRAT; iRRAT = 0;} + if(iFRAT) {delete iFRAT; iFRAT = 0;} + if(ifreeL) {delete ifreeL;ifreeL= 0;} + if(ffreeL) {delete ffreeL;ffreeL= 0;} + if(idcl) {delete idcl; idcl = 0;} + if(fdcl) {delete fdcl; fdcl = 0;} + if(RAHT) {delete RAHT; RAHT = 0;} + } + +LoadStoreU ::~LoadStoreU(){ + + if (!exist) return; + if(LSQ) {delete LSQ; LSQ = 0;} + } + +MemManU ::~MemManU(){ + + if (!exist) return; + if(itlb) {delete itlb; itlb = 0;} + if(dtlb) {delete dtlb; dtlb = 0;} + } + +RegFU ::~RegFU(){ + + if (!exist) return; + if(IRF) {delete IRF; IRF = 0;} + if(FRF) {delete FRF; FRF = 0;} + if(RFWIN) {delete RFWIN; RFWIN = 0;} + } + +SchedulerU ::~SchedulerU(){ + + if (!exist) return; + if(int_inst_window) {delete int_inst_window; int_inst_window = 0;} + if(fp_inst_window) {delete int_inst_window; int_inst_window = 0;} + if(ROB) {delete ROB; ROB = 0;} + if(instruction_selection) {delete instruction_selection;instruction_selection = 0;} + } + +EXECU ::~EXECU(){ + + if (!exist) return; + if(int_bypass) {delete int_bypass; int_bypass = 0;} + if(intTagBypass) {delete intTagBypass; intTagBypass =0;} + if(int_mul_bypass) {delete int_mul_bypass; int_mul_bypass = 0;} + if(intTag_mul_Bypass) {delete intTag_mul_Bypass; intTag_mul_Bypass =0;} + if(fp_bypass) {delete fp_bypass;fp_bypass = 0;} + if(fpTagBypass) {delete fpTagBypass;fpTagBypass = 0;} + if(fp_u) {delete fp_u;fp_u = 0;} + if(exeu) {delete exeu;exeu = 0;} + if(mul) {delete mul;mul = 0;} + if(rfu) {delete rfu;rfu = 0;} + if(scheu) {delete scheu; scheu = 0;} + } + +Core ::~Core(){ + + if(ifu) {delete ifu; ifu = 0;} + if(lsu) {delete lsu; lsu = 0;} + if(rnu) {delete rnu; rnu = 0;} + if(mmu) {delete mmu; mmu = 0;} + if(exu) {delete exu; exu = 0;} + if(corepipe) {delete corepipe; corepipe = 0;} + if(undiffCore) {delete undiffCore;undiffCore = 0;} + if(l2cache) {delete l2cache;l2cache = 0;} + } + +void Core::set_core_param() +{ + coredynp.opt_local = XML->sys.core[ithCore].opt_local; + coredynp.x86 = XML->sys.core[ithCore].x86; + coredynp.Embedded = XML->sys.Embedded; + coredynp.core_ty = (enum Core_type)XML->sys.core[ithCore].machine_type; + coredynp.rm_ty = (enum Renaming_type)XML->sys.core[ithCore].rename_scheme; + coredynp.fetchW = XML->sys.core[ithCore].fetch_width; + coredynp.decodeW = XML->sys.core[ithCore].decode_width; + coredynp.issueW = XML->sys.core[ithCore].issue_width; + coredynp.peak_issueW = XML->sys.core[ithCore].peak_issue_width; + coredynp.commitW = XML->sys.core[ithCore].commit_width; + coredynp.peak_commitW = XML->sys.core[ithCore].peak_issue_width; + coredynp.predictionW = XML->sys.core[ithCore].prediction_width; + coredynp.fp_issueW = XML->sys.core[ithCore].fp_issue_width; + coredynp.fp_decodeW = XML->sys.core[ithCore].fp_issue_width; + coredynp.num_alus = XML->sys.core[ithCore].ALU_per_core; + coredynp.num_fpus = XML->sys.core[ithCore].FPU_per_core; + coredynp.num_muls = XML->sys.core[ithCore].MUL_per_core; + + + coredynp.num_hthreads = XML->sys.core[ithCore].number_hardware_threads; + coredynp.multithreaded = coredynp.num_hthreads>1? true:false; + coredynp.instruction_length = XML->sys.core[ithCore].instruction_length; + coredynp.pc_width = XML->sys.virtual_address_width; + + coredynp.opcode_length = XML->sys.core[ithCore].opcode_width; + coredynp.micro_opcode_length = XML->sys.core[ithCore].micro_opcode_width; + coredynp.num_pipelines = XML->sys.core[ithCore].pipelines_per_core[0]; + coredynp.pipeline_stages = XML->sys.core[ithCore].pipeline_depth[0]; + coredynp.num_fp_pipelines = XML->sys.core[ithCore].pipelines_per_core[1]; + coredynp.fp_pipeline_stages = XML->sys.core[ithCore].pipeline_depth[1]; + coredynp.int_data_width = int(ceil(XML->sys.machine_bits/32.0))*32; + coredynp.fp_data_width = coredynp.int_data_width; + coredynp.v_address_width = XML->sys.virtual_address_width; + coredynp.p_address_width = XML->sys.physical_address_width; + + coredynp.scheu_ty = (enum Scheduler_type)XML->sys.core[ithCore].instruction_window_scheme; + coredynp.arch_ireg_width = int(ceil(log2(XML->sys.core[ithCore].archi_Regs_IRF_size))); + coredynp.arch_freg_width = int(ceil(log2(XML->sys.core[ithCore].archi_Regs_FRF_size))); + coredynp.num_IRF_entry = XML->sys.core[ithCore].archi_Regs_IRF_size; + coredynp.num_FRF_entry = XML->sys.core[ithCore].archi_Regs_FRF_size; + coredynp.pipeline_duty_cycle = XML->sys.core[ithCore].pipeline_duty_cycle; + coredynp.total_cycles = XML->sys.core[ithCore].total_cycles; + coredynp.busy_cycles = XML->sys.core[ithCore].busy_cycles; + coredynp.idle_cycles = XML->sys.core[ithCore].idle_cycles; + + //Max power duty cycle for peak power estimation +// if (coredynp.core_ty==OOO) +// { +// coredynp.IFU_duty_cycle = 1; +// coredynp.LSU_duty_cycle = 1; +// coredynp.MemManU_I_duty_cycle =1; +// coredynp.MemManU_D_duty_cycle =1; +// coredynp.ALU_duty_cycle =1; +// coredynp.MUL_duty_cycle =1; +// coredynp.FPU_duty_cycle =1; +// coredynp.ALU_cdb_duty_cycle =1; +// coredynp.MUL_cdb_duty_cycle =1; +// coredynp.FPU_cdb_duty_cycle =1; +// } +// else +// { + coredynp.IFU_duty_cycle = XML->sys.core[ithCore].IFU_duty_cycle; + coredynp.BR_duty_cycle = XML->sys.core[ithCore].BR_duty_cycle; + coredynp.LSU_duty_cycle = XML->sys.core[ithCore].LSU_duty_cycle; + coredynp.MemManU_I_duty_cycle = XML->sys.core[ithCore].MemManU_I_duty_cycle; + coredynp.MemManU_D_duty_cycle = XML->sys.core[ithCore].MemManU_D_duty_cycle; + coredynp.ALU_duty_cycle = XML->sys.core[ithCore].ALU_duty_cycle; + coredynp.MUL_duty_cycle = XML->sys.core[ithCore].MUL_duty_cycle; + coredynp.FPU_duty_cycle = XML->sys.core[ithCore].FPU_duty_cycle; + coredynp.ALU_cdb_duty_cycle = XML->sys.core[ithCore].ALU_cdb_duty_cycle; + coredynp.MUL_cdb_duty_cycle = XML->sys.core[ithCore].MUL_cdb_duty_cycle; + coredynp.FPU_cdb_duty_cycle = XML->sys.core[ithCore].FPU_cdb_duty_cycle; +// } + + + if (!((coredynp.core_ty==OOO)||(coredynp.core_ty==Inorder))) + { + cout<<"Invalid Core Type"<sys.core[ithCore].phy_Regs_IRF_size))); + coredynp.phy_freg_width = int(ceil(log2(XML->sys.core[ithCore].phy_Regs_FRF_size))); + coredynp.num_ifreelist_entries = coredynp.num_IRF_entry = XML->sys.core[ithCore].phy_Regs_IRF_size; + coredynp.num_ffreelist_entries = coredynp.num_FRF_entry = XML->sys.core[ithCore].phy_Regs_FRF_size; + } + else if (coredynp.scheu_ty==ReservationStation) + {//ROB serves as Phy RF in RS based OOO + coredynp.phy_ireg_width = int(ceil(log2(XML->sys.core[ithCore].ROB_size))); + coredynp.phy_freg_width = int(ceil(log2(XML->sys.core[ithCore].ROB_size))); + coredynp.num_ifreelist_entries = XML->sys.core[ithCore].ROB_size; + coredynp.num_ffreelist_entries = XML->sys.core[ithCore].ROB_size; + + } -Core::~Core() { - if (ifu) { - delete ifu; - ifu = 0; - } - if (lsu) { - delete lsu; - lsu = 0; - } - if (rnu) { - delete rnu; - rnu = 0; - } - if (mmu) { - delete mmu; - mmu = 0; - } - if (exu) { - delete exu; - exu = 0; - } - if (corepipe) { - delete corepipe; - corepipe = 0; - } - if (undiffCore) { - delete undiffCore; - undiffCore = 0; - } - if (l2cache) { - delete l2cache; - l2cache = 0; - } } - -void Core::set_core_param() { - coredynp.opt_local = XML->sys.core[ithCore].opt_local; - coredynp.x86 = XML->sys.core[ithCore].x86; - coredynp.Embedded = XML->sys.Embedded; - coredynp.core_ty = (enum Core_type)XML->sys.core[ithCore].machine_type; - coredynp.rm_ty = (enum Renaming_type)XML->sys.core[ithCore].rename_scheme; - coredynp.fetchW = XML->sys.core[ithCore].fetch_width; - coredynp.decodeW = XML->sys.core[ithCore].decode_width; - coredynp.issueW = XML->sys.core[ithCore].issue_width; - coredynp.peak_issueW = XML->sys.core[ithCore].peak_issue_width; - coredynp.commitW = XML->sys.core[ithCore].commit_width; - coredynp.peak_commitW = XML->sys.core[ithCore].peak_issue_width; - coredynp.predictionW = XML->sys.core[ithCore].prediction_width; - coredynp.fp_issueW = XML->sys.core[ithCore].fp_issue_width; - coredynp.fp_decodeW = XML->sys.core[ithCore].fp_issue_width; - coredynp.num_alus = XML->sys.core[ithCore].ALU_per_core; - coredynp.num_fpus = XML->sys.core[ithCore].FPU_per_core; - coredynp.num_muls = XML->sys.core[ithCore].MUL_per_core; - - coredynp.num_hthreads = XML->sys.core[ithCore].number_hardware_threads; - coredynp.multithreaded = coredynp.num_hthreads > 1 ? true : false; - coredynp.instruction_length = XML->sys.core[ithCore].instruction_length; - coredynp.pc_width = XML->sys.virtual_address_width; - - coredynp.opcode_length = XML->sys.core[ithCore].opcode_width; - coredynp.micro_opcode_length = XML->sys.core[ithCore].micro_opcode_width; - coredynp.num_pipelines = XML->sys.core[ithCore].pipelines_per_core[0]; - coredynp.pipeline_stages = XML->sys.core[ithCore].pipeline_depth[0]; - coredynp.num_fp_pipelines = XML->sys.core[ithCore].pipelines_per_core[1]; - coredynp.fp_pipeline_stages = XML->sys.core[ithCore].pipeline_depth[1]; - coredynp.int_data_width = int(ceil(XML->sys.machine_bits / 32.0)) * 32; - coredynp.fp_data_width = coredynp.int_data_width; - coredynp.v_address_width = XML->sys.virtual_address_width; - coredynp.p_address_width = XML->sys.physical_address_width; - - coredynp.scheu_ty = - (enum Scheduler_type)XML->sys.core[ithCore].instruction_window_scheme; - coredynp.arch_ireg_width = - int(ceil(log2(XML->sys.core[ithCore].archi_Regs_IRF_size))); - coredynp.arch_freg_width = - int(ceil(log2(XML->sys.core[ithCore].archi_Regs_FRF_size))); - coredynp.num_IRF_entry = XML->sys.core[ithCore].archi_Regs_IRF_size; - coredynp.num_FRF_entry = XML->sys.core[ithCore].archi_Regs_FRF_size; - coredynp.pipeline_duty_cycle = XML->sys.core[ithCore].pipeline_duty_cycle; - coredynp.total_cycles = XML->sys.core[ithCore].total_cycles; - coredynp.busy_cycles = XML->sys.core[ithCore].busy_cycles; - coredynp.idle_cycles = XML->sys.core[ithCore].idle_cycles; - - // Max power duty cycle for peak power estimation - // if (coredynp.core_ty==OOO) - // { - // coredynp.IFU_duty_cycle = 1; - // coredynp.LSU_duty_cycle = 1; - // coredynp.MemManU_I_duty_cycle =1; - // coredynp.MemManU_D_duty_cycle =1; - // coredynp.ALU_duty_cycle =1; - // coredynp.MUL_duty_cycle =1; - // coredynp.FPU_duty_cycle =1; - // coredynp.ALU_cdb_duty_cycle =1; - // coredynp.MUL_cdb_duty_cycle =1; - // coredynp.FPU_cdb_duty_cycle =1; - // } - // else - // { - coredynp.IFU_duty_cycle = XML->sys.core[ithCore].IFU_duty_cycle; - coredynp.BR_duty_cycle = XML->sys.core[ithCore].BR_duty_cycle; - coredynp.LSU_duty_cycle = XML->sys.core[ithCore].LSU_duty_cycle; - coredynp.MemManU_I_duty_cycle = XML->sys.core[ithCore].MemManU_I_duty_cycle; - coredynp.MemManU_D_duty_cycle = XML->sys.core[ithCore].MemManU_D_duty_cycle; - coredynp.ALU_duty_cycle = XML->sys.core[ithCore].ALU_duty_cycle; - coredynp.MUL_duty_cycle = XML->sys.core[ithCore].MUL_duty_cycle; - coredynp.FPU_duty_cycle = XML->sys.core[ithCore].FPU_duty_cycle; - coredynp.ALU_cdb_duty_cycle = XML->sys.core[ithCore].ALU_cdb_duty_cycle; - coredynp.MUL_cdb_duty_cycle = XML->sys.core[ithCore].MUL_cdb_duty_cycle; - coredynp.FPU_cdb_duty_cycle = XML->sys.core[ithCore].FPU_cdb_duty_cycle; - // } - - if (!((coredynp.core_ty == OOO) || (coredynp.core_ty == Inorder))) { - cout << "Invalid Core Type" << endl; - exit(0); - } - // if (coredynp.core_ty==OOO) - // { - // cout<<"OOO processor models are being updated and will be available - //in next release"<sys.core[ithCore].phy_Regs_IRF_size))); - coredynp.phy_freg_width = - int(ceil(log2(XML->sys.core[ithCore].phy_Regs_FRF_size))); - coredynp.num_ifreelist_entries = coredynp.num_IRF_entry = - XML->sys.core[ithCore].phy_Regs_IRF_size; - coredynp.num_ffreelist_entries = coredynp.num_FRF_entry = - XML->sys.core[ithCore].phy_Regs_FRF_size; - } else if (coredynp.scheu_ty == - ReservationStation) { // ROB serves as Phy RF in RS based OOO - coredynp.phy_ireg_width = - int(ceil(log2(XML->sys.core[ithCore].ROB_size))); - coredynp.phy_freg_width = - int(ceil(log2(XML->sys.core[ithCore].ROB_size))); - coredynp.num_ifreelist_entries = XML->sys.core[ithCore].ROB_size; - coredynp.num_ffreelist_entries = XML->sys.core[ithCore].ROB_size; - } - } - coredynp.globalCheckpoint = 32; // best check pointing entries for a 4~8 - // issue OOO should be 16~48;See TR for - // reference. - coredynp.perThreadState = 8; - coredynp.instruction_length = 32; - coredynp.clockRate = XML->sys.core[ithCore].clock_rate; - coredynp.clockRate *= 1e6; - coredynp.regWindowing = (XML->sys.core[ithCore].register_windows_size > 0 && - coredynp.core_ty == Inorder) - ? true - : false; - coredynp.executionTime = XML->sys.total_cycles / coredynp.clockRate; - set_pppm(coredynp.pppm_lkg_multhread, 0, coredynp.num_hthreads, - coredynp.num_hthreads, 0); + coredynp.globalCheckpoint = 32;//best check pointing entries for a 4~8 issue OOO should be 16~48;See TR for reference. + coredynp.perThreadState = 8; + coredynp.instruction_length = 32; + coredynp.clockRate = XML->sys.core[ithCore].clock_rate; + coredynp.clockRate *= 1e6; + coredynp.regWindowing= (XML->sys.core[ithCore].register_windows_size>0&&coredynp.core_ty==Inorder)?true:false; + coredynp.executionTime = XML->sys.total_cycles/coredynp.clockRate; + set_pppm(coredynp.pppm_lkg_multhread, 0, coredynp.num_hthreads, coredynp.num_hthreads, 0); } diff --git a/src/gpuwattch/core.h b/src/gpuwattch/core.h index f012c42..b43a57c 100644 --- a/src/gpuwattch/core.h +++ b/src/gpuwattch/core.h @@ -29,530 +29,470 @@ * ***************************************************************************/ /******************************************************************** -* Modified by: -** +* 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 * ********************************************************************/ + #ifndef CORE_H_ #define CORE_H_ #include "XML_Parse.h" +#include "logic.h" +#include "cacti/parameter.h" #include "array.h" +#include "interconnect.h" #include "basic_components.h" -#include "cacti/arbiter.h" +#include "sharedcache.h" #include "cacti/crossbar.h" -#include "cacti/parameter.h" -#include "interconnect.h" -#include "logic.h" +#include "cacti/arbiter.h" #include "noc.h" -#include "sharedcache.h" -class BranchPredictor : public Component { - public: - ParseXML *XML; - int ithCore; - InputParameter interface_ip; - CoreDynParam coredynp; - double clockRate, executionTime; - double scktRatio, chip_PR_overhead, macro_PR_overhead; - ArrayST *globalBPT; - ArrayST *localBPT; - ArrayST *L1_localBPT; - ArrayST *L2_localBPT; - ArrayST *chooser; - ArrayST *RAS; - bool exist; - - BranchPredictor(ParseXML *XML_interface, int ithCore_, - InputParameter *interface_ip_, const CoreDynParam &dyn_p_, - bool exsit = true); - void computeEnergy(bool is_tdp = true); - void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); - ~BranchPredictor(); +class BranchPredictor :public Component { + public: + + ParseXML *XML; + int ithCore; + InputParameter interface_ip; + CoreDynParam coredynp; + double clockRate,executionTime; + double scktRatio, chip_PR_overhead, macro_PR_overhead; + ArrayST * globalBPT; + ArrayST * localBPT; + ArrayST * L1_localBPT; + ArrayST * L2_localBPT; + ArrayST * chooser; + ArrayST * RAS; + bool exist; + + BranchPredictor(ParseXML *XML_interface, int ithCore_, InputParameter* interface_ip_,const CoreDynParam & dyn_p_, bool exsit=true); + void computeEnergy(bool is_tdp=true); + void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); + ~BranchPredictor(); }; -class InstFetchU : public Component { - public: - ParseXML *XML; - int ithCore; - InputParameter interface_ip; - CoreDynParam coredynp; - double clockRate, executionTime; - double scktRatio, chip_PR_overhead, macro_PR_overhead; - enum Cache_policy cache_p; - InstCache icache; - ArrayST *IB; - ArrayST *BTB; - BranchPredictor *BPT; - inst_decoder *ID_inst; - inst_decoder *ID_operand; - inst_decoder *ID_misc; - bool exist; - - InstFetchU(ParseXML *XML_interface, int ithCore_, - InputParameter *interface_ip_, const CoreDynParam &dyn_p_, - bool exsit = true); - void computeEnergy(bool is_tdp = true); - void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); - ~InstFetchU(); + +class InstFetchU :public Component { + public: + + ParseXML *XML; + int ithCore; + InputParameter interface_ip; + CoreDynParam coredynp; + double clockRate,executionTime; + double scktRatio, chip_PR_overhead, macro_PR_overhead; + enum Cache_policy cache_p; + InstCache icache; + ArrayST * IB; + ArrayST * BTB; + BranchPredictor * BPT; + inst_decoder * ID_inst; + inst_decoder * ID_operand; + inst_decoder * ID_misc; + bool exist; + + InstFetchU(ParseXML *XML_interface, int ithCore_, InputParameter* interface_ip_,const CoreDynParam & dyn_p_, bool exsit=true); + void computeEnergy(bool is_tdp=true); + void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); + ~InstFetchU(); }; -class SchedulerU : public Component { - public: - ParseXML *XML; - int ithCore; - InputParameter interface_ip; - CoreDynParam coredynp; - double clockRate, executionTime; - double scktRatio, chip_PR_overhead, macro_PR_overhead; - double Iw_height, fp_Iw_height, ROB_height; - ArrayST *int_inst_window; - ArrayST *fp_inst_window; - ArrayST *ROB; - selection_logic *instruction_selection; - bool exist; - - SchedulerU(ParseXML *XML_interface, int ithCore_, - InputParameter *interface_ip_, const CoreDynParam &dyn_p_, - bool exist_ = true); - void computeEnergy(bool is_tdp = true); - void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); - ~SchedulerU(); + +class SchedulerU :public Component { + public: + + ParseXML *XML; + int ithCore; + InputParameter interface_ip; + CoreDynParam coredynp; + double clockRate,executionTime; + double scktRatio, chip_PR_overhead, macro_PR_overhead; + double Iw_height, fp_Iw_height,ROB_height; + ArrayST * int_inst_window; + ArrayST * fp_inst_window; + ArrayST * ROB; + selection_logic * instruction_selection; + bool exist; + + SchedulerU(ParseXML *XML_interface, int ithCore_, InputParameter* interface_ip_,const CoreDynParam & dyn_p_, bool exist_=true); + void computeEnergy(bool is_tdp=true); + void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); + ~SchedulerU(); }; -class RENAMINGU : public Component { - public: - ParseXML *XML; - int ithCore; - InputParameter interface_ip; - double clockRate, executionTime; - CoreDynParam coredynp; - ArrayST *iFRAT; - ArrayST *fFRAT; - ArrayST *iRRAT; - ArrayST *fRRAT; - ArrayST *ifreeL; - ArrayST *ffreeL; - dep_resource_conflict_check *idcl; - dep_resource_conflict_check *fdcl; - ArrayST *RAHT; // register alias history table Used to store GC - bool exist; - - RENAMINGU(ParseXML *XML_interface, int ithCore_, - InputParameter *interface_ip_, const CoreDynParam &dyn_p_, - bool exist_ = true); - void computeEnergy(bool is_tdp = true); - void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); - ~RENAMINGU(); +class RENAMINGU :public Component { + public: + + ParseXML *XML; + int ithCore; + InputParameter interface_ip; + double clockRate,executionTime; + CoreDynParam coredynp; + ArrayST * iFRAT; + ArrayST * fFRAT; + ArrayST * iRRAT; + ArrayST * fRRAT; + ArrayST * ifreeL; + ArrayST * ffreeL; + dep_resource_conflict_check * idcl; + dep_resource_conflict_check * fdcl; + ArrayST * RAHT;//register alias history table Used to store GC + bool exist; + + + RENAMINGU(ParseXML *XML_interface, int ithCore_, InputParameter* interface_ip_, const CoreDynParam & dyn_p_, bool exist_=true); + void computeEnergy(bool is_tdp=true); + void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); + ~RENAMINGU(); }; -class LoadStoreU : public Component { - public: - ParseXML *XML; - int ithCore; - InputParameter interface_ip; - CoreDynParam coredynp; - enum Cache_policy cache_p; - double clockRate, executionTime; - double scktRatio, chip_PR_overhead, macro_PR_overhead; - double lsq_height; - DataCache dcache; - DataCache ccache; - DataCache tcache; - DataCache sharedmemory; - ArrayST *LSQ; // it is actually the store queue but for inorder processors it - // serves as both loadQ and StoreQ - ArrayST *LoadQ; - vector nocs; - bool exist; - Crossbar *xbar_shared; - Component noc; - LoadStoreU(ParseXML *XML_interface, int ithCore_, - InputParameter *interface_ip_, const CoreDynParam &dyn_p_, - bool exist_ = true); - void computeEnergy(bool is_tdp = true); - void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); - void displayDeviceType(int device_type_, - uint32_t indent); // Added by Syed Gilani - - ~LoadStoreU(); +class LoadStoreU :public Component { + public: + + ParseXML *XML; + int ithCore; + InputParameter interface_ip; + CoreDynParam coredynp; + enum Cache_policy cache_p; + double clockRate,executionTime; + double scktRatio, chip_PR_overhead, macro_PR_overhead; + double lsq_height; + DataCache dcache; + DataCache ccache; + DataCache tcache; + DataCache sharedmemory; + ArrayST * LSQ;//it is actually the store queue but for inorder processors it serves as both loadQ and StoreQ + ArrayST * LoadQ; + vector nocs; + bool exist; + Crossbar *xbar_shared; + Component noc; + LoadStoreU(ParseXML *XML_interface, int ithCore_, InputParameter* interface_ip_,const CoreDynParam & dyn_p_, bool exist_=true); + void computeEnergy(bool is_tdp=true); + void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); + void displayDeviceType(int device_type_, uint32_t indent);//Added by Syed Gilani + + ~LoadStoreU(); }; -class MemManU : public Component { - public: - ParseXML *XML; - int ithCore; - InputParameter interface_ip; - CoreDynParam coredynp; - double clockRate, executionTime; - double scktRatio, chip_PR_overhead, macro_PR_overhead; - ArrayST *itlb; - ArrayST *dtlb; - bool exist; - - MemManU(ParseXML *XML_interface, int ithCore_, InputParameter *interface_ip_, - const CoreDynParam &dyn_p_, bool exist_ = false); - void computeEnergy(bool is_tdp = true); - void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); - ~MemManU(); +class MemManU :public Component { + public: + + ParseXML *XML; + int ithCore; + InputParameter interface_ip; + CoreDynParam coredynp; + double clockRate,executionTime; + double scktRatio, chip_PR_overhead, macro_PR_overhead; + ArrayST * itlb; + ArrayST * dtlb; + bool exist; + + MemManU(ParseXML *XML_interface, int ithCore_, InputParameter* interface_ip_,const CoreDynParam & dyn_p_, bool exist_=false); + void computeEnergy(bool is_tdp=true); + void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); + ~MemManU(); }; -class RegFU : public Component { - public: - ParseXML *XML; - int ithCore; - InputParameter interface_ip; - CoreDynParam coredynp; - double clockRate, executionTime; - double scktRatio, chip_PR_overhead, macro_PR_overhead; - double int_regfile_height, fp_regfile_height; - ArrayST *IRF; - ArrayST *FRF; - ArrayST *RFWIN; - ArrayST *OPC; // Operand collectors - bool exist; - double exClockRate; - // OC Modelling (Syed) - Crossbar *xbar_rfu; - MCPAT_Arbiter *arbiter_rfu; - RegFU(ParseXML *XML_interface, int ithCore_, InputParameter *interface_ip_, - const CoreDynParam &dyn_p_, double exClockRate, bool exist_ = true); - void computeEnergy(bool is_tdp = true); - void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); - ~RegFU(); +class RegFU :public Component { + public: + + ParseXML *XML; + int ithCore; + InputParameter interface_ip; + CoreDynParam coredynp; + double clockRate,executionTime; + double scktRatio, chip_PR_overhead, macro_PR_overhead; + double int_regfile_height, fp_regfile_height; + ArrayST * IRF; + ArrayST * FRF; + ArrayST * RFWIN; + ArrayST * OPC;//Operand collectors + bool exist; + double exClockRate; + //OC Modelling (Syed) + Crossbar * xbar_rfu; + MCPAT_Arbiter * arbiter_rfu; + RegFU(ParseXML *XML_interface, int ithCore_, InputParameter* interface_ip_,const CoreDynParam & dyn_p_, double exClockRate, bool exist_=true); + void computeEnergy(bool is_tdp=true); + void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); + ~RegFU(); }; -class EXECU : public Component { - public: - ParseXML *XML; - int ithCore; - InputParameter interface_ip; - double clockRate, executionTime; - double scktRatio, chip_PR_overhead, macro_PR_overhead; - double lsq_height; - CoreDynParam coredynp; - RegFU *rfu; - SchedulerU *scheu; - FunctionalUnit *fp_u; - FunctionalUnit *exeu; - FunctionalUnit *mul; - interconnect *int_bypass; - interconnect *intTagBypass; - interconnect *int_mul_bypass; - interconnect *intTag_mul_Bypass; - interconnect *fp_bypass; - interconnect *fpTagBypass; - bool exist; - double rf_fu_clockRate; - Component bypass; - - EXECU(ParseXML *XML_interface, int ithCore_, InputParameter *interface_ip_, - double lsq_height_, const CoreDynParam &dyn_p_, double exClockRate, - bool exist_); - void computeEnergy(bool is_tdp = true); - void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); - ~EXECU(); +class EXECU :public Component { + public: + + ParseXML *XML; + int ithCore; + InputParameter interface_ip; + double clockRate,executionTime; + double scktRatio, chip_PR_overhead, macro_PR_overhead; + double lsq_height; + CoreDynParam coredynp; + RegFU * rfu; + SchedulerU * scheu; + FunctionalUnit * fp_u; + FunctionalUnit * exeu; + FunctionalUnit * mul; + interconnect * int_bypass; + interconnect * intTagBypass; + interconnect * int_mul_bypass; + interconnect * intTag_mul_Bypass; + interconnect * fp_bypass; + interconnect * fpTagBypass; + bool exist; + double rf_fu_clockRate; + Component bypass; + + + EXECU(ParseXML *XML_interface, int ithCore_, InputParameter* interface_ip_, double lsq_height_,const CoreDynParam & dyn_p_, double exClockRate, bool exist_); + void computeEnergy(bool is_tdp=true); + void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); + ~EXECU(); }; -class Core : public Component { - public: - ParseXML *XML; - int ithCore; - InputParameter interface_ip; - double clockRate, executionTime; - double exClockRate; - double scktRatio, chip_PR_overhead, macro_PR_overhead; - InstFetchU *ifu; - LoadStoreU *lsu; - MemManU *mmu; - EXECU *exu; - RENAMINGU *rnu; - double IdleCoreEnergy; - double IdlePower_PerCore; - Pipeline *corepipe; - UndiffCore *undiffCore; - SharedCache *l2cache; - CoreDynParam coredynp; - double Pipeline_energy; - // full_decoder inst_decoder; - // clock_network clockNetwork; - Core(ParseXML *XML_interface, int ithCore_, InputParameter *interface_ip_); - void set_core_param(); - void computeEnergy(bool is_tdp = true); - void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); - - float get_coefficient_icache_hits() { - // return 1.5*ifu->icache.caches->local_result.power.readOp.dynamic; - return ifu->icache.caches->local_result.power.readOp.dynamic; - } - - float get_coefficient_icache_misses() { - float value = 0; - value += ifu->icache.caches->local_result.power.writeOp.dynamic; - value += ifu->icache.caches->local_result.power.readOp.dynamic; - value += ifu->icache.missb->local_result.power.searchOp.dynamic; - value += ifu->icache.missb->local_result.power.writeOp.dynamic; - value += ifu->icache.ifb->local_result.power.searchOp.dynamic; - value += ifu->icache.ifb->local_result.power.writeOp.dynamic; - value += ifu->icache.prefetchb->local_result.power.searchOp.dynamic; - value += ifu->icache.prefetchb->local_result.power.writeOp.dynamic; - return value; - } - - float get_coefficient_tot_insts() { - float value = 0; - value += ifu->IB->local_result.power.readOp.dynamic; - value += ifu->IB->local_result.power.writeOp.dynamic; - value += ifu->ID_inst->power_t.readOp.dynamic; - value += ifu->ID_operand->power_t.readOp.dynamic; - value += ifu->ID_misc->power_t.readOp.dynamic; - return value; - } - - float get_coefficient_fpint_insts() { - float value = 0; - value += exu->scheu->int_inst_window->local_result.power.readOp.dynamic; - value += - 2 * exu->scheu->int_inst_window->local_result.power.searchOp.dynamic; - value += exu->scheu->int_inst_window->local_result.power.writeOp.dynamic; - value += exu->scheu->instruction_selection->power.readOp.dynamic; - return value; - } - - float get_coefficient_dcache_readhits() { - float value = 0; - value += lsu->dcache.caches->local_result.power.readOp.dynamic; - value += lsu->xbar_shared->power.readOp.dynamic; - // return 0.5*value; - return value; - } - float get_coefficient_dcache_readmisses() { - float value = 0; - value += lsu->dcache.caches->local_result.power.readOp.dynamic; - value += (lsu->cache_p == Write_back) - ? 0 - : lsu->dcache.missb->local_result.power.searchOp.dynamic; - value += (lsu->cache_p == Write_back) - ? 0 - : lsu->dcache.ifb->local_result.power.searchOp.dynamic; - value += (lsu->cache_p == Write_back) - ? 0 - : lsu->dcache.prefetchb->local_result.power.searchOp.dynamic; - value += (lsu->cache_p == Write_back) - ? 0 - : lsu->dcache.missb->local_result.power.writeOp.dynamic; - value += (lsu->cache_p == Write_back) - ? 0 - : lsu->dcache.ifb->local_result.power.writeOp.dynamic; - value += (lsu->cache_p == Write_back) - ? 0 - : lsu->dcache.prefetchb->local_result.power.writeOp.dynamic; - - // return 0.5*value; - return value; - } - float get_coefficient_dcache_writehits() { - float value = 0; - value += lsu->dcache.caches->local_result.power.writeOp.dynamic; - value += lsu->xbar_shared->power.readOp.dynamic; - return value; - } - float get_coefficient_dcache_writemisses() { - float value = 0; - value += lsu->dcache.caches->local_result.power.writeOp.dynamic; - value += lsu->dcache.caches->local_result.tag_array2->power.readOp.dynamic; - value += (lsu->cache_p == Write_back) - ? lsu->dcache.caches->local_result.power.writeOp.dynamic - : 0; - value += (lsu->cache_p == Write_back) - ? lsu->dcache.missb->local_result.power.searchOp.dynamic - : 0; - value += (lsu->cache_p == Write_back) - ? lsu->dcache.ifb->local_result.power.searchOp.dynamic - : 0; - value += (lsu->cache_p == Write_back) - ? lsu->dcache.prefetchb->local_result.power.searchOp.dynamic - : 0; - value += (lsu->cache_p == Write_back) - ? lsu->dcache.wbb->local_result.power.searchOp.dynamic - : 0; - value += (lsu->cache_p == Write_back) - ? lsu->dcache.missb->local_result.power.writeOp.dynamic - : 0; - value += (lsu->cache_p == Write_back) - ? lsu->dcache.ifb->local_result.power.writeOp.dynamic - : 0; - value += (lsu->cache_p == Write_back) - ? lsu->dcache.prefetchb->local_result.power.writeOp.dynamic - : 0; - value += (lsu->cache_p == Write_back) - ? lsu->dcache.wbb->local_result.power.writeOp.dynamic - : 0; - // return 1.6*value; - return value; - } - - float get_coefficient_tcache_readhits() { - float value = 0; - value += lsu->tcache.caches->local_result.power.readOp.dynamic; - value += lsu->xbar_shared->power.readOp.dynamic; - // return 0.2*value; - return value; - } - float get_coefficient_tcache_readmisses() { - float value = 0; - value += lsu->tcache.caches->local_result.power.readOp.dynamic; - value += (lsu->cache_p == Write_back) - ? 0 - : lsu->tcache.missb->local_result.power.searchOp.dynamic; - value += (lsu->cache_p == Write_back) - ? 0 - : lsu->tcache.missb->local_result.power.writeOp.dynamic; - value += (lsu->cache_p == Write_back) - ? 0 - : lsu->tcache.ifb->local_result.power.searchOp.dynamic; - value += (lsu->cache_p == Write_back) - ? 0 - : lsu->tcache.ifb->local_result.power.writeOp.dynamic; - value += (lsu->cache_p == Write_back) - ? 0 - : lsu->tcache.prefetchb->local_result.power.searchOp.dynamic; - value += (lsu->cache_p == Write_back) - ? 0 - : lsu->tcache.prefetchb->local_result.power.writeOp.dynamic; - - // return 0.2*value; - return value; - } - float get_coefficient_tcache_readmisses1() { - return lsu->tcache.caches->local_result.power.readOp.dynamic; - } - float get_coefficient_tcache_readmisses2() { - float value = 0; - value += (lsu->cache_p == Write_back) - ? 0 - : lsu->tcache.missb->local_result.power.searchOp.dynamic; - value += (lsu->cache_p == Write_back) - ? 0 - : lsu->tcache.missb->local_result.power.writeOp.dynamic; - value += (lsu->cache_p == Write_back) - ? 0 - : lsu->tcache.ifb->local_result.power.searchOp.dynamic; - value += (lsu->cache_p == Write_back) - ? 0 - : lsu->tcache.ifb->local_result.power.writeOp.dynamic; - value += (lsu->cache_p == Write_back) - ? 0 - : lsu->tcache.prefetchb->local_result.power.searchOp.dynamic; - value += (lsu->cache_p == Write_back) - ? 0 - : lsu->tcache.prefetchb->local_result.power.writeOp.dynamic; - return value; - } - - float get_coefficient_ccache_readhits() { - // return - // 1.2*lsu->ccache.caches->local_result.power.readOp.dynamic+lsu->xbar_shared->power.readOp.dynamic; - // return - // 1.2*lsu->ccache.caches->local_result.power.readOp.dynamic+lsu->xbar_shared->power.readOp.dynamic; - return lsu->ccache.caches->local_result.power.readOp.dynamic + - lsu->xbar_shared->power.readOp.dynamic; - } - float get_coefficient_ccache_readmisses() { - float value = 0; - value += lsu->ccache.caches->local_result.power.readOp.dynamic; - value += (lsu->cache_p == Write_back) - ? 0 - : lsu->ccache.missb->local_result.power.searchOp.dynamic; - value += (lsu->cache_p == Write_back) - ? 0 - : lsu->ccache.ifb->local_result.power.searchOp.dynamic; - value += (lsu->cache_p == Write_back) - ? 0 - : lsu->ccache.prefetchb->local_result.power.searchOp.dynamic; - value += (lsu->cache_p == Write_back) - ? 0 - : lsu->ccache.missb->local_result.power.writeOp.dynamic; - value += (lsu->cache_p == Write_back) - ? 0 - : lsu->ccache.ifb->local_result.power.writeOp.dynamic; - value += (lsu->cache_p == Write_back) - ? 0 - : lsu->ccache.prefetchb->local_result.power.writeOp.dynamic; - return value; - } - - float get_coefficient_sharedmemory_readhits() { - float value = 0; - value += lsu->sharedmemory.caches->local_result.power.readOp.dynamic; - value += lsu->xbar_shared->power.readOp.dynamic; - // return 3*value; - return value; - } - - float get_coefficient_lsq_accesses() { - float value = 0; - // Changed by Syed -- We have removed LSQ - // value+=2*lsu->LSQ->local_result.power.searchOp.dynamic; - // value+=2*lsu->LSQ->local_result.power.readOp.dynamic; - // value+=2*lsu->LSQ->local_result.power.writeOp.dynamic; - return value; - } - - float get_coefficient_regreads_accesses() { - float value = 0; - value += ((exu->rfu->IRF->local_result.power.readOp.dynamic / 32) * - (4 * 2) /*/1.5*/); - value += exu->rfu->xbar_rfu->power.readOp.dynamic / (32 /**1.5*/); - value += (exu->rfu->arbiter_rfu->power.readOp.dynamic / 32 /**1.5)*/); - value += exu->rfu->OPC->local_result.power.readOp.dynamic /*/1.5*/; - return value; - } - - float get_coefficient_regwrites_accesses() { - return ((exu->rfu->IRF->local_result.power.writeOp.dynamic / 32) * - (4 * 2) /*/1.5*/); - } - - float get_coefficient_noregfileops_accesses() { - return ((exu->rfu->xbar_rfu->power.readOp.dynamic / (32 /**1.5*/)) + - (exu->rfu->arbiter_rfu->power.readOp.dynamic / (32 /**1.5*/)) + - (exu->rfu->OPC->local_result.power.readOp.dynamic /*/(1.5)*/)); - } - - float get_coefficient_ialu_accesses() { - // return 10*exu->exeu->per_access_energy*g_tp.sckt_co_eff; - return exu->exeu->per_access_energy * g_tp.sckt_co_eff; - } - - float get_coefficient_sfu_accesses() { - return exu->mul->per_access_energy * g_tp.sckt_co_eff; - // return 2.6*exu->mul->per_access_energy*g_tp.sckt_co_eff; - } - - float get_coefficient_fpu_accesses() { - // return 3.2*exu->fp_u->per_access_energy*g_tp.sckt_co_eff; - return exu->fp_u->per_access_energy * g_tp.sckt_co_eff; - } - - float get_coefficient_duty_cycle() { - float value = 0; - float num_units = 4.0; - value = XML->sys.total_cycles * XML->sys.number_of_cores; - value *= coredynp.num_pipelines; - value /= num_units; - value *= corepipe->power.readOp.dynamic; - value *= 3; - return value; - // return 1.5*value; - } - - void compute(); - ~Core(); + +class Core :public Component { + public: + + ParseXML *XML; + int ithCore; + InputParameter interface_ip; + double clockRate,executionTime; + double exClockRate; + double scktRatio, chip_PR_overhead, macro_PR_overhead; + InstFetchU * ifu; + LoadStoreU * lsu; + MemManU * mmu; + EXECU * exu; + RENAMINGU * rnu; + double IdleCoreEnergy; + double IdlePower_PerCore; + Pipeline * corepipe; + UndiffCore * undiffCore; + SharedCache * l2cache; + CoreDynParam coredynp; + double Pipeline_energy; + //full_decoder inst_decoder; + //clock_network clockNetwork; + Core(ParseXML *XML_interface, int ithCore_, InputParameter* interface_ip_); + void set_core_param(); + void computeEnergy(bool is_tdp=true); + void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); + + float get_coefficient_icache_hits(){ + //return 1.5*ifu->icache.caches->local_result.power.readOp.dynamic; + return ifu->icache.caches->local_result.power.readOp.dynamic; + } + + float get_coefficient_icache_misses(){ + float value=0; + value+=ifu->icache.caches->local_result.power.writeOp.dynamic; + value+=ifu->icache.caches->local_result.power.readOp.dynamic; + value+=ifu->icache.missb->local_result.power.searchOp.dynamic; + value+=ifu->icache.missb->local_result.power.writeOp.dynamic; + value+=ifu->icache.ifb->local_result.power.searchOp.dynamic; + value+= ifu->icache.ifb->local_result.power.writeOp.dynamic; + value+= ifu->icache.prefetchb->local_result.power.searchOp.dynamic; + value+=ifu->icache.prefetchb->local_result.power.writeOp.dynamic; + return value; + } + + float get_coefficient_tot_insts(){ + float value=0; + value+=ifu->IB->local_result.power.readOp.dynamic; + value+=ifu->IB->local_result.power.writeOp.dynamic; + value+=ifu->ID_inst->power_t.readOp.dynamic; + value+=ifu->ID_operand->power_t.readOp.dynamic; + value+=ifu->ID_misc->power_t.readOp.dynamic; + return value; + } + + float get_coefficient_fpint_insts(){ + float value=0; + value+=exu->scheu->int_inst_window->local_result.power.readOp.dynamic; + value+=2*exu->scheu->int_inst_window->local_result.power.searchOp.dynamic; + value+=exu->scheu->int_inst_window->local_result.power.writeOp.dynamic; + value+=exu->scheu->instruction_selection->power.readOp.dynamic; + return value; + } + + + float get_coefficient_dcache_readhits() + { + float value=0; + value+=lsu->dcache.caches->local_result.power.readOp.dynamic; + value+=lsu->xbar_shared->power.readOp.dynamic; + //return 0.5*value; + return value; + } + float get_coefficient_dcache_readmisses() + { + float value=0; + value+=lsu->dcache.caches->local_result.power.readOp.dynamic; + value+=(lsu->cache_p==Write_back)? 0:lsu->dcache.missb->local_result.power.searchOp.dynamic; + value+=(lsu->cache_p==Write_back)? 0:lsu->dcache.ifb->local_result.power.searchOp.dynamic; + value+=(lsu->cache_p==Write_back)? 0:lsu->dcache.prefetchb->local_result.power.searchOp.dynamic; + value+=(lsu->cache_p==Write_back)? 0:lsu->dcache.missb->local_result.power.writeOp.dynamic; + value+=(lsu->cache_p==Write_back)? 0:lsu->dcache.ifb->local_result.power.writeOp.dynamic; + value+=(lsu->cache_p==Write_back)? 0:lsu->dcache.prefetchb->local_result.power.writeOp.dynamic; + + //return 0.5*value; + return value; + } + float get_coefficient_dcache_writehits() + { + float value=0; + value+=lsu->dcache.caches->local_result.power.writeOp.dynamic; + value+=lsu->xbar_shared->power.readOp.dynamic; + return value; + } + float get_coefficient_dcache_writemisses(){ + float value=0; + value+=lsu->dcache.caches->local_result.power.writeOp.dynamic; + value+=lsu->dcache.caches->local_result.tag_array2->power.readOp.dynamic; + value+= (lsu->cache_p==Write_back)? lsu->dcache.caches->local_result.power.writeOp.dynamic:0; + value+= (lsu->cache_p==Write_back)? lsu->dcache.missb->local_result.power.searchOp.dynamic:0; + value+= (lsu->cache_p==Write_back)? lsu->dcache.ifb->local_result.power.searchOp.dynamic:0; + value+= (lsu->cache_p==Write_back)? lsu->dcache.prefetchb->local_result.power.searchOp.dynamic:0; + value+= (lsu->cache_p==Write_back)? lsu->dcache.wbb->local_result.power.searchOp.dynamic:0; + value+= (lsu->cache_p==Write_back)? lsu->dcache.missb->local_result.power.writeOp.dynamic:0; + value+= (lsu->cache_p==Write_back)? lsu->dcache.ifb->local_result.power.writeOp.dynamic:0; + value+= (lsu->cache_p==Write_back)? lsu->dcache.prefetchb->local_result.power.writeOp.dynamic:0; + value+= (lsu->cache_p==Write_back)? lsu->dcache.wbb->local_result.power.writeOp.dynamic:0; + //return 1.6*value; + return value; + } + + + + float get_coefficient_tcache_readhits() + { + float value=0; + value+=lsu->tcache.caches->local_result.power.readOp.dynamic; + value+=lsu->xbar_shared->power.readOp.dynamic; + //return 0.2*value; + return value; + } + float get_coefficient_tcache_readmisses() + { + float value=0; + value+= lsu->tcache.caches->local_result.power.readOp.dynamic; + value+=(lsu->cache_p==Write_back)? 0:lsu->tcache.missb->local_result.power.searchOp.dynamic; + value+=(lsu->cache_p==Write_back)? 0:lsu->tcache.missb->local_result.power.writeOp.dynamic; + value+=(lsu->cache_p==Write_back)? 0:lsu->tcache.ifb->local_result.power.searchOp.dynamic; + value+=(lsu->cache_p==Write_back)? 0:lsu->tcache.ifb->local_result.power.writeOp.dynamic; + value+=(lsu->cache_p==Write_back)? 0:lsu->tcache.prefetchb->local_result.power.searchOp.dynamic; + value+=(lsu->cache_p==Write_back)? 0:lsu->tcache.prefetchb->local_result.power.writeOp.dynamic; + + //return 0.2*value; + return value; + } + float get_coefficient_tcache_readmisses1(){ + + return lsu->tcache.caches->local_result.power.readOp.dynamic; + + } + float get_coefficient_tcache_readmisses2(){ + float value=0; + value+=(lsu->cache_p==Write_back)? 0:lsu->tcache.missb->local_result.power.searchOp.dynamic; + value+=(lsu->cache_p==Write_back)? 0:lsu->tcache.missb->local_result.power.writeOp.dynamic; + value+=(lsu->cache_p==Write_back)? 0:lsu->tcache.ifb->local_result.power.searchOp.dynamic; + value+=(lsu->cache_p==Write_back)? 0:lsu->tcache.ifb->local_result.power.writeOp.dynamic; + value+=(lsu->cache_p==Write_back)? 0:lsu->tcache.prefetchb->local_result.power.searchOp.dynamic; + value+=(lsu->cache_p==Write_back)? 0:lsu->tcache.prefetchb->local_result.power.writeOp.dynamic; + return value; + } + + + float get_coefficient_ccache_readhits() + { + //return 1.2*lsu->ccache.caches->local_result.power.readOp.dynamic+lsu->xbar_shared->power.readOp.dynamic; + //return 1.2*lsu->ccache.caches->local_result.power.readOp.dynamic+lsu->xbar_shared->power.readOp.dynamic; + return lsu->ccache.caches->local_result.power.readOp.dynamic+lsu->xbar_shared->power.readOp.dynamic; + } + float get_coefficient_ccache_readmisses() + { + float value=0; + value+=lsu->ccache.caches->local_result.power.readOp.dynamic; + value+=(lsu->cache_p==Write_back)? 0:lsu->ccache.missb->local_result.power.searchOp.dynamic; + value+=(lsu->cache_p==Write_back)? 0:lsu->ccache.ifb->local_result.power.searchOp.dynamic; + value+=(lsu->cache_p==Write_back)? 0:lsu->ccache.prefetchb->local_result.power.searchOp.dynamic; + value+=(lsu->cache_p==Write_back)? 0:lsu->ccache.missb->local_result.power.writeOp.dynamic; + value+=(lsu->cache_p==Write_back)? 0:lsu->ccache.ifb->local_result.power.writeOp.dynamic; + value+=(lsu->cache_p==Write_back)? 0:lsu->ccache.prefetchb->local_result.power.writeOp.dynamic; + return value; + } + + float get_coefficient_sharedmemory_readhits() + { + float value=0; + value+=lsu->sharedmemory.caches->local_result.power.readOp.dynamic; + value+=lsu->xbar_shared->power.readOp.dynamic; + //return 3*value; + return value; + } + + float get_coefficient_lsq_accesses() + { + float value=0; + //Changed by Syed -- We have removed LSQ + //value+=2*lsu->LSQ->local_result.power.searchOp.dynamic; + //value+=2*lsu->LSQ->local_result.power.readOp.dynamic; + //value+=2*lsu->LSQ->local_result.power.writeOp.dynamic; + return value; + } + + float get_coefficient_regreads_accesses(){ + float value=0; + value+=((exu->rfu->IRF->local_result.power.readOp.dynamic/32)*(4*2)/*/1.5*/); + value+=exu->rfu->xbar_rfu->power.readOp.dynamic/(32/**1.5*/); + value+=(exu->rfu->arbiter_rfu->power.readOp.dynamic/32/**1.5)*/); + value+=exu->rfu->OPC->local_result.power.readOp.dynamic/*/1.5*/; + return value; + } + + float get_coefficient_regwrites_accesses(){return ((exu->rfu->IRF->local_result.power.writeOp.dynamic/32)*(4*2)/*/1.5*/);} + + float get_coefficient_noregfileops_accesses(){return ((exu->rfu->xbar_rfu->power.readOp.dynamic/(32/**1.5*/))+ + (exu->rfu->arbiter_rfu->power.readOp.dynamic/(32/**1.5*/))+ + (exu->rfu->OPC->local_result.power.readOp.dynamic/*/(1.5)*/));} + + float get_coefficient_ialu_accesses(){ + //return 10*exu->exeu->per_access_energy*g_tp.sckt_co_eff; + return exu->exeu->per_access_energy*g_tp.sckt_co_eff; + } + + float get_coefficient_sfu_accesses(){ + return exu->mul->per_access_energy*g_tp.sckt_co_eff; + //return 2.6*exu->mul->per_access_energy*g_tp.sckt_co_eff; + } + + float get_coefficient_fpu_accesses(){ + //return 3.2*exu->fp_u->per_access_energy*g_tp.sckt_co_eff; + return exu->fp_u->per_access_energy*g_tp.sckt_co_eff; + } + + float get_coefficient_duty_cycle() + { + float value=0; + float num_units=4.0; + value=XML->sys.total_cycles * XML->sys.number_of_cores; + value*=coredynp.num_pipelines; + value/=num_units; + value*=corepipe->power.readOp.dynamic; + value*=3; + return value; + //return 1.5*value; + } + + + + void compute(); + ~Core(); }; #endif /* CORE_H_ */ diff --git a/src/gpuwattch/globalvar.h b/src/gpuwattch/globalvar.h index e0b76c2..9532576 100644 --- a/src/gpuwattch/globalvar.h +++ b/src/gpuwattch/globalvar.h @@ -29,10 +29,11 @@ * ***************************************************************************/ + #ifndef GLOBALVAR_H_ #define GLOBALVAR_H_ -#ifdef GLOBALVAR +#ifdef GLOBALVAR #define EXTERN #else #define EXTERN extern @@ -41,3 +42,7 @@ EXTERN bool opt_for_clk; #endif /* GLOBALVAR_H_ */ + + + + diff --git a/src/gpuwattch/gpgpu_sim_wrapper.cc b/src/gpuwattch/gpgpu_sim_wrapper.cc index 2431f65..efb3e6b 100644 --- a/src/gpuwattch/gpgpu_sim_wrapper.cc +++ b/src/gpuwattch/gpgpu_sim_wrapper.cc @@ -7,16 +7,14 @@ // // Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. -// Redistributions in binary form must reproduce the above copyright notice, -// this +// Redistributions in binary form must reproduce the above copyright notice, this // list of conditions and the following disclaimer in the documentation and/or // other materials provided with the distribution. // Neither the name of The University of British Columbia nor the names of its // contributors may be used to endorse or promote products derived from this // software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE @@ -30,836 +28,734 @@ #include "gpgpu_sim_wrapper.h" #include #define SP_BASE_POWER 0 -#define SFU_BASE_POWER 0 +#define SFU_BASE_POWER 0 -static const char* pwr_cmp_label[] = { - "IBP,", "ICP,", "DCP,", "TCP,", "CCP,", "SHRDP,", - "RFP,", "SPP,", "SFUP,", "FPUP,", "SCHEDP,", "L2CP,", - "MCP,", "NOCP,", "DRAMP,", "PIPEP,", "IDLE_COREP,", "CONST_DYNAMICP"}; + +static const char * pwr_cmp_label[] = {"IBP,", "ICP,", "DCP,", "TCP,", "CCP,", "SHRDP,", "RFP,", "SPP,", + "SFUP,", "FPUP,", "SCHEDP,", "L2CP,", "MCP,", "NOCP,", "DRAMP,", + "PIPEP,", "IDLE_COREP,", "CONST_DYNAMICP"}; enum pwr_cmp_t { - IBP = 0, - ICP, - DCP, - TCP, - CCP, - SHRDP, - RFP, - SPP, - SFUP, - FPUP, - SCHEDP, - L2CP, - MCP, - NOCP, - DRAMP, - PIPEP, - IDLE_COREP, - CONST_DYNAMICP, - NUM_COMPONENTS_MODELLED + IBP=0, + ICP, + DCP, + TCP, + CCP, + SHRDP, + RFP, + SPP, + SFUP, + FPUP, + SCHEDP, + L2CP, + MCP, + NOCP, + DRAMP, + PIPEP, + IDLE_COREP, + CONST_DYNAMICP, + NUM_COMPONENTS_MODELLED }; -gpgpu_sim_wrapper::gpgpu_sim_wrapper(bool power_simulation_enabled, - char* xmlfile) { - kernel_sample_count = 0; - total_sample_count = 0; - - kernel_tot_power = 0; - - num_pwr_cmps = NUM_COMPONENTS_MODELLED; - num_perf_counters = NUM_PERFORMANCE_COUNTERS; - - // Initialize per-component counter/power vectors - avg_max_min_counters init; - kernel_cmp_pwr.resize(NUM_COMPONENTS_MODELLED, init); - kernel_cmp_perf_counters.resize(NUM_PERFORMANCE_COUNTERS, init); - - kernel_power = init; // Per-kernel powers - gpu_tot_power = init; // Global powers - - sample_cmp_pwr.resize(NUM_COMPONENTS_MODELLED, 0); - - sample_perf_counters.resize(NUM_PERFORMANCE_COUNTERS, 0); - initpower_coeff.resize(NUM_PERFORMANCE_COUNTERS, 0); - effpower_coeff.resize(NUM_PERFORMANCE_COUNTERS, 0); - - const_dynamic_power = 0; - proc_power = 0; - - g_power_filename = NULL; - g_power_trace_filename = NULL; - g_metric_trace_filename = NULL; - g_steady_state_tracking_filename = NULL; - xml_filename = xmlfile; - g_power_simulation_enabled = power_simulation_enabled; - g_power_trace_enabled = false; - g_steady_power_levels_enabled = false; - g_power_trace_zlevel = 0; - g_power_per_cycle_dump = false; - gpu_steady_power_deviation = 0; - gpu_steady_min_period = 0; - - gpu_stat_sample_freq = 0; - p = new ParseXML(); - if (g_power_simulation_enabled) { - p->parse(xml_filename); - } - proc = new Processor(p); - power_trace_file = NULL; - metric_trace_file = NULL; - steady_state_tacking_file = NULL; - has_written_avg = false; - init_inst_val = false; + +gpgpu_sim_wrapper::gpgpu_sim_wrapper( bool power_simulation_enabled, char* xmlfile) { + kernel_sample_count=0; + total_sample_count=0; + + kernel_tot_power=0; + + num_pwr_cmps=NUM_COMPONENTS_MODELLED; + num_perf_counters=NUM_PERFORMANCE_COUNTERS; + + // Initialize per-component counter/power vectors + avg_max_min_counters init; + kernel_cmp_pwr.resize(NUM_COMPONENTS_MODELLED, init); + kernel_cmp_perf_counters.resize(NUM_PERFORMANCE_COUNTERS, init); + + kernel_power = init; // Per-kernel powers + gpu_tot_power = init; // Global powers + + sample_cmp_pwr.resize(NUM_COMPONENTS_MODELLED, 0); + + sample_perf_counters.resize(NUM_PERFORMANCE_COUNTERS, 0); + initpower_coeff.resize(NUM_PERFORMANCE_COUNTERS, 0); + effpower_coeff.resize(NUM_PERFORMANCE_COUNTERS, 0); + + const_dynamic_power=0; + proc_power=0; + + g_power_filename = NULL; + g_power_trace_filename = NULL; + g_metric_trace_filename = NULL; + g_steady_state_tracking_filename = NULL; + xml_filename= xmlfile; + g_power_simulation_enabled= power_simulation_enabled; + g_power_trace_enabled= false; + g_steady_power_levels_enabled= false; + g_power_trace_zlevel= 0; + g_power_per_cycle_dump= false; + gpu_steady_power_deviation= 0; + gpu_steady_min_period= 0; + + gpu_stat_sample_freq=0; + p=new ParseXML(); + if (g_power_simulation_enabled){ + p->parse(xml_filename); + } + proc = new Processor(p); + power_trace_file = NULL; + metric_trace_file = NULL; + steady_state_tacking_file = NULL; + has_written_avg=false; + init_inst_val=false; + } -gpgpu_sim_wrapper::~gpgpu_sim_wrapper() {} +gpgpu_sim_wrapper::~gpgpu_sim_wrapper() { } -bool gpgpu_sim_wrapper::sanity_check(double a, double b) { - if (b == 0) - return (abs(a - b) < 0.00001); - else - return (abs(a - b) / abs(b) < 0.00001); +bool gpgpu_sim_wrapper::sanity_check(double a, double b) +{ + if (b == 0) + return (abs(a-b)<0.00001); + else + return (abs(a-b)/abs(b)<0.00001); - return false; + return false; } -void gpgpu_sim_wrapper::init_mcpat( - char* xmlfile, char* powerfilename, char* power_trace_filename, - char* metric_trace_filename, char* steady_state_filename, - bool power_sim_enabled, bool trace_enabled, bool steady_state_enabled, - bool power_per_cycle_dump, double steady_power_deviation, - double steady_min_period, int zlevel, double init_val, - int stat_sample_freq) { - // Write File Headers for (-metrics trace, -power trace) - - reset_counters(); - static bool mcpat_init = true; - - // initialize file name if it is not set - time_t curr_time; - time(&curr_time); - char* date = ctime(&curr_time); - char* s = date; - while (*s) { - if (*s == ' ' || *s == '\t' || *s == ':') *s = '-'; - if (*s == '\n' || *s == '\r') *s = 0; - s++; - } - - if (mcpat_init) { - g_power_filename = powerfilename; - g_power_trace_filename = power_trace_filename; - g_metric_trace_filename = metric_trace_filename; - g_steady_state_tracking_filename = steady_state_filename; - xml_filename = xmlfile; - g_power_simulation_enabled = power_sim_enabled; - g_power_trace_enabled = trace_enabled; - g_steady_power_levels_enabled = steady_state_enabled; - g_power_trace_zlevel = zlevel; - g_power_per_cycle_dump = power_per_cycle_dump; - gpu_steady_power_deviation = steady_power_deviation; - gpu_steady_min_period = steady_min_period; - - gpu_stat_sample_freq = stat_sample_freq; - - // p->sys.total_cycles=gpu_stat_sample_freq*4; - p->sys.total_cycles = gpu_stat_sample_freq; - power_trace_file = NULL; - metric_trace_file = NULL; - steady_state_tacking_file = NULL; - - if (g_power_trace_enabled) { - power_trace_file = gzopen(g_power_trace_filename, "w"); - metric_trace_file = gzopen(g_metric_trace_filename, "w"); - if ((power_trace_file == NULL) || (metric_trace_file == NULL)) { - printf("error - could not open trace files \n"); - exit(1); - } - gzsetparams(power_trace_file, g_power_trace_zlevel, Z_DEFAULT_STRATEGY); - - gzprintf(power_trace_file, "power,"); - for (unsigned i = 0; i < num_pwr_cmps; i++) { - gzprintf(power_trace_file, pwr_cmp_label[i]); - } - gzprintf(power_trace_file, "\n"); - - gzsetparams(metric_trace_file, g_power_trace_zlevel, Z_DEFAULT_STRATEGY); - for (unsigned i = 0; i < num_perf_counters; i++) { - gzprintf(metric_trace_file, perf_count_label[i]); - } - gzprintf(metric_trace_file, "\n"); - - gzclose(power_trace_file); - gzclose(metric_trace_file); - } - if (g_steady_power_levels_enabled) { - steady_state_tacking_file = gzopen(g_steady_state_tracking_filename, "w"); - if ((steady_state_tacking_file == NULL)) { - printf("error - could not open trace files \n"); - exit(1); - } - gzsetparams(steady_state_tacking_file, g_power_trace_zlevel, - Z_DEFAULT_STRATEGY); - gzprintf(steady_state_tacking_file, "start,end,power,IPC,"); - for (unsigned i = 0; i < num_perf_counters; i++) { - gzprintf(steady_state_tacking_file, perf_count_label[i]); - } - gzprintf(steady_state_tacking_file, "\n"); - - gzclose(steady_state_tacking_file); - } +void gpgpu_sim_wrapper::init_mcpat(char* xmlfile, char* powerfilename, char* power_trace_filename,char* metric_trace_filename, + char * steady_state_filename, bool power_sim_enabled,bool trace_enabled, + bool steady_state_enabled,bool power_per_cycle_dump,double steady_power_deviation, + double steady_min_period, int zlevel, double init_val,int stat_sample_freq ){ + // Write File Headers for (-metrics trace, -power trace) + + reset_counters(); + static bool mcpat_init=true; + + // initialize file name if it is not set + time_t curr_time; + time(&curr_time); + char *date = ctime(&curr_time); + char *s = date; + while (*s) { + if (*s == ' ' || *s == '\t' || *s == ':') *s = '-'; + if (*s == '\n' || *s == '\r' ) *s = 0; + s++; + } + + if(mcpat_init){ + g_power_filename = powerfilename; + g_power_trace_filename =power_trace_filename; + g_metric_trace_filename = metric_trace_filename; + g_steady_state_tracking_filename = steady_state_filename; + xml_filename=xmlfile; + g_power_simulation_enabled=power_sim_enabled; + g_power_trace_enabled=trace_enabled; + g_steady_power_levels_enabled=steady_state_enabled; + g_power_trace_zlevel=zlevel; + g_power_per_cycle_dump=power_per_cycle_dump; + gpu_steady_power_deviation=steady_power_deviation; + gpu_steady_min_period=steady_min_period; + + gpu_stat_sample_freq=stat_sample_freq; + + //p->sys.total_cycles=gpu_stat_sample_freq*4; + p->sys.total_cycles=gpu_stat_sample_freq; + power_trace_file = NULL; + metric_trace_file = NULL; + steady_state_tacking_file = NULL; + + + if (g_power_trace_enabled ){ + power_trace_file = gzopen(g_power_trace_filename, "w"); + metric_trace_file = gzopen(g_metric_trace_filename, "w"); + if ((power_trace_file == NULL) || (metric_trace_file == NULL)) { + printf("error - could not open trace files \n"); + exit(1); + } + gzsetparams(power_trace_file, g_power_trace_zlevel, Z_DEFAULT_STRATEGY); + + gzprintf(power_trace_file,"power,"); + for(unsigned i=0; i init; - for (unsigned i = 0; i < num_perf_counters; ++i) { - sample_perf_counters[i] = 0; - kernel_cmp_perf_counters[i] = init; - } - for (unsigned i = 0; i < num_pwr_cmps; ++i) { - sample_cmp_pwr[i] = 0; - kernel_cmp_pwr[i] = init; - } - - // Reset per-kernel counters - kernel_sample_count = 0; - kernel_tot_power = 0; - kernel_power = init; - - return; +void gpgpu_sim_wrapper::reset_counters(){ + + avg_max_min_counters init; + for(unsigned i=0; isys.core[0].gpgpu_clock_gated_lanes = clk_gated_lanes; - p->sys.core[0].total_cycles = tot_cycles; - p->sys.core[0].busy_cycles = busy_cycles; - p->sys.core[0].total_instructions = - tot_inst * p->sys.scaling_coefficients[TOT_INST]; - p->sys.core[0].int_instructions = - int_inst * p->sys.scaling_coefficients[FP_INT]; - p->sys.core[0].fp_instructions = - fp_inst * p->sys.scaling_coefficients[FP_INT]; - p->sys.core[0].load_instructions = load_inst; - p->sys.core[0].store_instructions = store_inst; - p->sys.core[0].committed_instructions = committed_inst; - sample_perf_counters[FP_INT] = int_inst + fp_inst; - sample_perf_counters[TOT_INST] = tot_inst; +void gpgpu_sim_wrapper::set_inst_power(bool clk_gated_lanes, double tot_cycles, double busy_cycles, double tot_inst, double int_inst, double fp_inst, double load_inst, double store_inst, double committed_inst) +{ + p->sys.core[0].gpgpu_clock_gated_lanes = clk_gated_lanes; + p->sys.core[0].total_cycles = tot_cycles; + p->sys.core[0].busy_cycles = busy_cycles; + p->sys.core[0].total_instructions = tot_inst * p->sys.scaling_coefficients[TOT_INST]; + p->sys.core[0].int_instructions = int_inst * p->sys.scaling_coefficients[FP_INT]; + p->sys.core[0].fp_instructions = fp_inst * p->sys.scaling_coefficients[FP_INT]; + p->sys.core[0].load_instructions = load_inst; + p->sys.core[0].store_instructions = store_inst; + p->sys.core[0].committed_instructions = committed_inst; + sample_perf_counters[FP_INT]=int_inst+fp_inst; + sample_perf_counters[TOT_INST]=tot_inst; } -void gpgpu_sim_wrapper::set_regfile_power(double reads, double writes, - double ops) { - p->sys.core[0].int_regfile_reads = - reads * p->sys.scaling_coefficients[REG_RD]; - p->sys.core[0].int_regfile_writes = - writes * p->sys.scaling_coefficients[REG_WR]; - p->sys.core[0].non_rf_operands = - ops * p->sys.scaling_coefficients[NON_REG_OPs]; - sample_perf_counters[REG_RD] = reads; - sample_perf_counters[REG_WR] = writes; - sample_perf_counters[NON_REG_OPs] = ops; +void gpgpu_sim_wrapper::set_regfile_power(double reads, double writes,double ops) +{ + p->sys.core[0].int_regfile_reads = reads * p->sys.scaling_coefficients[REG_RD]; + p->sys.core[0].int_regfile_writes = writes * p->sys.scaling_coefficients[REG_WR]; + p->sys.core[0].non_rf_operands = ops *p->sys.scaling_coefficients[NON_REG_OPs]; + sample_perf_counters[REG_RD]=reads; + sample_perf_counters[REG_WR]=writes; + sample_perf_counters[NON_REG_OPs]=ops; + + + } -void gpgpu_sim_wrapper::set_icache_power(double hits, double misses) { - p->sys.core[0].icache.read_accesses = - hits * p->sys.scaling_coefficients[IC_H] + - misses * p->sys.scaling_coefficients[IC_M]; - p->sys.core[0].icache.read_misses = - misses * p->sys.scaling_coefficients[IC_M]; - sample_perf_counters[IC_H] = hits; - sample_perf_counters[IC_M] = misses; +void gpgpu_sim_wrapper::set_icache_power(double hits, double misses) +{ + p->sys.core[0].icache.read_accesses = hits * p->sys.scaling_coefficients[IC_H]+misses * p->sys.scaling_coefficients[IC_M]; + p->sys.core[0].icache.read_misses = misses * p->sys.scaling_coefficients[IC_M]; + sample_perf_counters[IC_H]=hits; + sample_perf_counters[IC_M]=misses; + + } -void gpgpu_sim_wrapper::set_ccache_power(double hits, double misses) { - p->sys.core[0].ccache.read_accesses = - hits * p->sys.scaling_coefficients[CC_H] + - misses * p->sys.scaling_coefficients[CC_M]; - p->sys.core[0].ccache.read_misses = - misses * p->sys.scaling_coefficients[CC_M]; - sample_perf_counters[CC_H] = hits; - sample_perf_counters[CC_M] = misses; - // TODO: coalescing logic is counted as part of the caches power (this is not - // valid for no-caches architectures) +void gpgpu_sim_wrapper::set_ccache_power(double hits, double misses) +{ + p->sys.core[0].ccache.read_accesses = hits * p->sys.scaling_coefficients[CC_H]+misses * p->sys.scaling_coefficients[CC_M]; + p->sys.core[0].ccache.read_misses = misses * p->sys.scaling_coefficients[CC_M]; + sample_perf_counters[CC_H]=hits; + sample_perf_counters[CC_M]=misses; + // TODO: coalescing logic is counted as part of the caches power (this is not valid for no-caches architectures) + } -void gpgpu_sim_wrapper::set_tcache_power(double hits, double misses) { - p->sys.core[0].tcache.read_accesses = - hits * p->sys.scaling_coefficients[TC_H] + - misses * p->sys.scaling_coefficients[TC_M]; - p->sys.core[0].tcache.read_misses = - misses * p->sys.scaling_coefficients[TC_M]; - sample_perf_counters[TC_H] = hits; - sample_perf_counters[TC_M] = misses; - // TODO: coalescing logic is counted as part of the caches power (this is not - // valid for no-caches architectures) +void gpgpu_sim_wrapper::set_tcache_power(double hits, double misses) +{ + p->sys.core[0].tcache.read_accesses = hits * p->sys.scaling_coefficients[TC_H]+misses * p->sys.scaling_coefficients[TC_M]; + p->sys.core[0].tcache.read_misses = misses* p->sys.scaling_coefficients[TC_M]; + sample_perf_counters[TC_H]=hits; + sample_perf_counters[TC_M]=misses; + // TODO: coalescing logic is counted as part of the caches power (this is not valid for no-caches architectures) } -void gpgpu_sim_wrapper::set_shrd_mem_power(double accesses) { - p->sys.core[0].sharedmemory.read_accesses = - accesses * p->sys.scaling_coefficients[SHRD_ACC]; - sample_perf_counters[SHRD_ACC] = accesses; +void gpgpu_sim_wrapper::set_shrd_mem_power(double accesses) +{ + p->sys.core[0].sharedmemory.read_accesses = accesses * p->sys.scaling_coefficients[SHRD_ACC]; + sample_perf_counters[SHRD_ACC]=accesses; + + } -void gpgpu_sim_wrapper::set_l1cache_power(double read_hits, double read_misses, - double write_hits, - double write_misses) { - p->sys.core[0].dcache.read_accesses = - read_hits * p->sys.scaling_coefficients[DC_RH] + - read_misses * p->sys.scaling_coefficients[DC_RM]; - p->sys.core[0].dcache.read_misses = - read_misses * p->sys.scaling_coefficients[DC_RM]; - p->sys.core[0].dcache.write_accesses = - write_hits * p->sys.scaling_coefficients[DC_WH] + - write_misses * p->sys.scaling_coefficients[DC_WM]; - p->sys.core[0].dcache.write_misses = - write_misses * p->sys.scaling_coefficients[DC_WM]; - sample_perf_counters[DC_RH] = read_hits; - sample_perf_counters[DC_RM] = read_misses; - sample_perf_counters[DC_WH] = write_hits; - sample_perf_counters[DC_WM] = write_misses; - // TODO: coalescing logic is counted as part of the caches power (this is not - // valid for no-caches architectures) +void gpgpu_sim_wrapper::set_l1cache_power(double read_hits, double read_misses, double write_hits, double write_misses) +{ + p->sys.core[0].dcache.read_accesses = read_hits * p->sys.scaling_coefficients[DC_RH] +read_misses * p->sys.scaling_coefficients[DC_RM]; + p->sys.core[0].dcache.read_misses = read_misses * p->sys.scaling_coefficients[DC_RM]; + p->sys.core[0].dcache.write_accesses = write_hits * p->sys.scaling_coefficients[DC_WH]+write_misses * p->sys.scaling_coefficients[DC_WM]; + p->sys.core[0].dcache.write_misses = write_misses * p->sys.scaling_coefficients[DC_WM]; + sample_perf_counters[DC_RH]=read_hits; + sample_perf_counters[DC_RM]=read_misses; + sample_perf_counters[DC_WH]=write_hits; + sample_perf_counters[DC_WM]=write_misses; + // TODO: coalescing logic is counted as part of the caches power (this is not valid for no-caches architectures) + + + } -void gpgpu_sim_wrapper::set_l2cache_power(double read_hits, double read_misses, - double write_hits, - double write_misses) { - p->sys.l2.total_accesses = read_hits * p->sys.scaling_coefficients[L2_RH] + - read_misses * p->sys.scaling_coefficients[L2_RM] + - write_hits * p->sys.scaling_coefficients[L2_WH] + - write_misses * p->sys.scaling_coefficients[L2_WM]; - p->sys.l2.read_accesses = read_hits * p->sys.scaling_coefficients[L2_RH] + - read_misses * p->sys.scaling_coefficients[L2_RM]; - p->sys.l2.write_accesses = write_hits * p->sys.scaling_coefficients[L2_WH] + - write_misses * p->sys.scaling_coefficients[L2_WM]; - p->sys.l2.read_hits = read_hits * p->sys.scaling_coefficients[L2_RH]; - p->sys.l2.read_misses = read_misses * p->sys.scaling_coefficients[L2_RM]; - p->sys.l2.write_hits = write_hits * p->sys.scaling_coefficients[L2_WH]; - p->sys.l2.write_misses = write_misses * p->sys.scaling_coefficients[L2_WM]; - sample_perf_counters[L2_RH] = read_hits; - sample_perf_counters[L2_RM] = read_misses; - sample_perf_counters[L2_WH] = write_hits; - sample_perf_counters[L2_WM] = write_misses; +void gpgpu_sim_wrapper::set_l2cache_power(double read_hits, double read_misses, double write_hits, double write_misses) +{ + p->sys.l2.total_accesses = read_hits* p->sys.scaling_coefficients[L2_RH]+read_misses * p->sys.scaling_coefficients[L2_RM]+ write_hits * p->sys.scaling_coefficients[L2_WH]+write_misses * p->sys.scaling_coefficients[L2_WM]; + p->sys.l2.read_accesses = read_hits* p->sys.scaling_coefficients[L2_RH]+read_misses* p->sys.scaling_coefficients[L2_RM]; + p->sys.l2.write_accesses = write_hits * p->sys.scaling_coefficients[L2_WH]+write_misses * p->sys.scaling_coefficients[L2_WM]; + p->sys.l2.read_hits = read_hits * p->sys.scaling_coefficients[L2_RH]; + p->sys.l2.read_misses = read_misses * p->sys.scaling_coefficients[L2_RM]; + p->sys.l2.write_hits =write_hits * p->sys.scaling_coefficients[L2_WH]; + p->sys.l2.write_misses = write_misses * p->sys.scaling_coefficients[L2_WM]; + sample_perf_counters[L2_RH]=read_hits; + sample_perf_counters[L2_RM]=read_misses; + sample_perf_counters[L2_WH]=write_hits; + sample_perf_counters[L2_WM]=write_misses; } -void gpgpu_sim_wrapper::set_idle_core_power(double num_idle_core) { - p->sys.num_idle_cores = num_idle_core; - sample_perf_counters[IDLE_CORE_N] = num_idle_core; +void gpgpu_sim_wrapper::set_idle_core_power(double num_idle_core) +{ + p->sys.num_idle_cores = num_idle_core; + sample_perf_counters[IDLE_CORE_N]=num_idle_core; } -void gpgpu_sim_wrapper::set_duty_cycle_power(double duty_cycle) { - p->sys.core[0].pipeline_duty_cycle = - duty_cycle * p->sys.scaling_coefficients[PIPE_A]; - sample_perf_counters[PIPE_A] = duty_cycle; +void gpgpu_sim_wrapper::set_duty_cycle_power(double duty_cycle) +{ + p->sys.core[0].pipeline_duty_cycle = duty_cycle * p->sys.scaling_coefficients[PIPE_A]; + sample_perf_counters[PIPE_A]=duty_cycle; + } -void gpgpu_sim_wrapper::set_mem_ctrl_power(double reads, double writes, - double dram_precharge) { - p->sys.mc.memory_accesses = reads * p->sys.scaling_coefficients[MEM_RD] + - writes * p->sys.scaling_coefficients[MEM_WR]; - p->sys.mc.memory_reads = reads * p->sys.scaling_coefficients[MEM_RD]; - p->sys.mc.memory_writes = writes * p->sys.scaling_coefficients[MEM_WR]; - p->sys.mc.dram_pre = dram_precharge * p->sys.scaling_coefficients[MEM_PRE]; - sample_perf_counters[MEM_RD] = reads; - sample_perf_counters[MEM_WR] = writes; - sample_perf_counters[MEM_PRE] = dram_precharge; +void gpgpu_sim_wrapper::set_mem_ctrl_power(double reads, double writes, double dram_precharge) +{ + p->sys.mc.memory_accesses = reads * p->sys.scaling_coefficients[MEM_RD]+ writes * p->sys.scaling_coefficients[MEM_WR]; + p->sys.mc.memory_reads = reads *p->sys.scaling_coefficients[MEM_RD]; + p->sys.mc.memory_writes = writes*p->sys.scaling_coefficients[MEM_WR]; + p->sys.mc.dram_pre = dram_precharge*p->sys.scaling_coefficients[MEM_PRE]; + sample_perf_counters[MEM_RD]=reads; + sample_perf_counters[MEM_WR]=writes; + sample_perf_counters[MEM_PRE]=dram_precharge; + } -void gpgpu_sim_wrapper::set_exec_unit_power(double fpu_accesses, - double ialu_accesses, - double sfu_accesses) { - p->sys.core[0].fpu_accesses = - fpu_accesses * p->sys.scaling_coefficients[FPU_ACC]; - // Integer ALU (not present in Tesla) - p->sys.core[0].ialu_accesses = - ialu_accesses * p->sys.scaling_coefficients[SP_ACC]; - // Sfu accesses - p->sys.core[0].mul_accesses = - sfu_accesses * p->sys.scaling_coefficients[SFU_ACC]; - - sample_perf_counters[SP_ACC] = ialu_accesses; - sample_perf_counters[SFU_ACC] = sfu_accesses; - sample_perf_counters[FPU_ACC] = fpu_accesses; +void gpgpu_sim_wrapper::set_exec_unit_power(double fpu_accesses, double ialu_accesses, double sfu_accesses) +{ + p->sys.core[0].fpu_accesses = fpu_accesses*p->sys.scaling_coefficients[FPU_ACC]; + //Integer ALU (not present in Tesla) + p->sys.core[0].ialu_accesses = ialu_accesses*p->sys.scaling_coefficients[SP_ACC]; + //Sfu accesses + p->sys.core[0].mul_accesses = sfu_accesses*p->sys.scaling_coefficients[SFU_ACC]; + + sample_perf_counters[SP_ACC]=ialu_accesses; + sample_perf_counters[SFU_ACC]=sfu_accesses; + sample_perf_counters[FPU_ACC]=fpu_accesses; + + } -void gpgpu_sim_wrapper::set_active_lanes_power(double sp_avg_active_lane, - double sfu_avg_active_lane) { - p->sys.core[0].sp_average_active_lanes = sp_avg_active_lane; - p->sys.core[0].sfu_average_active_lanes = sfu_avg_active_lane; +void gpgpu_sim_wrapper::set_active_lanes_power(double sp_avg_active_lane, double sfu_avg_active_lane) +{ + p->sys.core[0].sp_average_active_lanes = sp_avg_active_lane; + p->sys.core[0].sfu_average_active_lanes = sfu_avg_active_lane; } -void gpgpu_sim_wrapper::set_NoC_power(double noc_tot_reads, - double noc_tot_writes) { - p->sys.NoC[0].total_accesses = - noc_tot_reads * p->sys.scaling_coefficients[NOC_A] + - noc_tot_writes * p->sys.scaling_coefficients[NOC_A]; - sample_perf_counters[NOC_A] = noc_tot_reads + noc_tot_writes; +void gpgpu_sim_wrapper::set_NoC_power(double noc_tot_reads, double noc_tot_writes ) +{ + p->sys.NoC[0].total_accesses = noc_tot_reads * p->sys.scaling_coefficients[NOC_A] + noc_tot_writes * p->sys.scaling_coefficients[NOC_A]; + sample_perf_counters[NOC_A]=noc_tot_reads+noc_tot_writes; } -void gpgpu_sim_wrapper::power_metrics_calculations() { - total_sample_count++; - kernel_sample_count++; - - // Current sample power - double sample_power = - proc->rt_power.readOp.dynamic + sample_cmp_pwr[CONST_DYNAMICP]; - - // Average power - // Previous + new + constant dynamic power (e.g., dynamic clocking power) - kernel_tot_power += sample_power; - kernel_power.avg = kernel_tot_power / kernel_sample_count; - for (unsigned ind = 0; ind < num_pwr_cmps; ++ind) { - kernel_cmp_pwr[ind].avg += (double)sample_cmp_pwr[ind]; - } - - for (unsigned ind = 0; ind < num_perf_counters; ++ind) { - kernel_cmp_perf_counters[ind].avg += (double)sample_perf_counters[ind]; - } - - // Max Power - if (sample_power > kernel_power.max) { - kernel_power.max = sample_power; - for (unsigned ind = 0; ind < num_pwr_cmps; ++ind) { - kernel_cmp_pwr[ind].max = (double)sample_cmp_pwr[ind]; - } - for (unsigned ind = 0; ind < num_perf_counters; ++ind) { - kernel_cmp_perf_counters[ind].max = sample_perf_counters[ind]; - } - } - // Min Power - if (sample_power < kernel_power.min || (kernel_power.min == 0)) { - kernel_power.min = sample_power; - for (unsigned ind = 0; ind < num_pwr_cmps; ++ind) { - kernel_cmp_pwr[ind].min = (double)sample_cmp_pwr[ind]; - } - for (unsigned ind = 0; ind < num_perf_counters; ++ind) { - kernel_cmp_perf_counters[ind].min = sample_perf_counters[ind]; - } - } - - gpu_tot_power.avg = (gpu_tot_power.avg + sample_power); - gpu_tot_power.max = - (sample_power > gpu_tot_power.max) ? sample_power : gpu_tot_power.max; - gpu_tot_power.min = - ((sample_power < gpu_tot_power.min) || (gpu_tot_power.min == 0)) - ? sample_power - : gpu_tot_power.min; +void gpgpu_sim_wrapper::power_metrics_calculations() +{ + total_sample_count++; + kernel_sample_count++; + + // Current sample power + double sample_power = proc->rt_power.readOp.dynamic + sample_cmp_pwr[CONST_DYNAMICP]; + + // Average power + // Previous + new + constant dynamic power (e.g., dynamic clocking power) + kernel_tot_power += sample_power; + kernel_power.avg = kernel_tot_power / kernel_sample_count; + for(unsigned ind=0; ind kernel_power.max){ + kernel_power.max = sample_power; + for(unsigned ind=0; ind gpu_tot_power.max) ? sample_power : gpu_tot_power.max; + gpu_tot_power.min = ((sample_power < gpu_tot_power.min) || (gpu_tot_power.min == 0)) ? sample_power : gpu_tot_power.min; + } -void gpgpu_sim_wrapper::print_trace_files() { - open_files(); - for (unsigned i = 0; i < num_perf_counters; ++i) { - gzprintf(metric_trace_file, "%f,", sample_perf_counters[i]); - } - gzprintf(metric_trace_file, "\n"); +void gpgpu_sim_wrapper::print_trace_files() +{ + open_files(); - gzprintf(power_trace_file, "%f,", proc_power); - for (unsigned i = 0; i < num_pwr_cmps; ++i) { - gzprintf(power_trace_file, "%f,", sample_cmp_pwr[i]); - } - gzprintf(power_trace_file, "\n"); + for(unsigned i=0; icores[0]->get_coefficient_fpint_insts(); - effpower_coeff[FP_INT] = - initpower_coeff[FP_INT] * p->sys.scaling_coefficients[FP_INT]; - - initpower_coeff[TOT_INST] = proc->cores[0]->get_coefficient_tot_insts(); - effpower_coeff[TOT_INST] = - initpower_coeff[TOT_INST] * p->sys.scaling_coefficients[TOT_INST]; - - initpower_coeff[REG_RD] = - proc->cores[0]->get_coefficient_regreads_accesses() * - (proc->cores[0]->exu->rf_fu_clockRate / proc->cores[0]->exu->clockRate); - initpower_coeff[REG_WR] = - proc->cores[0]->get_coefficient_regwrites_accesses() * - (proc->cores[0]->exu->rf_fu_clockRate / proc->cores[0]->exu->clockRate); - initpower_coeff[NON_REG_OPs] = - proc->cores[0]->get_coefficient_noregfileops_accesses() * - (proc->cores[0]->exu->rf_fu_clockRate / proc->cores[0]->exu->clockRate); - effpower_coeff[REG_RD] = - initpower_coeff[REG_RD] * p->sys.scaling_coefficients[REG_RD]; - effpower_coeff[REG_WR] = - initpower_coeff[REG_WR] * p->sys.scaling_coefficients[REG_WR]; - effpower_coeff[NON_REG_OPs] = - initpower_coeff[NON_REG_OPs] * p->sys.scaling_coefficients[NON_REG_OPs]; - - initpower_coeff[IC_H] = proc->cores[0]->get_coefficient_icache_hits(); - initpower_coeff[IC_M] = proc->cores[0]->get_coefficient_icache_misses(); - effpower_coeff[IC_H] = - initpower_coeff[IC_H] * p->sys.scaling_coefficients[IC_H]; - effpower_coeff[IC_M] = - initpower_coeff[IC_M] * p->sys.scaling_coefficients[IC_M]; - - initpower_coeff[CC_H] = (proc->cores[0]->get_coefficient_ccache_readhits() + - proc->get_coefficient_readcoalescing()); - initpower_coeff[CC_M] = (proc->cores[0]->get_coefficient_ccache_readmisses() + - proc->get_coefficient_readcoalescing()); - effpower_coeff[CC_H] = - initpower_coeff[CC_H] * p->sys.scaling_coefficients[CC_H]; - effpower_coeff[CC_M] = - initpower_coeff[CC_M] * p->sys.scaling_coefficients[CC_M]; - - initpower_coeff[TC_H] = (proc->cores[0]->get_coefficient_tcache_readhits() + - proc->get_coefficient_readcoalescing()); - initpower_coeff[TC_M] = (proc->cores[0]->get_coefficient_tcache_readmisses() + - proc->get_coefficient_readcoalescing()); - effpower_coeff[TC_H] = - initpower_coeff[TC_H] * p->sys.scaling_coefficients[TC_H]; - effpower_coeff[TC_M] = - initpower_coeff[TC_M] * p->sys.scaling_coefficients[TC_M]; - - initpower_coeff[SHRD_ACC] = - proc->cores[0]->get_coefficient_sharedmemory_readhits(); - effpower_coeff[SHRD_ACC] = - initpower_coeff[SHRD_ACC] * p->sys.scaling_coefficients[SHRD_ACC]; - - initpower_coeff[DC_RH] = (proc->cores[0]->get_coefficient_dcache_readhits() + - proc->get_coefficient_readcoalescing()); - initpower_coeff[DC_RM] = - (proc->cores[0]->get_coefficient_dcache_readmisses() + - proc->get_coefficient_readcoalescing()); - initpower_coeff[DC_WH] = (proc->cores[0]->get_coefficient_dcache_writehits() + - proc->get_coefficient_writecoalescing()); - initpower_coeff[DC_WM] = - (proc->cores[0]->get_coefficient_dcache_writemisses() + - proc->get_coefficient_writecoalescing()); - effpower_coeff[DC_RH] = - initpower_coeff[DC_RH] * p->sys.scaling_coefficients[DC_RH]; - effpower_coeff[DC_RM] = - initpower_coeff[DC_RM] * p->sys.scaling_coefficients[DC_RM]; - effpower_coeff[DC_WH] = - initpower_coeff[DC_WH] * p->sys.scaling_coefficients[DC_WH]; - effpower_coeff[DC_WM] = - initpower_coeff[DC_WM] * p->sys.scaling_coefficients[DC_WM]; - - initpower_coeff[L2_RH] = proc->get_coefficient_l2_read_hits(); - initpower_coeff[L2_RM] = proc->get_coefficient_l2_read_misses(); - initpower_coeff[L2_WH] = proc->get_coefficient_l2_write_hits(); - initpower_coeff[L2_WM] = proc->get_coefficient_l2_write_misses(); - effpower_coeff[L2_RH] = - initpower_coeff[L2_RH] * p->sys.scaling_coefficients[L2_RH]; - effpower_coeff[L2_RM] = - initpower_coeff[L2_RM] * p->sys.scaling_coefficients[L2_RM]; - effpower_coeff[L2_WH] = - initpower_coeff[L2_WH] * p->sys.scaling_coefficients[L2_WH]; - effpower_coeff[L2_WM] = - initpower_coeff[L2_WM] * p->sys.scaling_coefficients[L2_WM]; - - initpower_coeff[IDLE_CORE_N] = - p->sys.idle_core_power * proc->cores[0]->executionTime; - effpower_coeff[IDLE_CORE_N] = - initpower_coeff[IDLE_CORE_N] * p->sys.scaling_coefficients[IDLE_CORE_N]; - - initpower_coeff[PIPE_A] = proc->cores[0]->get_coefficient_duty_cycle(); - effpower_coeff[PIPE_A] = - initpower_coeff[PIPE_A] * p->sys.scaling_coefficients[PIPE_A]; - - initpower_coeff[MEM_RD] = proc->get_coefficient_mem_reads(); - initpower_coeff[MEM_WR] = proc->get_coefficient_mem_writes(); - initpower_coeff[MEM_PRE] = proc->get_coefficient_mem_pre(); - effpower_coeff[MEM_RD] = - initpower_coeff[MEM_RD] * p->sys.scaling_coefficients[MEM_RD]; - effpower_coeff[MEM_WR] = - initpower_coeff[MEM_WR] * p->sys.scaling_coefficients[MEM_WR]; - effpower_coeff[MEM_PRE] = - initpower_coeff[MEM_PRE] * p->sys.scaling_coefficients[MEM_PRE]; - - initpower_coeff[SP_ACC] = - proc->cores[0]->get_coefficient_ialu_accesses() * - (proc->cores[0]->exu->rf_fu_clockRate / proc->cores[0]->exu->clockRate); - ; - initpower_coeff[SFU_ACC] = proc->cores[0]->get_coefficient_sfu_accesses(); - initpower_coeff[FPU_ACC] = proc->cores[0]->get_coefficient_fpu_accesses(); - - effpower_coeff[SP_ACC] = - initpower_coeff[SP_ACC] * p->sys.scaling_coefficients[SP_ACC]; - effpower_coeff[SFU_ACC] = - initpower_coeff[SFU_ACC] * p->sys.scaling_coefficients[SFU_ACC]; - effpower_coeff[FPU_ACC] = - initpower_coeff[FPU_ACC] * p->sys.scaling_coefficients[FPU_ACC]; - - initpower_coeff[NOC_A] = proc->get_coefficient_noc_accesses(); - effpower_coeff[NOC_A] = - initpower_coeff[NOC_A] * p->sys.scaling_coefficients[NOC_A]; - - const_dynamic_power = - proc->get_const_dynamic_power() / (proc->cores[0]->executionTime); - - for (unsigned i = 0; i < num_perf_counters; i++) { - initpower_coeff[i] /= (proc->cores[0]->executionTime); - effpower_coeff[i] /= (proc->cores[0]->executionTime); - } } -void gpgpu_sim_wrapper::update_components_power() { - update_coefficients(); - - proc_power = proc->rt_power.readOp.dynamic; - - sample_cmp_pwr[IBP] = - (proc->cores[0]->ifu->IB->rt_power.readOp.dynamic + - proc->cores[0]->ifu->IB->rt_power.writeOp.dynamic + - proc->cores[0]->ifu->ID_misc->rt_power.readOp.dynamic + - proc->cores[0]->ifu->ID_operand->rt_power.readOp.dynamic + - proc->cores[0]->ifu->ID_inst->rt_power.readOp.dynamic) / - (proc->cores[0]->executionTime); - - sample_cmp_pwr[ICP] = proc->cores[0]->ifu->icache.rt_power.readOp.dynamic / - (proc->cores[0]->executionTime); - - sample_cmp_pwr[DCP] = proc->cores[0]->lsu->dcache.rt_power.readOp.dynamic / - (proc->cores[0]->executionTime); - - sample_cmp_pwr[TCP] = proc->cores[0]->lsu->tcache.rt_power.readOp.dynamic / - (proc->cores[0]->executionTime); - - sample_cmp_pwr[CCP] = proc->cores[0]->lsu->ccache.rt_power.readOp.dynamic / - (proc->cores[0]->executionTime); - - sample_cmp_pwr[SHRDP] = - proc->cores[0]->lsu->sharedmemory.rt_power.readOp.dynamic / - (proc->cores[0]->executionTime); - - sample_cmp_pwr[RFP] = - (proc->cores[0]->exu->rfu->rt_power.readOp.dynamic / - (proc->cores[0]->executionTime)) * - (proc->cores[0]->exu->rf_fu_clockRate / proc->cores[0]->exu->clockRate); - - sample_cmp_pwr[SPP] = - (proc->cores[0]->exu->exeu->rt_power.readOp.dynamic / - (proc->cores[0]->executionTime)) * - (proc->cores[0]->exu->rf_fu_clockRate / proc->cores[0]->exu->clockRate); - - sample_cmp_pwr[SFUP] = (proc->cores[0]->exu->mul->rt_power.readOp.dynamic / - (proc->cores[0]->executionTime)); - - sample_cmp_pwr[FPUP] = (proc->cores[0]->exu->fp_u->rt_power.readOp.dynamic / - (proc->cores[0]->executionTime)); - - sample_cmp_pwr[SCHEDP] = proc->cores[0]->exu->scheu->rt_power.readOp.dynamic / - (proc->cores[0]->executionTime); - - sample_cmp_pwr[L2CP] = (proc->XML->sys.number_of_L2s > 0) - ? proc->l2array[0]->rt_power.readOp.dynamic / - (proc->cores[0]->executionTime) - : 0; - - sample_cmp_pwr[MCP] = (proc->mc->rt_power.readOp.dynamic - - proc->mc->dram->rt_power.readOp.dynamic) / - (proc->cores[0]->executionTime); - - sample_cmp_pwr[NOCP] = - proc->nocs[0]->rt_power.readOp.dynamic / (proc->cores[0]->executionTime); - - sample_cmp_pwr[DRAMP] = - proc->mc->dram->rt_power.readOp.dynamic / (proc->cores[0]->executionTime); - - sample_cmp_pwr[PIPEP] = - proc->cores[0]->Pipeline_energy / (proc->cores[0]->executionTime); - - sample_cmp_pwr[IDLE_COREP] = - proc->cores[0]->IdleCoreEnergy / (proc->cores[0]->executionTime); - - // This constant dynamic power (e.g., clock power) part is estimated via - // regression model. - sample_cmp_pwr[CONST_DYNAMICP] = 0; - double cnst_dyn = - proc->get_const_dynamic_power() / (proc->cores[0]->executionTime); - // If the regression scaling term is greater than the recorded constant - // dynamic power - // then use the difference (other portion already added to dynamic power). - // Else, - // all the constant dynamic power is accounted for, add nothing. - if (p->sys.scaling_coefficients[CONST_DYNAMICN] > cnst_dyn) - sample_cmp_pwr[CONST_DYNAMICP] = - (p->sys.scaling_coefficients[CONST_DYNAMICN] - cnst_dyn); - - proc_power += sample_cmp_pwr[CONST_DYNAMICP]; - - double sum_pwr_cmp = 0; - for (unsigned i = 0; i < num_pwr_cmps; i++) { - sum_pwr_cmp += sample_cmp_pwr[i]; - } - bool check = false; - check = sanity_check(sum_pwr_cmp, proc_power); - assert("Total Power does not equal the sum of the components\n" && (check)); +void gpgpu_sim_wrapper::update_coefficients() +{ + + initpower_coeff[FP_INT]=proc->cores[0]->get_coefficient_fpint_insts(); + effpower_coeff[FP_INT]=initpower_coeff[FP_INT] * p->sys.scaling_coefficients[FP_INT]; + + initpower_coeff[TOT_INST]=proc->cores[0]->get_coefficient_tot_insts(); + effpower_coeff[TOT_INST]=initpower_coeff[TOT_INST] * p->sys.scaling_coefficients[TOT_INST]; + + initpower_coeff[REG_RD]=proc->cores[0]->get_coefficient_regreads_accesses()*(proc->cores[0]->exu->rf_fu_clockRate/proc->cores[0]->exu->clockRate); + initpower_coeff[REG_WR]=proc->cores[0]->get_coefficient_regwrites_accesses()*(proc->cores[0]->exu->rf_fu_clockRate/proc->cores[0]->exu->clockRate); + initpower_coeff[NON_REG_OPs]=proc->cores[0]->get_coefficient_noregfileops_accesses()*(proc->cores[0]->exu->rf_fu_clockRate/proc->cores[0]->exu->clockRate); + effpower_coeff[REG_RD]=initpower_coeff[REG_RD]*p->sys.scaling_coefficients[REG_RD]; + effpower_coeff[REG_WR]=initpower_coeff[REG_WR]*p->sys.scaling_coefficients[REG_WR]; + effpower_coeff[NON_REG_OPs]=initpower_coeff[NON_REG_OPs]*p->sys.scaling_coefficients[NON_REG_OPs]; + + initpower_coeff[IC_H]=proc->cores[0]->get_coefficient_icache_hits(); + initpower_coeff[IC_M]=proc->cores[0]->get_coefficient_icache_misses(); + effpower_coeff[IC_H]=initpower_coeff[IC_H]*p->sys.scaling_coefficients[IC_H]; + effpower_coeff[IC_M]=initpower_coeff[IC_M]*p->sys.scaling_coefficients[IC_M]; + + initpower_coeff[CC_H]=(proc->cores[0]->get_coefficient_ccache_readhits()+proc->get_coefficient_readcoalescing()); + initpower_coeff[CC_M]=(proc->cores[0]->get_coefficient_ccache_readmisses()+proc->get_coefficient_readcoalescing()); + effpower_coeff[CC_H]=initpower_coeff[CC_H]*p->sys.scaling_coefficients[CC_H]; + effpower_coeff[CC_M]=initpower_coeff[CC_M]*p->sys.scaling_coefficients[CC_M]; + + initpower_coeff[TC_H]=(proc->cores[0]->get_coefficient_tcache_readhits()+proc->get_coefficient_readcoalescing()); + initpower_coeff[TC_M]=(proc->cores[0]->get_coefficient_tcache_readmisses()+proc->get_coefficient_readcoalescing()); + effpower_coeff[TC_H]=initpower_coeff[TC_H]*p->sys.scaling_coefficients[TC_H]; + effpower_coeff[TC_M]=initpower_coeff[TC_M]*p->sys.scaling_coefficients[TC_M]; + + initpower_coeff[SHRD_ACC]=proc->cores[0]->get_coefficient_sharedmemory_readhits(); + effpower_coeff[SHRD_ACC]=initpower_coeff[SHRD_ACC]*p->sys.scaling_coefficients[SHRD_ACC]; + + initpower_coeff[DC_RH]=(proc->cores[0]->get_coefficient_dcache_readhits() + proc->get_coefficient_readcoalescing()); + initpower_coeff[DC_RM]=(proc->cores[0]->get_coefficient_dcache_readmisses() + proc->get_coefficient_readcoalescing()); + initpower_coeff[DC_WH]=(proc->cores[0]->get_coefficient_dcache_writehits() + proc->get_coefficient_writecoalescing()); + initpower_coeff[DC_WM]=(proc->cores[0]->get_coefficient_dcache_writemisses() + proc->get_coefficient_writecoalescing()); + effpower_coeff[DC_RH]=initpower_coeff[DC_RH]*p->sys.scaling_coefficients[DC_RH]; + effpower_coeff[DC_RM]=initpower_coeff[DC_RM]*p->sys.scaling_coefficients[DC_RM]; + effpower_coeff[DC_WH]=initpower_coeff[DC_WH]*p->sys.scaling_coefficients[DC_WH]; + effpower_coeff[DC_WM]=initpower_coeff[DC_WM]*p->sys.scaling_coefficients[DC_WM]; + + initpower_coeff[L2_RH]=proc->get_coefficient_l2_read_hits(); + initpower_coeff[L2_RM]=proc->get_coefficient_l2_read_misses(); + initpower_coeff[L2_WH]=proc->get_coefficient_l2_write_hits(); + initpower_coeff[L2_WM]=proc->get_coefficient_l2_write_misses(); + effpower_coeff[L2_RH]=initpower_coeff[L2_RH]*p->sys.scaling_coefficients[L2_RH]; + effpower_coeff[L2_RM]=initpower_coeff[L2_RM]*p->sys.scaling_coefficients[L2_RM]; + effpower_coeff[L2_WH]=initpower_coeff[L2_WH]*p->sys.scaling_coefficients[L2_WH]; + effpower_coeff[L2_WM]=initpower_coeff[L2_WM]*p->sys.scaling_coefficients[L2_WM]; + + initpower_coeff[IDLE_CORE_N]=p->sys.idle_core_power * proc->cores[0]->executionTime; + effpower_coeff[IDLE_CORE_N]=initpower_coeff[IDLE_CORE_N]*p->sys.scaling_coefficients[IDLE_CORE_N]; + + initpower_coeff[PIPE_A]=proc->cores[0]->get_coefficient_duty_cycle(); + effpower_coeff[PIPE_A]=initpower_coeff[PIPE_A]*p->sys.scaling_coefficients[PIPE_A]; + + initpower_coeff[MEM_RD]=proc->get_coefficient_mem_reads(); + initpower_coeff[MEM_WR]=proc->get_coefficient_mem_writes(); + initpower_coeff[MEM_PRE]=proc->get_coefficient_mem_pre(); + effpower_coeff[MEM_RD]=initpower_coeff[MEM_RD]*p->sys.scaling_coefficients[MEM_RD]; + effpower_coeff[MEM_WR]=initpower_coeff[MEM_WR]*p->sys.scaling_coefficients[MEM_WR]; + effpower_coeff[MEM_PRE]=initpower_coeff[MEM_PRE]*p->sys.scaling_coefficients[MEM_PRE]; + + initpower_coeff[SP_ACC]=proc->cores[0]->get_coefficient_ialu_accesses()*(proc->cores[0]->exu->rf_fu_clockRate/proc->cores[0]->exu->clockRate);; + initpower_coeff[SFU_ACC]=proc->cores[0]->get_coefficient_sfu_accesses(); + initpower_coeff[FPU_ACC]=proc->cores[0]->get_coefficient_fpu_accesses(); + + effpower_coeff[SP_ACC]=initpower_coeff[SP_ACC]*p->sys.scaling_coefficients[SP_ACC]; + effpower_coeff[SFU_ACC]=initpower_coeff[SFU_ACC]*p->sys.scaling_coefficients[SFU_ACC]; + effpower_coeff[FPU_ACC]=initpower_coeff[FPU_ACC]*p->sys.scaling_coefficients[FPU_ACC]; + + initpower_coeff[NOC_A]=proc->get_coefficient_noc_accesses(); + effpower_coeff[NOC_A]=initpower_coeff[NOC_A]*p->sys.scaling_coefficients[NOC_A]; + + const_dynamic_power=proc->get_const_dynamic_power()/(proc->cores[0]->executionTime); + + for(unsigned i=0; icores[0]->executionTime); + effpower_coeff[i]/=(proc->cores[0]->executionTime); + } } -void gpgpu_sim_wrapper::compute() { proc->compute(); } -void gpgpu_sim_wrapper::print_power_kernel_stats( - double gpu_sim_cycle, double gpu_tot_sim_cycle, double init_value, - const std::string& kernel_info_string, bool print_trace) { - detect_print_steady_state(1, init_value); - if (g_power_simulation_enabled) { - powerfile << kernel_info_string << std::endl; - - sanity_check((kernel_power.avg * kernel_sample_count), kernel_tot_power); - powerfile << "Kernel Average Power Data:" << std::endl; - powerfile << "kernel_avg_power = " << kernel_power.avg << std::endl; - - for (unsigned i = 0; i < num_pwr_cmps; ++i) { - powerfile << "gpu_avg_" << pwr_cmp_label[i] << " = " - << kernel_cmp_pwr[i].avg / kernel_sample_count << std::endl; - } - for (unsigned i = 0; i < num_perf_counters; ++i) { - powerfile << "gpu_avg_" << perf_count_label[i] << " = " - << kernel_cmp_perf_counters[i].avg / kernel_sample_count - << std::endl; - } +void gpgpu_sim_wrapper::update_components_power() +{ - powerfile << std::endl << "Kernel Maximum Power Data:" << std::endl; - powerfile << "kernel_max_power = " << kernel_power.max << std::endl; - for (unsigned i = 0; i < num_pwr_cmps; ++i) { - powerfile << "gpu_max_" << pwr_cmp_label[i] << " = " - << kernel_cmp_pwr[i].max << std::endl; - } - for (unsigned i = 0; i < num_perf_counters; ++i) { - powerfile << "gpu_max_" << perf_count_label[i] << " = " - << kernel_cmp_perf_counters[i].max << std::endl; - } + update_coefficients(); - powerfile << std::endl << "Kernel Minimum Power Data:" << std::endl; - powerfile << "kernel_min_power = " << kernel_power.min << std::endl; - for (unsigned i = 0; i < num_pwr_cmps; ++i) { - powerfile << "gpu_min_" << pwr_cmp_label[i] << " = " - << kernel_cmp_pwr[i].min << std::endl; - } - for (unsigned i = 0; i < num_perf_counters; ++i) { - powerfile << "gpu_min_" << perf_count_label[i] << " = " - << kernel_cmp_perf_counters[i].min << std::endl; - } + proc_power=proc->rt_power.readOp.dynamic; + + sample_cmp_pwr[IBP]=(proc->cores[0]->ifu->IB->rt_power.readOp.dynamic + +proc->cores[0]->ifu->IB->rt_power.writeOp.dynamic + +proc->cores[0]->ifu->ID_misc->rt_power.readOp.dynamic + +proc->cores[0]->ifu->ID_operand->rt_power.readOp.dynamic + +proc->cores[0]->ifu->ID_inst->rt_power.readOp.dynamic)/(proc->cores[0]->executionTime); + + sample_cmp_pwr[ICP]=proc->cores[0]->ifu->icache.rt_power.readOp.dynamic/(proc->cores[0]->executionTime); + + sample_cmp_pwr[DCP]=proc->cores[0]->lsu->dcache.rt_power.readOp.dynamic/(proc->cores[0]->executionTime); + + sample_cmp_pwr[TCP]=proc->cores[0]->lsu->tcache.rt_power.readOp.dynamic/(proc->cores[0]->executionTime); + + sample_cmp_pwr[CCP]=proc->cores[0]->lsu->ccache.rt_power.readOp.dynamic/(proc->cores[0]->executionTime); + + sample_cmp_pwr[SHRDP]=proc->cores[0]->lsu->sharedmemory.rt_power.readOp.dynamic/(proc->cores[0]->executionTime); + + sample_cmp_pwr[RFP]=(proc->cores[0]->exu->rfu->rt_power.readOp.dynamic/(proc->cores[0]->executionTime)) + *(proc->cores[0]->exu->rf_fu_clockRate/proc->cores[0]->exu->clockRate); + + sample_cmp_pwr[SPP]=(proc->cores[0]->exu->exeu->rt_power.readOp.dynamic/(proc->cores[0]->executionTime)) + *(proc->cores[0]->exu->rf_fu_clockRate/proc->cores[0]->exu->clockRate); + + sample_cmp_pwr[SFUP]=(proc->cores[0]->exu->mul->rt_power.readOp.dynamic/(proc->cores[0]->executionTime)); + + sample_cmp_pwr[FPUP]=(proc->cores[0]->exu->fp_u->rt_power.readOp.dynamic/(proc->cores[0]->executionTime)); + + sample_cmp_pwr[SCHEDP]=proc->cores[0]->exu->scheu->rt_power.readOp.dynamic/(proc->cores[0]->executionTime); + + sample_cmp_pwr[L2CP]=(proc->XML->sys.number_of_L2s>0)? proc->l2array[0]->rt_power.readOp.dynamic/(proc->cores[0]->executionTime):0; + + sample_cmp_pwr[MCP]=(proc->mc->rt_power.readOp.dynamic-proc->mc->dram->rt_power.readOp.dynamic)/(proc->cores[0]->executionTime); + + sample_cmp_pwr[NOCP]=proc->nocs[0]->rt_power.readOp.dynamic/(proc->cores[0]->executionTime); + + sample_cmp_pwr[DRAMP]=proc->mc->dram->rt_power.readOp.dynamic/(proc->cores[0]->executionTime); + + sample_cmp_pwr[PIPEP]=proc->cores[0]->Pipeline_energy/(proc->cores[0]->executionTime); + + sample_cmp_pwr[IDLE_COREP]=proc->cores[0]->IdleCoreEnergy/(proc->cores[0]->executionTime); + + // This constant dynamic power (e.g., clock power) part is estimated via regression model. + sample_cmp_pwr[CONST_DYNAMICP]=0; + double cnst_dyn = proc->get_const_dynamic_power()/(proc->cores[0]->executionTime); + // If the regression scaling term is greater than the recorded constant dynamic power + // then use the difference (other portion already added to dynamic power). Else, + // all the constant dynamic power is accounted for, add nothing. + if(p->sys.scaling_coefficients[CONST_DYNAMICN] > cnst_dyn) + sample_cmp_pwr[CONST_DYNAMICP] = (p->sys.scaling_coefficients[CONST_DYNAMICN]-cnst_dyn); + + proc_power+=sample_cmp_pwr[CONST_DYNAMICP]; + + double sum_pwr_cmp=0; + for(unsigned i=0; idisplayEnergy(2,5); } -void gpgpu_sim_wrapper::detect_print_steady_state(int position, - double init_val) { - // Calculating Average - if (g_power_simulation_enabled && g_steady_power_levels_enabled) { - steady_state_tacking_file = gzopen(g_steady_state_tracking_filename, "a"); - if (position == 0) { - if (samples.size() == 0) { - // First sample - sample_start = total_sample_count; - sample_val = proc->rt_power.readOp.dynamic; - init_inst_val = init_val; - samples.push_back(proc->rt_power.readOp.dynamic); - assert(samples_counter.size() == 0); - assert(pwr_counter.size() == 0); - - for (unsigned i = 0; i < (num_perf_counters); ++i) { - samples_counter.push_back(sample_perf_counters[i]); - } +void gpgpu_sim_wrapper::print_steady_state(int position, double init_val){ + double temp_avg = sample_val / (double)samples.size() ; + double temp_ipc = (init_val-init_inst_val)/ (double) (samples.size()*gpu_stat_sample_freq); + + if((samples.size() > gpu_steady_min_period)){ // If steady state occurred for some time, print to file + has_written_avg=true; + gzprintf(steady_state_tacking_file,"%u,%d,%f,%f,",sample_start,total_sample_count,temp_avg,temp_ipc); + for(unsigned i=0; irt_power.readOp.dynamic - temp_avg) < - gpu_steady_power_deviation) { // Value is within threshold - sample_val += proc->rt_power.readOp.dynamic; - samples.push_back(proc->rt_power.readOp.dynamic); - for (unsigned i = 0; i < (num_perf_counters); ++i) { - samples_counter.at(i) += sample_perf_counters[i]; - } - - for (unsigned i = 0; i < (num_pwr_cmps); ++i) { - pwr_counter.at(i) += sample_cmp_pwr[i]; - } - - } else { // Value exceeds threshold, not considered steady state - print_steady_state(position, init_val); - } - } - } else { - print_steady_state(position, init_val); +void gpgpu_sim_wrapper::detect_print_steady_state(int position, double init_val) +{ + // Calculating Average + if(g_power_simulation_enabled && g_steady_power_levels_enabled){ + steady_state_tacking_file = gzopen(g_steady_state_tracking_filename,"a"); + if(position==0){ + if(samples.size() == 0){ + // First sample + sample_start = total_sample_count; + sample_val = proc->rt_power.readOp.dynamic; + init_inst_val=init_val; + samples.push_back(proc->rt_power.readOp.dynamic); + assert(samples_counter.size() == 0); + assert(pwr_counter.size() == 0); + + for(unsigned i=0; i<(num_perf_counters); ++i){ + samples_counter.push_back(sample_perf_counters[i]); + } + + for(unsigned i=0; i<(num_pwr_cmps); ++i){ + pwr_counter.push_back(sample_cmp_pwr[i]); + } + assert(pwr_counter.size() == (double)num_pwr_cmps); + assert(samples_counter.size() == (double)num_perf_counters); + }else{ + // Get current average + double temp_avg = sample_val / (double)samples.size() ; + + if( abs(proc->rt_power.readOp.dynamic-temp_avg) < gpu_steady_power_deviation){ // Value is within threshold + sample_val += proc->rt_power.readOp.dynamic; + samples.push_back(proc->rt_power.readOp.dynamic); + for(unsigned i=0; i<(num_perf_counters); ++i){ + samples_counter.at(i) += sample_perf_counters[i]; + } + + for(unsigned i=0; i<(num_pwr_cmps); ++i){ + pwr_counter.at(i) += sample_cmp_pwr[i]; + } + + }else{ // Value exceeds threshold, not considered steady state + print_steady_state(position, init_val); + } + } + }else{ + print_steady_state(position, init_val); + } + gzclose(steady_state_tacking_file); } - gzclose(steady_state_tacking_file); - } } -void gpgpu_sim_wrapper::open_files() { - if (g_power_simulation_enabled) { - if (g_power_trace_enabled) { - power_trace_file = gzopen(g_power_trace_filename, "a"); - metric_trace_file = gzopen(g_metric_trace_filename, "a"); +void gpgpu_sim_wrapper::open_files() +{ + if(g_power_simulation_enabled){ + if (g_power_trace_enabled ){ + power_trace_file = gzopen(g_power_trace_filename, "a"); + metric_trace_file = gzopen(g_metric_trace_filename, "a"); + } } - } } -void gpgpu_sim_wrapper::close_files() { - if (g_power_simulation_enabled) { - if (g_power_trace_enabled) { - gzclose(power_trace_file); - gzclose(metric_trace_file); - } - } +void gpgpu_sim_wrapper::close_files() +{ + if(g_power_simulation_enabled){ + if(g_power_trace_enabled){ + gzclose(power_trace_file); + gzclose(metric_trace_file); + } + } + } diff --git a/src/gpuwattch/gpgpu_sim_wrapper.h b/src/gpuwattch/gpgpu_sim_wrapper.h index a3356b7..9d06092 100644 --- a/src/gpuwattch/gpgpu_sim_wrapper.h +++ b/src/gpuwattch/gpgpu_sim_wrapper.h @@ -7,16 +7,14 @@ // // Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. -// Redistributions in binary form must reproduce the above copyright notice, -// this +// Redistributions in binary form must reproduce the above copyright notice, this // list of conditions and the following disclaimer in the documentation and/or // other materials provided with the distribution. // Neither the name of The University of British Columbia nor the names of its // contributors may be used to endorse or promote products derived from this // software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE @@ -30,140 +28,120 @@ #ifndef GPGPU_SIM_WRAPPER_H_ #define GPGPU_SIM_WRAPPER_H_ -#include +#include "processor.h" #include #include -#include -#include -#include -#include +#include #include -#include "processor.h" +#include +#include +#include +#include + using namespace std; template -struct avg_max_min_counters { - T avg; - T max; - T min; - - avg_max_min_counters() { - avg = 0; - max = 0; - min = 0; - } +struct avg_max_min_counters{ + T avg; + T max; + T min; + + avg_max_min_counters(){avg=0; max=0; min=0;} }; class gpgpu_sim_wrapper { - public: - gpgpu_sim_wrapper(bool power_simulation_enabled, char* xmlfile); - ~gpgpu_sim_wrapper(); - - void init_mcpat(char* xmlfile, char* powerfile, char* power_trace_file, - char* metric_trace_file, char* steady_state_file, - bool power_sim_enabled, bool trace_enabled, - bool steady_state_enabled, bool power_per_cycle_dump, - double steady_power_deviation, double steady_min_period, - int zlevel, double init_val, int stat_sample_freq); - void detect_print_steady_state(int position, double init_val); - void close_files(); - void open_files(); - void compute(); - void dump(); - void print_trace_files(); - void update_components_power(); - void update_coefficients(); - void reset_counters(); - void print_power_kernel_stats(double gpu_sim_cycle, double gpu_tot_sim_cycle, - double init_value, - const std::string& kernel_info_string, - bool print_trace); - void power_metrics_calculations(); - void set_inst_power(bool clk_gated_lanes, double tot_cycles, - double busy_cycles, double tot_inst, double int_inst, - double fp_inst, double load_inst, double store_inst, - double committed_inst); - void set_regfile_power(double reads, double writes, double ops); - void set_icache_power(double accesses, double misses); - void set_ccache_power(double accesses, double misses); - void set_tcache_power(double accesses, double misses); - void set_shrd_mem_power(double accesses); - void set_l1cache_power(double read_accesses, double read_misses, - double write_accesses, double write_misses); - void set_l2cache_power(double read_accesses, double read_misses, - double write_accesses, double write_misses); - void set_idle_core_power(double num_idle_core); - void set_duty_cycle_power(double duty_cycle); - void set_mem_ctrl_power(double reads, double writes, double dram_precharge); - void set_exec_unit_power(double fpu_accesses, double ialu_accesses, - double sfu_accesses); - void set_active_lanes_power(double sp_avg_active_lane, - double sfu_avg_active_lane); - void set_NoC_power(double noc_tot_reads, double noc_tot_write); - bool sanity_check(double a, double b); - - private: - void print_steady_state(int position, double init_val); - - Processor* proc; - ParseXML* p; - // power parameters - double const_dynamic_power; - double proc_power; - - unsigned num_perf_counters; // # of performance counters - unsigned num_pwr_cmps; // # of components modelled - int kernel_sample_count; // # of samples per kernel - int total_sample_count; // # of samples per benchmark - - std::vector > - kernel_cmp_pwr; // Per-kernel component power avg/max/min values - std::vector > - kernel_cmp_perf_counters; // Per-kernel component avg/max/min performance - // counters - - double kernel_tot_power; // Total per-kernel power - avg_max_min_counters - kernel_power; // Per-kernel power avg/max/min values - avg_max_min_counters - gpu_tot_power; // Global GPU power avg/max/min values (across kernels) - - bool has_written_avg; - - std::vector sample_cmp_pwr; // Current sample component powers - std::vector - sample_perf_counters; // Current sample component perf. counts - std::vector initpower_coeff; - std::vector effpower_coeff; - - // For calculating steady-state average - unsigned sample_start; - double sample_val; - double init_inst_val; - std::vector samples; - std::vector samples_counter; - std::vector pwr_counter; - - char* xml_filename; - char* g_power_filename; - char* g_power_trace_filename; - char* g_metric_trace_filename; - char* g_steady_state_tracking_filename; - bool g_power_simulation_enabled; - bool g_steady_power_levels_enabled; - bool g_power_trace_enabled; - bool g_power_per_cycle_dump; - double gpu_steady_power_deviation; - double gpu_steady_min_period; - int g_power_trace_zlevel; - double gpu_stat_sample_frequency; - int gpu_stat_sample_freq; - - std::ofstream powerfile; - gzFile power_trace_file; - gzFile metric_trace_file; - gzFile steady_state_tacking_file; +public: + gpgpu_sim_wrapper(bool power_simulation_enabled, char* xmlfile); + ~gpgpu_sim_wrapper(); + + void init_mcpat(char* xmlfile, char* powerfile, char* power_trace_file,char* metric_trace_file, + char * steady_state_file,bool power_sim_enabled,bool trace_enabled,bool steady_state_enabled, + bool power_per_cycle_dump,double steady_power_deviation,double steady_min_period,int zlevel, + double init_val,int stat_sample_freq); + void detect_print_steady_state(int position, double init_val); + void close_files(); + void open_files(); + void compute(); + void dump(); + void print_trace_files(); + void update_components_power(); + void update_coefficients(); + void reset_counters(); + void print_power_kernel_stats(double gpu_sim_cycle, double gpu_tot_sim_cycle, double init_value, const std::string & kernel_info_string, bool print_trace); + void power_metrics_calculations(); + void set_inst_power(bool clk_gated_lanes, double tot_cycles, double busy_cycles, double tot_inst, double int_inst, double fp_inst, double load_inst, double store_inst, double committed_inst); + void set_regfile_power(double reads, double writes, double ops); + void set_icache_power(double accesses, double misses); + void set_ccache_power(double accesses, double misses); + void set_tcache_power(double accesses, double misses); + void set_shrd_mem_power(double accesses); + void set_l1cache_power(double read_accesses, double read_misses, double write_accesses, double write_misses); + void set_l2cache_power(double read_accesses, double read_misses, double write_accesses, double write_misses); + void set_idle_core_power(double num_idle_core); + void set_duty_cycle_power(double duty_cycle); + void set_mem_ctrl_power(double reads, double writes, double dram_precharge); + void set_exec_unit_power(double fpu_accesses, double ialu_accesses, double sfu_accesses); + void set_active_lanes_power(double sp_avg_active_lane, double sfu_avg_active_lane); + void set_NoC_power(double noc_tot_reads, double noc_tot_write); + bool sanity_check(double a, double b); + +private: + + void print_steady_state(int position, double init_val); + + Processor* proc; + ParseXML * p; + // power parameters + double const_dynamic_power; + double proc_power; + + unsigned num_perf_counters; // # of performance counters + unsigned num_pwr_cmps; // # of components modelled + int kernel_sample_count; // # of samples per kernel + int total_sample_count; // # of samples per benchmark + + std::vector< avg_max_min_counters > kernel_cmp_pwr; // Per-kernel component power avg/max/min values + std::vector< avg_max_min_counters > kernel_cmp_perf_counters; // Per-kernel component avg/max/min performance counters + + double kernel_tot_power; // Total per-kernel power + avg_max_min_counters kernel_power; // Per-kernel power avg/max/min values + avg_max_min_counters gpu_tot_power; // Global GPU power avg/max/min values (across kernels) + + bool has_written_avg; + + std::vector sample_cmp_pwr; // Current sample component powers + std::vector sample_perf_counters; // Current sample component perf. counts + std::vector initpower_coeff; + std::vector effpower_coeff; + + // For calculating steady-state average + unsigned sample_start; + double sample_val; + double init_inst_val; + std::vector samples; + std::vector samples_counter; + std::vector pwr_counter; + + char *xml_filename; + char *g_power_filename; + char *g_power_trace_filename; + char *g_metric_trace_filename; + char * g_steady_state_tracking_filename; + bool g_power_simulation_enabled; + bool g_steady_power_levels_enabled; + bool g_power_trace_enabled; + bool g_power_per_cycle_dump; + double gpu_steady_power_deviation; + double gpu_steady_min_period; + int g_power_trace_zlevel; + double gpu_stat_sample_frequency; + int gpu_stat_sample_freq; + + std::ofstream powerfile; + gzFile power_trace_file; + gzFile metric_trace_file; + gzFile steady_state_tacking_file; }; #endif /* GPGPU_SIM_WRAPPER_H_ */ diff --git a/src/gpuwattch/interconnect.cc b/src/gpuwattch/interconnect.cc index caf66b3..f109da7 100644 --- a/src/gpuwattch/interconnect.cc +++ b/src/gpuwattch/interconnect.cc @@ -29,51 +29,63 @@ * ***************************************************************************/ + #include "interconnect.h" +#include "wire.h" #include #include #include "globalvar.h" -#include "wire.h" -interconnect::interconnect(string name_, enum Device_ty device_ty_, - double base_w, double base_h, int data_w, double len, - const InputParameter *configure_interface, - int start_wiring_level_, bool pipelinable_, - double route_over_perc_, bool opt_local_, - enum Core_type core_ty_, enum Wire_type wire_model, - double width_s, double space_s, - TechnologyParameter::DeviceType *dt) - : name(name_), - device_ty(device_ty_), - in_rise_time(0), - out_rise_time(0), - base_width(base_w), - base_height(base_h), - data_width(data_w), - wt(wire_model), - width_scaling(width_s), - space_scaling(space_s), - start_wiring_level(start_wiring_level_), - length(len), - // interconnect_latency(1e-12), - // interconnect_throughput(1e-12), - opt_local(opt_local_), - core_ty(core_ty_), - pipelinable(pipelinable_), - route_over_perc(route_over_perc_), - deviceType(dt) { +interconnect::interconnect( + string name_, + enum Device_ty device_ty_, + double base_w, double base_h, + int data_w, double len,const InputParameter *configure_interface, + int start_wiring_level_, + bool pipelinable_ , + double route_over_perc_ , + bool opt_local_, + enum Core_type core_ty_, + enum Wire_type wire_model, + double width_s, double space_s, + TechnologyParameter::DeviceType *dt +) + :name(name_), + device_ty(device_ty_), + in_rise_time(0), + out_rise_time(0), + base_width(base_w), + base_height(base_h), + data_width(data_w), + wt(wire_model), + width_scaling(width_s), + space_scaling(space_s), + start_wiring_level(start_wiring_level_), + length(len), + //interconnect_latency(1e-12), + //interconnect_throughput(1e-12), + opt_local(opt_local_), + core_ty(core_ty_), + pipelinable(pipelinable_), + route_over_perc(route_over_perc_), + deviceType(dt) +{ + wt = Global; - l_ip = *configure_interface; + l_ip=*configure_interface; local_result = init_interface(&l_ip); - max_unpipelined_link_delay = 0; // TODO + + max_unpipelined_link_delay = 0; //TODO min_w_nmos = g_tp.min_w_nmos_; min_w_pmos = deviceType->n_to_p_eff_curr_drv_ratio * min_w_nmos; - latency = l_ip.latency; - throughput = l_ip.throughput; - latency_overflow = false; - throughput_overflow = false; + + + latency = l_ip.latency; + throughput = l_ip.throughput; + latency_overflow=false; + throughput_overflow=false; /* * TODO: Add wiring option from semi-global to global automatically @@ -84,62 +96,66 @@ interconnect::interconnect(string name_, enum Device_ty device_ty_, * not have fat wires. */ if (pipelinable == false) - // Non-pipelinable wires, such as bypass logic, care latency + //Non-pipelinable wires, such as bypass logic, care latency { - compute(); - if (opt_for_clk && opt_local) { - while (delay > latency && width_scaling < 3.0) { - width_scaling *= 2; - space_scaling *= 2; - Wire winit(width_scaling, space_scaling); - compute(); - } - if (delay > latency) { - latency_overflow = true; - } - } - } else // Pipelinable wires, such as bus, does not care latency but - // throughput + compute(); + if (opt_for_clk && opt_local) + { + while (delay > latency && width_scaling<3.0) + { + width_scaling *= 2; + space_scaling *= 2; + Wire winit(width_scaling, space_scaling); + compute(); + } + if (delay > latency) + { + latency_overflow=true; + } + } + } + else //Pipelinable wires, such as bus, does not care latency but throughput { - /* - * TODO: Add pipe regs power, area, and timing; - * Pipelinable wires optimize latency first. - */ - compute(); - if (opt_for_clk && opt_local) { - while (delay > throughput && width_scaling < 3.0) { - width_scaling *= 2; - space_scaling *= 2; - Wire winit(width_scaling, space_scaling); - compute(); - } - if (delay > throughput) - // insert pipeline stages - { - num_pipe_stages = (int)ceil(delay / throughput); - assert(num_pipe_stages > 0); - delay = delay / num_pipe_stages + num_pipe_stages * 0.05 * delay; - } - } + /* + * TODO: Add pipe regs power, area, and timing; + * Pipelinable wires optimize latency first. + */ + compute(); + if (opt_for_clk && opt_local) + { + while (delay > throughput && width_scaling<3.0) + { + width_scaling *= 2; + space_scaling *= 2; + Wire winit(width_scaling, space_scaling); + compute(); + } + if (delay > throughput) + // insert pipeline stages + { + num_pipe_stages = (int)ceil(delay/throughput); + assert(num_pipe_stages>0); + delay = delay/num_pipe_stages + num_pipe_stages*0.05*delay; + } + } } power_bit = power; power.readOp.dynamic *= data_width; power.readOp.leakage *= data_width; power.readOp.gate_leakage *= data_width; - area.set_area(area.get_area() * data_width); + area.set_area(area.get_area()*data_width); no_device_under_wire_area.h *= data_width; - if (latency_overflow == true) - cout << "Warning: " << name - << " wire structure cannot satisfy latency constraint." << endl; + if (latency_overflow==true) + cout<< "Warning: "<< name <<" wire structure cannot satisfy latency constraint." << endl; + assert(power.readOp.dynamic > 0); assert(power.readOp.leakage > 0); assert(power.readOp.gate_leakage > 0); - double long_channel_device_reduction = - longer_channel_device_reduction(device_ty, core_ty); + double long_channel_device_reduction = longer_channel_device_reduction(device_ty,core_ty); double sckRation = g_tp.sckt_co_eff; power.readOp.dynamic *= sckRation; @@ -147,17 +163,20 @@ interconnect::interconnect(string name_, enum Device_ty device_ty_, power.searchOp.dynamic *= sckRation; power.readOp.longer_channel_leakage = - power.readOp.leakage * long_channel_device_reduction; + power.readOp.leakage*long_channel_device_reduction; - if (pipelinable) // Only global wires has the option to choose whether - // routing over or not - area.set_area(area.get_area() * route_over_perc + - no_device_under_wire_area.get_area() * (1 - route_over_perc)); + if (pipelinable)//Only global wires has the option to choose whether routing over or not + area.set_area(area.get_area()*route_over_perc + no_device_under_wire_area.get_area()*(1-route_over_perc)); Wire wreset(); } -void interconnect::compute() { + + +void +interconnect::compute() +{ + Wire *wtemp1 = 0; wtemp1 = new Wire(wt, length, 1, width_scaling, space_scaling); delay = wtemp1->delay; @@ -166,15 +185,18 @@ void interconnect::compute() { power.readOp.gate_leakage = wtemp1->power.readOp.gate_leakage; area.set_area(wtemp1->area.get_area()); - no_device_under_wire_area.h = (wtemp1->wire_width + wtemp1->wire_spacing); + no_device_under_wire_area.h = (wtemp1->wire_width + wtemp1->wire_spacing); no_device_under_wire_area.w = length; - if (wtemp1) delete wtemp1; + if (wtemp1) + delete wtemp1; + } -void interconnect::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 interconnect::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 compute(); @@ -187,14 +209,13 @@ void interconnect::leakage_feedback(double temperature) { assert(power.readOp.leakage > 0); assert(power.readOp.gate_leakage > 0); - double long_channel_device_reduction = - longer_channel_device_reduction(device_ty, core_ty); + double long_channel_device_reduction = longer_channel_device_reduction(device_ty,core_ty); double sckRation = g_tp.sckt_co_eff; power.readOp.dynamic *= sckRation; power.writeOp.dynamic *= sckRation; power.searchOp.dynamic *= sckRation; - power.readOp.longer_channel_leakage = - power.readOp.leakage * long_channel_device_reduction; + power.readOp.longer_channel_leakage = power.readOp.leakage*long_channel_device_reduction; } + diff --git a/src/gpuwattch/interconnect.h b/src/gpuwattch/interconnect.h index b725c1d..9471c7a 100644 --- a/src/gpuwattch/interconnect.h +++ b/src/gpuwattch/interconnect.h @@ -29,72 +29,83 @@ * ***************************************************************************/ + #ifndef __INTERCONNECT_H__ #define __INTERCONNECT_H__ -#include "assert.h" -#include "basic_components.h" #include "cacti/basic_circuit.h" -#include "cacti/cacti_interface.h" +#include "basic_components.h" #include "cacti/component.h" #include "cacti/parameter.h" +#include "assert.h" #include "cacti/subarray.h" +#include "cacti/cacti_interface.h" #include "cacti/wire.h" // leakge power includes entire htree in a bank (when uca_tree == false) // leakge power includes only part to one bank when uca_tree == true -class interconnect : public Component { - public: - interconnect(string name_, enum Device_ty device_ty_, double base_w = 0, - double base_h = 0, int data_w = 0, double len = 0, - const InputParameter *configure_interface = NULL, - int start_wiring_level_ = 0, bool pipelinable_ = false, - double route_over_perc_ = 0.5, bool opt_local_ = true, - enum Core_type core_ty_ = Inorder, - enum Wire_type wire_model = Global, double width_s = 1.0, - double space_s = 1.0, - TechnologyParameter::DeviceType *dt = &(g_tp.peri_global)); +class interconnect : public Component +{ + public: + interconnect( + string name_, + enum Device_ty device_ty_, + double base_w =0, double base_h =0, int data_w =0, double len =0, + const InputParameter *configure_interface = NULL, int start_wiring_level_ =0, + bool pipelinable_ = false, + double route_over_perc_ =0.5, + bool opt_local_=true, + enum Core_type core_ty_=Inorder, + enum Wire_type wire_model=Global, + double width_s=1.0, double space_s=1.0, + TechnologyParameter::DeviceType *dt = &(g_tp.peri_global) + ); - ~interconnect(){}; + ~interconnect() {}; - void compute(); - string name; - enum Device_ty device_ty; - double in_rise_time, out_rise_time; - InputParameter l_ip; - uca_org_t local_result; - Area no_device_under_wire_area; - void set_in_rise_time(double rt) { in_rise_time = rt; } + void compute(); + string name; + enum Device_ty device_ty; + double in_rise_time, out_rise_time; + InputParameter l_ip; + uca_org_t local_result; + Area no_device_under_wire_area; + void set_in_rise_time(double rt) + { + in_rise_time = rt; + } + + void leakage_feedback(double temperature); + double max_unpipelined_link_delay; + powerDef power_bit; - void leakage_feedback(double temperature); - double max_unpipelined_link_delay; - powerDef power_bit; + double wire_bw; + double init_wire_bw; // bus width at root + double base_width; + double base_height; + int data_width; + enum Wire_type wt; + double width_scaling, space_scaling; + int start_wiring_level; + double length; + double min_w_nmos; + double min_w_pmos; + double latency, throughput; + bool latency_overflow; + bool throughput_overflow; + double interconnect_latency; + double interconnect_throughput; + bool opt_local; + enum Core_type core_ty; + bool pipelinable; + double route_over_perc; + int num_pipe_stages; - double wire_bw; - double init_wire_bw; // bus width at root - double base_width; - double base_height; - int data_width; - enum Wire_type wt; - double width_scaling, space_scaling; - int start_wiring_level; - double length; - double min_w_nmos; - double min_w_pmos; - double latency, throughput; - bool latency_overflow; - bool throughput_overflow; - double interconnect_latency; - double interconnect_throughput; - bool opt_local; - enum Core_type core_ty; - bool pipelinable; - double route_over_perc; - int num_pipe_stages; + private: + TechnologyParameter::DeviceType *deviceType; - private: - TechnologyParameter::DeviceType *deviceType; }; #endif + diff --git a/src/gpuwattch/iocontrollers.cc b/src/gpuwattch/iocontrollers.cc index 2425d40..7575cc9 100644 --- a/src/gpuwattch/iocontrollers.cc +++ b/src/gpuwattch/iocontrollers.cc @@ -29,18 +29,19 @@ * ***************************************************************************/ #include "io.h" -#include -#include -#include +#include "parameter.h" +#include "const.h" +#include "logic.h" +#include "cacti/basic_circuit.h" #include -#include +#include #include "XML_Parse.h" -#include "basic_components.h" -#include "cacti/basic_circuit.h" -#include "const.h" +#include +#include +#include #include "iocontrollers.h" -#include "logic.h" -#include "parameter.h" +#include "basic_components.h" + /* SUN Niagara 2 I/O power analysis: @@ -51,461 +52,390 @@ PCIe bits: (8 + 8)*2 = 32 Debug I/Os: 168 Other I/Os: 711- 32-32 - 384 - 168 = 95 -According to "Implementation of an 8-Core, 64-Thread, Power-Efficient SPARC -Server on a Chip" -90% of I/Os are SerDers (the calucaltion is 384+64/(711-168)=83% about the same -as the 90% reported in the paper) +According to "Implementation of an 8-Core, 64-Thread, Power-Efficient SPARC Server on a Chip" +90% of I/Os are SerDers (the calucaltion is 384+64/(711-168)=83% about the same as the 90% reported in the paper) --> around 80Pins are common I/Os. Common I/Os consumes 71mW/Gb/s according to Cadence ChipEstimate @65nm -Niagara 2 I/O clock is 1/4 of core clock. --> 87pin (<--((711-168)*17%)) * -71mW/Gb/s *0.25*1.4Ghz = 2.17W +Niagara 2 I/O clock is 1/4 of core clock. --> 87pin (<--((711-168)*17%)) * 71mW/Gb/s *0.25*1.4Ghz = 2.17W -Total dynamic power of FBDIMM, NIC, PCIe = 84*0.132 + 84*0.049*0.132 = 11.14 - -2.17 = 8.98 -Further, if assuming I/O logic power is about 50% of I/Os then Total energy of -FBDIMM, NIC, PCIe = 11.14 - 2.17*1.5 = 7.89 +Total dynamic power of FBDIMM, NIC, PCIe = 84*0.132 + 84*0.049*0.132 = 11.14 - 2.17 = 8.98 +Further, if assuming I/O logic power is about 50% of I/Os then Total energy of FBDIMM, NIC, PCIe = 11.14 - 2.17*1.5 = 7.89 */ /* - * A bug in Cadence ChipEstimator: After update the clock rate in the clock tab, - * a user - * need to re-select the IP clock (the same clk) and then click Estimate. if not - * reselect + * A bug in Cadence ChipEstimator: After update the clock rate in the clock tab, a user + * need to re-select the IP clock (the same clk) and then click Estimate. if not reselect * the new clock rate may not be propogate into the IPs. * */ -NIUController::NIUController(ParseXML* XML_interface, - InputParameter* interface_ip_) - : XML(XML_interface), interface_ip(*interface_ip_) { - local_result = init_interface(&interface_ip); - - double frontend_area, mac_area, SerDer_area; - double frontend_dyn, mac_dyn, SerDer_dyn; - double frontend_gates, mac_gates; - double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio(); - double NMOS_sizing, PMOS_sizing; - - set_niu_param(); - - if (niup.type == 0) // high performance NIU - { - // Area estimation based on average of die photo from Niagara 2 and Cadence - // ChipEstimate using 65nm. - mac_area = (1.53 + 0.3) / 2 * (interface_ip.F_sz_um / 0.065) * - (interface_ip.F_sz_um / 0.065); - // Area estimation based on average of die photo from Niagara 2, ISSCC "An - // 800mW 10Gb Ethernet Transceiver in 0.13μm CMOS" - // and"A 1.2-V-Only 900-mW 10 Gb Ethernet Transceiver and XAUI Interface - // With Robust VCO Tuning Technique" Frontend is PCS - frontend_area = (9.8 + (6 + 18) * 65 / 130 * 65 / 130) / 3 * - (interface_ip.F_sz_um / 0.065) * - (interface_ip.F_sz_um / 0.065); - // Area estimation based on average of die photo from Niagara 2 and Cadence - // ChipEstimate hard IP @65nm. - // SerDer is very hard to scale - SerDer_area = (1.39 + 0.36) * (interface_ip.F_sz_um / - 0.065); //* (interface_ip.F_sz_um/0.065); - // total area - area.set_area((mac_area + frontend_area + SerDer_area) * 1e6); - // Power - // Cadence ChipEstimate using 65nm (mac, front_end are all energy. E=P*T = - // P/F = 1.37/1Ghz = 1.37e-9); - mac_dyn = 2.19e-9 * g_tp.peri_global.Vdd / 1.1 * g_tp.peri_global.Vdd / - 1.1 * (interface_ip.F_sz_nm / 65.0); // niup.clockRate; - // //2.19W@1GHz fully active - // according to Cadence - // ChipEstimate @65nm - // Cadence ChipEstimate using 65nm soft IP; - frontend_dyn = 0.27e-9 * g_tp.peri_global.Vdd / 1.1 * g_tp.peri_global.Vdd / - 1.1 * (interface_ip.F_sz_nm / 65.0); // niup.clockRate; - // according to "A 100mW 9.6Gb/s Transceiver in 90nm CMOS..." ISSCC 2006 - // SerDer_dyn is power not energy, scaling from 10mw/Gb/s @90nm - SerDer_dyn = 0.01 * 10 * sqrt(interface_ip.F_sz_um / 0.09) * - g_tp.peri_global.Vdd / 1.2 * g_tp.peri_global.Vdd / 1.2; - SerDer_dyn /= - niup.clockRate; // covert to energy per clock cycle of whole NIU - - // Cadence ChipEstimate using 65nm - mac_gates = 111700; - frontend_gates = 320000; - NMOS_sizing = 5 * g_tp.min_w_nmos_; - PMOS_sizing = 5 * g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r; - - } else { // Low power implementations are mostly from Cadence ChipEstimator; - // Ignore the multiple IP effect - // ---When there are multiple IP (same kind or not) selected, Cadence - // ChipEstimator results are not - // a simple summation of all IPs. Ignore this effect - mac_area = - 0.24 * (interface_ip.F_sz_um / 0.065) * (interface_ip.F_sz_um / 0.065); - frontend_area = - 0.1 * (interface_ip.F_sz_um / 0.065) * - (interface_ip.F_sz_um / 0.065); // Frontend is the PCS layer - SerDer_area = - 0.35 * (interface_ip.F_sz_um / 0.065) * (interface_ip.F_sz_um / 0.065); - // Compare 130um implementation in "A 1.2-V-Only 900-mW 10 Gb Ethernet - // Transceiver and XAUI Interface With Robust VCO Tuning Technique" - // and the ChipEstimator XAUI PHY hard IP, confirm that even PHY can scale - // perfectly with the technology - // total area - area.set_area((mac_area + frontend_area + SerDer_area) * 1e6); - // Power - // Cadence ChipEstimate using 65nm (mac, front_end are all energy. E=P*T = - // P/F = 1.37/1Ghz = 1.37e-9); - mac_dyn = 1.257e-9 * g_tp.peri_global.Vdd / 1.1 * g_tp.peri_global.Vdd / - 1.1 * (interface_ip.F_sz_nm / 65.0); // niup.clockRate; - // //2.19W@1GHz fully active - // according to Cadence - // ChipEstimate @65nm - // Cadence ChipEstimate using 65nm soft IP; - frontend_dyn = 0.6e-9 * g_tp.peri_global.Vdd / 1.1 * g_tp.peri_global.Vdd / - 1.1 * (interface_ip.F_sz_nm / 65.0); // niup.clockRate; - // SerDer_dyn is power not energy, scaling from 216mw/10Gb/s @130nm - SerDer_dyn = 0.0216 * 10 * (interface_ip.F_sz_um / 0.13) * - g_tp.peri_global.Vdd / 1.2 * g_tp.peri_global.Vdd / 1.2; - SerDer_dyn /= - niup.clockRate; // covert to energy per clock cycle of whole NIU - - mac_gates = 111700; - frontend_gates = 52000; - - NMOS_sizing = g_tp.min_w_nmos_; - PMOS_sizing = g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r; - } - - power_t.readOp.dynamic = mac_dyn + frontend_dyn + SerDer_dyn; - power_t.readOp.leakage = - (mac_gates + frontend_gates + frontend_gates) * - cmos_Isub_leakage(NMOS_sizing, PMOS_sizing, 2, nand) * - g_tp.peri_global.Vdd; // unit W - double long_channel_device_reduction = - longer_channel_device_reduction(Uncore_device); - power_t.readOp.longer_channel_leakage = - power_t.readOp.leakage * long_channel_device_reduction; - power_t.readOp.gate_leakage = - (mac_gates + frontend_gates + frontend_gates) * - cmos_Ig_leakage(NMOS_sizing, PMOS_sizing, 2, nand) * - g_tp.peri_global.Vdd; // unit W +NIUController::NIUController(ParseXML *XML_interface,InputParameter* interface_ip_) +:XML(XML_interface), + interface_ip(*interface_ip_) + { + local_result = init_interface(&interface_ip); + + double frontend_area,mac_area, SerDer_area; + double frontend_dyn, mac_dyn, SerDer_dyn; + double frontend_gates, mac_gates; + double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio(); + double NMOS_sizing, PMOS_sizing; + + set_niu_param(); + + if (niup.type == 0) //high performance NIU + { + //Area estimation based on average of die photo from Niagara 2 and Cadence ChipEstimate using 65nm. + mac_area = (1.53 + 0.3)/2 * (interface_ip.F_sz_um/0.065)* (interface_ip.F_sz_um/0.065); + //Area estimation based on average of die photo from Niagara 2, ISSCC "An 800mW 10Gb Ethernet Transceiver in 0.13μm CMOS" + //and"A 1.2-V-Only 900-mW 10 Gb Ethernet Transceiver and XAUI Interface With Robust VCO Tuning Technique" Frontend is PCS + frontend_area = (9.8 + (6 + 18)*65/130*65/130)/3 * (interface_ip.F_sz_um/0.065)* (interface_ip.F_sz_um/0.065); + //Area estimation based on average of die photo from Niagara 2 and Cadence ChipEstimate hard IP @65nm. + //SerDer is very hard to scale + SerDer_area = (1.39 + 0.36) * (interface_ip.F_sz_um/0.065);//* (interface_ip.F_sz_um/0.065); + //total area + area.set_area((mac_area + frontend_area + SerDer_area)*1e6); + //Power + //Cadence ChipEstimate using 65nm (mac, front_end are all energy. E=P*T = P/F = 1.37/1Ghz = 1.37e-9); + mac_dyn = 2.19e-9*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0);//niup.clockRate; //2.19W@1GHz fully active according to Cadence ChipEstimate @65nm + //Cadence ChipEstimate using 65nm soft IP; + frontend_dyn = 0.27e-9*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0);//niup.clockRate; + //according to "A 100mW 9.6Gb/s Transceiver in 90nm CMOS..." ISSCC 2006 + //SerDer_dyn is power not energy, scaling from 10mw/Gb/s @90nm + SerDer_dyn = 0.01*10*sqrt(interface_ip.F_sz_um/0.09)*g_tp.peri_global.Vdd/1.2*g_tp.peri_global.Vdd/1.2; + SerDer_dyn /= niup.clockRate;//covert to energy per clock cycle of whole NIU + + //Cadence ChipEstimate using 65nm + mac_gates = 111700; + frontend_gates = 320000; + NMOS_sizing = 5*g_tp.min_w_nmos_; + PMOS_sizing = 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r; + + + } + else + {//Low power implementations are mostly from Cadence ChipEstimator; Ignore the multiple IP effect + // ---When there are multiple IP (same kind or not) selected, Cadence ChipEstimator results are not + // a simple summation of all IPs. Ignore this effect + mac_area = 0.24 * (interface_ip.F_sz_um/0.065)* (interface_ip.F_sz_um/0.065); + frontend_area = 0.1 * (interface_ip.F_sz_um/0.065)* (interface_ip.F_sz_um/0.065);//Frontend is the PCS layer + SerDer_area = 0.35 * (interface_ip.F_sz_um/0.065)* (interface_ip.F_sz_um/0.065); + //Compare 130um implementation in "A 1.2-V-Only 900-mW 10 Gb Ethernet Transceiver and XAUI Interface With Robust VCO Tuning Technique" + //and the ChipEstimator XAUI PHY hard IP, confirm that even PHY can scale perfectly with the technology + //total area + area.set_area((mac_area + frontend_area + SerDer_area)*1e6); + //Power + //Cadence ChipEstimate using 65nm (mac, front_end are all energy. E=P*T = P/F = 1.37/1Ghz = 1.37e-9); + mac_dyn = 1.257e-9*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0);//niup.clockRate; //2.19W@1GHz fully active according to Cadence ChipEstimate @65nm + //Cadence ChipEstimate using 65nm soft IP; + frontend_dyn = 0.6e-9*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0);//niup.clockRate; + //SerDer_dyn is power not energy, scaling from 216mw/10Gb/s @130nm + SerDer_dyn = 0.0216*10*(interface_ip.F_sz_um/0.13)*g_tp.peri_global.Vdd/1.2*g_tp.peri_global.Vdd/1.2; + SerDer_dyn /= niup.clockRate;//covert to energy per clock cycle of whole NIU + + mac_gates = 111700; + frontend_gates = 52000; + + NMOS_sizing = g_tp.min_w_nmos_; + PMOS_sizing = g_tp.min_w_nmos_*pmos_to_nmos_sizing_r; + + } + + power_t.readOp.dynamic = mac_dyn + frontend_dyn + SerDer_dyn; + power_t.readOp.leakage = (mac_gates + frontend_gates + frontend_gates)*cmos_Isub_leakage(NMOS_sizing, PMOS_sizing, 2, nand)*g_tp.peri_global.Vdd;//unit W + double long_channel_device_reduction = longer_channel_device_reduction(Uncore_device); + power_t.readOp.longer_channel_leakage = power_t.readOp.leakage * long_channel_device_reduction; + power_t.readOp.gate_leakage = (mac_gates + frontend_gates + frontend_gates)*cmos_Ig_leakage(NMOS_sizing, PMOS_sizing, 2, nand)*g_tp.peri_global.Vdd;//unit W + } + +void NIUController::computeEnergy(bool is_tdp) +{ + if (is_tdp) + { + + + power = power_t; + power.readOp.dynamic *= niup.duty_cycle; + + } + else + { + rt_power = power_t; + rt_power.readOp.dynamic *= niup.perc_load; + } } -void NIUController::computeEnergy(bool is_tdp) { - if (is_tdp) { - power = power_t; - power.readOp.dynamic *= niup.duty_cycle; - - } else { - rt_power = power_t; - rt_power.readOp.dynamic *= niup.perc_load; - } -} +void NIUController::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 << "NIU:" << endl; + cout << indent_str<< "Area = " << area.get_area()*1e-6<< " mm^2" << endl; + cout << indent_str << "Peak Dynamic = " << power.readOp.dynamic*niup.clockRate << " W" << endl; + cout << indent_str<< "Subthreshold Leakage = " + << (long_channel? power.readOp.longer_channel_leakage:power.readOp.leakage) <<" W" << endl; + //cout << indent_str<< "Subthreshold Leakage = " << power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str<< "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl; + cout << indent_str << "Runtime Dynamic = " << rt_power.readOp.dynamic*niup.clockRate << " W" << endl; + cout<sys.longer_channel_device; - - if (is_tdp) { - cout << "NIU:" << endl; - cout << indent_str << "Area = " << area.get_area() * 1e-6 << " mm^2" - << endl; - cout << indent_str - << "Peak Dynamic = " << power.readOp.dynamic * niup.clockRate << " W" - << endl; - cout << indent_str << "Subthreshold Leakage = " - << (long_channel ? power.readOp.longer_channel_leakage - : power.readOp.leakage) - << " W" << endl; - // cout << indent_str<< "Subthreshold Leakage = " << - // power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str << "Gate Leakage = " << power.readOp.gate_leakage << " W" - << endl; - cout << indent_str - << "Runtime Dynamic = " << rt_power.readOp.dynamic * niup.clockRate - << " W" << endl; - cout << endl; - } else { - } } -void NIUController::set_niu_param() { - niup.clockRate = XML->sys.niu.clockrate; - niup.clockRate *= 1e6; - niup.num_units = XML->sys.niu.number_units; - niup.duty_cycle = XML->sys.niu.duty_cycle; - niup.perc_load = XML->sys.niu.total_load_perc; - niup.type = XML->sys.niu.type; - // niup.executionTime = - //XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); +void NIUController::set_niu_param() +{ + niup.clockRate = XML->sys.niu.clockrate; + niup.clockRate *= 1e6; + niup.num_units = XML->sys.niu.number_units; + niup.duty_cycle = XML->sys.niu.duty_cycle; + niup.perc_load = XML->sys.niu.total_load_perc; + niup.type = XML->sys.niu.type; +// niup.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); } -PCIeController::PCIeController(ParseXML* XML_interface, - InputParameter* interface_ip_) - : XML(XML_interface), interface_ip(*interface_ip_) { - local_result = init_interface(&interface_ip); - double ctrl_area, SerDer_area; - double ctrl_dyn, SerDer_dyn; - double ctrl_gates, SerDer_gates; - double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio(); - double NMOS_sizing, PMOS_sizing; - - /* Assuming PCIe is bit-slice based architecture - * This is the reason for /8 in both area and power calculation - * to get per lane numbers - */ - - set_pcie_param(); - if (pciep.type == 0) // high performance NIU - { - // Area estimation based on average of die photo from Niagara 2 and Cadence - // ChipEstimate @ 65nm. - ctrl_area = (5.2 + 0.5) / 2 * (interface_ip.F_sz_um / 0.065) * - (interface_ip.F_sz_um / 0.065); - // Area estimation based on average of die photo from Niagara 2, and Cadence - // ChipEstimate @ 65nm. - // Area estimation based on average of die photo from Niagara 2 and Cadence - // ChipEstimate hard IP @65nm. - // SerDer is very hard to scale - SerDer_area = (3.03 + 0.36) * (interface_ip.F_sz_um / - 0.065); //* (interface_ip.F_sz_um/0.065); - // total area - // Power - // Cadence ChipEstimate using 65nm the controller includes everything: the - // PHY, the data link and transaction layer - ctrl_dyn = 3.75e-9 / 8 * g_tp.peri_global.Vdd / 1.1 * g_tp.peri_global.Vdd / - 1.1 * (interface_ip.F_sz_nm / 65.0); - // //Cadence ChipEstimate using 65nm soft IP; - // frontend_dyn = - //0.27e-9/8*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0); - // SerDer_dyn is power not energy, scaling from 10mw/Gb/s @90nm - SerDer_dyn = 0.01 * 4 * (interface_ip.F_sz_um / 0.09) * - g_tp.peri_global.Vdd / 1.2 * g_tp.peri_global.Vdd / - 1.2; // PCIe 2.0 max per lane speed is 4Gb/s - SerDer_dyn /= pciep.clockRate; // covert to energy per clock cycle - - // power_t.readOp.dynamic = (ctrl_dyn)*pciep.num_channels; - // Cadence ChipEstimate using 65nm - ctrl_gates = 900000 / 8 * pciep.num_channels; - // frontend_gates = 120000/8; - // SerDer_gates = 200000/8; - NMOS_sizing = 5 * g_tp.min_w_nmos_; - PMOS_sizing = 5 * g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r; - } else { - ctrl_area = - 0.412 * (interface_ip.F_sz_um / 0.065) * (interface_ip.F_sz_um / 0.065); - // Area estimation based on average of die photo from Niagara 2, and Cadence - // ChipEstimate @ 65nm. - SerDer_area = - 0.36 * (interface_ip.F_sz_um / 0.065) * (interface_ip.F_sz_um / 0.065); - // total area - // Power - // Cadence ChipEstimate using 65nm the controller includes everything: the - // PHY, the data link and transaction layer - ctrl_dyn = 2.21e-9 / 8 * g_tp.peri_global.Vdd / 1.1 * g_tp.peri_global.Vdd / - 1.1 * (interface_ip.F_sz_nm / 65.0); - // //Cadence ChipEstimate using 65nm soft IP; - // frontend_dyn = - //0.27e-9/8*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0); - // SerDer_dyn is power not energy, scaling from 10mw/Gb/s @90nm - SerDer_dyn = 0.01 * 4 * (interface_ip.F_sz_um / 0.09) * - g_tp.peri_global.Vdd / 1.2 * g_tp.peri_global.Vdd / - 1.2; // PCIe 2.0 max per lane speed is 4Gb/s - SerDer_dyn /= pciep.clockRate; // covert to energy per clock cycle - - // Cadence ChipEstimate using 65nm - ctrl_gates = 200000 / 8 * pciep.num_channels; - // frontend_gates = 120000/8; - SerDer_gates = 200000 / 8 * pciep.num_channels; - NMOS_sizing = g_tp.min_w_nmos_; - PMOS_sizing = g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r; - } - area.set_area(((ctrl_area + (pciep.withPHY ? SerDer_area : 0)) / 8 * - pciep.num_channels) * - 1e6); - power_t.readOp.dynamic = - (ctrl_dyn + (pciep.withPHY ? SerDer_dyn : 0)) * pciep.num_channels; - power_t.readOp.leakage = - (ctrl_gates + (pciep.withPHY ? SerDer_gates : 0)) * - cmos_Isub_leakage(NMOS_sizing, PMOS_sizing, 2, nand) * - g_tp.peri_global.Vdd; // unit W - double long_channel_device_reduction = - longer_channel_device_reduction(Uncore_device); - power_t.readOp.longer_channel_leakage = - power_t.readOp.leakage * long_channel_device_reduction; - power_t.readOp.gate_leakage = - (ctrl_gates + (pciep.withPHY ? SerDer_gates : 0)) * - cmos_Ig_leakage(NMOS_sizing, PMOS_sizing, 2, nand) * - g_tp.peri_global.Vdd; // unit W +PCIeController::PCIeController(ParseXML *XML_interface,InputParameter* interface_ip_) +:XML(XML_interface), + interface_ip(*interface_ip_) + { + local_result = init_interface(&interface_ip); + double ctrl_area, SerDer_area; + double ctrl_dyn, SerDer_dyn; + double ctrl_gates, SerDer_gates; + double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio(); + double NMOS_sizing, PMOS_sizing; + + /* Assuming PCIe is bit-slice based architecture + * This is the reason for /8 in both area and power calculation + * to get per lane numbers + */ + + set_pcie_param(); + if (pciep.type == 0) //high performance NIU + { + //Area estimation based on average of die photo from Niagara 2 and Cadence ChipEstimate @ 65nm. + ctrl_area = (5.2 + 0.5)/2 * (interface_ip.F_sz_um/0.065)* (interface_ip.F_sz_um/0.065); + //Area estimation based on average of die photo from Niagara 2, and Cadence ChipEstimate @ 65nm. + //Area estimation based on average of die photo from Niagara 2 and Cadence ChipEstimate hard IP @65nm. + //SerDer is very hard to scale + SerDer_area = (3.03 + 0.36) * (interface_ip.F_sz_um/0.065);//* (interface_ip.F_sz_um/0.065); + //total area + //Power + //Cadence ChipEstimate using 65nm the controller includes everything: the PHY, the data link and transaction layer + ctrl_dyn = 3.75e-9/8*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0); + // //Cadence ChipEstimate using 65nm soft IP; + // frontend_dyn = 0.27e-9/8*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0); + //SerDer_dyn is power not energy, scaling from 10mw/Gb/s @90nm + SerDer_dyn = 0.01*4*(interface_ip.F_sz_um/0.09)*g_tp.peri_global.Vdd/1.2*g_tp.peri_global.Vdd/1.2;//PCIe 2.0 max per lane speed is 4Gb/s + SerDer_dyn /= pciep.clockRate;//covert to energy per clock cycle + + //power_t.readOp.dynamic = (ctrl_dyn)*pciep.num_channels; + //Cadence ChipEstimate using 65nm + ctrl_gates = 900000/8*pciep.num_channels; + // frontend_gates = 120000/8; + // SerDer_gates = 200000/8; + NMOS_sizing = 5*g_tp.min_w_nmos_; + PMOS_sizing = 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r; + } + else + { + ctrl_area = 0.412 * (interface_ip.F_sz_um/0.065)* (interface_ip.F_sz_um/0.065); + //Area estimation based on average of die photo from Niagara 2, and Cadence ChipEstimate @ 65nm. + SerDer_area = 0.36 * (interface_ip.F_sz_um/0.065)* (interface_ip.F_sz_um/0.065); + //total area + //Power + //Cadence ChipEstimate using 65nm the controller includes everything: the PHY, the data link and transaction layer + ctrl_dyn = 2.21e-9/8*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0); + // //Cadence ChipEstimate using 65nm soft IP; + // frontend_dyn = 0.27e-9/8*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0); + //SerDer_dyn is power not energy, scaling from 10mw/Gb/s @90nm + SerDer_dyn = 0.01*4*(interface_ip.F_sz_um/0.09)*g_tp.peri_global.Vdd/1.2*g_tp.peri_global.Vdd/1.2;//PCIe 2.0 max per lane speed is 4Gb/s + SerDer_dyn /= pciep.clockRate;//covert to energy per clock cycle + + //Cadence ChipEstimate using 65nm + ctrl_gates = 200000/8*pciep.num_channels; + // frontend_gates = 120000/8; + SerDer_gates = 200000/8*pciep.num_channels; + NMOS_sizing = g_tp.min_w_nmos_; + PMOS_sizing = g_tp.min_w_nmos_*pmos_to_nmos_sizing_r; + + } + area.set_area(((ctrl_area + (pciep.withPHY? SerDer_area:0))/8*pciep.num_channels)*1e6); + power_t.readOp.dynamic = (ctrl_dyn + (pciep.withPHY? SerDer_dyn:0))*pciep.num_channels; + power_t.readOp.leakage = (ctrl_gates + (pciep.withPHY? SerDer_gates:0))*cmos_Isub_leakage(NMOS_sizing, PMOS_sizing, 2, nand)*g_tp.peri_global.Vdd;//unit W + double long_channel_device_reduction = longer_channel_device_reduction(Uncore_device); + power_t.readOp.longer_channel_leakage = power_t.readOp.leakage * long_channel_device_reduction; + power_t.readOp.gate_leakage = (ctrl_gates + (pciep.withPHY? SerDer_gates:0))*cmos_Ig_leakage(NMOS_sizing, PMOS_sizing, 2, nand)*g_tp.peri_global.Vdd;//unit W + } + +void PCIeController::computeEnergy(bool is_tdp) +{ + if (is_tdp) + { + + + power = power_t; + power.readOp.dynamic *= pciep.duty_cycle; + + } + else + { + rt_power = power_t; + rt_power.readOp.dynamic *= pciep.perc_load; + } } -void PCIeController::computeEnergy(bool is_tdp) { - if (is_tdp) { - power = power_t; - power.readOp.dynamic *= pciep.duty_cycle; +void PCIeController::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 << "PCIe:" << endl; + cout << indent_str<< "Area = " << area.get_area()*1e-6<< " mm^2" << endl; + cout << indent_str << "Peak Dynamic = " << power.readOp.dynamic*pciep.clockRate << " W" << endl; + cout << indent_str<< "Subthreshold Leakage = " + << (long_channel? power.readOp.longer_channel_leakage:power.readOp.leakage) <<" W" << endl; + //cout << indent_str<< "Subthreshold Leakage = " << power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str<< "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl; + cout << indent_str << "Runtime Dynamic = " << rt_power.readOp.dynamic*pciep.clockRate << " W" << endl; + cout<sys.longer_channel_device; - - if (is_tdp) { - cout << "PCIe:" << endl; - cout << indent_str << "Area = " << area.get_area() * 1e-6 << " mm^2" - << endl; - cout << indent_str - << "Peak Dynamic = " << power.readOp.dynamic * pciep.clockRate << " W" - << endl; - cout << indent_str << "Subthreshold Leakage = " - << (long_channel ? power.readOp.longer_channel_leakage - : power.readOp.leakage) - << " W" << endl; - // cout << indent_str<< "Subthreshold Leakage = " << - // power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str << "Gate Leakage = " << power.readOp.gate_leakage << " W" - << endl; - cout << indent_str - << "Runtime Dynamic = " << rt_power.readOp.dynamic * pciep.clockRate - << " W" << endl; - cout << endl; - } else { - } -} +void PCIeController::set_pcie_param() +{ + pciep.clockRate = XML->sys.pcie.clockrate; + pciep.clockRate *= 1e6; + pciep.num_units = XML->sys.pcie.number_units; + pciep.num_channels = XML->sys.pcie.num_channels; + pciep.duty_cycle = XML->sys.pcie.duty_cycle; + pciep.perc_load = XML->sys.pcie.total_load_perc; + pciep.type = XML->sys.pcie.type; + pciep.withPHY = XML->sys.pcie.withPHY; +// pciep.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); -void PCIeController::set_pcie_param() { - pciep.clockRate = XML->sys.pcie.clockrate; - pciep.clockRate *= 1e6; - pciep.num_units = XML->sys.pcie.number_units; - pciep.num_channels = XML->sys.pcie.num_channels; - pciep.duty_cycle = XML->sys.pcie.duty_cycle; - pciep.perc_load = XML->sys.pcie.total_load_perc; - pciep.type = XML->sys.pcie.type; - pciep.withPHY = XML->sys.pcie.withPHY; - // pciep.executionTime = - //XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); } -FlashController::FlashController(ParseXML* XML_interface, - InputParameter* interface_ip_) - : XML(XML_interface), interface_ip(*interface_ip_) { - local_result = init_interface(&interface_ip); - double ctrl_area, SerDer_area; - double ctrl_dyn, SerDer_dyn; - double ctrl_gates, SerDer_gates; - double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio(); - double NMOS_sizing, PMOS_sizing; - - /* Assuming PCIe is bit-slice based architecture - * This is the reason for /8 in both area and power calculation - * to get per lane numbers - */ - - set_fc_param(); - if (fcp.type == 0) // high performance NIU - { - cout << "Current McPAT does not support high performance flash contorller " - "since even low power designs are enough for maintain throughput" - << endl; - exit(0); - NMOS_sizing = 5 * g_tp.min_w_nmos_; - PMOS_sizing = 5 * g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r; - } else { - ctrl_area = - 0.243 * (interface_ip.F_sz_um / 0.065) * (interface_ip.F_sz_um / 0.065); - // Area estimation based on Cadence ChipEstimate @ 65nm: NANDFLASH-CTRL from - // CAST - SerDer_area = 0.36 / 8 * (interface_ip.F_sz_um / 0.065) * - (interface_ip.F_sz_um / 0.065); - // based On PCIe PHY TSMC65GP from Cadence ChipEstimate @ 65nm, it support - // 8x lanes with each lane - // speed up to 250MB/s (PCIe1.1x) This is already saturate the 200MB/s of - // the flash controller core above. - ctrl_gates = 129267; - SerDer_gates = 200000 / 8; - NMOS_sizing = g_tp.min_w_nmos_; - PMOS_sizing = g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r; - - // Power - // Cadence ChipEstimate using 65nm the controller 125mW for every 200MB/s - // This is power not energy! - ctrl_dyn = 0.125 * g_tp.peri_global.Vdd / 1.1 * g_tp.peri_global.Vdd / 1.1 * - (interface_ip.F_sz_nm / 65.0); - // SerDer_dyn is power not energy, scaling from 10mw/Gb/s @90nm - SerDer_dyn = 0.01 * 1.6 * (interface_ip.F_sz_um / 0.09) * - g_tp.peri_global.Vdd / 1.2 * g_tp.peri_global.Vdd / 1.2; - // max Per controller speed is 1.6Gb/s (200MB/s) - } - double number_channel = 1 + (fcp.num_channels - 1) * 0.2; - area.set_area((ctrl_area + (fcp.withPHY ? SerDer_area : 0)) * 1e6 * - number_channel); - power_t.readOp.dynamic = - (ctrl_dyn + (fcp.withPHY ? SerDer_dyn : 0)) * number_channel; - power_t.readOp.leakage = - ((ctrl_gates + (fcp.withPHY ? SerDer_gates : 0)) * number_channel) * - cmos_Isub_leakage(NMOS_sizing, PMOS_sizing, 2, nand) * - g_tp.peri_global.Vdd; // unit W - double long_channel_device_reduction = - longer_channel_device_reduction(Uncore_device); - power_t.readOp.longer_channel_leakage = - power_t.readOp.leakage * long_channel_device_reduction; - power_t.readOp.gate_leakage = - ((ctrl_gates + (fcp.withPHY ? SerDer_gates : 0)) * number_channel) * - cmos_Ig_leakage(NMOS_sizing, PMOS_sizing, 2, nand) * - g_tp.peri_global.Vdd; // unit W +FlashController::FlashController(ParseXML *XML_interface,InputParameter* interface_ip_) +:XML(XML_interface), + interface_ip(*interface_ip_) + { + local_result = init_interface(&interface_ip); + double ctrl_area, SerDer_area; + double ctrl_dyn, SerDer_dyn; + double ctrl_gates, SerDer_gates; + double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio(); + double NMOS_sizing, PMOS_sizing; + + /* Assuming PCIe is bit-slice based architecture + * This is the reason for /8 in both area and power calculation + * to get per lane numbers + */ + + set_fc_param(); + if (fcp.type == 0) //high performance NIU + { + cout<<"Current McPAT does not support high performance flash contorller since even low power designs are enough for maintain throughput"<sys.longer_channel_device; + + if (is_tdp) + { + cout << "Flash Controller:" << endl; + cout << indent_str<< "Area = " << area.get_area()*1e-6<< " mm^2" << endl; + cout << indent_str << "Peak Dynamic = " << power.readOp.dynamic << " W" << endl;//no multiply of clock since this is power already + cout << indent_str<< "Subthreshold Leakage = " + << (long_channel? power.readOp.longer_channel_leakage:power.readOp.leakage) <<" W" << endl; + //cout << indent_str<< "Subthreshold Leakage = " << power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str<< "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl; + cout << indent_str << "Runtime Dynamic = " << rt_power.readOp.dynamic << " W" << endl; + cout<sys.longer_channel_device; - - if (is_tdp) { - cout << "Flash Controller:" << endl; - cout << indent_str << "Area = " << area.get_area() * 1e-6 << " mm^2" - << endl; - cout << indent_str << "Peak Dynamic = " << power.readOp.dynamic << " W" - << endl; // no multiply of clock since this is power already - cout << indent_str << "Subthreshold Leakage = " - << (long_channel ? power.readOp.longer_channel_leakage - : power.readOp.leakage) - << " W" << endl; - // cout << indent_str<< "Subthreshold Leakage = " << - // power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str << "Gate Leakage = " << power.readOp.gate_leakage << " W" - << endl; - cout << indent_str << "Runtime Dynamic = " << rt_power.readOp.dynamic - << " W" << endl; - cout << endl; - } else { - } -} +void FlashController::set_fc_param() +{ +// fcp.clockRate = XML->sys.flashc.mc_clock; +// fcp.clockRate *= 1e6; + fcp.peakDataTransferRate = XML->sys.flashc.peak_transfer_rate; + fcp.num_channels = ceil(fcp.peakDataTransferRate/200); + fcp.num_mcs = XML->sys.flashc.number_mcs; + fcp.duty_cycle = XML->sys.flashc.duty_cycle; + fcp.perc_load = XML->sys.flashc.total_load_perc; + fcp.type = XML->sys.flashc.type; + fcp.withPHY = XML->sys.flashc.withPHY; +// flashcp.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); -void FlashController::set_fc_param() { - // fcp.clockRate = XML->sys.flashc.mc_clock; - // fcp.clockRate *= 1e6; - fcp.peakDataTransferRate = XML->sys.flashc.peak_transfer_rate; - fcp.num_channels = ceil(fcp.peakDataTransferRate / 200); - fcp.num_mcs = XML->sys.flashc.number_mcs; - fcp.duty_cycle = XML->sys.flashc.duty_cycle; - fcp.perc_load = XML->sys.flashc.total_load_perc; - fcp.type = XML->sys.flashc.type; - fcp.withPHY = XML->sys.flashc.withPHY; - // flashcp.executionTime = - //XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); } diff --git a/src/gpuwattch/iocontrollers.h b/src/gpuwattch/iocontrollers.h index 9d6c48a..68ddbcb 100644 --- a/src/gpuwattch/iocontrollers.h +++ b/src/gpuwattch/iocontrollers.h @@ -31,6 +31,7 @@ #ifndef IOCONTROLLERS_H_ #define IOCONTROLLERS_H_ + #endif /* IOCONTROLLERS_H_ */ #include "XML_Parse.h" @@ -42,43 +43,44 @@ #include "basic_components.h" class NIUController : public Component { - public: - ParseXML *XML; - InputParameter interface_ip; - NIUParam niup; - powerDef power_t; - uca_org_t local_result; - NIUController(ParseXML *XML_interface, InputParameter *interface_ip_); - void set_niu_param(); - void computeEnergy(bool is_tdp = true); - void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); - ~NIUController(){}; + public: + ParseXML *XML; + InputParameter interface_ip; + NIUParam niup; + powerDef power_t; + uca_org_t local_result; + NIUController(ParseXML *XML_interface,InputParameter* interface_ip_); + void set_niu_param(); + void computeEnergy(bool is_tdp=true); + void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); + ~NIUController(){}; }; class PCIeController : public Component { - public: - ParseXML *XML; - InputParameter interface_ip; - PCIeParam pciep; - powerDef power_t; - uca_org_t local_result; - PCIeController(ParseXML *XML_interface, InputParameter *interface_ip_); - void set_pcie_param(); - void computeEnergy(bool is_tdp = true); - void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); - ~PCIeController(){}; + public: + ParseXML *XML; + InputParameter interface_ip; + PCIeParam pciep; + powerDef power_t; + uca_org_t local_result; + PCIeController(ParseXML *XML_interface,InputParameter* interface_ip_); + void set_pcie_param(); + void computeEnergy(bool is_tdp=true); + void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); + ~PCIeController(){}; }; class FlashController : public Component { - public: - ParseXML *XML; - InputParameter interface_ip; - MCParam fcp; - powerDef power_t; - uca_org_t local_result; - FlashController(ParseXML *XML_interface, InputParameter *interface_ip_); - void set_fc_param(); - void computeEnergy(bool is_tdp = true); - void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); - ~FlashController(){}; + public: + ParseXML *XML; + InputParameter interface_ip; + MCParam fcp; + powerDef power_t; + uca_org_t local_result; + FlashController(ParseXML *XML_interface,InputParameter* interface_ip_); + void set_fc_param(); + void computeEnergy(bool is_tdp=true); + void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); + ~FlashController(){}; }; + diff --git a/src/gpuwattch/logic.cc b/src/gpuwattch/logic.cc index 65e3875..106b381 100644 --- a/src/gpuwattch/logic.cc +++ b/src/gpuwattch/logic.cc @@ -29,258 +29,217 @@ * ***************************************************************************/ /******************************************************************** -* Modified by: -** +* 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; - - 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 +//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; + } + +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 - - 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 - - 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; + //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; + + //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); + + 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); - - 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; + 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); + + 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; - 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); - - 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); +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); + + 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); - - 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); + 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); } -// 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); @@ -288,1089 +247,838 @@ 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); - - // 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; - ; - - /* 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) +void DFFCell::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 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;; + + /* 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) ); } -void Pipeline::compute() { - compute_stage_vector(); - DFFCell pipe_reg(false, WNANDn, WNANDp, load_per_pipeline_stage, &l_ip); - pipe_reg.compute_DFF_cell(); - - 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; +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(); - 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; - - } 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 - */ - - /* 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; - - 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; - } - } +void Pipeline::compute() +{ + compute_stage_vector(); + DFFCell pipe_reg(false, WNANDn,WNANDp, load_per_pipeline_stage, &l_ip); + pipe_reg.compute_DFF_cell(); + + 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); } -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: "<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 - - } 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 *= (g_tp.peri_global.Vdd * g_tp.peri_global.Vdd / 1.2 / 1.2); - - // 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: "<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; - } +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 { - cout << "Unknown Functional Unit Type" << endl; - exit(0); - } + 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; + + } + 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 */ + + /* 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; + + 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; + } } - // 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; - - } 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 "<sys.core[ithCore].ialu_accesses; - rtp_stats = stats_t; - // cout<<"ALU: --accesses "<sys.core[ithCore].mul_accesses; - rtp_stats = stats_t; - // cout<<"MUL: --accesses "<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 + + } + 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"<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 *=(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2); + + + //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: "<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"<sys.Embedded) + area.set_area(area.get_area()*macro_layout_overhead); +} - // rt_power.readOp.dynamic = base_energy*executionTime + - // energy*stats_t.readAc.access; +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; + + } + 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 "<sys.core[ithCore].ialu_accesses; + rtp_stats = stats_t; + //cout<<"ALU: --accesses "<sys.core[ithCore].mul_accesses; + rtp_stats = stats_t; + //cout<<"MUL: --accesses "<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) { - 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: "<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: "<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: "<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"<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); - } + 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"<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); + + + +// 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<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); - - // 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<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; - } } -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; - - 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; - - 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); - - 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); - - PredecBlkDrv *predec_blk_drv1 = new PredecBlkDrv(0, predec_blk1, false); - PredecBlkDrv *predec_blk_drv2 = new PredecBlkDrv(0, predec_blk2, false); - - pre_dec = new Predec(predec_blk_drv1, predec_blk_drv2); - - 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); - - inst_decoder_delay_power(); - double sckRation = g_tp.sckt_co_eff; - power.readOp.dynamic *= sckRation; - power.writeOp.dynamic *= sckRation; - power.searchOp.dynamic *= sckRation; +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 <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; +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; + + 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; + + 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); + + 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); + + PredecBlkDrv * predec_blk_drv1 = new PredecBlkDrv(0, predec_blk1, false); + PredecBlkDrv * predec_blk_drv2 = new PredecBlkDrv(0, predec_blk2, false); + + pre_dec = new Predec(predec_blk_drv1, predec_blk_drv2); + + 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); + + inst_decoder_delay_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; + } -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::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; +} +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; @@ -1378,20 +1086,19 @@ 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; } diff --git a/src/gpuwattch/logic.h b/src/gpuwattch/logic.h index df00837..406b249 100644 --- a/src/gpuwattch/logic.h +++ b/src/gpuwattch/logic.h @@ -29,8 +29,7 @@ * ***************************************************************************/ /******************************************************************** -* Modified by: -** +* Modified by: * * Jingwen Leng, Univeristy of Texas, Austin * * Syed Gilani, University of Wisconsin–Madison * * Tayler Hetherington, University of British Columbia * @@ -39,206 +38,203 @@ #ifndef LOGIC_H_ #define LOGIC_H_ -#include -#include -#include -#include -#include "XML_Parse.h" -#include "arch_const.h" +#include "cacti/const.h" +#include "cacti/component.h" #include "basic_components.h" #include "cacti/basic_circuit.h" #include "cacti/cacti_interface.h" -#include "cacti/component.h" -#include "cacti/const.h" #include "cacti/decoder.h" #include "cacti/parameter.h" #include "xmlParser.h" +#include "XML_Parse.h" +#include "arch_const.h" +#include +#include +#include +#include + using namespace std; -class selection_logic : public Component { - public: - selection_logic( - bool _is_default, int win_entries_, int issue_width_, - const InputParameter *configure_interface, - enum Device_ty device_ty_ = Core_device, - enum Core_type core_ty_ = Inorder); //, const ParseXML *_XML_interface); - bool is_default; - InputParameter l_ip; - uca_org_t local_result; - const ParseXML *XML_interface; - int win_entries; - int issue_width; - int num_threads; - enum Device_ty device_ty; - enum Core_type core_ty; - - void selection_power(); - void leakage_feedback(double temperature); // TODO +class selection_logic : public Component{ +public: + selection_logic(bool _is_default, int win_entries_, + int issue_width_, const InputParameter *configure_interface, + enum Device_ty device_ty_=Core_device, + enum Core_type core_ty_=Inorder);//, const ParseXML *_XML_interface); + bool is_default; + InputParameter l_ip; + uca_org_t local_result; + const ParseXML *XML_interface; + int win_entries; + int issue_width; + int num_threads; + enum Device_ty device_ty; + enum Core_type core_ty; + + void selection_power(); + void leakage_feedback(double temperature); // TODO }; -class dep_resource_conflict_check : public Component { - public: - dep_resource_conflict_check(const InputParameter *configure_interface, - const CoreDynParam &dyn_p_, int compare_bits_, - bool _is_default = true); - InputParameter l_ip; - uca_org_t local_result; - double WNORn, WNORp, Wevalinvp, Wevalinvn, Wcompn, Wcompp, Wcomppreequ; - CoreDynParam coredynp; - int compare_bits; - bool is_default; - statsDef tdp_stats; - statsDef rtp_stats; - statsDef stats_t; - powerDef power_t; - - void conflict_check_power(); - double compare_cap(); - ~dep_resource_conflict_check() { local_result.cleanup(); } - - void leakage_feedback(double temperature); +class dep_resource_conflict_check : public Component{ +public: + dep_resource_conflict_check(const InputParameter *configure_interface, const CoreDynParam & dyn_p_, int compare_bits_, bool _is_default=true); + InputParameter l_ip; + uca_org_t local_result; + double WNORn, WNORp, Wevalinvp, Wevalinvn, Wcompn, Wcompp, Wcomppreequ; + CoreDynParam coredynp; + int compare_bits; + bool is_default; + statsDef tdp_stats; + statsDef rtp_stats; + statsDef stats_t; + powerDef power_t; + + void conflict_check_power(); + double compare_cap(); + ~dep_resource_conflict_check(){ + local_result.cleanup(); + } + + void leakage_feedback(double temperature); }; -class inst_decoder : public Component { - public: - inst_decoder(bool _is_default, const InputParameter *configure_interface, - int opcode_length_, int num_decoders_, bool x86_, - enum Device_ty device_ty_ = Core_device, - enum Core_type core_ty_ = Inorder); - inst_decoder(); - bool is_default; - int opcode_length; - int num_decoders; - bool x86; - int num_decoder_segments; - int num_decoded_signals; - InputParameter l_ip; - uca_org_t local_result; - enum Device_ty device_ty; - enum Core_type core_ty; - - Decoder *final_dec; - Predec *pre_dec; - - statsDef tdp_stats; - statsDef rtp_stats; - statsDef stats_t; - powerDef power_t; - void inst_decoder_delay_power(); - ~inst_decoder(); - void leakage_feedback(double temperature); +class inst_decoder: public Component{ +public: + inst_decoder(bool _is_default, const InputParameter *configure_interface, + int opcode_length_, + int num_decoders_, + bool x86_, + enum Device_ty device_ty_=Core_device, + enum Core_type core_ty_=Inorder); + inst_decoder(); + bool is_default; + int opcode_length; + int num_decoders; + bool x86; + int num_decoder_segments; + int num_decoded_signals; + InputParameter l_ip; + uca_org_t local_result; + enum Device_ty device_ty; + enum Core_type core_ty; + + Decoder * final_dec; + Predec * pre_dec; + + statsDef tdp_stats; + statsDef rtp_stats; + statsDef stats_t; + powerDef power_t; + void inst_decoder_delay_power(); + ~inst_decoder(); + void leakage_feedback(double temperature); }; class DFFCell : public Component { - public: - DFFCell(bool _is_dram, double _WdecNANDn, double _WdecNANDp, - double _cell_load, const InputParameter *configure_interface); - InputParameter l_ip; - bool is_dram; - double cell_load; - double WdecNANDn; - double WdecNANDp; - double clock_cap; - int model; - int n_switch; - int n_keep_1; - int n_keep_0; - int n_clock; - powerDef e_switch; - powerDef e_keep_1; - powerDef e_keep_0; - powerDef e_clock; - - double fpfp_node_cap(unsigned int fan_in, unsigned int fan_out); - void compute_DFF_cell(void); -}; +public: + DFFCell(bool _is_dram, double _WdecNANDn, double _WdecNANDp,double _cell_load, + const InputParameter *configure_interface); + InputParameter l_ip; + bool is_dram; + double cell_load; + double WdecNANDn; + double WdecNANDp; + double clock_cap; + int model; + int n_switch; + int n_keep_1; + int n_keep_0; + int n_clock; + powerDef e_switch; + powerDef e_keep_1; + powerDef e_keep_0; + powerDef e_clock; + + double fpfp_node_cap(unsigned int fan_in, unsigned int fan_out); + void compute_DFF_cell(void); + }; + +class Pipeline : public Component{ +public: + Pipeline(const InputParameter *configure_interface, const CoreDynParam & dyn_p_, enum Device_ty device_ty_=Core_device, bool _is_core_pipeline=true, bool _is_default=true); + InputParameter l_ip; + uca_org_t local_result; + CoreDynParam coredynp; + enum Device_ty device_ty; + bool is_core_pipeline, is_default; + double num_piperegs; +// int pipeline_stages; +// int tot_stage_vector, per_stage_vector; + bool process_ind; + double WNANDn ; + double WNANDp; + double load_per_pipeline_stage; +// int Hthread, num_thread, fetchWidth, decodeWidth, issueWidth, commitWidth, instruction_length; +// int PC_width, opcode_length, num_arch_reg_tag, data_width,num_phsical_reg_tag, address_width; +// bool thread_clock_gated; +// bool in_order, multithreaded; + void compute_stage_vector(); + void compute(); + ~Pipeline(){ + local_result.cleanup(); + }; -class Pipeline : public Component { - public: - Pipeline(const InputParameter *configure_interface, - const CoreDynParam &dyn_p_, enum Device_ty device_ty_ = Core_device, - bool _is_core_pipeline = true, bool _is_default = true); - InputParameter l_ip; - uca_org_t local_result; - CoreDynParam coredynp; - enum Device_ty device_ty; - bool is_core_pipeline, is_default; - double num_piperegs; - // int pipeline_stages; - // int tot_stage_vector, per_stage_vector; - bool process_ind; - double WNANDn; - double WNANDp; - double load_per_pipeline_stage; - // int Hthread, num_thread, fetchWidth, decodeWidth, issueWidth, - //commitWidth, instruction_length; - // int PC_width, opcode_length, num_arch_reg_tag, - //data_width,num_phsical_reg_tag, address_width; - // bool thread_clock_gated; - // bool in_order, multithreaded; - void compute_stage_vector(); - void compute(); - ~Pipeline() { local_result.cleanup(); }; }; -// class core_pipeline :public pipeline{ -// public: -// int Hthread, num_thread, fetchWidth, decodeWidth, issueWidth, -//commitWidth, instruction_length; -// int PC_width, opcode_length, num_arch_reg_tag, -//data_width,num_phsical_reg_tag, address_width; +//class core_pipeline :public pipeline{ +//public: +// int Hthread, num_thread, fetchWidth, decodeWidth, issueWidth, commitWidth, instruction_length; +// int PC_width, opcode_length, num_arch_reg_tag, data_width,num_phsical_reg_tag, address_width; // bool thread_clock_gated; // bool in_order, multithreaded; -// core_pipeline(bool _is_default, const InputParameter -//*configure_interface); +// core_pipeline(bool _is_default, const InputParameter *configure_interface); // virtual void compute_stage_vector(); // //}; -class FunctionalUnit : public Component { - public: - ParseXML *XML; - int ithCore; - InputParameter interface_ip; - CoreDynParam coredynp; - double FU_height; - double clockRate, executionTime; - double num_fu; - double energy, base_energy, per_access_energy, leakage, gate_leakage; - bool is_default; - enum FU_type fu_type; - statsDef tdp_stats; - statsDef rtp_stats; - statsDef stats_t; - powerDef power_t; - - FunctionalUnit(ParseXML *XML_interface, int ithCore_, - InputParameter *interface_ip_, const CoreDynParam &dyn_p_, - enum FU_type fu_type, double exClockRate); - void computeEnergy(bool is_tdp = true); - void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); - void leakage_feedback(double temperature); +class FunctionalUnit :public Component{ +public: + ParseXML *XML; + int ithCore; + InputParameter interface_ip; + CoreDynParam coredynp; + double FU_height; + double clockRate,executionTime; + double num_fu; + double energy, base_energy,per_access_energy, leakage, gate_leakage; + bool is_default; + enum FU_type fu_type; + statsDef tdp_stats; + statsDef rtp_stats; + statsDef stats_t; + powerDef power_t; + + FunctionalUnit(ParseXML *XML_interface, int ithCore_, InputParameter* interface_ip_,const CoreDynParam & dyn_p_, enum FU_type fu_type, double exClockRate); + void computeEnergy(bool is_tdp=true); + void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); + void leakage_feedback(double temperature); + }; -class UndiffCore : public Component { - public: - UndiffCore(ParseXML *XML_interface, int ithCore_, - InputParameter *interface_ip_, const CoreDynParam &dyn_p_, - bool exist_ = true, bool embedded_ = false); - ParseXML *XML; - int ithCore; - InputParameter interface_ip; - CoreDynParam coredynp; - double clockRate, executionTime; - double scktRatio, chip_PR_overhead, macro_PR_overhead; - enum Core_type core_ty; - bool opt_performance, embedded; - double pipeline_stage, num_hthreads, issue_width; - bool is_default; - - void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); - ~UndiffCore(){}; - bool exist; +class UndiffCore :public Component{ +public: + UndiffCore(ParseXML* XML_interface, int ithCore_, InputParameter* interface_ip_, const CoreDynParam & dyn_p_, bool exist_=true, bool embedded_=false); + ParseXML *XML; + int ithCore; + InputParameter interface_ip; + CoreDynParam coredynp; + double clockRate,executionTime; + double scktRatio, chip_PR_overhead, macro_PR_overhead; + enum Core_type core_ty; + bool opt_performance, embedded; + double pipeline_stage,num_hthreads,issue_width; + bool is_default; + + void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); + ~UndiffCore(){}; + bool exist; + + }; #endif /* LOGIC_H_ */ diff --git a/src/gpuwattch/main.cc b/src/gpuwattch/main.cc index 03d3e7c..c370e32 100644 --- a/src/gpuwattch/main.cc +++ b/src/gpuwattch/main.cc @@ -28,68 +28,74 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.” * ***************************************************************************/ +#include "io.h" #include +#include "xmlParser.h" #include "XML_Parse.h" -#include "globalvar.h" -#include "io.h" #include "processor.h" +#include "globalvar.h" #include "version.h" -#include "xmlParser.h" + using namespace std; -void print_usage(char *argv0); +void print_usage(char * argv0); + +int main(int argc,char *argv[]) +{ + char * fb ; + bool infile_specified = false; + int plevel = 2; + opt_for_clk =true; + //cout.precision(10); + if (argc <= 1 || argv[1] == string("-h") || argv[1] == string("--help")) + { + print_usage(argv[0]); + } -int main(int argc, char *argv[]) { - char *fb; - bool infile_specified = false; - int plevel = 2; - opt_for_clk = true; - // cout.precision(10); - if (argc <= 1 || argv[1] == string("-h") || argv[1] == string("--help")) { - print_usage(argv[0]); - } + for (int32_t i = 0; i < argc; i++) + { + if (argv[i] == string("-infile")) + { + infile_specified = true; + i++; + fb = argv[ i]; + } - for (int32_t i = 0; i < argc; i++) { - if (argv[i] == string("-infile")) { - infile_specified = true; - i++; - fb = argv[i]; - } + if (argv[i] == string("-print_level")) + { + i++; + plevel = atoi(argv[i]); + } - if (argv[i] == string("-print_level")) { - i++; - plevel = atoi(argv[i]); - } + if (argv[i] == string("-opt_for_clk")) + { + i++; + opt_for_clk = (bool)atoi(argv[i]); + } + } + if (infile_specified == false) + { + print_usage(argv[0]); + } - if (argv[i] == string("-opt_for_clk")) { - i++; - opt_for_clk = (bool)atoi(argv[i]); - } - } - if (infile_specified == false) { - print_usage(argv[0]); - } - cout << "McPAT (version " << VER_MAJOR << "." << VER_MINOR << " of " - << VER_UPDATE << ") is computing the target processor...\n " << endl; + cout<<"McPAT (version "<< VER_MAJOR <<"."<< VER_MINOR + << " of " << VER_UPDATE << ") is computing the target processor...\n "<parse(fb); - Processor proc(p1); - proc.displayEnergy(2, plevel); - delete p1; - return 0; + //parse XML-based interface + ParseXML *p1= new ParseXML(); + p1->parse(fb); + Processor proc(p1); + proc.displayEnergy(2, plevel); + delete p1; + return 0; } -void print_usage(char *argv0) { - cerr << "How to use McPAT:" << endl; - cerr << " mcpat -infile -print_level < level of details " - "0~5 > -opt_for_clk < 0 (optimize for ED^2P only)/1 (optimzed for " - "target clock rate)>" - << endl; - // cerr << " Note:default print level is at processor level, please - // increase it to see the details" << endl; - exit(1); +void print_usage(char * argv0) +{ + cerr << "How to use McPAT:" << endl; + cerr << " mcpat -infile -print_level < level of details 0~5 > -opt_for_clk < 0 (optimize for ED^2P only)/1 (optimzed for target clock rate)>"<< endl; + //cerr << " Note:default print level is at processor level, please increase it to see the details" << endl; + exit(1); } diff --git a/src/gpuwattch/memoryctrl.cc b/src/gpuwattch/memoryctrl.cc index 07e2f77..f13c695 100644 --- a/src/gpuwattch/memoryctrl.cc +++ b/src/gpuwattch/memoryctrl.cc @@ -29,8 +29,7 @@ * ***************************************************************************/ /******************************************************************** -* Modified by: -** +* Modified by: * * Jingwen Leng, Univeristy of Texas, Austin * * Syed Gilani, University of Wisconsin–Madison * * Tayler Hetherington, University of British Columbia * @@ -52,1241 +51,944 @@ #include "basic_components.h" // clang-format on /* overview of MC models: - * McPAT memory controllers are modeled according to large number of industrial - * data points. + * McPAT memory controllers are modeled according to large number of industrial data points. * The Basic memory controller architecture is base on the Synopsis designs - * (DesignWare DDR2/DDR3-Lite memory controllers and DDR2/DDR3-Lite protocol - * controllers) + * (DesignWare DDR2/DDR3-Lite memory controllers and DDR2/DDR3-Lite protocol controllers) * as in Cadence ChipEstimator Tool * - * An MC has 3 parts as shown in this design. McPAT models both high performance - * MC - * based on Niagara processor designs and curving and low power MC based on data - * points in + * An MC has 3 parts as shown in this design. McPAT models both high performance MC + * based on Niagara processor designs and curving and low power MC based on data points in * Cadence ChipEstimator Tool. * - * The frontend is modeled analytically, the backend is modeled empirically - * according to + * The frontend is modeled analytically, the backend is modeled empirically according to * DDR2/DDR3-Lite protocol controllers in Cadence ChipEstimator Tool * The PHY is modeled based on - * "A 100mW 9.6Gb/s Transceiver in 90nm CMOS for next-generation memory - * interfaces ," ISSCC 2006, - * and A 14mW 6.25Gb/s Transceiver in 90nm CMOS for Serial Chip-to-Chip - * Communication," ISSCC 2007 + * "A 100mW 9.6Gb/s Transceiver in 90nm CMOS for next-generation memory interfaces ," ISSCC 2006, + * and A 14mW 6.25Gb/s Transceiver in 90nm CMOS for Serial Chip-to-Chip Communication," ISSCC 2007 * - * In Cadence ChipEstimator Tool there are two types of memory controllers: the - * full memory controllers - * that includes the frontend as the DesignWare DDR2/DDR3-Lite memory - * controllers and the backend only - * memory controllers as the DDR2/DDR3-Lite protocol controllers (except - * DesignWare DDR2/DDR3-Lite memory - * controllers, all memory controller IP in Cadence ChipEstimator Tool are - * backend memory controllers such as - * DDRC 1600A and DDRC 800A). Thus,to some extend the area and power difference - * between DesignWare - * DDR2/DDR3-Lite memory controllers and DDR2/DDR3-Lite protocol controllers can - * be an estimation to the - * frontend power and area, which is very close the analitically modeled results - * of the frontend for Niagara2@65nm + * In Cadence ChipEstimator Tool there are two types of memory controllers: the full memory controllers + * that includes the frontend as the DesignWare DDR2/DDR3-Lite memory controllers and the backend only + * memory controllers as the DDR2/DDR3-Lite protocol controllers (except DesignWare DDR2/DDR3-Lite memory + * controllers, all memory controller IP in Cadence ChipEstimator Tool are backend memory controllers such as + * DDRC 1600A and DDRC 800A). Thus,to some extend the area and power difference between DesignWare + * DDR2/DDR3-Lite memory controllers and DDR2/DDR3-Lite protocol controllers can be an estimation to the + * frontend power and area, which is very close the analitically modeled results of the frontend for Niagara2@65nm * */ -MCBackend::MCBackend(InputParameter* interface_ip_, const MCParam& mcp_, - enum MemoryCtrl_type mc_type_) - : l_ip(*interface_ip_), mc_type(mc_type_), mcp(mcp_) { +MCBackend::MCBackend(InputParameter* interface_ip_, const MCParam & mcp_, enum MemoryCtrl_type mc_type_) +:l_ip(*interface_ip_), + mc_type(mc_type_), + mcp(mcp_) +{ + local_result = init_interface(&l_ip); compute(); + } -void MCBackend::compute() { - // double max_row_addr_width = 20.0;//Current address 12~18bits - double C_MCB, mc_power, backend_dyn, - backend_gates; //, refresh_period,refresh_freq;//Equivalent per bit Cap - //for backend, + +void MCBackend::compute() +{ + //double max_row_addr_width = 20.0;//Current address 12~18bits + double C_MCB, mc_power, backend_dyn, backend_gates;//, refresh_period,refresh_freq;//Equivalent per bit Cap for backend, double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio(); double NMOS_sizing, PMOS_sizing; - if (mc_type == MC) { - if (mcp.type == 0) { - // area = - // (2.2927*log(peakDataTransferRate)-14.504)*memDataWidth/144.0*(l_ip.F_sz_um/0.09); - area.set_area((2.7927 * log(mcp.peakDataTransferRate * 2) - 19.862) / - 2.0 * mcp.dataBusWidth / 128.0 * (l_ip.F_sz_um / 0.09) * - mcp.num_channels * 1e6); // um^2 - // assuming the approximately same scaling factor as seen in processors. - // C_MCB=0.2/1.3/1.3/266/64/0.09*g_ip.F_sz_um;//based on AMD Geode - // processor which has a very basic mc on chip. - // C_MCB = 1.6/200/1e6/144/1.2/1.2*g_ip.F_sz_um/0.19;//Based on Niagara - // power numbers.The base power (W) is divided by device frequency and vdd - // and scale to target process. - // mc_power = 0.0291*2;//29.1mW@200MHz @130nm From Power Analysis of - // SystemLevel OnChip Communication Architectures by Lahiri et - mc_power = - 4.32 * - 0.1; // 4.32W@1GhzMHz @65nm Cadence ChipEstimator 10% for backend - C_MCB = mc_power / 1e9 / 72 / 1.1 / 1.1 * l_ip.F_sz_um / 0.065; - power_t.readOp.dynamic = - C_MCB * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd * - (mcp.dataBusWidth /*+mcp.addressBusWidth*/); // per access energy in - // memory controller - power_t.readOp.leakage = - area.get_area() / 2 * (g_tp.scaling_factor.core_tx_density) * - cmos_Isub_leakage(g_tp.min_w_nmos_, - g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r, 1, inv) * - g_tp.peri_global.Vdd; // unit W - power_t.readOp.gate_leakage = - area.get_area() / 2 * (g_tp.scaling_factor.core_tx_density) * - cmos_Ig_leakage(g_tp.min_w_nmos_, - g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r, 1, inv) * - g_tp.peri_global.Vdd; // unit W - - } else { - NMOS_sizing = g_tp.min_w_nmos_; - PMOS_sizing = g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r; - area.set_area(0.15 * mcp.dataBusWidth / 72.0 * (l_ip.F_sz_um / 0.065) * - (l_ip.F_sz_um / 0.065) * mcp.num_channels * 1e6); // um^2 - backend_dyn = 0.9e-9 / 800e6 * mcp.clockRate / 12800 * - mcp.peakDataTransferRate * mcp.dataBusWidth / 72.0 * - g_tp.peri_global.Vdd / 1.1 * g_tp.peri_global.Vdd / 1.1 * - (l_ip.F_sz_nm / 65.0); // Average on DDR2/3 protocol - // controller and DDRC 1600/800A in - // Cadence ChipEstimate - // Scaling to technology and DIMM feature. The base IP support - // DDR3-1600(PC3 12800) - backend_gates = 50000 * mcp.dataBusWidth / - 64.0; // 5000 is from Cadence ChipEstimator - - power_t.readOp.dynamic = backend_dyn; - power_t.readOp.leakage = - (backend_gates)*cmos_Isub_leakage(NMOS_sizing, PMOS_sizing, 2, nand) * - g_tp.peri_global.Vdd; // unit W - power_t.readOp.gate_leakage = - (backend_gates)*cmos_Ig_leakage(NMOS_sizing, PMOS_sizing, 2, nand) * - g_tp.peri_global.Vdd; // unit W - } - } else { // skip old model - cout << "Unknown memory controllers" << endl; - exit(0); - area.set_area(0.243 * mcp.dataBusWidth / - 8); // area based on Cadence ChipEstimator for 8bit bus - // mc_power = 4.32*0.1;//4.32W@1GhzMHz @65nm Cadence ChipEstimator 10% for - // backend - C_MCB = mc_power / 1e9 / 72 / 1.1 / 1.1 * l_ip.F_sz_um / 0.065; - power_t.readOp.leakage = - area.get_area() / 2 * (g_tp.scaling_factor.core_tx_density) * - cmos_Isub_leakage(g_tp.min_w_nmos_, - g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r, 1, inv) * - g_tp.peri_global.Vdd; // unit W - power_t.readOp.gate_leakage = - area.get_area() / 2 * (g_tp.scaling_factor.core_tx_density) * - cmos_Ig_leakage(g_tp.min_w_nmos_, - g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r, 1, inv) * - g_tp.peri_global.Vdd; // unit W - power_t.readOp.dynamic *= 1.2; - power_t.readOp.leakage *= 1.2; - power_t.readOp.gate_leakage *= 1.2; - // flash controller has about 20% more backend power since BCH ECC in flash - // is complex and power hungry + if (mc_type == MC) + { + if (mcp.type == 0) + { + //area = (2.2927*log(peakDataTransferRate)-14.504)*memDataWidth/144.0*(l_ip.F_sz_um/0.09); + area.set_area((2.7927*log(mcp.peakDataTransferRate*2)-19.862)/2.0*mcp.dataBusWidth/128.0*(l_ip.F_sz_um/0.09)*mcp.num_channels*1e6);//um^2 + //assuming the approximately same scaling factor as seen in processors. + //C_MCB=0.2/1.3/1.3/266/64/0.09*g_ip.F_sz_um;//based on AMD Geode processor which has a very basic mc on chip. + //C_MCB = 1.6/200/1e6/144/1.2/1.2*g_ip.F_sz_um/0.19;//Based on Niagara power numbers.The base power (W) is divided by device frequency and vdd and scale to target process. + //mc_power = 0.0291*2;//29.1mW@200MHz @130nm From Power Analysis of SystemLevel OnChip Communication Architectures by Lahiri et + mc_power = 4.32*0.1;//4.32W@1GhzMHz @65nm Cadence ChipEstimator 10% for backend + C_MCB = mc_power/1e9/72/1.1/1.1*l_ip.F_sz_um/0.065; + power_t.readOp.dynamic = C_MCB*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(mcp.dataBusWidth/*+mcp.addressBusWidth*/);//per access energy in memory controller + power_t.readOp.leakage = area.get_area()/2 *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(g_tp.min_w_nmos_, g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd;//unit W + power_t.readOp.gate_leakage = area.get_area()/2 *(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(g_tp.min_w_nmos_, g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd;//unit W + + } + else + { NMOS_sizing = g_tp.min_w_nmos_; + PMOS_sizing = g_tp.min_w_nmos_*pmos_to_nmos_sizing_r; + area.set_area(0.15*mcp.dataBusWidth/72.0*(l_ip.F_sz_um/0.065)* (l_ip.F_sz_um/0.065)*mcp.num_channels*1e6);//um^2 + backend_dyn = 0.9e-9/800e6*mcp.clockRate/12800*mcp.peakDataTransferRate*mcp.dataBusWidth/72.0*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(l_ip.F_sz_nm/65.0);//Average on DDR2/3 protocol controller and DDRC 1600/800A in Cadence ChipEstimate + //Scaling to technology and DIMM feature. The base IP support DDR3-1600(PC3 12800) + backend_gates = 50000*mcp.dataBusWidth/64.0;//5000 is from Cadence ChipEstimator + + power_t.readOp.dynamic = backend_dyn; + power_t.readOp.leakage = (backend_gates)*cmos_Isub_leakage(NMOS_sizing, PMOS_sizing, 2, nand)*g_tp.peri_global.Vdd;//unit W + power_t.readOp.gate_leakage = (backend_gates)*cmos_Ig_leakage(NMOS_sizing, PMOS_sizing, 2, nand)*g_tp.peri_global.Vdd;//unit W + + } } - double long_channel_device_reduction = - longer_channel_device_reduction(Uncore_device); - power_t.readOp.longer_channel_leakage = - power_t.readOp.leakage * long_channel_device_reduction; + else + {//skip old model + cout<<"Unknown memory controllers"<sys.physical_address_width + mcp.opcodeW) / 8.0)); - interface_ip.cache_sz = data * XML->sys.mc.req_window_size_per_channel; - interface_ip.line_sz = data; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.access_mode = 0; - interface_ip.throughput = 1.0 / mcp.clockRate; - interface_ip.latency = 1.0 / mcp.clockRate; - interface_ip.is_cache = true; - interface_ip.pure_cam = false; - interface_ip.pure_ram = false; + //memory request reorder buffer + tag = mcp.addressBusWidth + EXTRA_TAG_BITS + mcp.opcodeW; + data = int(ceil((XML->sys.physical_address_width + mcp.opcodeW)/8.0)); + interface_ip.cache_sz = data*XML->sys.mc.req_window_size_per_channel; + interface_ip.line_sz = data; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.access_mode = 0; + interface_ip.throughput = 1.0/mcp.clockRate; + interface_ip.latency = 1.0/mcp.clockRate; + interface_ip.is_cache = true; + interface_ip.pure_cam = false; + interface_ip.pure_ram = false; interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = XML->sys.mc.memory_channels_per_mc; - interface_ip.num_wr_ports = interface_ip.num_rd_ports; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = XML->sys.mc.memory_channels_per_mc; - frontendBuffer = - new ArrayST(&interface_ip, "MC ReorderBuffer", Uncore_device); - frontendBuffer->area.set_area(frontendBuffer->area.get_area() + - frontendBuffer->local_result.area * - XML->sys.mc.memory_channels_per_mc); - area.set_area(area.get_area() + - frontendBuffer->local_result.area * - XML->sys.mc.memory_channels_per_mc); - - // selection and arbitration logic - MC_arb = - new selection_logic(is_default, XML->sys.mc.req_window_size_per_channel, - 1, &interface_ip, Uncore_device); - - // read buffers. - data = (int)ceil(mcp.dataBusWidth / 8.0); // Support key words first - // operation //8 means converting - // bit to Byte - interface_ip.cache_sz = - data * XML->sys.mc.IO_buffer_size_per_channel; //*llcBlockSize; - interface_ip.line_sz = data; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 1; - interface_ip.throughput = 1.0 / mcp.clockRate; - interface_ip.latency = 2.0 / mcp.clockRate; - interface_ip.is_cache = false; - interface_ip.pure_cam = false; - interface_ip.pure_ram = true; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = XML->sys.mc.memory_channels_per_mc; + interface_ip.num_wr_ports = interface_ip.num_rd_ports; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = XML->sys.mc.memory_channels_per_mc; + frontendBuffer = new ArrayST(&interface_ip, "MC ReorderBuffer", Uncore_device); + frontendBuffer->area.set_area(frontendBuffer->area.get_area()+ frontendBuffer->local_result.area*XML->sys.mc.memory_channels_per_mc); + area.set_area(area.get_area()+ frontendBuffer->local_result.area*XML->sys.mc.memory_channels_per_mc); + + //selection and arbitration logic + MC_arb = new selection_logic(is_default, XML->sys.mc.req_window_size_per_channel,1,&interface_ip, Uncore_device); + + //read buffers. + data = (int)ceil(mcp.dataBusWidth/8.0);//Support key words first operation //8 means converting bit to Byte + interface_ip.cache_sz = data*XML->sys.mc.IO_buffer_size_per_channel;//*llcBlockSize; + interface_ip.line_sz = data; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 1; + interface_ip.throughput = 1.0/mcp.clockRate; + interface_ip.latency = 2.0/mcp.clockRate; + interface_ip.is_cache = false; + interface_ip.pure_cam = false; + interface_ip.pure_ram = true; interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = - 0; // XML->sys.mc.memory_channels_per_mc*2>2?2:XML->sys.mc.memory_channels_per_mc*2; - interface_ip.num_rd_ports = XML->sys.mc.memory_channels_per_mc; - interface_ip.num_wr_ports = interface_ip.num_rd_ports; - interface_ip.num_se_rd_ports = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0;//XML->sys.mc.memory_channels_per_mc*2>2?2:XML->sys.mc.memory_channels_per_mc*2; + interface_ip.num_rd_ports = XML->sys.mc.memory_channels_per_mc; + interface_ip.num_wr_ports = interface_ip.num_rd_ports; + interface_ip.num_se_rd_ports = 0; readBuffer = new ArrayST(&interface_ip, "MC ReadBuffer", Uncore_device); - readBuffer->area.set_area(readBuffer->area.get_area() + - readBuffer->local_result.area * - XML->sys.mc.memory_channels_per_mc); - area.set_area(area.get_area() + - readBuffer->local_result.area * - XML->sys.mc.memory_channels_per_mc); - - // write buffer - data = (int)ceil(mcp.dataBusWidth / 8.0); // Support key words first - // operation //8 means converting - // bit to Byte - interface_ip.cache_sz = - data * XML->sys.mc.IO_buffer_size_per_channel; //*llcBlockSize; - interface_ip.line_sz = data; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 0; - interface_ip.throughput = 1.0 / mcp.clockRate; - interface_ip.latency = 2.0 / mcp.clockRate; + readBuffer->area.set_area(readBuffer->area.get_area()+ readBuffer->local_result.area*XML->sys.mc.memory_channels_per_mc); + area.set_area(area.get_area()+ readBuffer->local_result.area*XML->sys.mc.memory_channels_per_mc); + + //write buffer + data = (int)ceil(mcp.dataBusWidth/8.0);//Support key words first operation //8 means converting bit to Byte + interface_ip.cache_sz = data*XML->sys.mc.IO_buffer_size_per_channel;//*llcBlockSize; + interface_ip.line_sz = data; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 0; + interface_ip.throughput = 1.0/mcp.clockRate; + interface_ip.latency = 2.0/mcp.clockRate; interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = XML->sys.mc.memory_channels_per_mc; - interface_ip.num_wr_ports = interface_ip.num_rd_ports; - interface_ip.num_se_rd_ports = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = XML->sys.mc.memory_channels_per_mc; + interface_ip.num_wr_ports = interface_ip.num_rd_ports; + interface_ip.num_se_rd_ports = 0; writeBuffer = new ArrayST(&interface_ip, "MC writeBuffer", Uncore_device); - writeBuffer->area.set_area(writeBuffer->area.get_area() + - writeBuffer->local_result.area * - XML->sys.mc.memory_channels_per_mc); - area.set_area(area.get_area() + - writeBuffer->local_result.area * - XML->sys.mc.memory_channels_per_mc); - - // SRAM structures for memory coalescing --Syed Gilani - // Pending Request Table (base addresses, offset addresses, threads IDs), - // Thread Masks + writeBuffer->area.set_area(writeBuffer->area.get_area()+ writeBuffer->local_result.area*XML->sys.mc.memory_channels_per_mc); + area.set_area(area.get_area()+ writeBuffer->local_result.area*XML->sys.mc.memory_channels_per_mc); + + //SRAM structures for memory coalescing --Syed Gilani + //Pending Request Table (base addresses, offset addresses, threads IDs), Thread Masks //***PRT - // We assume 24 bits of base address and 8 bits of offset address. - // THese values are used for coalesing memory requests to the same base - // address block. - // TIDs are assumed to be 8 bits - /*Contents of each PRT entry - * - * Warp ID (6 bits) | Memory address (32 bits) per thread | Request Size - * (2-bits) per thread | - * line size= 6+ 32*16 + 2*16 ~ 64 bytes - * - * - */ - data = - 64; // Support key words first operation //8 means converting bit to Byte - interface_ip.cache_sz = data * XML->sys.mc.PRT_entries; // PRT table; - interface_ip.line_sz = data; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 0; - interface_ip.throughput = 1.0 / XML->sys.target_core_clockrate; - interface_ip.latency = 2.0 / XML->sys.target_core_clockrate; + //We assume 24 bits of base address and 8 bits of offset address. + //THese values are used for coalesing memory requests to the same base address block. + //TIDs are assumed to be 8 bits + /*Contents of each PRT entry + * + * Warp ID (6 bits) | Memory address (32 bits) per thread | Request Size (2-bits) per thread | + * line size= 6+ 32*16 + 2*16 ~ 64 bytes + * + * + */ + data = 64;//Support key words first operation //8 means converting bit to Byte + interface_ip.cache_sz = data*XML->sys.mc.PRT_entries;//PRT table; + interface_ip.line_sz = data; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 0; + interface_ip.throughput = 1.0/XML->sys.target_core_clockrate; + interface_ip.latency = 2.0/XML->sys.target_core_clockrate; interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = 1; - interface_ip.num_wr_ports = 1; - interface_ip.num_se_rd_ports = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = 1; + interface_ip.num_wr_ports = 1; + interface_ip.num_se_rd_ports = 0; PRT = new ArrayST(&interface_ip, "MC PRT", Uncore_device); - PRT->area.set_area(PRT->area.get_area() + - PRT->local_result.area * - XML->sys.mc.memory_channels_per_mc); - area.set_area(area.get_area() + - PRT->local_result.area * XML->sys.mc.memory_channels_per_mc); - - //***ThreadMasks storage (coalesced threads whose memory requests are - //satisfied by each memory access) - /* contents of the thread masks Array - * 16-bit bit masks for up to 16 memory requests of a warp | Number of - * pending memory requests (5 bits) - * - * 16*PRT_entry thread Mask, each entry has 16 mask bits. - * - */ - data = 2; - interface_ip.cache_sz = data * XML->sys.mc.PRT_entries * 16; // PRT table; - interface_ip.line_sz = data; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 0; - interface_ip.throughput = 1.0 / XML->sys.target_core_clockrate; - interface_ip.latency = 2.0 / XML->sys.target_core_clockrate; + PRT->area.set_area(PRT->area.get_area()+ PRT->local_result.area*XML->sys.mc.memory_channels_per_mc); + area.set_area(area.get_area()+ PRT->local_result.area*XML->sys.mc.memory_channels_per_mc); + + + //***ThreadMasks storage (coalesced threads whose memory requests are satisfied by each memory access) + /* contents of the thread masks Array + * 16-bit bit masks for up to 16 memory requests of a warp | Number of pending memory requests (5 bits) + * + * 16*PRT_entry thread Mask, each entry has 16 mask bits. + * + */ + data = 2; + interface_ip.cache_sz = data*XML->sys.mc.PRT_entries*16;//PRT table; + interface_ip.line_sz = data; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 0; + interface_ip.throughput = 1.0/XML->sys.target_core_clockrate; + interface_ip.latency = 2.0/XML->sys.target_core_clockrate; interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = 1; - interface_ip.num_wr_ports = 1; - interface_ip.num_se_rd_ports = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = 1; + interface_ip.num_wr_ports = 1; + interface_ip.num_se_rd_ports = 0; threadMasks = new ArrayST(&interface_ip, "MC ThreadMasks", Uncore_device); - threadMasks->area.set_area(threadMasks->area.get_area() + - threadMasks->local_result.area * - XML->sys.mc.memory_channels_per_mc); - area.set_area(area.get_area() + - threadMasks->local_result.area * - XML->sys.mc.memory_channels_per_mc); + threadMasks->area.set_area(threadMasks->area.get_area()+ threadMasks->local_result.area*XML->sys.mc.memory_channels_per_mc); + area.set_area(area.get_area()+ threadMasks->local_result.area*XML->sys.mc.memory_channels_per_mc); //***Numer of pending requests per PRT entry - /* - * 1-byte data, PRT entries deep - */ - data = 1; - interface_ip.cache_sz = data * XML->sys.mc.PRT_entries; // PRT table; - interface_ip.line_sz = data; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.access_mode = 0; - interface_ip.throughput = 1.0 / XML->sys.target_core_clockrate; - interface_ip.latency = 2.0 / XML->sys.target_core_clockrate; + /* + * 1-byte data, PRT entries deep + */ + data = 1; + interface_ip.cache_sz = data*XML->sys.mc.PRT_entries;//PRT table; + interface_ip.line_sz = data; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 0; + interface_ip.throughput = 1.0/XML->sys.target_core_clockrate; + interface_ip.latency = 2.0/XML->sys.target_core_clockrate; interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = 1; - interface_ip.num_wr_ports = 1; - interface_ip.num_se_rd_ports = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = 1; + interface_ip.num_wr_ports = 1; + interface_ip.num_se_rd_ports = 0; PRC = new ArrayST(&interface_ip, "MC PendingRequestCount", Uncore_device); - PRC->area.set_area(PRC->area.get_area() + - PRC->local_result.area * - XML->sys.mc.memory_channels_per_mc); - area.set_area(area.get_area() + - PRC->local_result.area * XML->sys.mc.memory_channels_per_mc); + PRC->area.set_area(PRC->area.get_area()+ PRC->local_result.area*XML->sys.mc.memory_channels_per_mc); + area.set_area(area.get_area()+ PRC->local_result.area*XML->sys.mc.memory_channels_per_mc); + } -void DRAM::computeEnergy(bool is_tdp) { - if (is_tdp) { - power.reset(); - return; /// not supporting TDP calculation for DRAM - } - rt_power.reset(); - dramp.executionTime = - XML->sys.total_cycles / (XML->sys.target_core_clockrate * 1e6); - power_t.reset(); - power_t.readOp.dynamic += XML->sys.mc.memory_reads * dramp.rd_coeff; - power_t.readOp.dynamic += XML->sys.mc.memory_writes * dramp.wr_coeff; - power_t.readOp.dynamic += XML->sys.mc.dram_pre * dramp.pre_coeff; +void DRAM::computeEnergy(bool is_tdp) +{ + if (is_tdp){ + power.reset(); + return; /// not supporting TDP calculation for DRAM + } + rt_power.reset(); + dramp.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); - rt_power = rt_power + power_t; + power_t.reset(); + power_t.readOp.dynamic+=XML->sys.mc.memory_reads*dramp.rd_coeff; + power_t.readOp.dynamic+=XML->sys.mc.memory_writes*dramp.wr_coeff; + power_t.readOp.dynamic+=XML->sys.mc.dram_pre*dramp.pre_coeff; + + rt_power = rt_power + power_t ; } -void MCFrontEnd::computeEnergy(bool is_tdp) { - if (is_tdp) { - power.reset(); - // init stats for Peak - frontendBuffer->stats_t.readAc.access = - frontendBuffer->l_ip.num_search_ports; - frontendBuffer->stats_t.writeAc.access = frontendBuffer->l_ip.num_wr_ports; - frontendBuffer->tdp_stats = frontendBuffer->stats_t; - - readBuffer->stats_t.readAc.access = - readBuffer->l_ip.num_rd_ports * mcp.frontend_duty_cycle; - readBuffer->stats_t.writeAc.access = - readBuffer->l_ip.num_wr_ports * mcp.frontend_duty_cycle; - readBuffer->tdp_stats = readBuffer->stats_t; - - writeBuffer->stats_t.readAc.access = - writeBuffer->l_ip.num_rd_ports * mcp.frontend_duty_cycle; - writeBuffer->stats_t.writeAc.access = - writeBuffer->l_ip.num_wr_ports * mcp.frontend_duty_cycle; - writeBuffer->tdp_stats = writeBuffer->stats_t; - - PRT->stats_t.readAc.access = - PRT->l_ip.num_rd_ports * mcp.frontend_duty_cycle; - PRT->stats_t.writeAc.access = - PRT->l_ip.num_wr_ports * mcp.frontend_duty_cycle; - PRT->tdp_stats = PRT->stats_t; - - threadMasks->stats_t.readAc.access = - threadMasks->l_ip.num_rd_ports * mcp.frontend_duty_cycle; - threadMasks->stats_t.writeAc.access = - threadMasks->l_ip.num_wr_ports * mcp.frontend_duty_cycle; - threadMasks->tdp_stats = threadMasks->stats_t; - - PRC->stats_t.readAc.access = - threadMasks->l_ip.num_rd_ports * mcp.frontend_duty_cycle; - PRC->stats_t.writeAc.access = - threadMasks->l_ip.num_wr_ports * mcp.frontend_duty_cycle; - PRC->tdp_stats = threadMasks->stats_t; - - } else { - rt_power.reset(); // Jingwen - // init stats for runtime power (RTP) - frontendBuffer->stats_t.readAc.access = - XML->sys.mc.memory_reads * mcp.llcBlockSize * 8.0 / mcp.dataBusWidth * - mcp.dataBusWidth / 72; - // For each channel, each memory word need to check the address data to - // achieve best scheduling results. - // and this need to be done on all physical DIMMs in each logical memory - // DIMM *mcp.dataBusWidth/72 - frontendBuffer->stats_t.writeAc.access = - XML->sys.mc.memory_writes * mcp.llcBlockSize * 8.0 / mcp.dataBusWidth * - mcp.dataBusWidth / 72; - frontendBuffer->rtp_stats = frontendBuffer->stats_t; - - readBuffer->stats_t.readAc.access = - XML->sys.mc.memory_reads * mcp.llcBlockSize * 8.0 / - mcp.dataBusWidth; // support key word first - readBuffer->stats_t.writeAc.access = - XML->sys.mc.memory_reads * mcp.llcBlockSize * 8.0 / - mcp.dataBusWidth; // support key word first - readBuffer->rtp_stats = readBuffer->stats_t; - - writeBuffer->stats_t.readAc.access = - XML->sys.mc.memory_writes * mcp.llcBlockSize * 8.0 / mcp.dataBusWidth; - writeBuffer->stats_t.writeAc.access = - XML->sys.mc.memory_writes * mcp.llcBlockSize * 8.0 / mcp.dataBusWidth; - writeBuffer->rtp_stats = writeBuffer->stats_t; - - // Pending request table - // Co-alesce all misses in caches and add an entry for them in PRT - // TODO: Change 0 to ithCore and move to LSU (Syed) - // TODO: Do these accesses represent coalesced accesses? - PRT->stats_t.readAc.access = XML->sys.core[0].dcache.read_accesses + - XML->sys.core[0].ccache.read_accesses + - XML->sys.core[0].tcache.read_accesses; - PRT->stats_t.writeAc.access = XML->sys.core[0].dcache.write_accesses + - XML->sys.core[0].ccache.write_accesses + - XML->sys.core[0].tcache.write_accesses; - PRT->rtp_stats = PRT->stats_t; - - threadMasks->stats_t.readAc.access = XML->sys.core[0].dcache.read_accesses + - XML->sys.core[0].ccache.read_accesses + - XML->sys.core[0].tcache.read_accesses; - threadMasks->stats_t.writeAc.access = - XML->sys.core[0].dcache.write_accesses + - XML->sys.core[0].ccache.write_accesses + - XML->sys.core[0].tcache.write_accesses; - threadMasks->rtp_stats = threadMasks->stats_t; - - PRC->stats_t.readAc.access = XML->sys.core[0].dcache.read_accesses + - XML->sys.core[0].ccache.read_accesses + - XML->sys.core[0].tcache.read_accesses; - PRC->stats_t.writeAc.access = XML->sys.core[0].dcache.write_accesses + - XML->sys.core[0].ccache.write_accesses + - XML->sys.core[0].tcache.write_accesses; - PRC->rtp_stats = threadMasks->stats_t; - } - frontendBuffer->power_t.reset(); - readBuffer->power_t.reset(); - writeBuffer->power_t.reset(); - threadMasks->power_t.reset(); - PRT->power_t.reset(); - PRC->power_t.reset(); - - // frontendBuffer->power_t.readOp.dynamic += - //(frontendBuffer->stats_t.readAc.access* - // (frontendBuffer->local_result.power.searchOp.dynamic+frontendBuffer->local_result.power.readOp.dynamic)+ - // frontendBuffer->stats_t.writeAc.access*frontendBuffer->local_result.power.writeOp.dynamic); - - frontendBuffer->power_t.readOp.dynamic += - (frontendBuffer->stats_t.readAc.access + - frontendBuffer->stats_t.writeAc.access) * - frontendBuffer->local_result.power.searchOp.dynamic + - frontendBuffer->stats_t.readAc.access * - frontendBuffer->local_result.power.readOp.dynamic + - frontendBuffer->stats_t.writeAc.access * - frontendBuffer->local_result.power.writeOp.dynamic; - - readBuffer->power_t.readOp.dynamic += - (readBuffer->stats_t.readAc.access * - readBuffer->local_result.power.readOp.dynamic + - readBuffer->stats_t.writeAc.access * - readBuffer->local_result.power.writeOp.dynamic); - writeBuffer->power_t.readOp.dynamic += - (writeBuffer->stats_t.readAc.access * - writeBuffer->local_result.power.readOp.dynamic + - writeBuffer->stats_t.writeAc.access * - writeBuffer->local_result.power.writeOp.dynamic); - - PRT->power_t.readOp.dynamic += - (PRT->stats_t.readAc.access * PRT->local_result.power.readOp.dynamic + - PRT->stats_t.writeAc.access * PRT->local_result.power.writeOp.dynamic); - - threadMasks->power_t.readOp.dynamic += - (threadMasks->stats_t.readAc.access * - threadMasks->local_result.power.readOp.dynamic + - threadMasks->stats_t.writeAc.access * - threadMasks->local_result.power.writeOp.dynamic); - - PRC->power_t.readOp.dynamic += - (PRC->stats_t.readAc.access * PRC->local_result.power.readOp.dynamic + - PRC->stats_t.writeAc.access * PRC->local_result.power.writeOp.dynamic); - -// Add coalescing logic power (Estimated from Verilog HDL description and -// Synopsys PowerCompiler)--Syed -#define COALESCE_SCALE 1 - double perAccessCoalescingEnergy = - coalesce_scale * - ((0.443e-3) * (0.5e-9) * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd) / - (1 * 1); - threadMasks->power_t.readOp.dynamic += (threadMasks->stats_t.readAc.access + - threadMasks->stats_t.writeAc.access) * - perAccessCoalescingEnergy; - - // printf("***PRT: %10.30f, threadMasks: %10.30f, PRC: - // %10.30f\n",PRT->power_t.readOp.dynamic,threadMasks->power_t.readOp.dynamic,PRC->power_t.readOp.dynamic); - // printf("***Accesses: read:%lf - // write:%lf\n",threadMasks->stats_t.readAc.access, - // threadMasks->stats_t.writeAc.access); - if (is_tdp) { - power = - power + frontendBuffer->power_t + readBuffer->power_t + - writeBuffer->power_t + PRT->power_t + threadMasks->power_t + - PRC->power_t + - (frontendBuffer->local_result.power + readBuffer->local_result.power + - writeBuffer->local_result.power + PRT->local_result.power + - threadMasks->local_result.power + PRC->local_result.power) * - pppm_lkg; - - } else { - rt_power = - rt_power + frontendBuffer->power_t + readBuffer->power_t + - writeBuffer->power_t + PRT->power_t + threadMasks->power_t + - PRC->power_t + - (frontendBuffer->local_result.power + readBuffer->local_result.power + - writeBuffer->local_result.power + PRT->local_result.power + - threadMasks->local_result.power + PRC->local_result.power) * - pppm_lkg; - rt_power.readOp.dynamic = rt_power.readOp.dynamic + - power.readOp.dynamic * 0.1 * mcp.clockRate * - mcp.num_mcs * mcp.executionTime; - } +void MCFrontEnd::computeEnergy(bool is_tdp) +{ + if (is_tdp) + { + power.reset(); + //init stats for Peak + frontendBuffer->stats_t.readAc.access = frontendBuffer->l_ip.num_search_ports; + frontendBuffer->stats_t.writeAc.access = frontendBuffer->l_ip.num_wr_ports; + frontendBuffer->tdp_stats = frontendBuffer->stats_t; + + readBuffer->stats_t.readAc.access = readBuffer->l_ip.num_rd_ports*mcp.frontend_duty_cycle; + readBuffer->stats_t.writeAc.access = readBuffer->l_ip.num_wr_ports*mcp.frontend_duty_cycle; + readBuffer->tdp_stats = readBuffer->stats_t; + + writeBuffer->stats_t.readAc.access = writeBuffer->l_ip.num_rd_ports*mcp.frontend_duty_cycle; + writeBuffer->stats_t.writeAc.access = writeBuffer->l_ip.num_wr_ports*mcp.frontend_duty_cycle; + writeBuffer->tdp_stats = writeBuffer->stats_t; + + PRT->stats_t.readAc.access = PRT->l_ip.num_rd_ports*mcp.frontend_duty_cycle; + PRT->stats_t.writeAc.access = PRT->l_ip.num_wr_ports*mcp.frontend_duty_cycle; + PRT->tdp_stats = PRT->stats_t; + + threadMasks->stats_t.readAc.access = threadMasks->l_ip.num_rd_ports*mcp.frontend_duty_cycle; + threadMasks->stats_t.writeAc.access = threadMasks->l_ip.num_wr_ports*mcp.frontend_duty_cycle; + threadMasks->tdp_stats = threadMasks->stats_t; + + PRC->stats_t.readAc.access = threadMasks->l_ip.num_rd_ports*mcp.frontend_duty_cycle; + PRC->stats_t.writeAc.access = threadMasks->l_ip.num_wr_ports*mcp.frontend_duty_cycle; + PRC->tdp_stats = threadMasks->stats_t; + + } + else + { + rt_power.reset(); //Jingwen + //init stats for runtime power (RTP) + frontendBuffer->stats_t.readAc.access = XML->sys.mc.memory_reads *mcp.llcBlockSize*8.0/mcp.dataBusWidth*mcp.dataBusWidth/72; + //For each channel, each memory word need to check the address data to achieve best scheduling results. + //and this need to be done on all physical DIMMs in each logical memory DIMM *mcp.dataBusWidth/72 + frontendBuffer->stats_t.writeAc.access = XML->sys.mc.memory_writes*mcp.llcBlockSize*8.0/mcp.dataBusWidth*mcp.dataBusWidth/72; + frontendBuffer->rtp_stats = frontendBuffer->stats_t; + + readBuffer->stats_t.readAc.access = XML->sys.mc.memory_reads*mcp.llcBlockSize*8.0/mcp.dataBusWidth;//support key word first + readBuffer->stats_t.writeAc.access = XML->sys.mc.memory_reads*mcp.llcBlockSize*8.0/mcp.dataBusWidth;//support key word first + readBuffer->rtp_stats = readBuffer->stats_t; + + writeBuffer->stats_t.readAc.access = XML->sys.mc.memory_writes*mcp.llcBlockSize*8.0/mcp.dataBusWidth; + writeBuffer->stats_t.writeAc.access = XML->sys.mc.memory_writes*mcp.llcBlockSize*8.0/mcp.dataBusWidth; + writeBuffer->rtp_stats = writeBuffer->stats_t; + + //Pending request table + //Co-alesce all misses in caches and add an entry for them in PRT + //TODO: Change 0 to ithCore and move to LSU (Syed) + //TODO: Do these accesses represent coalesced accesses? + PRT->stats_t.readAc.access = XML->sys.core[0].dcache.read_accesses + XML->sys.core[0].ccache.read_accesses + + XML->sys.core[0].tcache.read_accesses; + PRT->stats_t.writeAc.access = XML->sys.core[0].dcache.write_accesses + XML->sys.core[0].ccache.write_accesses + + XML->sys.core[0].tcache.write_accesses; + PRT->rtp_stats = PRT->stats_t; + + threadMasks->stats_t.readAc.access = XML->sys.core[0].dcache.read_accesses + XML->sys.core[0].ccache.read_accesses + + XML->sys.core[0].tcache.read_accesses; + threadMasks->stats_t.writeAc.access = XML->sys.core[0].dcache.write_accesses + XML->sys.core[0].ccache.write_accesses + + XML->sys.core[0].tcache.write_accesses; + threadMasks->rtp_stats = threadMasks->stats_t; + + PRC->stats_t.readAc.access = XML->sys.core[0].dcache.read_accesses + XML->sys.core[0].ccache.read_accesses + + XML->sys.core[0].tcache.read_accesses; + PRC->stats_t.writeAc.access = XML->sys.core[0].dcache.write_accesses + XML->sys.core[0].ccache.write_accesses + + XML->sys.core[0].tcache.write_accesses; + PRC->rtp_stats = threadMasks->stats_t; + + } + + frontendBuffer->power_t.reset(); + readBuffer->power_t.reset(); + writeBuffer->power_t.reset(); + threadMasks->power_t.reset(); + PRT->power_t.reset(); + PRC->power_t.reset(); + +// frontendBuffer->power_t.readOp.dynamic += (frontendBuffer->stats_t.readAc.access* +// (frontendBuffer->local_result.power.searchOp.dynamic+frontendBuffer->local_result.power.readOp.dynamic)+ +// frontendBuffer->stats_t.writeAc.access*frontendBuffer->local_result.power.writeOp.dynamic); + + frontendBuffer->power_t.readOp.dynamic += (frontendBuffer->stats_t.readAc.access + + frontendBuffer->stats_t.writeAc.access)*frontendBuffer->local_result.power.searchOp.dynamic+ + frontendBuffer->stats_t.readAc.access * frontendBuffer->local_result.power.readOp.dynamic+ + frontendBuffer->stats_t.writeAc.access*frontendBuffer->local_result.power.writeOp.dynamic; + + readBuffer->power_t.readOp.dynamic += (readBuffer->stats_t.readAc.access* + readBuffer->local_result.power.readOp.dynamic+ + readBuffer->stats_t.writeAc.access*readBuffer->local_result.power.writeOp.dynamic); + writeBuffer->power_t.readOp.dynamic += (writeBuffer->stats_t.readAc.access* + writeBuffer->local_result.power.readOp.dynamic+ + writeBuffer->stats_t.writeAc.access*writeBuffer->local_result.power.writeOp.dynamic); + + PRT->power_t.readOp.dynamic += (PRT->stats_t.readAc.access* + PRT->local_result.power.readOp.dynamic+ + PRT->stats_t.writeAc.access*PRT->local_result.power.writeOp.dynamic); + + threadMasks->power_t.readOp.dynamic += (threadMasks->stats_t.readAc.access* + threadMasks->local_result.power.readOp.dynamic+ + threadMasks->stats_t.writeAc.access*threadMasks->local_result.power.writeOp.dynamic); + + PRC->power_t.readOp.dynamic += (PRC->stats_t.readAc.access* + PRC->local_result.power.readOp.dynamic+ + PRC->stats_t.writeAc.access*PRC->local_result.power.writeOp.dynamic); + + //Add coalescing logic power (Estimated from Verilog HDL description and Synopsys PowerCompiler)--Syed + #define COALESCE_SCALE 1 + double perAccessCoalescingEnergy=coalesce_scale * ((0.443e-3)*(0.5e-9)*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd)/(1*1); + threadMasks->power_t.readOp.dynamic += (threadMasks->stats_t.readAc.access+threadMasks->stats_t.writeAc.access)*perAccessCoalescingEnergy; + + //printf("***PRT: %10.30f, threadMasks: %10.30f, PRC: %10.30f\n",PRT->power_t.readOp.dynamic,threadMasks->power_t.readOp.dynamic,PRC->power_t.readOp.dynamic); + //printf("***Accesses: read:%lf write:%lf\n",threadMasks->stats_t.readAc.access, threadMasks->stats_t.writeAc.access); + if (is_tdp) + { + power = power + frontendBuffer->power_t + readBuffer->power_t + writeBuffer->power_t + PRT->power_t + threadMasks->power_t + + PRC->power_t + + (frontendBuffer->local_result.power + + readBuffer->local_result.power + + writeBuffer->local_result.power+PRT->local_result.power+ + threadMasks->local_result.power+PRC->local_result.power)*pppm_lkg; + + + } + else + { + rt_power = rt_power + frontendBuffer->power_t + readBuffer->power_t + writeBuffer->power_t + PRT->power_t + threadMasks->power_t + + PRC->power_t+ + (frontendBuffer->local_result.power + + readBuffer->local_result.power + + writeBuffer->local_result.power + PRT->local_result.power + threadMasks->local_result.power+ + PRC->local_result.power)*pppm_lkg; + rt_power.readOp.dynamic = rt_power.readOp.dynamic + power.readOp.dynamic*0.1*mcp.clockRate*mcp.num_mcs*mcp.executionTime; + } } -void MCFrontEnd::displayEnergy(uint32_t indent, int plevel, bool is_tdp) { - string indent_str(indent, ' '); - string indent_str_next(indent + 2, ' '); - - if (is_tdp) { - cout << indent_str << "Front End ROB:" << endl; - cout << indent_str_next - << "Area = " << frontendBuffer->area.get_area() * 1e-6 << " mm^2" - << endl; - cout << indent_str_next << "Peak Dynamic = " - << frontendBuffer->power.readOp.dynamic * mcp.clockRate << " W" - << endl; - cout << indent_str_next - << "Subthreshold Leakage = " << frontendBuffer->power.readOp.leakage - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << frontendBuffer->power.readOp.gate_leakage - << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " - << frontendBuffer->rt_power.readOp.dynamic / mcp.executionTime << " W" - << endl; - - cout << endl; - cout << indent_str << "Read Buffer:" << endl; - cout << indent_str_next << "Area = " << readBuffer->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " - << readBuffer->power.readOp.dynamic * mcp.clockRate << " W" << endl; - cout << indent_str_next - << "Subthreshold Leakage = " << readBuffer->power.readOp.leakage - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << readBuffer->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << readBuffer->rt_power.readOp.dynamic / mcp.executionTime << " W" - << endl; - cout << endl; - cout << indent_str << "Write Buffer:" << endl; - cout << indent_str_next << "Area = " << writeBuffer->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " - << writeBuffer->power.readOp.dynamic * mcp.clockRate << " W" << endl; - cout << indent_str_next - << "Subthreshold Leakage = " << writeBuffer->power.readOp.leakage - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << writeBuffer->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << writeBuffer->rt_power.readOp.dynamic / mcp.executionTime << " W" - << endl; - cout << endl; - cout << indent_str << "PRT:" << endl; - cout << indent_str_next << "Area = " << PRT->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << PRT->power.readOp.dynamic * mcp.clockRate - << " W" << endl; - cout << indent_str_next - << "Subthreshold Leakage = " << PRT->power.readOp.leakage << " W" - << endl; - cout << indent_str_next - << "Gate Leakage = " << PRT->power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " - << PRT->rt_power.readOp.dynamic / mcp.executionTime << " W" << endl; - cout << endl; - cout << indent_str << "Thread Masks and coalescing logic:" << endl; - cout << indent_str_next << "Area = " << threadMasks->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " - << threadMasks->power.readOp.dynamic * mcp.clockRate << " W" << endl; - cout << indent_str_next - << "Subthreshold Leakage = " << threadMasks->power.readOp.leakage - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << threadMasks->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << threadMasks->rt_power.readOp.dynamic / mcp.executionTime << " W" - << endl; - cout << endl; - - } else { - cout << indent_str << "Front End ROB:" << endl; - cout << indent_str_next - << "Area = " << frontendBuffer->area.get_area() * 1e-6 << " mm^2" - << endl; - cout << indent_str_next << "Peak Dynamic = " - << frontendBuffer->rt_power.readOp.dynamic * mcp.clockRate << " W" - << endl; - cout << indent_str_next - << "Subthreshold Leakage = " << frontendBuffer->rt_power.readOp.leakage - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << frontendBuffer->rt_power.readOp.gate_leakage - << " W" << endl; - cout << endl; - cout << indent_str << "Read Buffer:" << endl; - cout << indent_str_next << "Area = " << readBuffer->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " - << readBuffer->rt_power.readOp.dynamic * mcp.clockRate << " W" << endl; - cout << indent_str_next - << "Subthreshold Leakage = " << readBuffer->rt_power.readOp.leakage - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << readBuffer->rt_power.readOp.gate_leakage - << " W" << endl; - cout << endl; - cout << indent_str << "Write Buffer:" << endl; - cout << indent_str_next << "Area = " << writeBuffer->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " - << writeBuffer->rt_power.readOp.dynamic * mcp.clockRate << " W" - << endl; - cout << indent_str_next - << "Subthreshold Leakage = " << writeBuffer->rt_power.readOp.leakage - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << writeBuffer->rt_power.readOp.gate_leakage - << " W" << endl; - cout << endl; - cout << indent_str << "PRT:" << endl; - cout << indent_str_next << "Area = " << PRT->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << PRT->rt_power.readOp.dynamic * mcp.clockRate - << " W" << endl; - cout << indent_str_next - << "Subthreshold Leakage = " << PRT->rt_power.readOp.leakage << " W" - << endl; - cout << indent_str_next - << "Gate Leakage = " << PRT->rt_power.readOp.gate_leakage << " W" - << endl; - cout << endl; - cout << indent_str << "Thread masks and coalescing logic:" << endl; - cout << indent_str_next << "Area = " << threadMasks->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " - << threadMasks->rt_power.readOp.dynamic * mcp.clockRate << " W" - << endl; - cout << indent_str_next - << "Subthreshold Leakage = " << threadMasks->rt_power.readOp.leakage - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << threadMasks->rt_power.readOp.gate_leakage - << " W" << endl; - } +void MCFrontEnd::displayEnergy(uint32_t indent,int plevel,bool is_tdp) +{ + string indent_str(indent, ' '); + string indent_str_next(indent+2, ' '); + + if (is_tdp) + { + cout << indent_str << "Front End ROB:" << endl; + cout << indent_str_next << "Area = " << frontendBuffer->area.get_area()*1e-6<< " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << frontendBuffer->power.readOp.dynamic*mcp.clockRate << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " << frontendBuffer->power.readOp.leakage <<" W" << endl; + cout << indent_str_next << "Gate Leakage = " << frontendBuffer->power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << frontendBuffer->rt_power.readOp.dynamic/mcp.executionTime << " W" << endl; + + cout <area.get_area()); + area.set_area(area.get_area()+ frontend->area.get_area()); transecEngine = new MCBackend(&interface_ip, mcp, mc_type); - area.set_area(area.get_area() + transecEngine->area.get_area()); - if (mcp.type == 0 || (mcp.type == 1 && mcp.withPHY)) { - PHY = new MCPHY(&interface_ip, mcp, mc_type); - area.set_area(area.get_area() + PHY->area.get_area()); + area.set_area(area.get_area()+ transecEngine->area.get_area()); + if (mcp.type==0 || (mcp.type==1&&mcp.withPHY)) + { + PHY = new MCPHY(&interface_ip, mcp, mc_type); + area.set_area(area.get_area()+ PHY->area.get_area()); } - //+++++++++Transaction engine +++++++++++++++++ ////TODO needs better numbers, - //Run the RTL code from OpenSparc. - // transecEngine.initialize(&interface_ip); - // transecEngine.peakDataTransferRate = XML->sys.mem.peak_transfer_rate; - // transecEngine.memDataWidth = dataBusWidth; - // transecEngine.memRank = XML->sys.mem.number_ranks; - // //transecEngine.memAccesses=XML->sys.mc.memory_accesses; - // //transecEngine.llcBlocksize=llcBlockSize; - // transecEngine.compute(); - // transecEngine.area.set_area(XML->sys.mc.memory_channels_per_mc*transecEngine.area.get_area()) - // ; - // area.set_area(area.get_area()+ transecEngine.area.get_area()); - // ///cout<<"area="<sys.mem.peak_transfer_rate; - // PHY.memDataWidth = dataBusWidth; - // //PHY.memAccesses=PHY.peakDataTransferRate;//this is the max power - // //PHY.llcBlocksize=llcBlockSize; - // PHY.compute(); - // PHY.area.set_area(XML->sys.mc.memory_channels_per_mc*PHY.area.get_area()) - // ; - // area.set_area(area.get_area()+ PHY.area.get_area()); - /// cout<<"area="<sys.core[0].opcode_width + dataBusWidth; - // pipeLogic = new pipeline(is_default, &interface_ip); - // //pipeLogic.init_pipeline(is_default, &interface_ip); - // pipeLogic->compute_pipeline(); - // area.set_area(area.get_area()+ pipeLogic->area.get_area()*1e-6); - // area.set_area((area.get_area()+mc_area*1e-6)*1.1);//placement and routing - // overhead - // - // - //// //clock - //// clockNetwork.init_wire_external(is_default, &interface_ip); - //// clockNetwork.clk_area =area*1.1;//10% of placement overhead. - ///rule of thumb - //// clockNetwork.end_wiring_level =5;//toplevel metal - //// clockNetwork.start_wiring_level =5;//toplevel metal - //// clockNetwork.num_regs = pipeLogic.tot_stage_vector; - //// clockNetwork.optimize_wire(); + //+++++++++Transaction engine +++++++++++++++++ ////TODO needs better numbers, Run the RTL code from OpenSparc. +// transecEngine.initialize(&interface_ip); +// transecEngine.peakDataTransferRate = XML->sys.mem.peak_transfer_rate; +// transecEngine.memDataWidth = dataBusWidth; +// transecEngine.memRank = XML->sys.mem.number_ranks; +// //transecEngine.memAccesses=XML->sys.mc.memory_accesses; +// //transecEngine.llcBlocksize=llcBlockSize; +// transecEngine.compute(); +// transecEngine.area.set_area(XML->sys.mc.memory_channels_per_mc*transecEngine.area.get_area()) ; +// area.set_area(area.get_area()+ transecEngine.area.get_area()); +// ///cout<<"area="<sys.mem.peak_transfer_rate; +// PHY.memDataWidth = dataBusWidth; +// //PHY.memAccesses=PHY.peakDataTransferRate;//this is the max power +// //PHY.llcBlocksize=llcBlockSize; +// PHY.compute(); +// PHY.area.set_area(XML->sys.mc.memory_channels_per_mc*PHY.area.get_area()) ; +// area.set_area(area.get_area()+ PHY.area.get_area()); + ///cout<<"area="<sys.core[0].opcode_width + dataBusWidth; +// pipeLogic = new pipeline(is_default, &interface_ip); +// //pipeLogic.init_pipeline(is_default, &interface_ip); +// pipeLogic->compute_pipeline(); +// area.set_area(area.get_area()+ pipeLogic->area.get_area()*1e-6); +// area.set_area((area.get_area()+mc_area*1e-6)*1.1);//placement and routing overhead +// +// +//// //clock +//// clockNetwork.init_wire_external(is_default, &interface_ip); +//// clockNetwork.clk_area =area*1.1;//10% of placement overhead. rule of thumb +//// clockNetwork.end_wiring_level =5;//toplevel metal +//// clockNetwork.start_wiring_level =5;//toplevel metal +//// clockNetwork.num_regs = pipeLogic.tot_stage_vector; +//// clockNetwork.optimize_wire(); + + } -void MemoryController::computeEnergy(bool is_tdp) { - rt_power.reset(); // Jingwen +void MemoryController::computeEnergy(bool is_tdp) +{ + + rt_power.reset(); //Jingwen frontend->rt_power.reset(); transecEngine->rt_power.reset(); dram->rt_power.reset(); - mcp.executionTime = XML->sys.total_cycles / - (XML->sys.target_core_clockrate * 1e6); // Jingwen - frontend->mcp.executionTime = - XML->sys.total_cycles / - (XML->sys.target_core_clockrate * 1e6); // Jingwen - transecEngine->mcp.executionTime = - XML->sys.total_cycles / - (XML->sys.target_core_clockrate * 1e6); // Jingwen - + mcp.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); //Jingwen + frontend->mcp.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); //Jingwen + transecEngine->mcp.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); //Jingwen + /*Jingwen: give stats for backend and phy */ - transecEngine->mcp.reads = XML->sys.mc.memory_reads; - transecEngine->mcp.writes = XML->sys.mc.memory_writes; - - // set_mc_param(); - - frontend->computeEnergy(is_tdp); - transecEngine->computeEnergy(is_tdp); - dram->computeEnergy(is_tdp); - if (mcp.type == 0 || (mcp.type == 1 && mcp.withPHY)) { - if (!is_tdp) PHY->rt_power.reset(); // Jingwen - PHY->mcp.reads = XML->sys.mc.memory_reads; - PHY->mcp.writes = XML->sys.mc.memory_writes; - PHY->mcp.executionTime = XML->sys.total_cycles / - (XML->sys.target_core_clockrate * 1e6); // Jingwen - PHY->computeEnergy(is_tdp); - } - if (is_tdp) { - power = power + frontend->power + transecEngine->power; - if (mcp.type == 0 || (mcp.type == 1 && mcp.withPHY)) { - power = power + PHY->power; - } - } else { - rt_power = rt_power + frontend->rt_power + transecEngine->rt_power + - dram->rt_power; - if (mcp.type == 0 || (mcp.type == 1 && mcp.withPHY)) { - rt_power = rt_power + PHY->rt_power; - } - } + transecEngine->mcp.reads =XML->sys.mc.memory_reads; + transecEngine->mcp.writes =XML->sys.mc.memory_writes; + + //set_mc_param(); + + frontend->computeEnergy(is_tdp); + transecEngine->computeEnergy(is_tdp); + dram->computeEnergy(is_tdp); + if (mcp.type==0 || (mcp.type==1&&mcp.withPHY)) + { + if(!is_tdp) + PHY->rt_power.reset();//Jingwen + PHY->mcp.reads =XML->sys.mc.memory_reads; + PHY->mcp.writes =XML->sys.mc.memory_writes; + PHY->mcp.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); //Jingwen + PHY->computeEnergy(is_tdp); + } + if (is_tdp) + { + power = power + frontend->power + transecEngine->power; + if (mcp.type==0 || (mcp.type==1&&mcp.withPHY)) + { + power = power + PHY->power; + } + } + else + { + rt_power = rt_power + frontend->rt_power + transecEngine->rt_power+dram->rt_power; + if (mcp.type==0 || (mcp.type==1&&mcp.withPHY)) + { + rt_power = rt_power + PHY->rt_power; + } + } } -void MemoryController::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 << "Memory Controller:" << endl; - cout << indent_str << "Area = " << area.get_area() * 1e-6 << " mm^2" - << endl; - cout << indent_str - << "Peak Dynamic = " << power.readOp.dynamic * mcp.clockRate << " W" - << endl; - cout << indent_str << "Subthreshold Leakage = " - << (long_channel ? power.readOp.longer_channel_leakage - : power.readOp.leakage) - << " W" << endl; - // cout << indent_str<< "Subthreshold Leakage = " << - // power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str << "Gate Leakage = " << power.readOp.gate_leakage << " W" - << endl; - cout << indent_str - << "Runtime Dynamic = " << rt_power.readOp.dynamic / mcp.executionTime - << " W" << endl; - cout << endl; - cout << indent_str << "Front End Engine:" << endl; - cout << indent_str_next << "Area = " << frontend->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << frontend->power.readOp.dynamic * mcp.clockRate - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? frontend->power.readOp.longer_channel_leakage - : frontend->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << frontend->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << frontend->rt_power.readOp.dynamic / mcp.executionTime << " W" - << endl; - cout << endl; - // if (plevel >2){ - frontend->displayEnergy(indent + 4, is_tdp); - //} - cout << indent_str << "Transaction Engine:" << endl; - cout << indent_str_next - << "Area = " << transecEngine->area.get_area() * 1e-6 << " mm^2" - << endl; - cout << indent_str_next << "Peak Dynamic = " - << transecEngine->power.readOp.dynamic * mcp.clockRate << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? transecEngine->power.readOp.longer_channel_leakage - : transecEngine->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << transecEngine->power.readOp.gate_leakage - << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " - << transecEngine->rt_power.readOp.dynamic / mcp.executionTime << " W" - << endl; - cout << endl; - if (mcp.type == 0 || (mcp.type == 1 && mcp.withPHY)) { - cout << indent_str << "PHY:" << endl; - cout << indent_str_next << "Area = " << PHY->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next - << "Peak Dynamic = " << PHY->power.readOp.dynamic * mcp.clockRate - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? PHY->power.readOp.longer_channel_leakage - : PHY->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << PHY->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << PHY->rt_power.readOp.dynamic / mcp.executionTime << " W" << endl; - cout << endl; - } - } else { - cout << "Memory Controller:" << endl; - cout << indent_str_next << "Area = " << area.get_area() * 1e-6 << " mm^2" - << endl; - cout << indent_str_next - << "Peak Dynamic = " << power.readOp.dynamic * mcp.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 << endl; - } +void MemoryController::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 << "Memory Controller:" << endl; + cout << indent_str<< "Area = " << area.get_area()*1e-6<< " mm^2" << endl; + cout << indent_str << "Peak Dynamic = " << power.readOp.dynamic*mcp.clockRate << " W" << endl; + cout << indent_str<< "Subthreshold Leakage = " + << (long_channel? power.readOp.longer_channel_leakage:power.readOp.leakage) <<" W" << endl; + //cout << indent_str<< "Subthreshold Leakage = " << power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str<< "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl; + cout << indent_str << "Runtime Dynamic = " << rt_power.readOp.dynamic/mcp.executionTime << " W" << endl; + cout<2){ + frontend->displayEnergy(indent+4,is_tdp); + //} + cout << indent_str << "Transaction Engine:" << endl; + cout << indent_str_next << "Area = " << transecEngine->area.get_area()*1e-6<< " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << transecEngine->power.readOp.dynamic*mcp.clockRate << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? transecEngine->power.readOp.longer_channel_leakage:transecEngine->power.readOp.leakage) <<" W" << endl; + cout << indent_str_next << "Gate Leakage = " << transecEngine->power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << transecEngine->rt_power.readOp.dynamic/mcp.executionTime << " W" << endl; + cout <sys.mc.dram_rd_coeff; - dramp.act_coeff = XML->sys.mc.dram_act_coeff; - dramp.nop_coeff = XML->sys.mc.dram_nop_coeff; - dramp.activity_coeff = XML->sys.mc.dram_activity_coeff; - dramp.pre_coeff = XML->sys.mc.dram_pre_coeff; - dramp.rd_coeff = XML->sys.mc.dram_rd_coeff; - dramp.wr_coeff = XML->sys.mc.dram_wr_coeff; - dramp.req_coeff = XML->sys.mc.dram_req_coeff; - dramp.const_coeff = XML->sys.mc.dram_const_coeff; +void DRAM::set_dram_param() +{ + dramp.cmd_coeff = XML->sys.mc.dram_rd_coeff; + dramp.act_coeff = XML->sys.mc.dram_act_coeff; + dramp.nop_coeff = XML->sys.mc.dram_nop_coeff; + dramp.activity_coeff = XML->sys.mc.dram_activity_coeff; + dramp.pre_coeff = XML->sys.mc.dram_pre_coeff; + dramp.rd_coeff = XML->sys.mc.dram_rd_coeff; + dramp.wr_coeff = XML->sys.mc.dram_wr_coeff; + dramp.req_coeff = XML->sys.mc.dram_req_coeff; + dramp.const_coeff = XML->sys.mc.dram_const_coeff; } -void MemoryController::set_mc_param() { - if (mc_type == MC) { - mcp.clockRate = XML->sys.mc.mc_clock * 2; // DDR double pumped - mcp.clockRate *= 1e6; - mcp.executionTime = - XML->sys.total_cycles / (XML->sys.target_core_clockrate * 1e6); - - mcp.llcBlockSize = int(ceil(XML->sys.mc.llc_line_length / 8.0)) + - XML->sys.mc.llc_line_length; // ecc overhead - mcp.dataBusWidth = - int(ceil(XML->sys.mc.databus_width / 8.0)) + XML->sys.mc.databus_width; - mcp.addressBusWidth = int(ceil( - XML->sys.mc.addressbus_width)); // XML->sys.physical_address_width; - mcp.opcodeW = 16; - mcp.num_mcs = XML->sys.mc.number_mcs; - mcp.num_channels = XML->sys.mc.memory_channels_per_mc; - mcp.reads = XML->sys.mc.memory_reads; - mcp.writes = XML->sys.mc.memory_writes; - //+++++++++Transaction engine +++++++++++++++++ ////TODO needs better - //numbers, Run the RTL code from OpenSparc. - mcp.peakDataTransferRate = XML->sys.mc.peak_transfer_rate; - mcp.memRank = XML->sys.mc.number_ranks; - //++++++++++++++PHY ++++++++++++++++++++++++++ //TODO needs better numbers - // PHY.memAccesses=PHY.peakDataTransferRate;//this is the max power - // PHY.llcBlocksize=llcBlockSize; - mcp.frontend_duty_cycle = 0.5; // for max power, the actual off-chip links - // is bidirectional but time shared - mcp.LVDS = XML->sys.mc.LVDS; - mcp.type = XML->sys.mc.type; - mcp.withPHY = XML->sys.mc.withPHY; - } - // else if (mc_type==FLASHC) - // { - // mcp.clockRate =XML->sys.flashc.mc_clock*2;//DDR double - //pumped - // mcp.clockRate *= 1e6; - // mcp.executionTime = - //XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); - // - // mcp.llcBlockSize - //=int(ceil(XML->sys.flashc.llc_line_length/8.0))+XML->sys.flashc.llc_line_length;//ecc - //overhead - // mcp.dataBusWidth =int(ceil(XML->sys.flashc.databus_width/8.0)) + - //XML->sys.flashc.databus_width; - // mcp.addressBusWidth - //=int(ceil(XML->sys.flashc.addressbus_width));//XML->sys.physical_address_width; - // mcp.opcodeW =16; - // mcp.num_mcs = XML->sys.flashc.number_mcs; - // mcp.num_channels = XML->sys.flashc.memory_channels_per_mc; - // mcp.reads = XML->sys.flashc.memory_reads; - // mcp.writes = XML->sys.flashc.memory_writes; - // //+++++++++Transaction engine +++++++++++++++++ ////TODO needs - //better numbers, Run the RTL code from OpenSparc. - // mcp.peakDataTransferRate = XML->sys.flashc.peak_transfer_rate; - // mcp.memRank = XML->sys.flashc.number_ranks; - // //++++++++++++++PHY ++++++++++++++++++++++++++ //TODO needs better - //numbers - // //PHY.memAccesses=PHY.peakDataTransferRate;//this is the max - //power - // //PHY.llcBlocksize=llcBlockSize; - // mcp.frontend_duty_cycle = 0.5;//for max power, the actual off-chip - //links is bidirectional but time shared - // mcp.LVDS = XML->sys.flashc.LVDS; - // mcp.type = XML->sys.flashc.type; - // } - else { - cout << "Unknown memory controller type: neither DRAM controller nor Flash " - "controller" - << endl; - exit(0); - } +void MemoryController::set_mc_param() +{ + + if (mc_type==MC) + { + mcp.clockRate =XML->sys.mc.mc_clock*2;//DDR double pumped + mcp.clockRate *= 1e6; + mcp.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); + + mcp.llcBlockSize =int(ceil(XML->sys.mc.llc_line_length/8.0))+XML->sys.mc.llc_line_length;//ecc overhead + mcp.dataBusWidth =int(ceil(XML->sys.mc.databus_width/8.0)) + XML->sys.mc.databus_width; + mcp.addressBusWidth =int(ceil(XML->sys.mc.addressbus_width));//XML->sys.physical_address_width; + mcp.opcodeW =16; + mcp.num_mcs = XML->sys.mc.number_mcs; + mcp.num_channels = XML->sys.mc.memory_channels_per_mc; + mcp.reads = XML->sys.mc.memory_reads; + mcp.writes = XML->sys.mc.memory_writes; + //+++++++++Transaction engine +++++++++++++++++ ////TODO needs better numbers, Run the RTL code from OpenSparc. + mcp.peakDataTransferRate = XML->sys.mc.peak_transfer_rate; + mcp.memRank = XML->sys.mc.number_ranks; + //++++++++++++++PHY ++++++++++++++++++++++++++ //TODO needs better numbers + //PHY.memAccesses=PHY.peakDataTransferRate;//this is the max power + //PHY.llcBlocksize=llcBlockSize; + mcp.frontend_duty_cycle = 0.5;//for max power, the actual off-chip links is bidirectional but time shared + mcp.LVDS = XML->sys.mc.LVDS; + mcp.type = XML->sys.mc.type; + mcp.withPHY = XML->sys.mc.withPHY; + } +// else if (mc_type==FLASHC) +// { +// mcp.clockRate =XML->sys.flashc.mc_clock*2;//DDR double pumped +// mcp.clockRate *= 1e6; +// mcp.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); +// +// mcp.llcBlockSize =int(ceil(XML->sys.flashc.llc_line_length/8.0))+XML->sys.flashc.llc_line_length;//ecc overhead +// mcp.dataBusWidth =int(ceil(XML->sys.flashc.databus_width/8.0)) + XML->sys.flashc.databus_width; +// mcp.addressBusWidth =int(ceil(XML->sys.flashc.addressbus_width));//XML->sys.physical_address_width; +// mcp.opcodeW =16; +// mcp.num_mcs = XML->sys.flashc.number_mcs; +// mcp.num_channels = XML->sys.flashc.memory_channels_per_mc; +// mcp.reads = XML->sys.flashc.memory_reads; +// mcp.writes = XML->sys.flashc.memory_writes; +// //+++++++++Transaction engine +++++++++++++++++ ////TODO needs better numbers, Run the RTL code from OpenSparc. +// mcp.peakDataTransferRate = XML->sys.flashc.peak_transfer_rate; +// mcp.memRank = XML->sys.flashc.number_ranks; +// //++++++++++++++PHY ++++++++++++++++++++++++++ //TODO needs better numbers +// //PHY.memAccesses=PHY.peakDataTransferRate;//this is the max power +// //PHY.llcBlocksize=llcBlockSize; +// mcp.frontend_duty_cycle = 0.5;//for max power, the actual off-chip links is bidirectional but time shared +// mcp.LVDS = XML->sys.flashc.LVDS; +// mcp.type = XML->sys.flashc.type; +// } + else + { + cout<<"Unknown memory controller type: neither DRAM controller nor Flash controller" < -#include -#include -#include -#include -#include "XML_Parse.h" -#include "cacti/basic_circuit.h" -#include "const.h" #include "io.h" #include "parameter.h" +#include "const.h" +#include "cacti/basic_circuit.h" +#include +#include +#include "XML_Parse.h" +#include +#include +#include +#include "noc.h" + + + +NoC::NoC(ParseXML *XML_interface, int ithNoC_, InputParameter* interface_ip_, double M_traffic_pattern_, double link_len_) +:XML(XML_interface), +ithNoC(ithNoC_), +interface_ip(*interface_ip_), +router(0), +link_bus(0), +link_bus_exist(false), +router_exist(false), +M_traffic_pattern(M_traffic_pattern_) +{ + /* + * initialize, compute and optimize individual components. + */ + + if (XML->sys.Embedded) + { + interface_ip.wt =Global_30; + interface_ip.wire_is_mat_type = 0; + interface_ip.wire_os_mat_type = 1; + } + else + { + interface_ip.wt =Global; + interface_ip.wire_is_mat_type = 2; + interface_ip.wire_os_mat_type = 2; + } + set_noc_param(); + local_result=init_interface(&interface_ip); + scktRatio = g_tp.sckt_co_eff; + + if (nocdynp.type) + {/* + * if NOC compute router, router links must be computed separately + * and called from external + * since total chip area must be known first + */ + init_router(); + } + else + { + init_link_bus(link_len_); //if bus compute bus + } -NoC::NoC(ParseXML* XML_interface, int ithNoC_, InputParameter* interface_ip_, - double M_traffic_pattern_, double link_len_) - : XML(XML_interface), - ithNoC(ithNoC_), - interface_ip(*interface_ip_), - router(0), - link_bus(0), - link_bus_exist(false), - router_exist(false), - M_traffic_pattern(M_traffic_pattern_) { - /* - * initialize, compute and optimize individual components. - */ - - if (XML->sys.Embedded) { - interface_ip.wt = Global_30; - interface_ip.wire_is_mat_type = 0; - interface_ip.wire_os_mat_type = 1; - } else { - interface_ip.wt = Global; - interface_ip.wire_is_mat_type = 2; - interface_ip.wire_os_mat_type = 2; - } - set_noc_param(); - local_result = init_interface(&interface_ip); - scktRatio = g_tp.sckt_co_eff; - - if (nocdynp.type) { /* - * if NOC compute router, router links must be - * computed separately - * and called from external - * since total chip area must be known first - */ - init_router(); - } else { - init_link_bus(link_len_); // if bus compute bus - } - - // //clock power - // clockNetwork.init_wire_external(is_default, &interface_ip); - // clockNetwork.clk_area =area*1.1;//10% of placement overhead. - // rule of thumb - // clockNetwork.end_wiring_level =5;//toplevel metal - // clockNetwork.start_wiring_level =5;//toplevel metal - // clockNetwork.num_regs = corepipe.tot_stage_vector; - // clockNetwork.optimize_wire(); + // //clock power + // clockNetwork.init_wire_external(is_default, &interface_ip); + // clockNetwork.clk_area =area*1.1;//10% of placement overhead. rule of thumb + // clockNetwork.end_wiring_level =5;//toplevel metal + // clockNetwork.start_wiring_level =5;//toplevel metal + // clockNetwork.num_regs = corepipe.tot_stage_vector; + // clockNetwork.optimize_wire(); } -void NoC::init_router() { - router = new MCPAT_Router( - nocdynp.flit_size, - nocdynp.virtual_channel_per_port * nocdynp.input_buffer_entries_per_vc, - nocdynp.virtual_channel_per_port, &(g_tp.peri_global), - nocdynp.input_ports, nocdynp.output_ports, M_traffic_pattern); - // router->print_router(); - area.set_area(area.get_area() + - router->area.get_area() * nocdynp.total_nodes); - - double long_channel_device_reduction = - longer_channel_device_reduction(Uncore_device); - router->power.readOp.longer_channel_leakage = - router->power.readOp.leakage * long_channel_device_reduction; - router->buffer.power.readOp.longer_channel_leakage = - router->buffer.power.readOp.leakage * long_channel_device_reduction; - router->crossbar.power.readOp.longer_channel_leakage = - router->crossbar.power.readOp.leakage * long_channel_device_reduction; - router->arbiter.power.readOp.longer_channel_leakage = - router->arbiter.power.readOp.leakage * long_channel_device_reduction; - router_exist = true; +void NoC::init_router() +{ + router = new MCPAT_Router(nocdynp.flit_size, + nocdynp.virtual_channel_per_port*nocdynp.input_buffer_entries_per_vc, + nocdynp.virtual_channel_per_port, &(g_tp.peri_global), + nocdynp.input_ports,nocdynp.output_ports, M_traffic_pattern); + //router->print_router(); + area.set_area(area.get_area()+ router->area.get_area()*nocdynp.total_nodes); + + double long_channel_device_reduction = longer_channel_device_reduction(Uncore_device); + router->power.readOp.longer_channel_leakage = router->power.readOp.leakage * long_channel_device_reduction; + router->buffer.power.readOp.longer_channel_leakage = router->buffer.power.readOp.leakage * long_channel_device_reduction; + router->crossbar.power.readOp.longer_channel_leakage = router->crossbar.power.readOp.leakage * long_channel_device_reduction; + router->arbiter.power.readOp.longer_channel_leakage = router->arbiter.power.readOp.leakage * long_channel_device_reduction; + router_exist = true; } -void NoC::init_link_bus(double link_len_) { - // if (nocdynp.min_ports==1 ) - if (nocdynp.type) - link_name = "Links"; - else - link_name = "Bus"; +void NoC ::init_link_bus(double link_len_) +{ + + +// if (nocdynp.min_ports==1 ) + if (nocdynp.type) + link_name = "Links"; + else + link_name = "Bus"; - link_len = link_len_; - assert(link_len > 0); + link_len=link_len_; + assert(link_len>0); - interface_ip.throughput = nocdynp.link_throughput / nocdynp.clockRate; - interface_ip.latency = nocdynp.link_latency / nocdynp.clockRate; + interface_ip.throughput = nocdynp.link_throughput/nocdynp.clockRate; + interface_ip.latency = nocdynp.link_latency/nocdynp.clockRate; - link_len /= (nocdynp.horizontal_nodes + nocdynp.vertical_nodes) / 2; + link_len /= (nocdynp.horizontal_nodes + nocdynp.vertical_nodes)/2; - if (nocdynp.total_nodes > 1) - link_len /= 2; // All links are shared by neighbors - link_bus = new interconnect(name, Uncore_device, 1, 1, nocdynp.flit_size, - link_len, &interface_ip, 3, true /*pipelinable*/, - nocdynp.route_over_perc); + if (nocdynp.total_nodes >1) link_len /=2; //All links are shared by neighbors + link_bus = new interconnect(name, Uncore_device, 1, 1, nocdynp.flit_size, + link_len, &interface_ip, 3, true/*pipelinable*/, nocdynp.route_over_perc); - link_bus_tot_per_Router.area.set_area( - link_bus_tot_per_Router.area.get_area() + - link_bus->area.get_area() * nocdynp.global_linked_ports); + link_bus_tot_per_Router.area.set_area(link_bus_tot_per_Router.area.get_area()+ link_bus->area.get_area() + * nocdynp.global_linked_ports); - area.set_area(area.get_area() + - link_bus_tot_per_Router.area.get_area() * nocdynp.total_nodes); - link_bus_exist = true; + area.set_area(area.get_area()+ link_bus_tot_per_Router.area.get_area()* nocdynp.total_nodes); + link_bus_exist = true; } -void NoC::computeEnergy(bool is_tdp) { - // power_point_product_masks - double pppm_t[4] = {1, 1, 1, 1}; - double M = nocdynp.duty_cycle; - // nocdynp.executionTime=XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6);//Syed - // cout<<"NOC Total Cycles: "<sys.total_cycles<sys.target_core_clockrate<power = router->power * pppm_t; - set_pppm(pppm_t, nocdynp.total_nodes, nocdynp.total_nodes, - nocdynp.total_nodes, nocdynp.total_nodes); - power = power + router->power * pppm_t; - } - if (link_bus_exist) { - if (nocdynp.type) - set_pppm(pppm_t, 1 * M_traffic_pattern * M * (nocdynp.min_ports - 1), - nocdynp.global_linked_ports, nocdynp.global_linked_ports, - nocdynp.global_linked_ports); - // reset traffic pattern; local port do not have router links - else - set_pppm(pppm_t, 1 * M_traffic_pattern * M * (nocdynp.min_ports), - nocdynp.global_linked_ports, nocdynp.global_linked_ports, - nocdynp.global_linked_ports); // reset traffic pattern - - link_bus_tot_per_Router.power = link_bus->power * pppm_t; - - set_pppm(pppm_t, nocdynp.total_nodes, nocdynp.total_nodes, - nocdynp.total_nodes, nocdynp.total_nodes); - power = power + link_bus_tot_per_Router.power * pppm_t; - } - } else { - rt_power.reset(); - router->buffer.rt_power.reset(); - router->crossbar.rt_power.reset(); - router->arbiter.rt_power.reset(); - router->rt_power.reset(); - // link_bus->rt_power.reset(); - - // init stats for runtime power (RTP) - stats_t.readAc.access = XML->sys.NoC[ithNoC].total_accesses; - // cout<<"NOC(computeEnergy) read accesses: "<< stats_t.readAc.access<buffer.rt_power.readOp.dynamic = - (router->buffer.power.readOp.dynamic + - router->buffer.power.writeOp.dynamic) * - rtp_stats.readAc.access; - router->crossbar.rt_power.readOp.dynamic = - router->crossbar.power.readOp.dynamic * rtp_stats.readAc.access; - router->arbiter.rt_power.readOp.dynamic = - router->arbiter.power.readOp.dynamic * rtp_stats.readAc.access; - - router->rt_power = - router->rt_power + - (router->buffer.rt_power + router->crossbar.rt_power + - router->arbiter.rt_power) * - pppm_t + - router->power * pppm_lkg; // TDP power must be calculated first! - rt_power = rt_power + router->rt_power; - } - if (link_bus_exist) { - link_bus->rt_power.reset(); - set_pppm(pppm_t, rtp_stats.readAc.access, 1, 1, rtp_stats.readAc.access); - link_bus->rt_power = link_bus->power * pppm_t; - rt_power = rt_power + link_bus->rt_power; - } - } +void NoC::computeEnergy(bool is_tdp) +{ + //power_point_product_masks + double pppm_t[4] = {1,1,1,1}; + double M=nocdynp.duty_cycle; + // nocdynp.executionTime=XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6);//Syed + //cout<<"NOC Total Cycles: "<sys.total_cycles<sys.target_core_clockrate<power = router->power*pppm_t; + set_pppm(pppm_t, nocdynp.total_nodes, nocdynp.total_nodes, nocdynp.total_nodes, nocdynp.total_nodes); + power = power + router->power*pppm_t; + } + if (link_bus_exist) + { + if (nocdynp.type) + set_pppm(pppm_t, 1*M_traffic_pattern*M*(nocdynp.min_ports -1), nocdynp.global_linked_ports, + nocdynp.global_linked_ports, nocdynp.global_linked_ports); + //reset traffic pattern; local port do not have router links + else + set_pppm(pppm_t, 1*M_traffic_pattern*M*(nocdynp.min_ports), nocdynp.global_linked_ports, + nocdynp.global_linked_ports, nocdynp.global_linked_ports);//reset traffic pattern + + link_bus_tot_per_Router.power = link_bus->power*pppm_t; + + set_pppm(pppm_t, nocdynp.total_nodes, + nocdynp.total_nodes, + nocdynp.total_nodes, + nocdynp.total_nodes); + power = power + link_bus_tot_per_Router.power*pppm_t; + + } + } + else + { + rt_power.reset(); + router->buffer.rt_power.reset(); + router->crossbar.rt_power.reset(); + router->arbiter.rt_power.reset(); + router->rt_power.reset(); + //link_bus->rt_power.reset(); + + //init stats for runtime power (RTP) + stats_t.readAc.access = XML->sys.NoC[ithNoC].total_accesses; + //cout<<"NOC(computeEnergy) read accesses: "<< stats_t.readAc.access<buffer.rt_power.readOp.dynamic = (router->buffer.power.readOp.dynamic + router->buffer.power.writeOp.dynamic)*rtp_stats.readAc.access ; + router->crossbar.rt_power.readOp.dynamic = router->crossbar.power.readOp.dynamic*rtp_stats.readAc.access ; + router->arbiter.rt_power.readOp.dynamic = router->arbiter.power.readOp.dynamic*rtp_stats.readAc.access ; + + router->rt_power = router->rt_power + (router->buffer.rt_power + router->crossbar.rt_power + router->arbiter.rt_power)*pppm_t + + router->power*pppm_lkg;//TDP power must be calculated first! + rt_power = rt_power + router->rt_power; + } + if (link_bus_exist) + { + link_bus->rt_power.reset(); + set_pppm(pppm_t, rtp_stats.readAc.access, 1 , 1, rtp_stats.readAc.access); + link_bus->rt_power = link_bus->power * pppm_t; + rt_power = rt_power + link_bus->rt_power; + } + + } } -void NoC::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; - - double M = M_traffic_pattern * nocdynp.duty_cycle; - /*only router as a whole has been applied the M_traffic_pattern(0.6 by - * default) factor in router.cc; - * When power of crossbars, arbiters, etc need to be displayed, the - * M_traffic_pattern factor need to - * be applied together with McPAT's extra traffic pattern. - * */ - if (is_tdp) { - cout << name << endl; - cout << indent_str << "Area = " << area.get_area() * 1e-6 << " mm^2" - << endl; - cout << indent_str - << "Peak Dynamic = " << power.readOp.dynamic * nocdynp.clockRate - << " W" << endl; - cout << indent_str << "Subthreshold Leakage = " - << (long_channel ? power.readOp.longer_channel_leakage - : power.readOp.leakage) - << " W" << endl; - cout << indent_str << "Gate Leakage = " << power.readOp.gate_leakage << " W" - << endl; - cout << indent_str << "Runtime Dynamic = " - << rt_power.readOp.dynamic / nocdynp.executionTime << " W" << endl; - // cout << indent_str<< "Execution Time = " << nocdynp.executionTime << " s" - // << endl; - cout << endl; - - if (router_exist) { - cout << indent_str << "Router: " << endl; - cout << indent_str_next << "Area = " << router->area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " - << router->power.readOp.dynamic * nocdynp.clockRate << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? router->power.readOp.longer_channel_leakage - : router->power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << router->power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next << "Runtime Dynamic = " - << router->rt_power.readOp.dynamic / nocdynp.executionTime << " W" - << endl; - cout << endl; - if (plevel > 2) { - cout << indent_str << indent_str << "Virtual Channel Buffer:" << endl; - cout << indent_str << indent_str_next << "Area = " - << router->buffer.area.get_area() * 1e-6 * nocdynp.input_ports - << " mm^2" << endl; - cout << indent_str << indent_str_next << "Peak Dynamic = " - << (router->buffer.power.readOp.dynamic + - router->buffer.power.writeOp.dynamic) * - nocdynp.min_ports * M * nocdynp.clockRate - << " W" << endl; - cout << indent_str << indent_str_next << "Subthreshold Leakage = " - << (long_channel - ? router->buffer.power.readOp.longer_channel_leakage * - nocdynp.input_ports - : router->buffer.power.readOp.leakage * - nocdynp.input_ports) - << " W" << endl; - cout << indent_str << indent_str_next << "Gate Leakage = " - << router->buffer.power.readOp.gate_leakage * nocdynp.input_ports - << " W" << endl; - cout << indent_str << indent_str_next << "Runtime Dynamic = " - << router->buffer.rt_power.readOp.dynamic / nocdynp.executionTime - << " W" << endl; - cout << endl; - cout << indent_str << indent_str << "Crossbar:" << endl; - cout << indent_str << indent_str_next - << "Area = " << router->crossbar.area.get_area() * 1e-6 << " mm^2" - << endl; - cout << indent_str << indent_str_next << "Peak Dynamic = " - << router->crossbar.power.readOp.dynamic * nocdynp.clockRate * - nocdynp.min_ports * M - << " W" << endl; - cout << indent_str << indent_str_next << "Subthreshold Leakage = " - << (long_channel - ? router->crossbar.power.readOp.longer_channel_leakage - : router->crossbar.power.readOp.leakage) - << " W" << endl; - cout << indent_str << indent_str_next - << "Gate Leakage = " << router->crossbar.power.readOp.gate_leakage - << " W" << endl; - cout << indent_str << indent_str_next << "Runtime Dynamic = " - << router->crossbar.rt_power.readOp.dynamic / nocdynp.executionTime - << " W" << endl; - cout << endl; - cout << indent_str << indent_str << "Arbiter:" << endl; - cout << indent_str << indent_str_next << "Peak Dynamic = " - << router->arbiter.power.readOp.dynamic * nocdynp.clockRate * - nocdynp.min_ports * M - << " W" << endl; - cout << indent_str << indent_str_next << "Subthreshold Leakage = " - << (long_channel - ? router->arbiter.power.readOp.longer_channel_leakage - : router->arbiter.power.readOp.leakage) - << " W" << endl; - cout << indent_str << indent_str_next - << "Gate Leakage = " << router->arbiter.power.readOp.gate_leakage - << " W" << endl; - cout << indent_str << indent_str_next << "Runtime Dynamic = " - << router->arbiter.rt_power.readOp.dynamic / nocdynp.executionTime - << " W" << endl; - cout << endl; - } - } - if (link_bus_exist) { - cout << indent_str << (nocdynp.type ? "Per Router " : "") << link_name - << ": " << endl; - cout << indent_str_next - << "Area = " << link_bus_tot_per_Router.area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " - << link_bus_tot_per_Router.power.readOp.dynamic * nocdynp.clockRate - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel - ? link_bus_tot_per_Router.power.readOp.longer_channel_leakage - : link_bus_tot_per_Router.power.readOp.leakage) - << " W" << endl; - cout << indent_str_next << "Gate Leakage = " - << link_bus_tot_per_Router.power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " - << link_bus->rt_power.readOp.dynamic / nocdynp.executionTime << " W" - << endl; - cout << endl; - } - } else { - // cout << indent_str_next << "Instruction Fetch Unit Peak Dynamic = " - //<< ifu->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Instruction Fetch Unit Subthreshold - //Leakage = " << ifu->rt_power.readOp.leakage <<" W" << endl; - // cout << indent_str_next << "Instruction Fetch Unit Gate Leakage = " - //<< ifu->rt_power.readOp.gate_leakage << " W" << endl; - // cout << indent_str_next << "Load Store Unit Peak Dynamic = " << - //lsu->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Load Store Unit Subthreshold Leakage = " - //<< lsu->rt_power.readOp.leakage << " W" << endl; - // cout << indent_str_next << "Load Store Unit Gate Leakage = " << - //lsu->rt_power.readOp.gate_leakage << " W" << endl; - // cout << indent_str_next << "Memory Management Unit Peak Dynamic = " - //<< mmu->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Memory Management Unit Subthreshold - //Leakage = " << mmu->rt_power.readOp.leakage << " W" << endl; - // cout << indent_str_next << "Memory Management Unit Gate Leakage = " - //<< mmu->rt_power.readOp.gate_leakage << " W" << endl; - // cout << indent_str_next << "Execution Unit Peak Dynamic = " << - //exu->rt_power.readOp.dynamic*clockRate << " W" << endl; - // cout << indent_str_next << "Execution Unit Subthreshold Leakage = " - //<< exu->rt_power.readOp.leakage << " W" << endl; - // cout << indent_str_next << "Execution Unit Gate Leakage = " << - //exu->rt_power.readOp.gate_leakage << " W" << endl; - } + +void NoC::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; + + double M =M_traffic_pattern*nocdynp.duty_cycle; + /*only router as a whole has been applied the M_traffic_pattern(0.6 by default) factor in router.cc; + * When power of crossbars, arbiters, etc need to be displayed, the M_traffic_pattern factor need to + * be applied together with McPAT's extra traffic pattern. + * */ + if (is_tdp) + { + cout << name << endl; + cout << indent_str << "Area = " << area.get_area()*1e-6<< " mm^2" << endl; + cout << indent_str<< "Peak Dynamic = " << power.readOp.dynamic*nocdynp.clockRate << " W" << endl; + cout << indent_str << "Subthreshold Leakage = " + << (long_channel? power.readOp.longer_channel_leakage:power.readOp.leakage) <<" W" << endl; + cout << indent_str << "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl; + cout << indent_str<< "Runtime Dynamic = " << rt_power.readOp.dynamic/nocdynp.executionTime << " W" << endl; + //cout << indent_str<< "Execution Time = " << nocdynp.executionTime << " s" << endl; + cout<2){ + cout << indent_str<< indent_str << "Virtual Channel Buffer:" << endl; + cout << indent_str<< indent_str_next << "Area = " << router->buffer.area.get_area()*1e-6*nocdynp.input_ports<< " mm^2" << endl; + cout << indent_str<< indent_str_next << "Peak Dynamic = " <<(router->buffer.power.readOp.dynamic + router->buffer.power.writeOp.dynamic) + *nocdynp.min_ports*M*nocdynp.clockRate << " W" << endl; + cout << indent_str<< indent_str_next << "Subthreshold Leakage = " + << (long_channel? router->buffer.power.readOp.longer_channel_leakage*nocdynp.input_ports:router->buffer.power.readOp.leakage*nocdynp.input_ports) <<" W" << endl; + cout << indent_str<< indent_str_next << "Gate Leakage = " << router->buffer.power.readOp.gate_leakage*nocdynp.input_ports << " W" << endl; + cout << indent_str<< indent_str_next << "Runtime Dynamic = " << router->buffer.rt_power.readOp.dynamic/nocdynp.executionTime << " W" << endl; + cout <sys.NoC[ithNoC].type; - nocdynp.clockRate = XML->sys.NoC[ithNoC].clockrate; - nocdynp.clockRate *= 1e6; - nocdynp.executionTime = - XML->sys.total_cycles / (XML->sys.target_core_clockrate * 1e6); - - nocdynp.flit_size = XML->sys.NoC[ithNoC].flit_bits; - if (nocdynp.type) { - nocdynp.input_ports = XML->sys.NoC[ithNoC].input_ports; - nocdynp.output_ports = XML->sys.NoC[ithNoC].output_ports; // later minus 1 - nocdynp.min_ports = min(nocdynp.input_ports, nocdynp.output_ports); - nocdynp.global_linked_ports = - (nocdynp.input_ports - 1) + (nocdynp.output_ports - 1); - /* - * Except local i/o ports, all ports needs links( global_linked_ports); - * However only min_ports can be fully active simultaneously - * since the fewer number of ports (input or output ) is the bottleneck. - */ - } else { - nocdynp.input_ports = 1; - nocdynp.output_ports = 1; - nocdynp.min_ports = min(nocdynp.input_ports, nocdynp.output_ports); - nocdynp.global_linked_ports = 1; - } - - nocdynp.virtual_channel_per_port = - XML->sys.NoC[ithNoC].virtual_channel_per_port; - nocdynp.input_buffer_entries_per_vc = - XML->sys.NoC[ithNoC].input_buffer_entries_per_vc; - - nocdynp.horizontal_nodes = XML->sys.NoC[ithNoC].horizontal_nodes; - nocdynp.vertical_nodes = XML->sys.NoC[ithNoC].vertical_nodes; - nocdynp.total_nodes = nocdynp.horizontal_nodes * nocdynp.vertical_nodes; - nocdynp.duty_cycle = XML->sys.NoC[ithNoC].duty_cycle; - nocdynp.has_global_link = XML->sys.NoC[ithNoC].has_global_link; - nocdynp.link_throughput = XML->sys.NoC[ithNoC].link_throughput; - nocdynp.link_latency = XML->sys.NoC[ithNoC].link_latency; - nocdynp.chip_coverage = XML->sys.NoC[ithNoC].chip_coverage; - nocdynp.route_over_perc = XML->sys.NoC[ithNoC].route_over_perc; - - assert(nocdynp.chip_coverage <= 1); - assert(nocdynp.route_over_perc <= 1); - - if (nocdynp.type) - name = "NOC"; - else - name = "BUSES"; +void NoC::set_noc_param() +{ + + nocdynp.type = XML->sys.NoC[ithNoC].type; + nocdynp.clockRate =XML->sys.NoC[ithNoC].clockrate; + nocdynp.clockRate *= 1e6; + nocdynp.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); + + nocdynp.flit_size = XML->sys.NoC[ithNoC].flit_bits; + if (nocdynp.type) + { + nocdynp.input_ports = XML->sys.NoC[ithNoC].input_ports; + nocdynp.output_ports = XML->sys.NoC[ithNoC].output_ports;//later minus 1 + nocdynp.min_ports = min(nocdynp.input_ports,nocdynp.output_ports); + nocdynp.global_linked_ports = (nocdynp.input_ports-1) + (nocdynp.output_ports-1); + /* + * Except local i/o ports, all ports needs links( global_linked_ports); + * However only min_ports can be fully active simultaneously + * since the fewer number of ports (input or output ) is the bottleneck. + */ + } + else + { + nocdynp.input_ports = 1; + nocdynp.output_ports = 1; + nocdynp.min_ports = min(nocdynp.input_ports,nocdynp.output_ports); + nocdynp.global_linked_ports = 1; + } + + nocdynp.virtual_channel_per_port = XML->sys.NoC[ithNoC].virtual_channel_per_port; + nocdynp.input_buffer_entries_per_vc = XML->sys.NoC[ithNoC].input_buffer_entries_per_vc; + + nocdynp.horizontal_nodes = XML->sys.NoC[ithNoC].horizontal_nodes; + nocdynp.vertical_nodes = XML->sys.NoC[ithNoC].vertical_nodes; + nocdynp.total_nodes = nocdynp.horizontal_nodes*nocdynp.vertical_nodes; + nocdynp.duty_cycle = XML->sys.NoC[ithNoC].duty_cycle; + nocdynp.has_global_link = XML->sys.NoC[ithNoC].has_global_link; + nocdynp.link_throughput = XML->sys.NoC[ithNoC].link_throughput; + nocdynp.link_latency = XML->sys.NoC[ithNoC].link_latency; + nocdynp.chip_coverage = XML->sys.NoC[ithNoC].chip_coverage; + nocdynp.route_over_perc = XML->sys.NoC[ithNoC].route_over_perc; + + assert (nocdynp.chip_coverage <=1); + assert (nocdynp.route_over_perc <=1); + + if (nocdynp.type) + name = "NOC"; + else + name = "BUSES"; + } -NoC::~NoC() { - if (router) { - delete router; - router = 0; - } - if (link_bus) { - delete link_bus; - link_bus = 0; - } + +NoC ::~NoC(){ + + if(router) {delete router; router = 0;} + if(link_bus) {delete link_bus; link_bus = 0;} } diff --git a/src/gpuwattch/noc.h b/src/gpuwattch/noc.h index c92e802..f3f6e84 100644 --- a/src/gpuwattch/noc.h +++ b/src/gpuwattch/noc.h @@ -29,8 +29,7 @@ * ***************************************************************************/ /******************************************************************** -* Modified by: -** +* Modified by: * * Jingwen Leng, Univeristy of Texas, Austin * * Syed Gilani, University of Wisconsin–Madison * * Tayler Hetherington, University of British Columbia * @@ -40,45 +39,44 @@ #ifndef NOC_H_ #define NOC_H_ #include "XML_Parse.h" +#include "logic.h" +#include "cacti/parameter.h" #include "array.h" +#include "interconnect.h" #include "basic_components.h" -#include "cacti/parameter.h" #include "cacti/router.h" -#include "interconnect.h" -#include "logic.h" -class NoC : public Component { - public: - ParseXML *XML; - int ithNoC; - InputParameter interface_ip; - double link_len; - double executionTime; - double scktRatio, chip_PR_overhead, macro_PR_overhead; - MCPAT_Router *router; - interconnect *link_bus; - NoCParam nocdynp; - uca_org_t local_result; - statsDef tdp_stats; - statsDef rtp_stats; - statsDef stats_t; - powerDef power_t; - Component link_bus_tot_per_Router; - bool link_bus_exist; - bool router_exist; - string name, link_name; - double M_traffic_pattern; - NoC(ParseXML *XML_interface, int ithNoC_, InputParameter *interface_ip_, - double M_traffic_pattern_ = 0.6, double link_len_ = 0); - void set_noc_param(); - void computeEnergy(bool is_tdp = true); - void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); - void init_link_bus(double link_len_); - void init_router(); - void computeEnergy_link_bus(bool is_tdp = true); - void displayEnergy_link_bus(uint32_t indent = 0, int plevel = 100, - bool is_tdp = true); - ~NoC(); +class NoC :public Component { + public: + + ParseXML *XML; + int ithNoC; + InputParameter interface_ip; + double link_len; + double executionTime; + double scktRatio, chip_PR_overhead, macro_PR_overhead; + MCPAT_Router * router; + interconnect * link_bus; + NoCParam nocdynp; + uca_org_t local_result; + statsDef tdp_stats; + statsDef rtp_stats; + statsDef stats_t; + powerDef power_t; + Component link_bus_tot_per_Router; + bool link_bus_exist; + bool router_exist; + string name, link_name; + double M_traffic_pattern; + NoC(ParseXML *XML_interface, int ithNoC_, InputParameter* interface_ip_, double M_traffic_pattern_ = 0.6,double link_len_=0); + void set_noc_param(); + void computeEnergy(bool is_tdp=true); + void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); + void init_link_bus(double link_len_); + void init_router(); + void computeEnergy_link_bus(bool is_tdp=true); + void displayEnergy_link_bus(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); + ~NoC(); }; #endif /* NOC_H_ */ diff --git a/src/gpuwattch/processor.cc b/src/gpuwattch/processor.cc index 96c3351..5dda9fc 100644 --- a/src/gpuwattch/processor.cc +++ b/src/gpuwattch/processor.cc @@ -29,1185 +29,1034 @@ * ***************************************************************************/ /******************************************************************** -* Modified by: -** +* 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 "processor.h" -#include -#include -#include #include +#include +#include #include +#include #include +#include #include -#include -#include "XML_Parse.h" +#include "parameter.h" #include "array.h" -#include "cacti/basic_circuit.h" #include "const.h" -#include "parameter.h" +#include "cacti/basic_circuit.h" +#include "XML_Parse.h" +#include "processor.h" #include "version.h" + Processor::Processor(ParseXML *XML_interface) - : XML(XML_interface), // TODO: using one global copy may have problems. - mc(0), - niu(0), - pcie(0), - flashcontroller(0) { +:XML(XML_interface),//TODO: using one global copy may have problems. + mc(0), + niu(0), + pcie(0), + flashcontroller(0) +{ /* - * placement and routing overhead is 10%, core scales worse than cache 40% is - * accumulated from 90 to 22nm + * placement and routing overhead is 10%, core scales worse than cache 40% is accumulated from 90 to 22nm * There is no point to have heterogeneous memory controller on chip, * thus McPAT only support homogeneous memory controllers. */ rt_power.reset(); int i; - double pppm_t[4] = {1, 1, 1, 1}; - l2_power = 0; - idle_core_power = 0; + double pppm_t[4] = {1,1,1,1}; + l2_power=0; + idle_core_power=0; set_proc_param(); if (procdynp.homoCore) - numCore = procdynp.numCore == 0 ? 0 : 1; + numCore = procdynp.numCore==0? 0:1; else - numCore = procdynp.numCore; + numCore = procdynp.numCore; if (procdynp.homoL2) - numL2 = procdynp.numL2 == 0 ? 0 : 1; + numL2 = procdynp.numL2==0? 0:1; else - numL2 = procdynp.numL2; + numL2 = procdynp.numL2; - if (XML->sys.Private_L2 && numCore != numL2) { - cout << "Number of private L2 does not match number of cores" << endl; - exit(0); + if (XML->sys.Private_L2 && numCore != numL2) + { + cout<<"Number of private L2 does not match number of cores"<computeEnergy(); - cores[i]->computeEnergy(false); - if (procdynp.homoCore) { - core.area.set_area(core.area.get_area() + - cores[i]->area.get_area() * procdynp.numCore); - set_pppm(pppm_t, cores[i]->clockRate * procdynp.numCore, procdynp.numCore, - procdynp.numCore, procdynp.numCore); - // set the exClockRate - exClockRate = cores[0]->clockRate * 2; // TODO; get from XML file - // cout<<"****EX clock rate:"<power * pppm_t; - set_pppm(pppm_t, 1 / cores[i]->executionTime, procdynp.numCore, - procdynp.numCore, procdynp.numCore); - core.rt_power = core.rt_power + cores[i]->rt_power * pppm_t; - area.set_area(area.get_area() + - core.area.get_area()); // placement and routing overhead is - // 10%, core scales worse than cache - // 40% is accumulated from 90 to - // 22nm - power = power + core.power; - rt_power = rt_power + core.rt_power; - } else { - core.area.set_area(core.area.get_area() + cores[i]->area.get_area()); - area.set_area(area.get_area() + - cores[i]->area.get_area()); // placement and routing - // overhead is 10%, core scales - // worse than cache 40% is - // accumulated from 90 to 22nm - - set_pppm(pppm_t, cores[i]->clockRate, 1, 1, 1); - // set the exClockRate - exClockRate = cores[0]->clockRate; // TODO; get from XML file - // cout<<"****EX clock rate:"<power * pppm_t; - power = power + cores[i]->power * pppm_t; - - set_pppm(pppm_t, 1 / cores[i]->executionTime, 1, 1, 1); - core.rt_power = core.rt_power + cores[i]->rt_power * pppm_t; - rt_power = rt_power + cores[i]->rt_power * pppm_t; - } + numL2Dir = procdynp.numL2Dir; + + for (i = 0;i < numCore; i++) + { + cores.push_back(new Core(XML,i, &interface_ip)); + cores[i]->computeEnergy(); + cores[i]->computeEnergy(false); + if (procdynp.homoCore){ + core.area.set_area(core.area.get_area() + cores[i]->area.get_area()*procdynp.numCore); + set_pppm(pppm_t,cores[i]->clockRate*procdynp.numCore, procdynp.numCore,procdynp.numCore,procdynp.numCore); + //set the exClockRate + exClockRate=cores[0]->clockRate*2;//TODO; get from XML file + //cout<<"****EX clock rate:"<power*pppm_t; + set_pppm(pppm_t,1/cores[i]->executionTime, procdynp.numCore,procdynp.numCore,procdynp.numCore); + core.rt_power = core.rt_power + cores[i]->rt_power*pppm_t; + area.set_area(area.get_area() + core.area.get_area());//placement and routing overhead is 10%, core scales worse than cache 40% is accumulated from 90 to 22nm + power = power + core.power; + rt_power = rt_power + core.rt_power; + } + else{ + core.area.set_area(core.area.get_area() + cores[i]->area.get_area()); + area.set_area(area.get_area() + cores[i]->area.get_area());//placement and routing overhead is 10%, core scales worse than cache 40% is accumulated from 90 to 22nm + + set_pppm(pppm_t,cores[i]->clockRate, 1, 1, 1); + //set the exClockRate + exClockRate=cores[0]->clockRate;//TODO; get from XML file + //cout<<"****EX clock rate:"<power*pppm_t; + power = power + cores[i]->power*pppm_t; + + set_pppm(pppm_t,1/cores[i]->executionTime, 1, 1, 1); + core.rt_power = core.rt_power + cores[i]->rt_power*pppm_t; + rt_power = rt_power + cores[i]->rt_power*pppm_t; + } } - if (!XML->sys.Private_L2) { - if (numL2 > 0) - for (i = 0; i < numL2; i++) { - l2array.push_back(new SharedCache(XML, i, &interface_ip)); - - l2array[i]->computeEnergy(); - l2array[i]->computeEnergy(false); - if (procdynp.homoL2) { - l2.area.set_area(l2.area.get_area() + - l2array[i]->area.get_area() * procdynp.numL2); - set_pppm(pppm_t, l2array[i]->cachep.clockRate * procdynp.numL2, - procdynp.numL2, procdynp.numL2, procdynp.numL2); - l2.power = l2.power + l2array[i]->power * pppm_t; - set_pppm(pppm_t, 1 / l2array[i]->cachep.executionTime, procdynp.numL2, - procdynp.numL2, procdynp.numL2); - l2.rt_power = l2.rt_power + l2array[i]->rt_power * pppm_t; - area.set_area(area.get_area() + - l2.area.get_area()); // placement and routing overhead - // is 10%, l2 scales worse than - // cache 40% is accumulated from - // 90 to 22nm - power = power + l2.power; - rt_power = rt_power + l2.rt_power; - } else { - l2.area.set_area(l2.area.get_area() + l2array[i]->area.get_area()); - area.set_area(area.get_area() + - l2array[i]->area.get_area()); // placement and routing - // overhead is 10%, l2 - // scales worse than - // cache 40% is - // accumulated from 90 to - // 22nm - - set_pppm(pppm_t, l2array[i]->cachep.clockRate, 1, 1, 1); - l2.power = l2.power + l2array[i]->power * pppm_t; - power = power + l2array[i]->power * pppm_t; - ; - set_pppm(pppm_t, 1 / l2array[i]->cachep.executionTime, 1, 1, 1); - l2.rt_power = l2.rt_power + l2array[i]->rt_power * pppm_t; - rt_power = rt_power + l2array[i]->rt_power * pppm_t; - } - } + if (!XML->sys.Private_L2) + { + + if (numL2 >0) + for (i = 0;i < numL2; i++) + { + l2array.push_back(new SharedCache(XML,i, &interface_ip)); + + l2array[i]->computeEnergy(); + l2array[i]->computeEnergy(false); + if (procdynp.homoL2){ + l2.area.set_area(l2.area.get_area() + l2array[i]->area.get_area()*procdynp.numL2); + set_pppm(pppm_t,l2array[i]->cachep.clockRate*procdynp.numL2, procdynp.numL2,procdynp.numL2,procdynp.numL2); + l2.power = l2.power + l2array[i]->power*pppm_t; + set_pppm(pppm_t,1/l2array[i]->cachep.executionTime, procdynp.numL2,procdynp.numL2,procdynp.numL2); + l2.rt_power = l2.rt_power + l2array[i]->rt_power*pppm_t; + area.set_area(area.get_area() + l2.area.get_area());//placement and routing overhead is 10%, l2 scales worse than cache 40% is accumulated from 90 to 22nm + power = power + l2.power; + rt_power = rt_power + l2.rt_power; + } + else{ + l2.area.set_area(l2.area.get_area() + l2array[i]->area.get_area()); + area.set_area(area.get_area() + l2array[i]->area.get_area());//placement and routing overhead is 10%, l2 scales worse than cache 40% is accumulated from 90 to 22nm + + set_pppm(pppm_t,l2array[i]->cachep.clockRate, 1, 1, 1); + l2.power = l2.power + l2array[i]->power*pppm_t; + power = power + l2array[i]->power*pppm_t;; + set_pppm(pppm_t,1/l2array[i]->cachep.executionTime, 1, 1, 1); + l2.rt_power = l2.rt_power + l2array[i]->rt_power*pppm_t; + rt_power = rt_power + l2array[i]->rt_power*pppm_t; + } + } } - if (numL3 > 0) - for (i = 0; i < numL3; i++) { - l3array.push_back(new SharedCache(XML, i, &interface_ip, L3)); - l3array[i]->computeEnergy(); - l3array[i]->computeEnergy(false); - if (procdynp.homoL3) { - l3.area.set_area(l3.area.get_area() + - l3array[i]->area.get_area() * procdynp.numL3); - set_pppm(pppm_t, l3array[i]->cachep.clockRate * procdynp.numL3, - procdynp.numL3, procdynp.numL3, procdynp.numL3); - l3.power = l3.power + l3array[i]->power * pppm_t; - set_pppm(pppm_t, 1 / l3array[i]->cachep.executionTime, procdynp.numL3, - procdynp.numL3, procdynp.numL3); - l3.rt_power = l3.rt_power + l3array[i]->rt_power * pppm_t; - area.set_area(area.get_area() + - l3.area.get_area()); // placement and routing overhead is - // 10%, l3 scales worse than cache - // 40% is accumulated from 90 to - // 22nm - power = power + l3.power; - rt_power = rt_power + l3.rt_power; - - } else { - l3.area.set_area(l3.area.get_area() + l3array[i]->area.get_area()); - area.set_area(area.get_area() + - l3array[i]->area.get_area()); // placement and routing - // overhead is 10%, l3 - // scales worse than cache - // 40% is accumulated from - // 90 to 22nm - set_pppm(pppm_t, l3array[i]->cachep.clockRate, 1, 1, 1); - l3.power = l3.power + l3array[i]->power * pppm_t; - power = power + l3array[i]->power * pppm_t; - set_pppm(pppm_t, 1 / l3array[i]->cachep.executionTime, 1, 1, 1); - l3.rt_power = l3.rt_power + l3array[i]->rt_power * pppm_t; - rt_power = rt_power + l3array[i]->rt_power * pppm_t; - } - } - if (numL1Dir > 0) - for (i = 0; i < numL1Dir; i++) { - l1dirarray.push_back(new SharedCache(XML, i, &interface_ip, L1Directory)); - l1dirarray[i]->computeEnergy(); - l1dirarray[i]->computeEnergy(false); - if (procdynp.homoL1Dir) { - l1dir.area.set_area(l1dir.area.get_area() + - l1dirarray[i]->area.get_area() * procdynp.numL1Dir); - set_pppm(pppm_t, l1dirarray[i]->cachep.clockRate * procdynp.numL1Dir, - procdynp.numL1Dir, procdynp.numL1Dir, procdynp.numL1Dir); - l1dir.power = l1dir.power + l1dirarray[i]->power * pppm_t; - set_pppm(pppm_t, 1 / l1dirarray[i]->cachep.executionTime, - procdynp.numL1Dir, procdynp.numL1Dir, procdynp.numL1Dir); - l1dir.rt_power = l1dir.rt_power + l1dirarray[i]->rt_power * pppm_t; - area.set_area(area.get_area() + - l1dir.area.get_area()); // placement and routing overhead - // is 10%, l1dir scales worse - // than cache 40% is accumulated - // from 90 to 22nm - power = power + l1dir.power; - rt_power = rt_power + l1dir.rt_power; - - } else { - l1dir.area.set_area(l1dir.area.get_area() + - l1dirarray[i]->area.get_area()); - area.set_area(area.get_area() + l1dirarray[i]->area.get_area()); - set_pppm(pppm_t, l1dirarray[i]->cachep.clockRate, 1, 1, 1); - l1dir.power = l1dir.power + l1dirarray[i]->power * pppm_t; - power = power + l1dirarray[i]->power; - set_pppm(pppm_t, 1 / l1dirarray[i]->cachep.executionTime, 1, 1, 1); - l1dir.rt_power = l1dir.rt_power + l1dirarray[i]->rt_power * pppm_t; - rt_power = rt_power + l1dirarray[i]->rt_power; - } - } - - if (numL2Dir > 0) - for (i = 0; i < numL2Dir; i++) { - l2dirarray.push_back(new SharedCache(XML, i, &interface_ip, L2Directory)); - l2dirarray[i]->computeEnergy(); - l2dirarray[i]->computeEnergy(false); - if (procdynp.homoL2Dir) { - l2dir.area.set_area(l2dir.area.get_area() + - l2dirarray[i]->area.get_area() * procdynp.numL2Dir); - set_pppm(pppm_t, l2dirarray[i]->cachep.clockRate * procdynp.numL2Dir, - procdynp.numL2Dir, procdynp.numL2Dir, procdynp.numL2Dir); - l2dir.power = l2dir.power + l2dirarray[i]->power * pppm_t; - set_pppm(pppm_t, 1 / l2dirarray[i]->cachep.executionTime, - procdynp.numL2Dir, procdynp.numL2Dir, procdynp.numL2Dir); - l2dir.rt_power = l2dir.rt_power + l2dirarray[i]->rt_power * pppm_t; - area.set_area(area.get_area() + - l2dir.area.get_area()); // placement and routing overhead - // is 10%, l2dir scales worse - // than cache 40% is accumulated - // from 90 to 22nm - power = power + l2dir.power; - rt_power = rt_power + l2dir.rt_power; - - } else { - l2dir.area.set_area(l2dir.area.get_area() + - l2dirarray[i]->area.get_area()); - area.set_area(area.get_area() + l2dirarray[i]->area.get_area()); - set_pppm(pppm_t, l2dirarray[i]->cachep.clockRate, 1, 1, 1); - l2dir.power = l2dir.power + l2dirarray[i]->power * pppm_t; - power = power + l2dirarray[i]->power * pppm_t; - set_pppm(pppm_t, 1 / l2dirarray[i]->cachep.executionTime, 1, 1, 1); - l2dir.rt_power = l2dir.rt_power + l2dirarray[i]->rt_power * pppm_t; - rt_power = rt_power + l2dirarray[i]->rt_power * pppm_t; - } - } - - if (XML->sys.mc.number_mcs > 0 && XML->sys.mc.memory_channels_per_mc > 0) { - if (XML->sys.architecture == 1) // 1 for fermi - mc = new MemoryController(XML, &interface_ip, MC, GDDR5); - else if (XML->sys.architecture == 2) // 2 for quadro - mc = new MemoryController(XML, &interface_ip, MC, GDDR3); - else { - printf("Architecture %d not defined!\n", XML->sys.architecture); - printf("use 1 for fermi and 2 for quadro!\n"); - exit(1); - } - mc->computeEnergy(); - mc->computeEnergy(false); - mcs.area.set_area(mcs.area.get_area() + - mc->area.get_area() * XML->sys.mc.number_mcs); - area.set_area(area.get_area() + - mc->area.get_area() * XML->sys.mc.number_mcs); - set_pppm(pppm_t, XML->sys.mc.number_mcs * mc->mcp.clockRate, - XML->sys.mc.number_mcs, XML->sys.mc.number_mcs, - XML->sys.mc.number_mcs); - mcs.power = mc->power * pppm_t; - power = power + mcs.power; - set_pppm(pppm_t, 1 / mc->mcp.executionTime, XML->sys.mc.number_mcs, - XML->sys.mc.number_mcs, XML->sys.mc.number_mcs); - mcs.rt_power = mc->rt_power * pppm_t; - rt_power = rt_power + mcs.rt_power; + if (numL3 >0) + for (i = 0;i < numL3; i++) + { + l3array.push_back(new SharedCache(XML,i, &interface_ip, L3)); + l3array[i]->computeEnergy(); + l3array[i]->computeEnergy(false); + if (procdynp.homoL3){ + l3.area.set_area(l3.area.get_area() + l3array[i]->area.get_area()*procdynp.numL3); + set_pppm(pppm_t,l3array[i]->cachep.clockRate*procdynp.numL3, procdynp.numL3,procdynp.numL3,procdynp.numL3); + l3.power = l3.power + l3array[i]->power*pppm_t; + set_pppm(pppm_t,1/l3array[i]->cachep.executionTime, procdynp.numL3,procdynp.numL3,procdynp.numL3); + l3.rt_power = l3.rt_power + l3array[i]->rt_power*pppm_t; + area.set_area(area.get_area() + l3.area.get_area());//placement and routing overhead is 10%, l3 scales worse than cache 40% is accumulated from 90 to 22nm + power = power + l3.power; + rt_power = rt_power + l3.rt_power; + + } + else{ + l3.area.set_area(l3.area.get_area() + l3array[i]->area.get_area()); + area.set_area(area.get_area() + l3array[i]->area.get_area());//placement and routing overhead is 10%, l3 scales worse than cache 40% is accumulated from 90 to 22nm + set_pppm(pppm_t,l3array[i]->cachep.clockRate, 1, 1, 1); + l3.power = l3.power + l3array[i]->power*pppm_t; + power = power + l3array[i]->power*pppm_t; + set_pppm(pppm_t,1/l3array[i]->cachep.executionTime, 1, 1, 1); + l3.rt_power = l3.rt_power + l3array[i]->rt_power*pppm_t; + rt_power = rt_power + l3array[i]->rt_power*pppm_t; + + } + } + if (numL1Dir >0) + for (i = 0;i < numL1Dir; i++) + { + l1dirarray.push_back(new SharedCache(XML,i, &interface_ip, L1Directory)); + l1dirarray[i]->computeEnergy(); + l1dirarray[i]->computeEnergy(false); + if (procdynp.homoL1Dir){ + l1dir.area.set_area(l1dir.area.get_area() + l1dirarray[i]->area.get_area()*procdynp.numL1Dir); + set_pppm(pppm_t,l1dirarray[i]->cachep.clockRate*procdynp.numL1Dir, procdynp.numL1Dir,procdynp.numL1Dir,procdynp.numL1Dir); + l1dir.power = l1dir.power + l1dirarray[i]->power*pppm_t; + set_pppm(pppm_t,1/l1dirarray[i]->cachep.executionTime, procdynp.numL1Dir,procdynp.numL1Dir,procdynp.numL1Dir); + l1dir.rt_power = l1dir.rt_power + l1dirarray[i]->rt_power*pppm_t; + area.set_area(area.get_area() + l1dir.area.get_area());//placement and routing overhead is 10%, l1dir scales worse than cache 40% is accumulated from 90 to 22nm + power = power + l1dir.power; + rt_power = rt_power + l1dir.rt_power; + + } + else{ + l1dir.area.set_area(l1dir.area.get_area() + l1dirarray[i]->area.get_area()); + area.set_area(area.get_area() + l1dirarray[i]->area.get_area()); + set_pppm(pppm_t,l1dirarray[i]->cachep.clockRate, 1, 1, 1); + l1dir.power = l1dir.power + l1dirarray[i]->power*pppm_t; + power = power + l1dirarray[i]->power; + set_pppm(pppm_t,1/l1dirarray[i]->cachep.executionTime, 1, 1, 1); + l1dir.rt_power = l1dir.rt_power + l1dirarray[i]->rt_power*pppm_t; + rt_power = rt_power + l1dirarray[i]->rt_power; + } + } + + if (numL2Dir >0) + for (i = 0;i < numL2Dir; i++) + { + l2dirarray.push_back(new SharedCache(XML,i, &interface_ip, L2Directory)); + l2dirarray[i]->computeEnergy(); + l2dirarray[i]->computeEnergy(false); + if (procdynp.homoL2Dir){ + l2dir.area.set_area(l2dir.area.get_area() + l2dirarray[i]->area.get_area()*procdynp.numL2Dir); + set_pppm(pppm_t,l2dirarray[i]->cachep.clockRate*procdynp.numL2Dir, procdynp.numL2Dir,procdynp.numL2Dir,procdynp.numL2Dir); + l2dir.power = l2dir.power + l2dirarray[i]->power*pppm_t; + set_pppm(pppm_t,1/l2dirarray[i]->cachep.executionTime, procdynp.numL2Dir,procdynp.numL2Dir,procdynp.numL2Dir); + l2dir.rt_power = l2dir.rt_power + l2dirarray[i]->rt_power*pppm_t; + area.set_area(area.get_area() + l2dir.area.get_area());//placement and routing overhead is 10%, l2dir scales worse than cache 40% is accumulated from 90 to 22nm + power = power + l2dir.power; + rt_power = rt_power + l2dir.rt_power; + + } + else{ + l2dir.area.set_area(l2dir.area.get_area() + l2dirarray[i]->area.get_area()); + area.set_area(area.get_area() + l2dirarray[i]->area.get_area()); + set_pppm(pppm_t,l2dirarray[i]->cachep.clockRate, 1, 1, 1); + l2dir.power = l2dir.power + l2dirarray[i]->power*pppm_t; + power = power + l2dirarray[i]->power*pppm_t; + set_pppm(pppm_t,1/l2dirarray[i]->cachep.executionTime, 1, 1, 1); + l2dir.rt_power = l2dir.rt_power + l2dirarray[i]->rt_power*pppm_t; + rt_power = rt_power + l2dirarray[i]->rt_power*pppm_t; + } + } + + if (XML->sys.mc.number_mcs >0 && XML->sys.mc.memory_channels_per_mc>0) + { + if(XML->sys.architecture==1) // 1 for fermi + mc = new MemoryController(XML, &interface_ip, MC,GDDR5); + else if (XML->sys.architecture==2) // 2 for quadro + mc = new MemoryController(XML, &interface_ip, MC,GDDR3); + else { + printf("Architecture %d not defined!\n", XML->sys.architecture); + printf("use 1 for fermi and 2 for quadro!\n"); + exit(1); + } + mc->computeEnergy(); + mc->computeEnergy(false); + mcs.area.set_area(mcs.area.get_area()+mc->area.get_area()*XML->sys.mc.number_mcs); + area.set_area(area.get_area()+mc->area.get_area()*XML->sys.mc.number_mcs); + set_pppm(pppm_t,XML->sys.mc.number_mcs*mc->mcp.clockRate, XML->sys.mc.number_mcs,XML->sys.mc.number_mcs,XML->sys.mc.number_mcs); + mcs.power = mc->power*pppm_t; + power = power + mcs.power; + set_pppm(pppm_t,1/mc->mcp.executionTime, XML->sys.mc.number_mcs,XML->sys.mc.number_mcs,XML->sys.mc.number_mcs); + mcs.rt_power = mc->rt_power*pppm_t; + rt_power = rt_power + mcs.rt_power; + } - if (XML->sys.flashc.number_mcs > 0) // flash controller + if (XML->sys.flashc.number_mcs >0 )//flash controller { - flashcontroller = new FlashController(XML, &interface_ip); - flashcontroller->computeEnergy(); - flashcontroller->computeEnergy(false); - double number_fcs = flashcontroller->fcp.num_mcs; - flashcontrollers.area.set_area(flashcontrollers.area.get_area() + - flashcontroller->area.get_area() * - number_fcs); - area.set_area(area.get_area() + flashcontrollers.area.get_area()); - set_pppm(pppm_t, number_fcs, number_fcs, number_fcs, number_fcs); - flashcontrollers.power = flashcontroller->power * pppm_t; - power = power + flashcontrollers.power; - set_pppm(pppm_t, number_fcs, number_fcs, number_fcs, number_fcs); - flashcontrollers.rt_power = flashcontroller->rt_power * pppm_t; - rt_power = rt_power + flashcontrollers.rt_power; + flashcontroller = new FlashController(XML, &interface_ip); + flashcontroller->computeEnergy(); + flashcontroller->computeEnergy(false); + double number_fcs = flashcontroller->fcp.num_mcs; + flashcontrollers.area.set_area(flashcontrollers.area.get_area()+flashcontroller->area.get_area()*number_fcs); + area.set_area(area.get_area()+flashcontrollers.area.get_area()); + set_pppm(pppm_t,number_fcs, number_fcs ,number_fcs, number_fcs ); + flashcontrollers.power = flashcontroller->power*pppm_t; + power = power + flashcontrollers.power; + set_pppm(pppm_t,number_fcs , number_fcs ,number_fcs ,number_fcs ); + flashcontrollers.rt_power = flashcontroller->rt_power*pppm_t; + rt_power = rt_power + flashcontrollers.rt_power; + } - if (XML->sys.niu.number_units > 0) { - niu = new NIUController(XML, &interface_ip); - niu->computeEnergy(); - niu->computeEnergy(false); - nius.area.set_area(nius.area.get_area() + - niu->area.get_area() * XML->sys.niu.number_units); - area.set_area(area.get_area() + - niu->area.get_area() * XML->sys.niu.number_units); - set_pppm(pppm_t, XML->sys.niu.number_units * niu->niup.clockRate, - XML->sys.niu.number_units, XML->sys.niu.number_units, - XML->sys.niu.number_units); - nius.power = niu->power * pppm_t; - power = power + nius.power; - set_pppm(pppm_t, XML->sys.niu.number_units * niu->niup.clockRate, - XML->sys.niu.number_units, XML->sys.niu.number_units, - XML->sys.niu.number_units); - nius.rt_power = niu->rt_power * pppm_t; - rt_power = rt_power + nius.rt_power; + if (XML->sys.niu.number_units >0) + { + niu = new NIUController(XML, &interface_ip); + niu->computeEnergy(); + niu->computeEnergy(false); + nius.area.set_area(nius.area.get_area()+niu->area.get_area()*XML->sys.niu.number_units); + area.set_area(area.get_area()+niu->area.get_area()*XML->sys.niu.number_units); + set_pppm(pppm_t,XML->sys.niu.number_units*niu->niup.clockRate, XML->sys.niu.number_units,XML->sys.niu.number_units,XML->sys.niu.number_units); + nius.power = niu->power*pppm_t; + power = power + nius.power; + set_pppm(pppm_t,XML->sys.niu.number_units*niu->niup.clockRate, XML->sys.niu.number_units,XML->sys.niu.number_units,XML->sys.niu.number_units); + nius.rt_power = niu->rt_power*pppm_t; + rt_power = rt_power + nius.rt_power; + } - if (XML->sys.pcie.number_units > 0 && XML->sys.pcie.num_channels > 0) { - pcie = new PCIeController(XML, &interface_ip); - pcie->computeEnergy(); - pcie->computeEnergy(false); - pcies.area.set_area(pcies.area.get_area() + - pcie->area.get_area() * XML->sys.pcie.number_units); - area.set_area(area.get_area() + - pcie->area.get_area() * XML->sys.pcie.number_units); - set_pppm(pppm_t, XML->sys.pcie.number_units * pcie->pciep.clockRate, - XML->sys.pcie.number_units, XML->sys.pcie.number_units, - XML->sys.pcie.number_units); - pcies.power = pcie->power * pppm_t; - power = power + pcies.power; - set_pppm(pppm_t, XML->sys.pcie.number_units * pcie->pciep.clockRate, - XML->sys.pcie.number_units, XML->sys.pcie.number_units, - XML->sys.pcie.number_units); - pcies.rt_power = pcie->rt_power * pppm_t; - rt_power = rt_power + pcies.rt_power; + if (XML->sys.pcie.number_units >0 && XML->sys.pcie.num_channels >0) + { + pcie = new PCIeController(XML, &interface_ip); + pcie->computeEnergy(); + pcie->computeEnergy(false); + pcies.area.set_area(pcies.area.get_area()+pcie->area.get_area()*XML->sys.pcie.number_units); + area.set_area(area.get_area()+pcie->area.get_area()*XML->sys.pcie.number_units); + set_pppm(pppm_t,XML->sys.pcie.number_units*pcie->pciep.clockRate, XML->sys.pcie.number_units,XML->sys.pcie.number_units,XML->sys.pcie.number_units); + pcies.power = pcie->power*pppm_t; + power = power + pcies.power; + set_pppm(pppm_t,XML->sys.pcie.number_units*pcie->pciep.clockRate, XML->sys.pcie.number_units,XML->sys.pcie.number_units,XML->sys.pcie.number_units); + pcies.rt_power = pcie->rt_power*pppm_t; + rt_power = rt_power + pcies.rt_power; + } - if (numNOC > 0) { - for (i = 0; i < numNOC; i++) { - if (XML->sys.NoC[i].type) { // First add up area of routers if NoC is - // used - nocs.push_back(new NoC(XML, i, &interface_ip, 1)); - - if (procdynp.homoNOC) { - noc.area.set_area(noc.area.get_area() + - nocs[i]->area.get_area() * procdynp.numNOC); - area.set_area(area.get_area() + noc.area.get_area()); - } else { - noc.area.set_area(noc.area.get_area() + nocs[i]->area.get_area()); - area.set_area(area.get_area() + nocs[i]->area.get_area()); - } - } else { // Bus based interconnect - nocs.push_back( - new NoC(XML, i, &interface_ip, 1, - sqrt(area.get_area() * XML->sys.NoC[i].chip_coverage))); - if (procdynp.homoNOC) { - noc.area.set_area(noc.area.get_area() + - nocs[i]->area.get_area() * procdynp.numNOC); - area.set_area(area.get_area() + noc.area.get_area()); - } else { - noc.area.set_area(noc.area.get_area() + nocs[i]->area.get_area()); - area.set_area(area.get_area() + nocs[i]->area.get_area()); - } - } - } - - /* - * Compute global links associated with each NOC, if any. This must be done - * at the end (even after the NOC router part) since the total chip - * area must be obtain to decide the link routing - */ - for (i = 0; i < numNOC; i++) { - if (nocs[i]->nocdynp.has_global_link && XML->sys.NoC[i].type) { - nocs[i]->init_link_bus( - sqrt(area.get_area() * - XML->sys.NoC[i].chip_coverage)); // compute global links - if (procdynp.homoNOC) { - noc.area.set_area(noc.area.get_area() + - nocs[i]->link_bus_tot_per_Router.area.get_area() * - nocs[i]->nocdynp.total_nodes * procdynp.numNOC); - area.set_area(area.get_area() + - nocs[i]->link_bus_tot_per_Router.area.get_area() * - nocs[i]->nocdynp.total_nodes * procdynp.numNOC); - } else { - noc.area.set_area(noc.area.get_area() + - nocs[i]->link_bus_tot_per_Router.area.get_area() * - nocs[i]->nocdynp.total_nodes); - area.set_area(area.get_area() + - nocs[i]->link_bus_tot_per_Router.area.get_area() * - nocs[i]->nocdynp.total_nodes); - } - } - } - // Compute energy of NoC (w or w/o links) or buses - for (i = 0; i < numNOC; i++) { - // cout<<"******************COMPUTE NOC ENERGY********************"<computeEnergy(); - nocs[i]->computeEnergy(false); - if (procdynp.homoNOC) { - set_pppm(pppm_t, procdynp.numNOC * nocs[i]->nocdynp.clockRate, - procdynp.numNOC, procdynp.numNOC, procdynp.numNOC); - noc.power = noc.power + nocs[i]->power * pppm_t; - set_pppm(pppm_t, 1 / nocs[i]->nocdynp.executionTime, procdynp.numNOC, - procdynp.numNOC, procdynp.numNOC); - noc.rt_power = noc.rt_power + nocs[i]->rt_power * pppm_t; - power = power + noc.power; - rt_power = rt_power + noc.rt_power; - } else { - set_pppm(pppm_t, nocs[i]->nocdynp.clockRate, 1, 1, 1); - noc.power = noc.power + nocs[i]->power * pppm_t; - power = power + nocs[i]->power * pppm_t; - set_pppm(pppm_t, 1 / nocs[i]->nocdynp.executionTime, 1, 1, 1); - noc.rt_power = noc.rt_power + nocs[i]->rt_power * pppm_t; - rt_power = rt_power + nocs[i]->rt_power * pppm_t; - } - } + if (numNOC >0) + { + for (i = 0;i < numNOC; i++) + { + if (XML->sys.NoC[i].type) + {//First add up area of routers if NoC is used + nocs.push_back(new NoC(XML,i, &interface_ip, 1)); + + if (procdynp.homoNOC) + { + noc.area.set_area(noc.area.get_area() + nocs[i]->area.get_area()*procdynp.numNOC); + area.set_area(area.get_area() + noc.area.get_area()); + } + else + { + noc.area.set_area(noc.area.get_area() + nocs[i]->area.get_area()); + area.set_area(area.get_area() + nocs[i]->area.get_area()); + } + } + else + {//Bus based interconnect + nocs.push_back(new NoC(XML,i, &interface_ip, 1, sqrt(area.get_area()*XML->sys.NoC[i].chip_coverage))); + if (procdynp.homoNOC){ + noc.area.set_area(noc.area.get_area() + nocs[i]->area.get_area()*procdynp.numNOC); + area.set_area(area.get_area() + noc.area.get_area()); + } + else + { + noc.area.set_area(noc.area.get_area() + nocs[i]->area.get_area()); + area.set_area(area.get_area() + nocs[i]->area.get_area()); + } + } + } + + /* + * Compute global links associated with each NOC, if any. This must be done at the end (even after the NOC router part) since the total chip + * area must be obtain to decide the link routing + */ + for (i = 0;i < numNOC; i++) + { + if (nocs[i]->nocdynp.has_global_link && XML->sys.NoC[i].type) + { + nocs[i]->init_link_bus(sqrt(area.get_area()*XML->sys.NoC[i].chip_coverage));//compute global links + if (procdynp.homoNOC) + { + noc.area.set_area(noc.area.get_area() + nocs[i]->link_bus_tot_per_Router.area.get_area() + * nocs[i]->nocdynp.total_nodes + * procdynp.numNOC); + area.set_area(area.get_area() + nocs[i]->link_bus_tot_per_Router.area.get_area() + * nocs[i]->nocdynp.total_nodes + * procdynp.numNOC); + } + else + { + noc.area.set_area(noc.area.get_area() + nocs[i]->link_bus_tot_per_Router.area.get_area() + * nocs[i]->nocdynp.total_nodes); + area.set_area(area.get_area() + nocs[i]->link_bus_tot_per_Router.area.get_area() + * nocs[i]->nocdynp.total_nodes); + } + } + } + //Compute energy of NoC (w or w/o links) or buses + for (i = 0;i < numNOC; i++) + { + //cout<<"******************COMPUTE NOC ENERGY********************"<computeEnergy(); + nocs[i]->computeEnergy(false); + if (procdynp.homoNOC){ + + set_pppm(pppm_t,procdynp.numNOC*nocs[i]->nocdynp.clockRate, procdynp.numNOC,procdynp.numNOC,procdynp.numNOC); + noc.power = noc.power + nocs[i]->power*pppm_t; + set_pppm(pppm_t,1/nocs[i]->nocdynp.executionTime, procdynp.numNOC,procdynp.numNOC,procdynp.numNOC); + noc.rt_power = noc.rt_power + nocs[i]->rt_power*pppm_t; + power = power + noc.power; + rt_power = rt_power + noc.rt_power; + } + else + { + set_pppm(pppm_t,nocs[i]->nocdynp.clockRate, 1, 1, 1); + noc.power = noc.power + nocs[i]->power*pppm_t; + power = power + nocs[i]->power*pppm_t; + set_pppm(pppm_t,1/nocs[i]->nocdynp.executionTime, 1, 1, 1); + noc.rt_power = noc.rt_power + nocs[i]->rt_power*pppm_t; + rt_power = rt_power + nocs[i]->rt_power*pppm_t; + + + } + } } - // //clock power - // globalClock.init_wire_external(is_default, &interface_ip); - // globalClock.clk_area =area*1e6; //change it from mm^2 to um^2 - // globalClock.end_wiring_level =5;//toplevel metal - // globalClock.start_wiring_level =5;//toplevel metal - // globalClock.l_ip.with_clock_grid=false;//global clock does not drive local - // final nodes - // globalClock.optimize_wire(); +// //clock power +// globalClock.init_wire_external(is_default, &interface_ip); +// globalClock.clk_area =area*1e6; //change it from mm^2 to um^2 +// globalClock.end_wiring_level =5;//toplevel metal +// globalClock.start_wiring_level =5;//toplevel metal +// globalClock.l_ip.with_clock_grid=false;//global clock does not drive local final nodes +// globalClock.optimize_wire(); } -void Processor::compute() { +void Processor::compute () +{ int i; - double pppm_t[4] = {1, 1, 1, 1}; + double pppm_t[4] = {1,1,1,1}; rt_power.reset(); - // power.reset(); - // core.power.reset(); + //power.reset(); + //core.power.reset(); core.rt_power.reset(); - for (i = 0; i < numCore; i++) { - cores[i]->executionTime = - XML->sys.total_cycles / (XML->sys.core[i].clock_rate * 1e6); - cores[i]->rt_power.reset(); - cores[i]->compute(); - // cores[i]->computeEnergy(false); - if (procdynp.homoCore) { - set_pppm(pppm_t, 1 / cores[i]->executionTime, procdynp.numCore, - procdynp.numCore, procdynp.numCore); - core.rt_power = core.rt_power + cores[i]->rt_power * pppm_t; - rt_power = rt_power + core.rt_power; - } else { - set_pppm(pppm_t, 1 / cores[i]->executionTime, 1, 1, 1); - core.rt_power = core.rt_power + cores[i]->rt_power * pppm_t; - rt_power = rt_power + cores[i]->rt_power * pppm_t; - } + for (i = 0;i < numCore; i++) + { + cores[i]->executionTime = XML->sys.total_cycles /(XML->sys.core[i].clock_rate*1e6); + cores[i]->rt_power.reset(); + cores[i]->compute(); + //cores[i]->computeEnergy(false); + if (procdynp.homoCore){ + set_pppm(pppm_t,1/cores[i]->executionTime, procdynp.numCore,procdynp.numCore,procdynp.numCore); + core.rt_power = core.rt_power + cores[i]->rt_power*pppm_t; + rt_power = rt_power + core.rt_power; + } + else{ + set_pppm(pppm_t,1/cores[i]->executionTime, 1, 1, 1); + core.rt_power = core.rt_power + cores[i]->rt_power*pppm_t; + rt_power = rt_power + cores[i]->rt_power*pppm_t; + } } - if (!XML->sys.Private_L2) { - if (numL2 > 0) l2.rt_power.reset(); - for (i = 0; i < numL2; i++) { + if (!XML->sys.Private_L2) + { + if (numL2 >0) + l2.rt_power.reset(); + for (i = 0;i < numL2; i++) + { l2array[i]->rt_power.reset(); - l2array[i]->cachep.executionTime = - XML->sys.total_cycles / (XML->sys.core[0].clock_rate * 1e6); - l2array[i]->computeEnergy(false); - if (procdynp.homoL2) { - set_pppm(pppm_t, 1 / l2array[i]->cachep.executionTime, procdynp.numL2, - procdynp.numL2, procdynp.numL2); - l2.rt_power = l2.rt_power + l2array[i]->rt_power * pppm_t; - rt_power = rt_power + l2.rt_power; - } else { - set_pppm(pppm_t, 1 / l2array[i]->cachep.executionTime, 1, 1, 1); - l2.rt_power = l2.rt_power + l2array[i]->rt_power * pppm_t; - rt_power = rt_power + l2array[i]->rt_power * pppm_t; - } - } + l2array[i]->cachep.executionTime=XML->sys.total_cycles /(XML->sys.core[0].clock_rate*1e6); + l2array[i]->computeEnergy(false); + if (procdynp.homoL2){ + set_pppm(pppm_t,1/l2array[i]->cachep.executionTime, procdynp.numL2,procdynp.numL2,procdynp.numL2); + l2.rt_power = l2.rt_power + l2array[i]->rt_power*pppm_t; + rt_power = rt_power + l2.rt_power; + } + else{ + set_pppm(pppm_t,1/l2array[i]->cachep.executionTime, 1, 1, 1); + l2.rt_power = l2.rt_power + l2array[i]->rt_power*pppm_t; + rt_power = rt_power + l2array[i]->rt_power*pppm_t; + } + } } l3.rt_power.reset(); - if (numL3 > 0) - for (i = 0; i < numL3; i++) { - l3array[i]->rt_power.reset(); - l3array[i]->computeEnergy(false); - if (procdynp.homoL3) { - set_pppm(pppm_t, 1 / l3array[i]->cachep.executionTime, procdynp.numL3, - procdynp.numL3, procdynp.numL3); - l3.rt_power = l3.rt_power + l3array[i]->rt_power * pppm_t; - rt_power = rt_power + l3.rt_power; - - } else { - set_pppm(pppm_t, 1 / l3array[i]->cachep.executionTime, 1, 1, 1); - l3.rt_power = l3.rt_power + l3array[i]->rt_power * pppm_t; - rt_power = rt_power + l3array[i]->rt_power * pppm_t; - } - } + if (numL3 >0) + for (i = 0;i < numL3; i++) + { + l3array[i]->rt_power.reset(); + l3array[i]->computeEnergy(false); + if (procdynp.homoL3){ + set_pppm(pppm_t,1/l3array[i]->cachep.executionTime, procdynp.numL3,procdynp.numL3,procdynp.numL3); + l3.rt_power = l3.rt_power + l3array[i]->rt_power*pppm_t; + rt_power = rt_power + l3.rt_power; + + } + else{ + set_pppm(pppm_t,1/l3array[i]->cachep.executionTime, 1, 1, 1); + l3.rt_power = l3.rt_power + l3array[i]->rt_power*pppm_t; + rt_power = rt_power + l3array[i]->rt_power*pppm_t; + + } + } l1dir.rt_power.reset(); - if (numL1Dir > 0) - for (i = 0; i < numL1Dir; i++) { - l1dirarray[i]->rt_power.reset(); - l1dirarray[i]->computeEnergy(false); - if (procdynp.homoL1Dir) { - set_pppm(pppm_t, 1 / l1dirarray[i]->cachep.executionTime, - procdynp.numL1Dir, procdynp.numL1Dir, procdynp.numL1Dir); - l1dir.rt_power = l1dir.rt_power + l1dirarray[i]->rt_power * pppm_t; - rt_power = rt_power + l1dir.rt_power; - - } else { - set_pppm(pppm_t, 1 / l1dirarray[i]->cachep.executionTime, 1, 1, 1); - l1dir.rt_power = l1dir.rt_power + l1dirarray[i]->rt_power * pppm_t; - rt_power = rt_power + l1dirarray[i]->rt_power; - } - } + if (numL1Dir >0) + for (i = 0;i < numL1Dir; i++) + { + l1dirarray[i]->rt_power.reset(); + l1dirarray[i]->computeEnergy(false); + if (procdynp.homoL1Dir){ + set_pppm(pppm_t,1/l1dirarray[i]->cachep.executionTime, procdynp.numL1Dir,procdynp.numL1Dir,procdynp.numL1Dir); + l1dir.rt_power = l1dir.rt_power + l1dirarray[i]->rt_power*pppm_t; + rt_power = rt_power + l1dir.rt_power; + + } + else{ + set_pppm(pppm_t,1/l1dirarray[i]->cachep.executionTime, 1, 1, 1); + l1dir.rt_power = l1dir.rt_power + l1dirarray[i]->rt_power*pppm_t; + rt_power = rt_power + l1dirarray[i]->rt_power; + } + } + l2dir.rt_power.reset(); - if (numL2Dir > 0) - for (i = 0; i < numL2Dir; i++) { - l2dirarray[i]->rt_power.reset(); - l2dirarray[i]->computeEnergy(false); - if (procdynp.homoL2Dir) { - set_pppm(pppm_t, 1 / l2dirarray[i]->cachep.executionTime, - procdynp.numL2Dir, procdynp.numL2Dir, procdynp.numL2Dir); - l2dir.rt_power = l2dir.rt_power + l2dirarray[i]->rt_power * pppm_t; - rt_power = rt_power + l2dir.rt_power; - - } else { - set_pppm(pppm_t, 1 / l2dirarray[i]->cachep.executionTime, 1, 1, 1); - l2dir.rt_power = l2dir.rt_power + l2dirarray[i]->rt_power * pppm_t; - rt_power = rt_power + l2dirarray[i]->rt_power * pppm_t; - } - } + if (numL2Dir >0) + for (i = 0;i < numL2Dir; i++) + { + l2dirarray[i]->rt_power.reset(); + l2dirarray[i]->computeEnergy(false); + if (procdynp.homoL2Dir){ + set_pppm(pppm_t,1/l2dirarray[i]->cachep.executionTime, procdynp.numL2Dir,procdynp.numL2Dir,procdynp.numL2Dir); + l2dir.rt_power = l2dir.rt_power + l2dirarray[i]->rt_power*pppm_t; + rt_power = rt_power + l2dir.rt_power; + + } + else{ + set_pppm(pppm_t,1/l2dirarray[i]->cachep.executionTime, 1, 1, 1); + l2dir.rt_power = l2dir.rt_power + l2dirarray[i]->rt_power*pppm_t; + rt_power = rt_power + l2dirarray[i]->rt_power*pppm_t; + } + } + mcs.rt_power.reset(); - if (XML->sys.mc.number_mcs > 0 && XML->sys.mc.memory_channels_per_mc > 0) { - mc->rt_power.reset(); - mc->mcp.executionTime = - XML->sys.total_cycles / (XML->sys.core[0].clock_rate * 1e6); // Jingwen - mc->computeEnergy(false); - set_pppm(pppm_t, 1 / mc->mcp.executionTime, XML->sys.mc.number_mcs, - XML->sys.mc.number_mcs, XML->sys.mc.number_mcs); - mcs.rt_power = mc->rt_power * pppm_t; - rt_power = rt_power + mcs.rt_power; + if (XML->sys.mc.number_mcs >0 && XML->sys.mc.memory_channels_per_mc>0) + { + mc->rt_power.reset(); + mc->mcp.executionTime = XML->sys.total_cycles /(XML->sys.core[0].clock_rate*1e6); //Jingwen + mc->computeEnergy(false); + set_pppm(pppm_t,1/mc->mcp.executionTime, XML->sys.mc.number_mcs,XML->sys.mc.number_mcs,XML->sys.mc.number_mcs); + mcs.rt_power = mc->rt_power*pppm_t; + rt_power = rt_power + mcs.rt_power; + } + + +/* + if (XML->sys.flashc.number_mcs >0 )//flash controller + { + flashcontrollers.rt_power.reset(); + flashcontroller->computeEnergy(false); + double number_fcs = flashcontroller->fcp.num_mcs; + set_pppm(pppm_t,number_fcs , number_fcs ,number_fcs ,number_fcs ); + flashcontrollers.rt_power = flashcontroller->rt_power*pppm_t; + rt_power = rt_power + flashcontrollers.rt_power; - /* - if (XML->sys.flashc.number_mcs >0 )//flash controller - { - flashcontrollers.rt_power.reset(); - flashcontroller->computeEnergy(false); - double number_fcs = flashcontroller->fcp.num_mcs; - set_pppm(pppm_t,number_fcs , number_fcs ,number_fcs ,number_fcs ); - flashcontrollers.rt_power = flashcontroller->rt_power*pppm_t; - rt_power = rt_power + flashcontrollers.rt_power; - - } - - if (XML->sys.niu.number_units >0) - { - niu->computeEnergy(false); - nius.rt_power.reset(); - set_pppm(pppm_t,XML->sys.niu.number_units*niu->niup.clockRate, - XML->sys.niu.number_units,XML->sys.niu.number_units,XML->sys.niu.number_units); - nius.rt_power = niu->rt_power*pppm_t; - rt_power = rt_power + nius.rt_power; - - } - - if (XML->sys.pcie.number_units >0 && XML->sys.pcie.num_channels >0) - { - pcie->computeEnergy(false); - pcies.rt_power.reset(); - set_pppm(pppm_t,XML->sys.pcie.number_units*pcie->pciep.clockRate, - XML->sys.pcie.number_units,XML->sys.pcie.number_units,XML->sys.pcie.number_units); - pcies.rt_power = pcie->rt_power*pppm_t; - rt_power = rt_power + pcies.rt_power; - - } - - - // * Compute global links associated with each NOC, if any. This - must be done at the end (even after the NOC router part) since the total - chip - // * area must be obtain to decide the link routing - */ - // Compute energy of NoC (w or w/o links) or buses - noc.rt_power.reset(); - for (i = 0; i < numNOC; i++) { - nocs[i]->nocdynp.executionTime = - XML->sys.total_cycles / (XML->sys.core[0].clock_rate * 1e6); - nocs[i]->computeEnergy(false); - if (procdynp.homoNOC) { - set_pppm(pppm_t, 1 / nocs[i]->nocdynp.executionTime, procdynp.numNOC, - procdynp.numNOC, procdynp.numNOC); - noc.rt_power = noc.rt_power + nocs[i]->rt_power * pppm_t; - rt_power = rt_power + noc.rt_power; - } else { - set_pppm(pppm_t, 1 / nocs[i]->nocdynp.executionTime, 1, 1, 1); - noc.rt_power = noc.rt_power + nocs[i]->rt_power * pppm_t; - rt_power = rt_power + nocs[i]->rt_power * pppm_t; - } } - // //clock power - // globalClock.init_wire_external(is_default, &interface_ip); - // globalClock.clk_area =area*1e6; //change it from mm^2 to um^2 - // globalClock.end_wiring_level =5;//toplevel metal - // globalClock.start_wiring_level =5;//toplevel metal - // globalClock.l_ip.with_clock_grid=false;//global clock does not drive local - // final nodes - // globalClock.optimize_wire(); -} + if (XML->sys.niu.number_units >0) + { + niu->computeEnergy(false); + nius.rt_power.reset(); + set_pppm(pppm_t,XML->sys.niu.number_units*niu->niup.clockRate, XML->sys.niu.number_units,XML->sys.niu.number_units,XML->sys.niu.number_units); + nius.rt_power = niu->rt_power*pppm_t; + rt_power = rt_power + nius.rt_power; -void Processor::displayDeviceType(int device_type_, uint32_t indent) { - string indent_str(indent, ' '); - - switch (device_type_) { - case 0: - cout << indent_str << "Device Type= " - << "ITRS high performance device type" << endl; - break; - case 1: - cout << indent_str << "Device Type= " - << "ITRS low standby power device type" << endl; - break; - case 2: - cout << indent_str << "Device Type= " - << "ITRS low operating power device type" << endl; - break; - case 3: - cout << indent_str << "Device Type= " - << "LP-DRAM device type" << endl; - break; - case 4: - cout << indent_str << "Device Type= " - << "COMM-DRAM device type" << endl; - break; - default: { - cout << indent_str << "Unknown Device Type" << endl; - exit(0); - } } -} -void Processor::displayInterconnectType(int interconnect_type_, - uint32_t indent) { - string indent_str(indent, ' '); - - switch (interconnect_type_) { - case 0: - cout << indent_str << "Interconnect metal projection= " - << "aggressive interconnect technology projection" << endl; - break; - case 1: - cout << indent_str << "Interconnect metal projection= " - << "conservative interconnect technology projection" << endl; - break; - default: { - cout << indent_str << "Unknown Interconnect Projection Type" << endl; - exit(0); - } + if (XML->sys.pcie.number_units >0 && XML->sys.pcie.num_channels >0) + { + pcie->computeEnergy(false); + pcies.rt_power.reset(); + set_pppm(pppm_t,XML->sys.pcie.number_units*pcie->pciep.clockRate, XML->sys.pcie.number_units,XML->sys.pcie.number_units,XML->sys.pcie.number_units); + pcies.rt_power = pcie->rt_power*pppm_t; + rt_power = rt_power + pcies.rt_power; + } + + + // * Compute global links associated with each NOC, if any. This must be done at the end (even after the NOC router part) since the total chip + // * area must be obtain to decide the link routing + */ + //Compute energy of NoC (w or w/o links) or buses + noc.rt_power.reset(); + for (i = 0;i < numNOC; i++) + { + nocs[i]->nocdynp.executionTime=XML->sys.total_cycles /(XML->sys.core[0].clock_rate*1e6); + nocs[i]->computeEnergy(false); + if (procdynp.homoNOC){ + set_pppm(pppm_t,1/nocs[i]->nocdynp.executionTime, procdynp.numNOC,procdynp.numNOC,procdynp.numNOC); + noc.rt_power = noc.rt_power + nocs[i]->rt_power*pppm_t; + rt_power = rt_power + noc.rt_power; + } + else + { + set_pppm(pppm_t,1/nocs[i]->nocdynp.executionTime, 1, 1, 1); + noc.rt_power = noc.rt_power + nocs[i]->rt_power*pppm_t; + rt_power = rt_power + nocs[i]->rt_power*pppm_t; + } + } + + +// //clock power +// globalClock.init_wire_external(is_default, &interface_ip); +// globalClock.clk_area =area*1e6; //change it from mm^2 to um^2 +// globalClock.end_wiring_level =5;//toplevel metal +// globalClock.start_wiring_level =5;//toplevel metal +// globalClock.l_ip.with_clock_grid=false;//global clock does not drive local final nodes +// globalClock.optimize_wire(); + } -void Processor::displayEnergy(uint32_t indent, int plevel, bool is_tdp_parm) { - int i; - bool long_channel = XML->sys.longer_channel_device; - string indent_str(indent, ' '); - string indent_str_next(indent + 2, ' '); - bool is_tdp = is_tdp_parm; - if (is_tdp_parm) { - if (plevel < 5) { - cout - << "\nMcPAT (version " << VER_MAJOR << "." << VER_MINOR << " of " - << VER_UPDATE << ") results (current print level is " << plevel - << ", please increase print level to see the details in components): " - << endl; - } else { - cout << "\nMcPAT (version " << VER_MAJOR << "." << VER_MINOR << " of " - << VER_UPDATE << ") results (current print level is 5)" << endl; - } - cout << "******************************************************************" - "***********************" - << endl; - cout << indent_str << "Technology " << XML->sys.core_tech_node << " nm" - << endl; - // cout <sys.interconnect_projection_type<sys.interconnect_projection_type, indent); - cout << indent_str << "Core clock Rate(MHz) " << XML->sys.core[0].clock_rate - << endl; - cout << endl; - cout << "******************************************************************" - "***********************" - << endl; - cout << "Processor: " << endl; - cout << indent_str << "Area = " << area.get_area() * 1e-6 << " mm^2" - << endl; - cout << indent_str << "Peak Power = " - << power.readOp.dynamic + - (long_channel ? power.readOp.longer_channel_leakage - : power.readOp.leakage) + - power.readOp.gate_leakage - << " W" << endl; - cout << indent_str << "Total Leakage = " - << (long_channel ? power.readOp.longer_channel_leakage - : power.readOp.leakage) + - power.readOp.gate_leakage - << " W" << endl; - cout << indent_str << "Peak Dynamic = " << power.readOp.dynamic << " W" - << endl; - cout << indent_str << "Subthreshold Leakage = " - << (long_channel ? power.readOp.longer_channel_leakage - : power.readOp.leakage) - << " W" << endl; - // cout << indent_str << "Subthreshold Leakage = " << - // power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str << "Gate Leakage = " << power.readOp.gate_leakage << " W" - << endl; - cout << indent_str << "Runtime Dynamic = " << rt_power.readOp.dynamic - << " W" << endl; - cout << endl; - if (numCore > 0) { - cout << indent_str << "Total Cores: " << XML->sys.number_of_cores - << " cores " << endl; - displayDeviceType(XML->sys.device_type, indent); - cout << indent_str_next << "Area = " << core.area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << core.power.readOp.dynamic - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? core.power.readOp.longer_channel_leakage - : core.power.readOp.leakage) - << " W" << endl; - // cout << indent_str_next << "Subthreshold Leakage = " << - // core.power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str_next - << "Gate Leakage = " << core.power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next - << "Runtime Dynamic = " << core.rt_power.readOp.dynamic << " W" - << endl; - cout << endl; - } - if (!XML->sys.Private_L2) { - if (numL2 > 0) { - cout << indent_str << "Total L2s: " << endl; - displayDeviceType(XML->sys.L2[0].device_type, indent); - cout << indent_str_next << "Area = " << l2.area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << l2.power.readOp.dynamic - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? l2.power.readOp.longer_channel_leakage - : l2.power.readOp.leakage) - << " W" << endl; - // cout << indent_str_next << "Subthreshold Leakage = " << - // l2.power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str_next - << "Gate Leakage = " << l2.power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next - << "Runtime Dynamic = " << l2.rt_power.readOp.dynamic << " W" - << endl; - cout << endl; - } - } - if (numL3 > 0) { - cout << indent_str << "Total L3s: " << endl; - displayDeviceType(XML->sys.L3[0].device_type, indent); - cout << indent_str_next << "Area = " << l3.area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << l3.power.readOp.dynamic - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? l3.power.readOp.longer_channel_leakage - : l3.power.readOp.leakage) - << " W" << endl; - // cout << indent_str_next << "Subthreshold Leakage = " << - // l3.power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str_next - << "Gate Leakage = " << l3.power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next - << "Runtime Dynamic = " << l3.rt_power.readOp.dynamic << " W" - << endl; - cout << endl; - } - if (numL1Dir > 0) { - cout << indent_str << "Total First Level Directory: " << endl; - displayDeviceType(XML->sys.L1Directory[0].device_type, indent); - cout << indent_str_next << "Area = " << l1dir.area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << l1dir.power.readOp.dynamic - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? l1dir.power.readOp.longer_channel_leakage - : l1dir.power.readOp.leakage) - << " W" << endl; - // cout << indent_str_next << "Subthreshold Leakage = " << - // l1dir.power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str_next - << "Gate Leakage = " << l1dir.power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next - << "Runtime Dynamic = " << l1dir.rt_power.readOp.dynamic << " W" - << endl; - cout << endl; - } - if (numL2Dir > 0) { - cout << indent_str << "Total First Level Directory: " << endl; - displayDeviceType(XML->sys.L1Directory[0].device_type, indent); - cout << indent_str_next << "Area = " << l2dir.area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << l2dir.power.readOp.dynamic - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? l2dir.power.readOp.longer_channel_leakage - : l2dir.power.readOp.leakage) - << " W" << endl; - // cout << indent_str_next << "Subthreshold Leakage = " << - // l2dir.power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str_next - << "Gate Leakage = " << l2dir.power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next - << "Runtime Dynamic = " << l2dir.rt_power.readOp.dynamic << " W" - << endl; - cout << endl; - } - if (numNOC > 0) { - cout << indent_str << "Total NoCs (Network/Bus): " << endl; - displayDeviceType(XML->sys.device_type, indent); - cout << indent_str_next << "Area = " << noc.area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << noc.power.readOp.dynamic - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? noc.power.readOp.longer_channel_leakage - : noc.power.readOp.leakage) - << " W" << endl; - // cout << indent_str_next << "Subthreshold Leakage = " << - // noc.power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str_next - << "Gate Leakage = " << noc.power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next - << "Runtime Dynamic = " << noc.rt_power.readOp.dynamic << " W" - << endl; - cout << endl; - } - if (XML->sys.mc.number_mcs > 0 && XML->sys.mc.memory_channels_per_mc > 0) { - cout << indent_str << "Total MCs: " << XML->sys.mc.number_mcs - << " Memory Controllers " << endl; - displayDeviceType(XML->sys.device_type, indent); - cout << indent_str_next << "Area = " << mcs.area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << mcs.power.readOp.dynamic - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? mcs.power.readOp.longer_channel_leakage - : mcs.power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << mcs.power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next - << "Runtime Dynamic = " << mcs.rt_power.readOp.dynamic << " W" - << endl; - cout << endl; - } - if (XML->sys.flashc.number_mcs > 0) { - cout << indent_str - << "Total Flash/SSD Controllers: " << flashcontroller->fcp.num_mcs - << " Flash/SSD Controllers " << endl; - displayDeviceType(XML->sys.device_type, indent); - cout << indent_str_next - << "Area = " << flashcontrollers.area.get_area() * 1e-6 << " mm^2" - << endl; - cout << indent_str_next - << "Peak Dynamic = " << flashcontrollers.power.readOp.dynamic << " W" - << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel - ? flashcontrollers.power.readOp.longer_channel_leakage - : flashcontrollers.power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << flashcontrollers.power.readOp.gate_leakage - << " W" << endl; - cout << indent_str_next - << "Runtime Dynamic = " << flashcontrollers.rt_power.readOp.dynamic - << " W" << endl; - cout << endl; - } - if (XML->sys.niu.number_units > 0) { - cout << indent_str << "Total NIUs: " << niu->niup.num_units - << " Network Interface Units " << endl; - displayDeviceType(XML->sys.device_type, indent); - cout << indent_str_next << "Area = " << nius.area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << nius.power.readOp.dynamic - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? nius.power.readOp.longer_channel_leakage - : nius.power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << nius.power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next - << "Runtime Dynamic = " << nius.rt_power.readOp.dynamic << " W" - << endl; - cout << endl; - } - if (XML->sys.pcie.number_units > 0 && XML->sys.pcie.num_channels > 0) { - cout << indent_str << "Total PCIes: " << pcie->pciep.num_units - << " PCIe Controllers " << endl; - displayDeviceType(XML->sys.device_type, indent); - cout << indent_str_next << "Area = " << pcies.area.get_area() * 1e-6 - << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << pcies.power.readOp.dynamic - << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel ? pcies.power.readOp.longer_channel_leakage - : pcies.power.readOp.leakage) - << " W" << endl; - cout << indent_str_next - << "Gate Leakage = " << pcies.power.readOp.gate_leakage << " W" - << endl; - cout << indent_str_next - << "Runtime Dynamic = " << pcies.rt_power.readOp.dynamic << " W" - << endl; - cout << endl; - } - cout << "******************************************************************" - "***********************" - << endl; - if (plevel > 1) { - for (i = 0; i < numCore; i++) { - cores[i]->displayEnergy(indent + 4, plevel, is_tdp); - cout << "**************************************************************" - "***************************" - << endl; - } - if (!XML->sys.Private_L2) { - for (i = 0; i < numL2; i++) { - l2array[i]->displayEnergy(indent + 4, is_tdp); - cout << "************************************************************" - "*****************************" - << endl; - } - } - for (i = 0; i < numL3; i++) { - l3array[i]->displayEnergy(indent + 4, is_tdp); - cout << "**************************************************************" - "***************************" - << endl; - } - for (i = 0; i < numL1Dir; i++) { - l1dirarray[i]->displayEnergy(indent + 4, is_tdp); - cout << "**************************************************************" - "***************************" - << endl; - } - for (i = 0; i < numL2Dir; i++) { - l2dirarray[i]->displayEnergy(indent + 4, is_tdp); - cout << "**************************************************************" - "***************************" - << endl; - } - if (XML->sys.mc.number_mcs > 0 && - XML->sys.mc.memory_channels_per_mc > 0) { - mc->displayEnergy(indent + 4, is_tdp); - cout << "**************************************************************" - "***************************" - << endl; - } - if (XML->sys.flashc.number_mcs > 0 && - XML->sys.flashc.memory_channels_per_mc > 0) { - flashcontroller->displayEnergy(indent + 4, is_tdp); - cout << "**************************************************************" - "***************************" - << endl; - } - if (XML->sys.niu.number_units > 0) { - niu->displayEnergy(indent + 4, is_tdp); - cout << "**************************************************************" - "***************************" - << endl; - } - if (XML->sys.pcie.number_units > 0 && XML->sys.pcie.num_channels > 0) { - pcie->displayEnergy(indent + 4, is_tdp); - cout << "**************************************************************" - "***************************" - << endl; - } - - for (i = 0; i < numNOC; i++) { - nocs[i]->displayEnergy(indent + 4, plevel, is_tdp); - cout << "**************************************************************" - "***************************" - << endl; - } - } - } else { - } +void Processor::displayDeviceType(int device_type_, uint32_t indent) +{ + string indent_str(indent, ' '); + + switch ( device_type_ ) { + + case 0 : + cout <sys.homogeneous_cores); - procdynp.homoL2 = bool(debug ? 1 : XML->sys.homogeneous_L2s); - procdynp.homoL3 = bool(debug ? 1 : XML->sys.homogeneous_L3s); - procdynp.homoNOC = bool(debug ? 1 : XML->sys.homogeneous_NoCs); - procdynp.homoL1Dir = bool(debug ? 1 : XML->sys.homogeneous_L1Directories); - procdynp.homoL2Dir = bool(debug ? 1 : XML->sys.homogeneous_L2Directories); - - procdynp.numCore = XML->sys.number_of_cores; - procdynp.numL2 = XML->sys.number_of_L2s; - procdynp.numL3 = XML->sys.number_of_L3s; - procdynp.numNOC = XML->sys.number_of_NoCs; - procdynp.numL1Dir = XML->sys.number_of_L1Directories; - procdynp.numL2Dir = XML->sys.number_of_L2Directories; - procdynp.numMC = XML->sys.mc.number_mcs; - procdynp.numMCChannel = XML->sys.mc.memory_channels_per_mc; - - // if (procdynp.numCore<1) - // { - // cout<<" The target processor should at least have one core on chip." - //<2) - // { - // cout <<"number of NOCs must be 1 (only global NOCs) or 2 (both global - // and local NOCs)"<sys.device_type; - interface_ip.data_arr_peri_global_tech_type = - debug ? 0 : XML->sys.device_type; - interface_ip.tag_arr_ram_cell_tech_type = debug ? 0 : XML->sys.device_type; - interface_ip.tag_arr_peri_global_tech_type = debug ? 0 : XML->sys.device_type; - - interface_ip.ic_proj_type = debug ? 0 : XML->sys.interconnect_projection_type; - interface_ip.delay_wt = - 100; // Fixed number, make sure timing can be satisfied. - interface_ip.area_wt = 0; // Fixed number, This is used to exhaustive search - // for individual components. - interface_ip.dynamic_power_wt = 100; // Fixed number, This is used to - // exhaustive search for individual - // components. - interface_ip.leakage_power_wt = 0; - interface_ip.cycle_time_wt = 0; - - interface_ip.delay_dev = - 10000; // Fixed number, make sure timing can be satisfied. - interface_ip.area_dev = 10000; // Fixed number, This is used to exhaustive - // search for individual components. - interface_ip.dynamic_power_dev = 10000; // Fixed number, This is used to - // exhaustive search for individual - // components. - interface_ip.leakage_power_dev = 10000; - interface_ip.cycle_time_dev = 10000; - - interface_ip.ed = 2; - interface_ip.burst_len = 1; // parameters are fixed for processor section, - // since memory is processed separately - interface_ip.int_prefetch_w = 1; - interface_ip.page_sz_bits = 0; - interface_ip.temp = debug ? 360 : XML->sys.temperature; - interface_ip.F_sz_nm = - debug ? 90 : XML->sys.core_tech_node; // XML->sys.core_tech_node; - interface_ip.F_sz_um = interface_ip.F_sz_nm / 1000; - - //***********This section of code does not have real meaning, they are just to - //ensure all data will have initial value to prevent errors. - // They will be overridden during each components initialization - interface_ip.cache_sz = 64; - interface_ip.line_sz = 1; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8; - interface_ip.specific_tag = 1; - interface_ip.tag_w = 64; - interface_ip.access_mode = 2; - - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - - interface_ip.is_main_mem = false; - interface_ip.rpters_in_htree = true; - interface_ip.ver_htree_wires_over_array = 0; - interface_ip.broadcast_addr_din_over_ver_htrees = 0; - - interface_ip.num_rw_ports = 1; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = 1; - interface_ip.nuca = 0; - interface_ip.nuca_bank_count = 0; - interface_ip.is_cache = true; - interface_ip.pure_ram = false; - interface_ip.pure_cam = false; - interface_ip.force_cache_config = false; - if (XML->sys.Embedded) { - interface_ip.wt = Global_30; - interface_ip.wire_is_mat_type = 0; - interface_ip.wire_os_mat_type = 0; - } else { - interface_ip.wt = Global; - interface_ip.wire_is_mat_type = 2; - interface_ip.wire_os_mat_type = 2; - } - interface_ip.force_wiretype = false; - interface_ip.print_detail = 1; - interface_ip.add_ecc_b_ = true; +void Processor::displayInterconnectType(int interconnect_type_, uint32_t indent) +{ + string indent_str(indent, ' '); + + switch ( interconnect_type_ ) { + + case 0 : + cout <sys.longer_channel_device; + string indent_str(indent, ' '); + string indent_str_next(indent+2, ' '); + bool is_tdp=is_tdp_parm; + if (is_tdp_parm) + { + + + if (plevel<5) + { + cout<<"\nMcPAT (version "<< VER_MAJOR <<"."<< VER_MINOR + << " of " << VER_UPDATE << ") results (current print level is "<< plevel + <<", please increase print level to see the details in components): "<sys.core_tech_node<<" nm"<sys.core[0].clock_rate<0){ + cout <sys.number_of_cores << " cores "<sys.device_type,indent); + cout << indent_str_next << "Area = " << core.area.get_area()*1e-6<< " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << core.power.readOp.dynamic << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? core.power.readOp.longer_channel_leakage:core.power.readOp.leakage) <<" W" << endl; + //cout << indent_str_next << "Subthreshold Leakage = " << core.power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str_next << "Gate Leakage = " << core.power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << core.rt_power.readOp.dynamic << " W" << endl; + cout <sys.Private_L2) + { + if (numL2 >0){ + cout <sys.L2[0].device_type,indent); + cout << indent_str_next << "Area = " << l2.area.get_area()*1e-6<< " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << l2.power.readOp.dynamic << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? l2.power.readOp.longer_channel_leakage:l2.power.readOp.leakage) <<" W" << endl; + //cout << indent_str_next << "Subthreshold Leakage = " << l2.power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str_next << "Gate Leakage = " << l2.power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << l2.rt_power.readOp.dynamic << " W" << endl; + cout <0){ + cout <sys.L3[0].device_type, indent); + cout << indent_str_next << "Area = " << l3.area.get_area()*1e-6<< " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << l3.power.readOp.dynamic << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? l3.power.readOp.longer_channel_leakage:l3.power.readOp.leakage) <<" W" << endl; + //cout << indent_str_next << "Subthreshold Leakage = " << l3.power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str_next << "Gate Leakage = " << l3.power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << l3.rt_power.readOp.dynamic << " W" << endl; + cout <0){ + cout <sys.L1Directory[0].device_type, indent); + cout << indent_str_next << "Area = " << l1dir.area.get_area()*1e-6<< " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << l1dir.power.readOp.dynamic << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? l1dir.power.readOp.longer_channel_leakage:l1dir.power.readOp.leakage) <<" W" << endl; + //cout << indent_str_next << "Subthreshold Leakage = " << l1dir.power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str_next << "Gate Leakage = " << l1dir.power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << l1dir.rt_power.readOp.dynamic << " W" << endl; + cout <0){ + cout <sys.L1Directory[0].device_type, indent); + cout << indent_str_next << "Area = " << l2dir.area.get_area()*1e-6<< " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << l2dir.power.readOp.dynamic << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? l2dir.power.readOp.longer_channel_leakage:l2dir.power.readOp.leakage) <<" W" << endl; + //cout << indent_str_next << "Subthreshold Leakage = " << l2dir.power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str_next << "Gate Leakage = " << l2dir.power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << l2dir.rt_power.readOp.dynamic << " W" << endl; + cout <0){ + cout <sys.device_type, indent); + cout << indent_str_next << "Area = " << noc.area.get_area()*1e-6<< " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << noc.power.readOp.dynamic << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? noc.power.readOp.longer_channel_leakage:noc.power.readOp.leakage) <<" W" << endl; + //cout << indent_str_next << "Subthreshold Leakage = " << noc.power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str_next << "Gate Leakage = " << noc.power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << noc.rt_power.readOp.dynamic << " W" << endl; + cout <sys.mc.number_mcs >0 && XML->sys.mc.memory_channels_per_mc>0) + { + cout <sys.mc.number_mcs << " Memory Controllers "<sys.device_type, indent); + cout << indent_str_next << "Area = " << mcs.area.get_area()*1e-6<< " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << mcs.power.readOp.dynamic << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? mcs.power.readOp.longer_channel_leakage:mcs.power.readOp.leakage) <<" W" << endl; + cout << indent_str_next << "Gate Leakage = " << mcs.power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << mcs.rt_power.readOp.dynamic << " W" << endl; + cout <sys.flashc.number_mcs >0) + { + cout <fcp.num_mcs << " Flash/SSD Controllers "<sys.device_type, indent); + cout << indent_str_next << "Area = " << flashcontrollers.area.get_area()*1e-6<< " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << flashcontrollers.power.readOp.dynamic << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? flashcontrollers.power.readOp.longer_channel_leakage:flashcontrollers.power.readOp.leakage) <<" W" << endl; + cout << indent_str_next << "Gate Leakage = " << flashcontrollers.power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << flashcontrollers.rt_power.readOp.dynamic << " W" << endl; + cout <sys.niu.number_units >0 ) + { + cout <niup.num_units << " Network Interface Units "<sys.device_type, indent); + cout << indent_str_next << "Area = " << nius.area.get_area()*1e-6<< " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << nius.power.readOp.dynamic << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? nius.power.readOp.longer_channel_leakage:nius.power.readOp.leakage) <<" W" << endl; + cout << indent_str_next << "Gate Leakage = " << nius.power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << nius.rt_power.readOp.dynamic << " W" << endl; + cout <sys.pcie.number_units >0 && XML->sys.pcie.num_channels>0) + { + cout <pciep.num_units << " PCIe Controllers "<sys.device_type, indent); + cout << indent_str_next << "Area = " << pcies.area.get_area()*1e-6<< " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << pcies.power.readOp.dynamic << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel? pcies.power.readOp.longer_channel_leakage:pcies.power.readOp.leakage) <<" W" << endl; + cout << indent_str_next << "Gate Leakage = " << pcies.power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " << pcies.rt_power.readOp.dynamic << " W" << endl; + cout <1) + { + for (i = 0;i < numCore; i++) + { + cores[i]->displayEnergy(indent+4,plevel,is_tdp); + cout <<"*****************************************************************************************"<sys.Private_L2) + { + for (i = 0;i < numL2; i++) + { + l2array[i]->displayEnergy(indent+4,is_tdp); + cout <<"*****************************************************************************************"<displayEnergy(indent+4,is_tdp); + cout <<"*****************************************************************************************"<displayEnergy(indent+4,is_tdp); + cout <<"*****************************************************************************************"<displayEnergy(indent+4,is_tdp); + cout <<"*****************************************************************************************"<sys.mc.number_mcs >0 && XML->sys.mc.memory_channels_per_mc>0) + { + mc->displayEnergy(indent+4,is_tdp); + cout <<"*****************************************************************************************"<sys.flashc.number_mcs >0 && XML->sys.flashc.memory_channels_per_mc>0) + { + flashcontroller->displayEnergy(indent+4,is_tdp); + cout <<"*****************************************************************************************"<sys.niu.number_units >0 ) + { + niu->displayEnergy(indent+4,is_tdp); + cout <<"*****************************************************************************************"<sys.pcie.number_units >0 && XML->sys.pcie.num_channels>0) + { + pcie->displayEnergy(indent+4,is_tdp); + cout <<"*****************************************************************************************"<displayEnergy(indent+4,plevel,is_tdp); + cout <<"*****************************************************************************************"<sys.homogeneous_cores); + procdynp.homoL2 = bool(debug?1:XML->sys.homogeneous_L2s); + procdynp.homoL3 = bool(debug?1:XML->sys.homogeneous_L3s); + procdynp.homoNOC = bool(debug?1:XML->sys.homogeneous_NoCs); + procdynp.homoL1Dir = bool(debug?1:XML->sys.homogeneous_L1Directories); + procdynp.homoL2Dir = bool(debug?1:XML->sys.homogeneous_L2Directories); + + procdynp.numCore = XML->sys.number_of_cores; + procdynp.numL2 = XML->sys.number_of_L2s; + procdynp.numL3 = XML->sys.number_of_L3s; + procdynp.numNOC = XML->sys.number_of_NoCs; + procdynp.numL1Dir = XML->sys.number_of_L1Directories; + procdynp.numL2Dir = XML->sys.number_of_L2Directories; + procdynp.numMC = XML->sys.mc.number_mcs; + procdynp.numMCChannel = XML->sys.mc.memory_channels_per_mc; + +// if (procdynp.numCore<1) +// { +// cout<<" The target processor should at least have one core on chip." <2) + // { + // cout <<"number of NOCs must be 1 (only global NOCs) or 2 (both global and local NOCs)"<sys.device_type; + interface_ip.data_arr_peri_global_tech_type = debug?0:XML->sys.device_type; + interface_ip.tag_arr_ram_cell_tech_type = debug?0:XML->sys.device_type; + interface_ip.tag_arr_peri_global_tech_type = debug?0:XML->sys.device_type; + + interface_ip.ic_proj_type = debug?0:XML->sys.interconnect_projection_type; + interface_ip.delay_wt = 100;//Fixed number, make sure timing can be satisfied. + interface_ip.area_wt = 0;//Fixed number, This is used to exhaustive search for individual components. + interface_ip.dynamic_power_wt = 100;//Fixed number, This is used to exhaustive search for individual components. + interface_ip.leakage_power_wt = 0; + interface_ip.cycle_time_wt = 0; + + interface_ip.delay_dev = 10000;//Fixed number, make sure timing can be satisfied. + interface_ip.area_dev = 10000;//Fixed number, This is used to exhaustive search for individual components. + interface_ip.dynamic_power_dev = 10000;//Fixed number, This is used to exhaustive search for individual components. + interface_ip.leakage_power_dev = 10000; + interface_ip.cycle_time_dev = 10000; + + interface_ip.ed = 2; + interface_ip.burst_len = 1;//parameters are fixed for processor section, since memory is processed separately + interface_ip.int_prefetch_w = 1; + interface_ip.page_sz_bits = 0; + interface_ip.temp = debug?360: XML->sys.temperature; + interface_ip.F_sz_nm = debug?90:XML->sys.core_tech_node;//XML->sys.core_tech_node; + interface_ip.F_sz_um = interface_ip.F_sz_nm / 1000; + + //***********This section of code does not have real meaning, they are just to ensure all data will have initial value to prevent errors. + //They will be overridden during each components initialization + interface_ip.cache_sz =64; + interface_ip.line_sz = 1; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.specific_tag = 1; + interface_ip.tag_w = 64; + interface_ip.access_mode = 2; + + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + + interface_ip.is_main_mem = false; + interface_ip.rpters_in_htree = true ; + interface_ip.ver_htree_wires_over_array = 0; + interface_ip.broadcast_addr_din_over_ver_htrees = 0; + + interface_ip.num_rw_ports = 1; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = 1; + interface_ip.nuca = 0; + interface_ip.nuca_bank_count = 0; + interface_ip.is_cache =true; + interface_ip.pure_ram =false; + interface_ip.pure_cam =false; + interface_ip.force_cache_config =false; + if (XML->sys.Embedded) + { + interface_ip.wt =Global_30; + interface_ip.wire_is_mat_type = 0; + interface_ip.wire_os_mat_type = 0; + } + else + { + interface_ip.wt =Global; + interface_ip.wire_is_mat_type = 2; + interface_ip.wire_os_mat_type = 2; + } + interface_ip.force_wiretype = false; + interface_ip.print_detail = 1; + interface_ip.add_ecc_b_ =true; +} + + +Processor::~Processor(){ + while (!cores.empty()) + { + delete cores.back(); + cores.pop_back(); + } + while (!l2array.empty()) + { + delete l2array.back(); + l2array.pop_back(); + } + while (!l3array.empty()) + { + delete l3array.back(); + l3array.pop_back(); + } + while (!nocs.empty()) + { + delete nocs.back(); + nocs.pop_back(); + } + if (!mc) + { + delete mc; + } + if (!niu) + { + delete niu; + } + if (!pcie) + { + delete pcie; + } + if (!flashcontroller) + { + delete flashcontroller; + } }; + + diff --git a/src/gpuwattch/processor.h b/src/gpuwattch/processor.h index 326206c..7202460 100644 --- a/src/gpuwattch/processor.h +++ b/src/gpuwattch/processor.h @@ -29,8 +29,7 @@ * ***************************************************************************/ /******************************************************************** -* Modified by: -** +* Modified by: * * Jingwen Leng, Univeristy of Texas, Austin * * Syed Gilani, University of Wisconsin–Madison * * Tayler Hetherington, University of British Columbia * @@ -39,287 +38,253 @@ #ifndef PROCESSOR_H_ #define PROCESSOR_H_ -#include -#include "../gpgpu-sim/visualizer.h" #include "XML_Parse.h" -#include "array.h" -#include "basic_components.h" -#include "cacti/arbiter.h" #include "cacti/area.h" #include "cacti/decoder.h" #include "cacti/parameter.h" -#include "cacti/router.h" +#include "array.h" +#include "cacti/arbiter.h" +#include +#include "basic_components.h" #include "core.h" -#include "iocontrollers.h" #include "memoryctrl.h" -#include "noc.h" +#include "cacti/router.h" #include "sharedcache.h" +#include "noc.h" +#include "iocontrollers.h" +#include "../gpgpu-sim/visualizer.h" + +class Processor : public Component +{ + public: + ParseXML *XML; + vector cores; + vector l2array; + vector l3array; + vector l1dirarray; + vector l2dirarray; + vector nocs; + MemoryController * mc; + NIUController * niu; + PCIeController * pcie; + FlashController * flashcontroller; + InputParameter interface_ip; + double exClockRate; + ProcParam procdynp; + //for debugging nonlinear model + double dyn_power_before_scaling; + + //wire globalInterconnect; + //clock_network globalClock; + Component core, l2, l3, l1dir, l2dir, noc, mcs, cc, nius, pcies,flashcontrollers; + int numCore, numL2, numL3, numNOC, numL1Dir, numL2Dir; + Processor(ParseXML *XML_interface); + void compute(); + void set_proc_param(); + void visualizer_print( gzFile visualizer_file ); + void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp_parm=true); + void displayDeviceType(int device_type_, uint32_t indent = 0); + void displayInterconnectType(int interconnect_type_, uint32_t indent = 0); + double l2_power; + double idle_core_power; + + double get_const_dynamic_power() + { + + double constpart=0; + constpart+=(mc->frontend->power.readOp.dynamic*0.1*mc->frontend->mcp.clockRate*mc->frontend->mcp.num_mcs*mc->frontend->mcp.executionTime); + constpart+=(mc->transecEngine->power.readOp.dynamic*0.1*mc->transecEngine->mcp.clockRate*mc->transecEngine->mcp.num_mcs*mc->transecEngine->mcp.executionTime); + constpart+=(mc->PHY->power.readOp.dynamic*0.1*mc->PHY->mcp.clockRate*mc->PHY->mcp.num_mcs*mc->PHY->mcp.executionTime); + constpart+=(cores[0]->exu->exeu->base_energy/cores[0]->exu->exeu->clockRate)*(cores[0]->exu->rf_fu_clockRate/cores[0]->exu->clockRate); + constpart+=(cores[0]->exu->mul->base_energy/cores[0]->exu->mul->clockRate); + constpart+=(cores[0]->exu->fp_u->base_energy/cores[0]->exu->fp_u->clockRate); + return constpart; + } +#define COALESCE_SCALE 1 + double get_coefficient_readcoalescing() + { + double value=0; + double perAccessCoalescingEnergy=COALESCE_SCALE * ((0.443e-3)*(0.5e-9)*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd)/(1*1); + value+=mc->frontend->PRT->local_result.power.readOp.dynamic; + value+=mc->frontend->threadMasks->local_result.power.readOp.dynamic; + value+=mc->frontend->PRC->local_result.power.readOp.dynamic; + value+=perAccessCoalescingEnergy; + return value; -class Processor : public Component { - public: - ParseXML *XML; - vector cores; - vector l2array; - vector l3array; - vector l1dirarray; - vector l2dirarray; - vector nocs; - MemoryController *mc; - NIUController *niu; - PCIeController *pcie; - FlashController *flashcontroller; - InputParameter interface_ip; - double exClockRate; - ProcParam procdynp; - // for debugging nonlinear model - double dyn_power_before_scaling; - - // wire globalInterconnect; - // clock_network globalClock; - Component core, l2, l3, l1dir, l2dir, noc, mcs, cc, nius, pcies, - flashcontrollers; - int numCore, numL2, numL3, numNOC, numL1Dir, numL2Dir; - Processor(ParseXML *XML_interface); - void compute(); - void set_proc_param(); - void visualizer_print(gzFile visualizer_file); - void displayEnergy(uint32_t indent = 0, int plevel = 100, - bool is_tdp_parm = true); - void displayDeviceType(int device_type_, uint32_t indent = 0); - void displayInterconnectType(int interconnect_type_, uint32_t indent = 0); - double l2_power; - double idle_core_power; - - double get_const_dynamic_power() { - double constpart = 0; - constpart += (mc->frontend->power.readOp.dynamic * 0.1 * - mc->frontend->mcp.clockRate * mc->frontend->mcp.num_mcs * - mc->frontend->mcp.executionTime); - constpart += - (mc->transecEngine->power.readOp.dynamic * 0.1 * - mc->transecEngine->mcp.clockRate * mc->transecEngine->mcp.num_mcs * - mc->transecEngine->mcp.executionTime); - constpart += (mc->PHY->power.readOp.dynamic * 0.1 * mc->PHY->mcp.clockRate * - mc->PHY->mcp.num_mcs * mc->PHY->mcp.executionTime); - constpart += - (cores[0]->exu->exeu->base_energy / cores[0]->exu->exeu->clockRate) * - (cores[0]->exu->rf_fu_clockRate / cores[0]->exu->clockRate); - constpart += - (cores[0]->exu->mul->base_energy / cores[0]->exu->mul->clockRate); - constpart += - (cores[0]->exu->fp_u->base_energy / cores[0]->exu->fp_u->clockRate); - return constpart; - } -#define COALESCE_SCALE 1 - double get_coefficient_readcoalescing() { - double value = 0; - double perAccessCoalescingEnergy = - COALESCE_SCALE * - ((0.443e-3) * (0.5e-9) * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd) / - (1 * 1); - value += mc->frontend->PRT->local_result.power.readOp.dynamic; - value += mc->frontend->threadMasks->local_result.power.readOp.dynamic; - value += mc->frontend->PRC->local_result.power.readOp.dynamic; - value += perAccessCoalescingEnergy; - return value; - } - double get_coefficient_writecoalescing() { - double value = 0; - double perAccessCoalescingEnergy = - COALESCE_SCALE * - ((0.443e-3) * (0.5e-9) * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd) / - (1 * 1); - value += (mc->frontend->PRT->local_result.power.writeOp.dynamic); - value += mc->frontend->threadMasks->local_result.power.writeOp.dynamic; - value += mc->frontend->PRC->local_result.power.writeOp.dynamic; - value += perAccessCoalescingEnergy; - return value; - } - - double get_coefficient_noc_accesses() { - double read_coef = 0; - // the 32/4 is applied to the NoC access counters (32/4*L2 cache access) - read_coef += nocs[0]->router->buffer.power.readOp.dynamic; - read_coef += nocs[0]->router->buffer.power.writeOp.dynamic; - read_coef += nocs[0]->router->crossbar.power.readOp.dynamic; - read_coef += nocs[0]->router->arbiter.power.readOp.dynamic; - return read_coef; - } - - double get_coefficient_l2_read_hits() { - double read_coef = 0; - if (XML->sys.number_of_L2s > 0) - read_coef = - l2array[0]->unicache.caches->local_result.power.readOp.dynamic; - return read_coef; - } - - double get_coefficient_l2_read_misses() { - double read_coef = 0; - if (XML->sys.number_of_L2s > 0) - read_coef = - l2array[0] - ->unicache.caches->local_result.tag_array2->power.readOp.dynamic; - return read_coef; - } - - double get_coefficient_l2_write_hits() { - double read_coef = 0; - if (XML->sys.number_of_L2s > 0) - read_coef = - l2array[0]->unicache.caches->local_result.power.writeOp.dynamic; - return read_coef; - } - double get_coefficient_l2_write_misses() { - double read_coef = 0; - if (XML->sys.number_of_L2s > 0) { - read_coef = l2array[0] - ->unicache.caches->local_result.tag_array2->power.writeOp - .dynamic; //*(32/4); // removed by Jingwen, the scaling - //of 32/4 is not used in the mcpat - read_coef += - l2array[0]->unicache.caches->local_result.power.writeOp.dynamic; - read_coef += - l2array[0]->unicache.missb->local_result.power.searchOp.dynamic; - read_coef += - l2array[0]->unicache.missb->local_result.power.writeOp.dynamic; - read_coef += - l2array[0]->unicache.ifb->local_result.power.searchOp.dynamic; - read_coef += l2array[0]->unicache.ifb->local_result.power.writeOp.dynamic; - read_coef += - l2array[0]->unicache.prefetchb->local_result.power.searchOp.dynamic; - read_coef += - l2array[0]->unicache.prefetchb->local_result.power.writeOp.dynamic; - read_coef += - l2array[0]->unicache.wbb->local_result.power.searchOp.dynamic; - read_coef += l2array[0]->unicache.wbb->local_result.power.writeOp.dynamic; } + double get_coefficient_writecoalescing() + { + double value=0; + double perAccessCoalescingEnergy=COALESCE_SCALE *((0.443e-3)*(0.5e-9)*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd)/(1*1); + value+=(mc->frontend->PRT->local_result.power.writeOp.dynamic); + value+=mc->frontend->threadMasks->local_result.power.writeOp.dynamic; + value+=mc->frontend->PRC->local_result.power.writeOp.dynamic; + value+=perAccessCoalescingEnergy; + return value; + } + + + double get_coefficient_noc_accesses() { + double read_coef=0; + // the 32/4 is applied to the NoC access counters (32/4*L2 cache access) + read_coef+= nocs[0]->router->buffer.power.readOp.dynamic; + read_coef+= nocs[0]->router->buffer.power.writeOp.dynamic; + read_coef+= nocs[0]->router->crossbar.power.readOp.dynamic; + read_coef+= nocs[0]->router->arbiter.power.readOp.dynamic; + return read_coef; + } + + double get_coefficient_l2_read_hits(){ + double read_coef=0; + if(XML->sys.number_of_L2s>0) + read_coef = l2array[0]->unicache.caches->local_result.power.readOp.dynamic; + return read_coef; + } + + double get_coefficient_l2_read_misses(){ + double read_coef=0; + if(XML->sys.number_of_L2s>0) + read_coef = l2array[0]->unicache.caches->local_result.tag_array2->power.readOp.dynamic; + return read_coef; + + } + + double get_coefficient_l2_write_hits(){ + double read_coef=0; + if(XML->sys.number_of_L2s>0) + read_coef = l2array[0]->unicache.caches->local_result.power.writeOp.dynamic; + return read_coef; + + } + double get_coefficient_l2_write_misses(){ + double read_coef=0; + if(XML->sys.number_of_L2s>0){ + read_coef = l2array[0]->unicache.caches->local_result.tag_array2->power.writeOp.dynamic;//*(32/4); // removed by Jingwen, the scaling of 32/4 is not used in the mcpat + read_coef +=l2array[0]->unicache.caches->local_result.power.writeOp.dynamic; + read_coef += l2array[0]->unicache.missb->local_result.power.searchOp.dynamic; + read_coef += l2array[0]->unicache.missb->local_result.power.writeOp.dynamic; + read_coef += l2array[0]->unicache.ifb->local_result.power.searchOp.dynamic; + read_coef += l2array[0]->unicache.ifb->local_result.power.writeOp.dynamic; + read_coef += l2array[0]->unicache.prefetchb->local_result.power.searchOp.dynamic; + read_coef += l2array[0]->unicache.prefetchb->local_result.power.writeOp.dynamic; + read_coef += l2array[0]->unicache.wbb->local_result.power.searchOp.dynamic; + read_coef += l2array[0]->unicache.wbb->local_result.power.writeOp.dynamic; + } + + return read_coef; + + } + + + double get_coefficient_mem_reads() + { + double value=0; + value+= (mc->frontend->mcp.llcBlockSize*8.0/mc->frontend->mcp.dataBusWidth*mc->frontend->mcp.dataBusWidth/72)* + (mc->frontend->frontendBuffer->local_result.power.searchOp.dynamic); + + value+= (mc->frontend->mcp.llcBlockSize*8.0/mc->frontend->mcp.dataBusWidth*mc->frontend->mcp.dataBusWidth/72)* + (mc->frontend->frontendBuffer->local_result.power.readOp.dynamic); + +//TODO: Jingwen this should only compute for one time? + //value+=(mc->frontend->mcp.llcBlockSize*8.0/mc->frontend->mcp.dataBusWidth*mc->frontend->mcp.dataBusWidth/72) + //*(mc->frontend->frontendBuffer->local_result.power.readOp.dynamic); + + value+=(mc->frontend->mcp.llcBlockSize*8.0/mc->mcp.dataBusWidth)* + (mc->frontend->readBuffer->local_result.power.readOp.dynamic); + + value+=(mc->frontend->mcp.llcBlockSize*8.0/mc->mcp.dataBusWidth)* + (mc->frontend->readBuffer->local_result.power.writeOp.dynamic); + + value+=mc->dram->dramp.rd_coeff; + /* + value+=mc->frontend->PRT->local_result.power.readOp.dynamic; + value+=mc->frontend->threadMasks->local_result.power.readOp.dynamic; + value+=mc->frontend->PRC->local_result.power.readOp.dynamic; + value+=perAccessCoalescingEnergy; + */ + value+=(mc->transecEngine->mcp.llcBlockSize*8.0/mc->transecEngine->mcp.dataBusWidth*mc->transecEngine->power_t.readOp.dynamic); + + //if mcp.type ==1 TODO: add this check here + value += (mc->PHY->power_t.readOp.dynamic)*(mc->PHY->mcp.llcBlockSize)*8/1e9/mc->PHY->mcp.executionTime*(mc->PHY->mcp.executionTime); + //printf("MC PHY read power coeff: %f\n",(mc->PHY->power_t.readOp.dynamic)*(mc->PHY->mcp.llcBlockSize)*8/1e9/mc->PHY->mcp.executionTime*(mc->PHY->mcp.executionTime)); + //printf("MC trans read power coeff: %f\n",(mc->transecEngine->mcp.llcBlockSize*8.0/mc->transecEngine->mcp.dataBusWidth*mc->transecEngine->power_t.readOp.dynamic)); + +//TODO: Jingwen nocs stats should not be here +// value+= nocs[0]->router->buffer.power.readOp.dynamic*(32/4); +// value+= nocs[0]->router->buffer.power.writeOp.dynamic*(32/4); +// value+= nocs[0]->router->crossbar.power.readOp.dynamic*(32/4); +// value+= nocs[0]->router->arbiter.power.readOp.dynamic*(32/4); + + //return 0.4*value; + return value; + } + + + double get_coefficient_mem_writes() + { + double value=0; + + value+=(mc->frontend->mcp.llcBlockSize*8.0/mc->frontend->mcp.dataBusWidth*mc->frontend->mcp.dataBusWidth/72)* + (mc->frontend->frontendBuffer->local_result.power.searchOp.dynamic); + + value+=(mc->frontend->mcp.llcBlockSize*8.0/mc->frontend->mcp.dataBusWidth*mc->frontend->mcp.dataBusWidth/72)* + (mc->frontend->frontendBuffer->local_result.power.writeOp.dynamic); + + //value+=(mc->frontend->mcp.llcBlockSize*8.0/mc->frontend->mcp.dataBusWidth*mc->frontend->mcp.dataBusWidth/72)* + // (mc->frontend->frontendBuffer->local_result.power.writeOp.dynamic); + + value+=(mc->frontend->mcp.llcBlockSize*8.0/mc->frontend->mcp.dataBusWidth)* + (mc->frontend->writeBuffer->local_result.power.readOp.dynamic); + + value+=(mc->frontend->mcp.llcBlockSize*8.0/mc->frontend->mcp.dataBusWidth)* + (mc->frontend->writeBuffer->local_result.power.writeOp.dynamic); + + value+=mc->dram->dramp.wr_coeff; + /* + value+=(mc->frontend->PRT->local_result.power.writeOp.dynamic); + + value+=mc->frontend->threadMasks->local_result.power.writeOp.dynamic; + + value+=mc->frontend->PRC->local_result.power.writeOp.dynamic; + + value+=perAccessCoalescingEnergy; + */ + + value+=(mc->transecEngine->mcp.llcBlockSize*8.0/mc->transecEngine->mcp.dataBusWidth*mc->transecEngine->power_t.readOp.dynamic); + + + //if mcp.type ==1 TODO: add this check here + value += (mc->PHY->power_t.readOp.dynamic)*(mc->PHY->mcp.llcBlockSize)*8/1e9/mc->PHY->mcp.executionTime*(mc->PHY->mcp.executionTime); + + +//TODO: Jingwen nocs stats should not be here +// value+= nocs[0]->router->buffer.power.readOp.dynamic*(32/4); +// +// value+= nocs[0]->router->buffer.power.writeOp.dynamic*(32/4); +// +// value+= nocs[0]->router->crossbar.power.readOp.dynamic*(32/4); +// +// value+= nocs[0]->router->arbiter.power.readOp.dynamic*(32/4); +// + //return 0.4*value; + return value; + } + + double get_coefficient_mem_pre() + { + double value=0; + value+=mc->dram->dramp.pre_coeff; + //return 0.4*value; + return value; + + } + + //nonlinear scale + void nonlinear_scale(int, double, int); + void coefficient_scale(); + void iterative_lse(double *, double* ); - return read_coef; - } - - double get_coefficient_mem_reads() { - double value = 0; - value += - (mc->frontend->mcp.llcBlockSize * 8.0 / mc->frontend->mcp.dataBusWidth * - mc->frontend->mcp.dataBusWidth / 72) * - (mc->frontend->frontendBuffer->local_result.power.searchOp.dynamic); - - value += - (mc->frontend->mcp.llcBlockSize * 8.0 / mc->frontend->mcp.dataBusWidth * - mc->frontend->mcp.dataBusWidth / 72) * - (mc->frontend->frontendBuffer->local_result.power.readOp.dynamic); - - // TODO: Jingwen this should only compute for one time? - // value+=(mc->frontend->mcp.llcBlockSize*8.0/mc->frontend->mcp.dataBusWidth*mc->frontend->mcp.dataBusWidth/72) - //*(mc->frontend->frontendBuffer->local_result.power.readOp.dynamic); - - value += (mc->frontend->mcp.llcBlockSize * 8.0 / mc->mcp.dataBusWidth) * - (mc->frontend->readBuffer->local_result.power.readOp.dynamic); - - value += (mc->frontend->mcp.llcBlockSize * 8.0 / mc->mcp.dataBusWidth) * - (mc->frontend->readBuffer->local_result.power.writeOp.dynamic); - - value += mc->dram->dramp.rd_coeff; - /* - value+=mc->frontend->PRT->local_result.power.readOp.dynamic; - value+=mc->frontend->threadMasks->local_result.power.readOp.dynamic; - value+=mc->frontend->PRC->local_result.power.readOp.dynamic; - value+=perAccessCoalescingEnergy; - */ - value += (mc->transecEngine->mcp.llcBlockSize * 8.0 / - mc->transecEngine->mcp.dataBusWidth * - mc->transecEngine->power_t.readOp.dynamic); - - // if mcp.type ==1 TODO: add this check here - value += (mc->PHY->power_t.readOp.dynamic) * (mc->PHY->mcp.llcBlockSize) * - 8 / 1e9 / mc->PHY->mcp.executionTime * - (mc->PHY->mcp.executionTime); - // printf("MC PHY read power coeff: - // %f\n",(mc->PHY->power_t.readOp.dynamic)*(mc->PHY->mcp.llcBlockSize)*8/1e9/mc->PHY->mcp.executionTime*(mc->PHY->mcp.executionTime)); - // printf("MC trans read power coeff: - // %f\n",(mc->transecEngine->mcp.llcBlockSize*8.0/mc->transecEngine->mcp.dataBusWidth*mc->transecEngine->power_t.readOp.dynamic)); - - // TODO: Jingwen nocs stats should not be here - // value+= nocs[0]->router->buffer.power.readOp.dynamic*(32/4); - // value+= nocs[0]->router->buffer.power.writeOp.dynamic*(32/4); - // value+= nocs[0]->router->crossbar.power.readOp.dynamic*(32/4); - // value+= nocs[0]->router->arbiter.power.readOp.dynamic*(32/4); - - // return 0.4*value; - return value; - } - - double get_coefficient_mem_writes() { - double value = 0; - - value += - (mc->frontend->mcp.llcBlockSize * 8.0 / mc->frontend->mcp.dataBusWidth * - mc->frontend->mcp.dataBusWidth / 72) * - (mc->frontend->frontendBuffer->local_result.power.searchOp.dynamic); - - value += - (mc->frontend->mcp.llcBlockSize * 8.0 / mc->frontend->mcp.dataBusWidth * - mc->frontend->mcp.dataBusWidth / 72) * - (mc->frontend->frontendBuffer->local_result.power.writeOp.dynamic); - - // value+=(mc->frontend->mcp.llcBlockSize*8.0/mc->frontend->mcp.dataBusWidth*mc->frontend->mcp.dataBusWidth/72)* - // (mc->frontend->frontendBuffer->local_result.power.writeOp.dynamic); - - value += (mc->frontend->mcp.llcBlockSize * 8.0 / - mc->frontend->mcp.dataBusWidth) * - (mc->frontend->writeBuffer->local_result.power.readOp.dynamic); - - value += (mc->frontend->mcp.llcBlockSize * 8.0 / - mc->frontend->mcp.dataBusWidth) * - (mc->frontend->writeBuffer->local_result.power.writeOp.dynamic); - - value += mc->dram->dramp.wr_coeff; - /* - value+=(mc->frontend->PRT->local_result.power.writeOp.dynamic); - - value+=mc->frontend->threadMasks->local_result.power.writeOp.dynamic; - - value+=mc->frontend->PRC->local_result.power.writeOp.dynamic; - - value+=perAccessCoalescingEnergy; - */ - - value += (mc->transecEngine->mcp.llcBlockSize * 8.0 / - mc->transecEngine->mcp.dataBusWidth * - mc->transecEngine->power_t.readOp.dynamic); - - // if mcp.type ==1 TODO: add this check here - value += (mc->PHY->power_t.readOp.dynamic) * (mc->PHY->mcp.llcBlockSize) * - 8 / 1e9 / mc->PHY->mcp.executionTime * - (mc->PHY->mcp.executionTime); - - // TODO: Jingwen nocs stats should not be here - // value+= nocs[0]->router->buffer.power.readOp.dynamic*(32/4); - // - // value+= nocs[0]->router->buffer.power.writeOp.dynamic*(32/4); - // - // value+= nocs[0]->router->crossbar.power.readOp.dynamic*(32/4); - // - // value+= nocs[0]->router->arbiter.power.readOp.dynamic*(32/4); - // - // return 0.4*value; - return value; - } - - double get_coefficient_mem_pre() { - double value = 0; - value += mc->dram->dramp.pre_coeff; - // return 0.4*value; - return value; - } - - // nonlinear scale - void nonlinear_scale(int, double, int); - void coefficient_scale(); - void iterative_lse(double *, double *); - - ~Processor(); + ~Processor(); }; #endif /* PROCESSOR_H_ */ diff --git a/src/gpuwattch/sharedcache.cc b/src/gpuwattch/sharedcache.cc index 147be43..9d4a045 100644 --- a/src/gpuwattch/sharedcache.cc +++ b/src/gpuwattch/sharedcache.cc @@ -29,251 +29,241 @@ * ***************************************************************************/ -#include "sharedcache.h" -#include -#include -#include -#include -#include -#include -#include "XML_Parse.h" -#include "array.h" -#include "cacti/arbiter.h" -#include "cacti/basic_circuit.h" +#include "io.h" #include "cacti/parameter.h" +#include "array.h" #include "const.h" -#include "io.h" #include "logic.h" +#include "cacti/basic_circuit.h" +#include "cacti/arbiter.h" +#include +#include +#include +#include "XML_Parse.h" +#include +#include +#include +#include "sharedcache.h" + -SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, - InputParameter* interface_ip_, - enum cache_level cacheL_) - : XML(XML_interface), - ithCache(ithCache_), - interface_ip(*interface_ip_), - cacheL(cacheL_), - dir_overhead(0) { + +SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, InputParameter* interface_ip_, enum cache_level cacheL_) +:XML(XML_interface), + ithCache(ithCache_), + interface_ip(*interface_ip_), + cacheL(cacheL_), + dir_overhead(0) +{ int idx; int tag, data; - bool debug; + bool debug; enum Device_ty device_t; - enum Core_type core_t; + enum Core_type core_t; double size, line, assoc, banks; - if (cacheL == L2 && XML->sys.Private_L2) { - device_t = Core_device; - core_t = (enum Core_type)XML->sys.core[ithCache].machine_type; - } else { - device_t = LLC_device; - core_t = Inorder; + if (cacheL==L2 && XML->sys.Private_L2) + { + device_t=Core_device; + core_t = (enum Core_type)XML->sys.core[ithCache].machine_type; } - - debug = false; - if (XML->sys.Embedded) { - interface_ip.wt = Global_30; - interface_ip.wire_is_mat_type = 0; - interface_ip.wire_os_mat_type = 1; - } else { - interface_ip.wt = Global; - interface_ip.wire_is_mat_type = 2; - interface_ip.wire_os_mat_type = 2; + else + { + device_t=LLC_device; + core_t = Inorder; } + + debug = false; + if (XML->sys.Embedded) + { + interface_ip.wt =Global_30; + interface_ip.wire_is_mat_type = 0; + interface_ip.wire_os_mat_type = 1; + } + else + { + interface_ip.wt =Global; + interface_ip.wire_is_mat_type = 2; + interface_ip.wire_os_mat_type = 2; + } set_cache_param(); - // All lower level cache are physically indexed and tagged. - size = cachep.capacity; - line = cachep.blockW; - assoc = cachep.assoc; - banks = cachep.nbanks; - if ((cachep.dir_ty == ST && cacheL == L1Directory) || - (cachep.dir_ty == ST && cacheL == L2Directory)) { - assoc = 0; - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - interface_ip.num_search_ports = 1; - } else { - idx = debug ? 9 : int(ceil(log2(size / line / assoc))); - tag = debug ? 51 : XML->sys.physical_address_width - idx - - int(ceil(log2(line))) + EXTRA_TAG_BITS; - interface_ip.num_search_ports = 0; - if (cachep.dir_ty == SBT) { - dir_overhead = - ceil(XML->sys.number_of_cores / 8.0) * 8 / (cachep.blockW * 8); - line = cachep.blockW * (1 + dir_overhead); - size = cachep.capacity * (1 + dir_overhead); - } + //All lower level cache are physically indexed and tagged. + size = cachep.capacity; + line = cachep.blockW; + assoc = cachep.assoc; + banks = cachep.nbanks; + if ((cachep.dir_ty==ST&& cacheL==L1Directory)||(cachep.dir_ty==ST&& cacheL==L2Directory)) + { + assoc = 0; + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + interface_ip.num_search_ports = 1; } - // if (XML->sys.first_level_dir==2) - // tag += int(XML->sys.domain_size + 5); - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.cache_sz = (int)size; - interface_ip.line_sz = (int)line; - interface_ip.assoc = (int)assoc; - interface_ip.nbanks = (int)banks; - interface_ip.out_w = interface_ip.line_sz * 8 / 2; - interface_ip.access_mode = 1; - interface_ip.throughput = cachep.throughput; - interface_ip.latency = cachep.latency; - interface_ip.is_cache = true; - interface_ip.pure_ram = false; - interface_ip.pure_cam = false; + else + { + idx = debug?9:int(ceil(log2(size/line/assoc))); + tag = debug?51:XML->sys.physical_address_width-idx-int(ceil(log2(line))) + EXTRA_TAG_BITS; + interface_ip.num_search_ports = 0; + if (cachep.dir_ty==SBT) + { + dir_overhead = ceil(XML->sys.number_of_cores/8.0)*8/(cachep.blockW*8); + line = cachep.blockW*(1+ dir_overhead) ; + size = cachep.capacity*(1+ dir_overhead); + + } + } +// if (XML->sys.first_level_dir==2) +// tag += int(XML->sys.domain_size + 5); + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.cache_sz = (int)size; + interface_ip.line_sz = (int)line; + interface_ip.assoc = (int)assoc; + interface_ip.nbanks = (int)banks; + interface_ip.out_w = interface_ip.line_sz*8/2; + interface_ip.access_mode = 1; + interface_ip.throughput = cachep.throughput; + interface_ip.latency = cachep.latency; + interface_ip.is_cache = true; + interface_ip.pure_ram = false; + interface_ip.pure_cam = false; interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; // lower level cache usually has one port. - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - // interface_ip.force_cache_config =true; - // interface_ip.ndwl = 4; - // interface_ip.ndbl = 8; - // interface_ip.nspd = 1; - // interface_ip.ndcm =1 ; - // interface_ip.ndsam1 =1; - // interface_ip.ndsam2 =1; - unicache.caches = - new ArrayST(&interface_ip, cachep.name + "cache", device_t, true, core_t); - unicache.area.set_area(unicache.area.get_area() + - unicache.caches->local_result.area); - area.set_area(area.get_area() + unicache.caches->local_result.area); - interface_ip.force_cache_config = false; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1;//lower level cache usually has one port. + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; +// interface_ip.force_cache_config =true; +// interface_ip.ndwl = 4; +// interface_ip.ndbl = 8; +// interface_ip.nspd = 1; +// interface_ip.ndcm =1 ; +// interface_ip.ndsam1 =1; +// interface_ip.ndsam2 =1; + unicache.caches = new ArrayST(&interface_ip, cachep.name + "cache", device_t, true, core_t); + unicache.area.set_area(unicache.area.get_area()+ unicache.caches->local_result.area); + area.set_area(area.get_area()+ unicache.caches->local_result.area); + interface_ip.force_cache_config =false; + - if (!((cachep.dir_ty == ST && cacheL == L1Directory) || - (cachep.dir_ty == ST && cacheL == L2Directory))) { - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = (XML->sys.physical_address_width) + int(ceil(log2(size / line))) + - unicache.caches->l_ip.line_sz; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = - int(ceil(data / 8.0)); // int(ceil(pow(2.0,ceil(log2(data)))/8.0)); - interface_ip.cache_sz = cachep.missb_size * interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.is_cache = true; - interface_ip.pure_ram = false; - interface_ip.pure_cam = false; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8 / 2; - interface_ip.access_mode = 0; - interface_ip.throughput = cachep.throughput; // means cycle time - interface_ip.latency = cachep.latency; // means access time - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = 1; - unicache.missb = new ArrayST(&interface_ip, cachep.name + "MissB", device_t, - true, core_t); - unicache.area.set_area(unicache.area.get_area() + - unicache.missb->local_result.area); - area.set_area(area.get_area() + unicache.missb->local_result.area); - // fill buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = unicache.caches->l_ip.line_sz; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data; // int(pow(2.0,ceil(log2(data)))); - interface_ip.cache_sz = data * cachep.fu_size; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8 / 2; - interface_ip.access_mode = 0; - interface_ip.throughput = cachep.throughput; - interface_ip.latency = cachep.latency; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - unicache.ifb = new ArrayST(&interface_ip, cachep.name + "FillB", device_t, - true, core_t); - unicache.area.set_area(unicache.area.get_area() + - unicache.ifb->local_result.area); - area.set_area(area.get_area() + unicache.ifb->local_result.area); - // prefetch buffer - tag = XML->sys.physical_address_width + - EXTRA_TAG_BITS; // check with previous entries to decide wthether to - // merge. - data = unicache.caches->l_ip - .line_sz; // separate queue to prevent from cache polution. - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data; // int(pow(2.0,ceil(log2(data)))); - interface_ip.cache_sz = cachep.prefetchb_size * interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8 / 2; - interface_ip.access_mode = 0; - interface_ip.throughput = cachep.throughput; - interface_ip.latency = cachep.latency; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - unicache.prefetchb = new ArrayST(&interface_ip, cachep.name + "PrefetchB", - device_t, true, core_t); - unicache.area.set_area(unicache.area.get_area() + - unicache.prefetchb->local_result.area); - area.set_area(area.get_area() + unicache.prefetchb->local_result.area); - // WBB - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = unicache.caches->l_ip.line_sz; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data; - interface_ip.cache_sz = cachep.wbb_size * interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz * 8 / 2; - interface_ip.access_mode = 0; - interface_ip.throughput = cachep.throughput; - interface_ip.latency = cachep.latency; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - unicache.wbb = - new ArrayST(&interface_ip, cachep.name + "WBB", device_t, true, core_t); - unicache.area.set_area(unicache.area.get_area() + - unicache.wbb->local_result.area); - area.set_area(area.get_area() + unicache.wbb->local_result.area); + if (!((cachep.dir_ty==ST&& cacheL==L1Directory)||(cachep.dir_ty==ST&& cacheL==L2Directory))) + { + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = (XML->sys.physical_address_width) + int(ceil(log2(size/line))) + unicache.caches->l_ip.line_sz; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = int(ceil(data/8.0));//int(ceil(pow(2.0,ceil(log2(data)))/8.0)); + interface_ip.cache_sz = cachep.missb_size*interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.is_cache = true; + interface_ip.pure_ram = false; + interface_ip.pure_cam = false; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8/2; + interface_ip.access_mode = 0; + interface_ip.throughput = cachep.throughput;//means cycle time + interface_ip.latency = cachep.latency;//means access time + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = 1; + unicache.missb = new ArrayST(&interface_ip, cachep.name + "MissB", device_t, true, core_t); + unicache.area.set_area(unicache.area.get_area()+ unicache.missb->local_result.area); + area.set_area(area.get_area()+ unicache.missb->local_result.area); + //fill buffer + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = unicache.caches->l_ip.line_sz; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); + interface_ip.cache_sz = data*cachep.fu_size ; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8/2; + interface_ip.access_mode = 0; + interface_ip.throughput = cachep.throughput; + interface_ip.latency = cachep.latency; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + unicache.ifb = new ArrayST(&interface_ip, cachep.name + "FillB", device_t, true, core_t); + unicache.area.set_area(unicache.area.get_area()+ unicache.ifb->local_result.area); + area.set_area(area.get_area()+ unicache.ifb->local_result.area); + //prefetch buffer + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS;//check with previous entries to decide wthether to merge. + data = unicache.caches->l_ip.line_sz;//separate queue to prevent from cache polution. + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); + interface_ip.cache_sz = cachep.prefetchb_size*interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8/2; + interface_ip.access_mode = 0; + interface_ip.throughput = cachep.throughput; + interface_ip.latency = cachep.latency; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + unicache.prefetchb = new ArrayST(&interface_ip, cachep.name + "PrefetchB", device_t, true, core_t); + unicache.area.set_area(unicache.area.get_area()+ unicache.prefetchb->local_result.area); + area.set_area(area.get_area()+ unicache.prefetchb->local_result.area); + //WBB + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = unicache.caches->l_ip.line_sz; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data; + interface_ip.cache_sz = cachep.wbb_size*interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz*8/2; + interface_ip.access_mode = 0; + interface_ip.throughput = cachep.throughput; + interface_ip.latency = cachep.latency; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + unicache.wbb = new ArrayST(&interface_ip, cachep.name + "WBB", device_t, true, core_t); + unicache.area.set_area(unicache.area.get_area()+ unicache.wbb->local_result.area); + area.set_area(area.get_area()+ unicache.wbb->local_result.area); } // //pipeline - // interface_ip.pipeline_stages = - // int(ceil(llCache.caches.local_result.access_time/llCache.caches.local_result.cycle_time)); - // interface_ip.per_stage_vector = llCache.caches.l_ip.out_w + - // llCache.caches.l_ip.tag_w ; - // pipeLogicCache.init_pipeline(is_default, &interface_ip); - // pipeLogicCache.compute_pipeline(); +// interface_ip.pipeline_stages = int(ceil(llCache.caches.local_result.access_time/llCache.caches.local_result.cycle_time)); +// interface_ip.per_stage_vector = llCache.caches.l_ip.out_w + llCache.caches.l_ip.tag_w ; +// pipeLogicCache.init_pipeline(is_default, &interface_ip); +// pipeLogicCache.compute_pipeline(); /* if (!((XML->sys.number_of_dir_levels==1 && XML->sys.first_level_dir ==1) - ||(XML->sys.number_of_dir_levels==1 && - XML->sys.first_level_dir ==2)))//not single level IC and DIC + ||(XML->sys.number_of_dir_levels==1 && XML->sys.first_level_dir ==2)))//not single level IC and DIC { //directory Now assuming one directory per bank, TODO:should change it later size = XML->sys.L2directory.L2Dir_config[0]; line = XML->sys.L2directory.L2Dir_config[1]; assoc = XML->sys.L2directory.L2Dir_config[2]; banks = XML->sys.L2directory.L2Dir_config[3]; - tag = - debug?51:XML->sys.physical_address_width + EXTRA_TAG_BITS;//TODO: a little bit - over estimate + tag = debug?51:XML->sys.physical_address_width + EXTRA_TAG_BITS;//TODO: a little bit over estimate interface_ip.specific_tag = 0; interface_ip.tag_w = tag; interface_ip.cache_sz = XML->sys.L2directory.L2Dir_config[0]; @@ -281,12 +271,9 @@ SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, interface_ip.assoc = XML->sys.L2directory.L2Dir_config[2]; interface_ip.nbanks = XML->sys.L2directory.L2Dir_config[3]; interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = - 0;//debug?0:XML->sys.core[ithCore].icache.icache_config[5]; - interface_ip.throughput = - XML->sys.L2directory.L2Dir_config[4]/clockRate; - interface_ip.latency = - XML->sys.L2directory.L2Dir_config[5]/clockRate; + interface_ip.access_mode = 0;//debug?0:XML->sys.core[ithCore].icache.icache_config[5]; + interface_ip.throughput = XML->sys.L2directory.L2Dir_config[4]/clockRate; + interface_ip.latency = XML->sys.L2directory.L2Dir_config[5]/clockRate; interface_ip.is_cache = true; interface_ip.obj_func_dyn_energy = 0; interface_ip.obj_func_dyn_power = 0; @@ -304,31 +291,21 @@ SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, //output_data_csv(directory.caches.local_result); ///cout<<"area="<sys.physical_address_width + EXTRA_TAG_BITS; - data = - (XML->sys.physical_address_width) + int(ceil(log2(size/line))) + - directory.caches.l_ip.line_sz; + //miss buffer Each MSHR contains enough state to handle one or more accesses of any type to a single memory line. + //Due to the generality of the MSHR mechanism, the amount of state involved is non-trivial, + //including the address, pointers to the cache entry and destination register, written data, and various other pieces of state. + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = (XML->sys.physical_address_width) + int(ceil(log2(size/line))) + directory.caches.l_ip.line_sz; interface_ip.specific_tag = 1; interface_ip.tag_w = tag; - interface_ip.line_sz = - int(ceil(data/8.0));//int(ceil(pow(2.0,ceil(log2(data)))/8.0)); - interface_ip.cache_sz = - XML->sys.L2[ithCache].buffer_sizes[0]*interface_ip.line_sz; + interface_ip.line_sz = int(ceil(data/8.0));//int(ceil(pow(2.0,ceil(log2(data)))/8.0)); + interface_ip.cache_sz = XML->sys.L2[ithCache].buffer_sizes[0]*interface_ip.line_sz; interface_ip.assoc = 0; interface_ip.nbanks = 1; interface_ip.out_w = interface_ip.line_sz*8; interface_ip.access_mode = 0; - interface_ip.throughput = - XML->sys.L2[ithCache].L2_config[4]/clockRate;//means cycle time - interface_ip.latency = - XML->sys.L2[ithCache].L2_config[5]/clockRate;//means access time + interface_ip.throughput = XML->sys.L2[ithCache].L2_config[4]/clockRate;//means cycle time + interface_ip.latency = XML->sys.L2[ithCache].L2_config[5]/clockRate;//means access time interface_ip.obj_func_dyn_energy = 0; interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = 0; @@ -345,10 +322,8 @@ SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, ///cout<<"area="<sys.physical_address_width + EXTRA_TAG_BITS; - data = - directory.caches.l_ip.line_sz; + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = directory.caches.l_ip.line_sz; interface_ip.specific_tag = 1; interface_ip.tag_w = tag; interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); @@ -357,10 +332,8 @@ SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, interface_ip.nbanks = 1; interface_ip.out_w = interface_ip.line_sz*8; interface_ip.access_mode = 0; - interface_ip.throughput = - XML->sys.L2[ithCache].L2_config[4]/clockRate; - interface_ip.latency = - XML->sys.L2[ithCache].L2_config[5]/clockRate; + interface_ip.throughput = XML->sys.L2[ithCache].L2_config[4]/clockRate; + interface_ip.latency = XML->sys.L2[ithCache].L2_config[5]/clockRate; interface_ip.obj_func_dyn_energy = 0; interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = 0; @@ -377,24 +350,18 @@ SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, ///cout<<"area="<sys.physical_address_width + EXTRA_TAG_BITS;//check with previous entries - to decide wthether to merge. - data = - directory.caches.l_ip.line_sz;//separate queue to prevent from cache polution. + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS;//check with previous entries to decide wthether to merge. + data = directory.caches.l_ip.line_sz;//separate queue to prevent from cache polution. interface_ip.specific_tag = 1; interface_ip.tag_w = tag; interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); - interface_ip.cache_sz = - XML->sys.L2[ithCache].buffer_sizes[2]*interface_ip.line_sz; + interface_ip.cache_sz = XML->sys.L2[ithCache].buffer_sizes[2]*interface_ip.line_sz; interface_ip.assoc = 0; interface_ip.nbanks = 1; interface_ip.out_w = interface_ip.line_sz*8; interface_ip.access_mode = 0; - interface_ip.throughput = - XML->sys.L2[ithCache].L2_config[4]/clockRate; - interface_ip.latency = - XML->sys.L2[ithCache].L2_config[5]/clockRate; + interface_ip.throughput = XML->sys.L2[ithCache].L2_config[4]/clockRate; + interface_ip.latency = XML->sys.L2[ithCache].L2_config[5]/clockRate; interface_ip.obj_func_dyn_energy = 0; interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = 0; @@ -411,23 +378,18 @@ SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, ///cout<<"area="<sys.physical_address_width + EXTRA_TAG_BITS; - data = - directory.caches.l_ip.line_sz; + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = directory.caches.l_ip.line_sz; interface_ip.specific_tag = 1; interface_ip.tag_w = tag; interface_ip.line_sz = data; - interface_ip.cache_sz = - XML->sys.L2[ithCache].buffer_sizes[3]*interface_ip.line_sz; + interface_ip.cache_sz = XML->sys.L2[ithCache].buffer_sizes[3]*interface_ip.line_sz; interface_ip.assoc = 0; interface_ip.nbanks = 1; interface_ip.out_w = interface_ip.line_sz*8; interface_ip.access_mode = 0; - interface_ip.throughput = - XML->sys.L2[ithCache].L2_config[4]/clockRate; - interface_ip.latency = - XML->sys.L2[ithCache].L2_config[4]/clockRate; + interface_ip.throughput = XML->sys.L2[ithCache].L2_config[4]/clockRate; + interface_ip.latency = XML->sys.L2[ithCache].L2_config[4]/clockRate; interface_ip.obj_func_dyn_energy = 0; interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = 0; @@ -445,14 +407,11 @@ SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, if (XML->sys.number_of_dir_levels ==2 && XML->sys.first_level_dir==0) { //first level directory - size = - XML->sys.L2directory.L2Dir_config[0]*XML->sys.domain_size/128; + size = XML->sys.L2directory.L2Dir_config[0]*XML->sys.domain_size/128; line = int(ceil(XML->sys.domain_size/8.0)); assoc = XML->sys.L2directory.L2Dir_config[2]; banks = XML->sys.L2directory.L2Dir_config[3]; - tag = - debug?51:XML->sys.physical_address_width + EXTRA_TAG_BITS;//TODO: a little bit - over estimate + tag = debug?51:XML->sys.physical_address_width + EXTRA_TAG_BITS;//TODO: a little bit over estimate interface_ip.specific_tag = 1; interface_ip.tag_w = tag; interface_ip.cache_sz = XML->sys.L2directory.L2Dir_config[0]; @@ -460,12 +419,9 @@ SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, interface_ip.assoc = XML->sys.L2directory.L2Dir_config[2]; interface_ip.nbanks = XML->sys.L2directory.L2Dir_config[3]; interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = - 0;//debug?0:XML->sys.core[ithCore].icache.icache_config[5]; - interface_ip.throughput = - XML->sys.L2directory.L2Dir_config[4]/clockRate; - interface_ip.latency = - XML->sys.L2directory.L2Dir_config[5]/clockRate; + interface_ip.access_mode = 0;//debug?0:XML->sys.core[ithCore].icache.icache_config[5]; + interface_ip.throughput = XML->sys.L2directory.L2Dir_config[4]/clockRate; + interface_ip.latency = XML->sys.L2directory.L2Dir_config[5]/clockRate; interface_ip.is_cache = true; interface_ip.obj_func_dyn_energy = 0; interface_ip.obj_func_dyn_power = 0; @@ -483,31 +439,21 @@ SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, //output_data_csv(directory.caches.local_result); ///cout<<"area="<sys.physical_address_width + EXTRA_TAG_BITS; - data = - (XML->sys.physical_address_width) + int(ceil(log2(size/line))) + - directory1.caches.l_ip.line_sz; + //miss buffer Each MSHR contains enough state to handle one or more accesses of any type to a single memory line. + //Due to the generality of the MSHR mechanism, the amount of state involved is non-trivial, + //including the address, pointers to the cache entry and destination register, written data, and various other pieces of state. + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = (XML->sys.physical_address_width) + int(ceil(log2(size/line))) + directory1.caches.l_ip.line_sz; interface_ip.specific_tag = 1; interface_ip.tag_w = tag; - interface_ip.line_sz = - int(ceil(data/8.0));//int(ceil(pow(2.0,ceil(log2(data)))/8.0)); - interface_ip.cache_sz = - XML->sys.L2[ithCache].buffer_sizes[0]*interface_ip.line_sz; + interface_ip.line_sz = int(ceil(data/8.0));//int(ceil(pow(2.0,ceil(log2(data)))/8.0)); + interface_ip.cache_sz = XML->sys.L2[ithCache].buffer_sizes[0]*interface_ip.line_sz; interface_ip.assoc = 0; interface_ip.nbanks = 1; interface_ip.out_w = interface_ip.line_sz*8; interface_ip.access_mode = 0; - interface_ip.throughput = - XML->sys.L2[ithCache].L2_config[4]/clockRate;//means cycle time - interface_ip.latency = - XML->sys.L2[ithCache].L2_config[5]/clockRate;//means access time + interface_ip.throughput = XML->sys.L2[ithCache].L2_config[4]/clockRate;//means cycle time + interface_ip.latency = XML->sys.L2[ithCache].L2_config[5]/clockRate;//means access time interface_ip.obj_func_dyn_energy = 0; interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = 0; @@ -524,10 +470,8 @@ SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, ///cout<<"area="<sys.physical_address_width + EXTRA_TAG_BITS; - data = - directory1.caches.l_ip.line_sz; + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = directory1.caches.l_ip.line_sz; interface_ip.specific_tag = 1; interface_ip.tag_w = tag; interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); @@ -536,10 +480,8 @@ SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, interface_ip.nbanks = 1; interface_ip.out_w = interface_ip.line_sz*8; interface_ip.access_mode = 0; - interface_ip.throughput = - XML->sys.L2[ithCache].L2_config[4]/clockRate; - interface_ip.latency = - XML->sys.L2[ithCache].L2_config[5]/clockRate; + interface_ip.throughput = XML->sys.L2[ithCache].L2_config[4]/clockRate; + interface_ip.latency = XML->sys.L2[ithCache].L2_config[5]/clockRate; interface_ip.obj_func_dyn_energy = 0; interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = 0; @@ -556,25 +498,18 @@ SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, ///cout<<"area="<sys.physical_address_width + EXTRA_TAG_BITS;//check with previous entries - to decide wthether to merge. - data = - directory1.caches.l_ip.line_sz;//separate queue to prevent from cache - polution. + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS;//check with previous entries to decide wthether to merge. + data = directory1.caches.l_ip.line_sz;//separate queue to prevent from cache polution. interface_ip.specific_tag = 1; interface_ip.tag_w = tag; interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); - interface_ip.cache_sz = - XML->sys.L2[ithCache].buffer_sizes[2]*interface_ip.line_sz; + interface_ip.cache_sz = XML->sys.L2[ithCache].buffer_sizes[2]*interface_ip.line_sz; interface_ip.assoc = 0; interface_ip.nbanks = 1; interface_ip.out_w = interface_ip.line_sz*8; interface_ip.access_mode = 0; - interface_ip.throughput = - XML->sys.L2[ithCache].L2_config[4]/clockRate; - interface_ip.latency = - XML->sys.L2[ithCache].L2_config[5]/clockRate; + interface_ip.throughput = XML->sys.L2[ithCache].L2_config[4]/clockRate; + interface_ip.latency = XML->sys.L2[ithCache].L2_config[5]/clockRate; interface_ip.obj_func_dyn_energy = 0; interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = 0; @@ -591,23 +526,18 @@ SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, ///cout<<"area="<sys.physical_address_width + EXTRA_TAG_BITS; - data = - directory1.caches.l_ip.line_sz; + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = directory1.caches.l_ip.line_sz; interface_ip.specific_tag = 1; interface_ip.tag_w = tag; interface_ip.line_sz = data; - interface_ip.cache_sz = - XML->sys.L2[ithCache].buffer_sizes[3]*interface_ip.line_sz; + interface_ip.cache_sz = XML->sys.L2[ithCache].buffer_sizes[3]*interface_ip.line_sz; interface_ip.assoc = 0; interface_ip.nbanks = 1; interface_ip.out_w = interface_ip.line_sz*8; interface_ip.access_mode = 0; - interface_ip.throughput = - XML->sys.L2[ithCache].L2_config[4]/clockRate; - interface_ip.latency = - XML->sys.L2[ithCache].L2_config[5]/clockRate; + interface_ip.throughput = XML->sys.L2[ithCache].L2_config[4]/clockRate; + interface_ip.latency = XML->sys.L2[ithCache].L2_config[5]/clockRate; interface_ip.obj_func_dyn_energy = 0; interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = 0; @@ -624,472 +554,357 @@ SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, if (XML->sys.first_level_dir==1)//IC { - tag = - XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = - int(ceil(XML->sys.domain_size/8.0)); - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data; - interface_ip.cache_sz = - XML->sys.domain_size*data*XML->sys.L2[ithCache].L2_config[0]/XML->sys.L2[ithCache].L2_config[1]; - interface_ip.assoc = 0; - interface_ip.nbanks = 1024; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 0; - interface_ip.throughput = - XML->sys.L2[ithCache].L2_config[4]/clockRate; - interface_ip.latency = - XML->sys.L2[ithCache].L2_config[5]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - strcpy(inv_dir.caches.name,"inv_dir"); - inv_dir.caches.init_cache(&interface_ip); - inv_dir.caches.optimize_array(); - inv_dir.area = inv_dir.caches.local_result.area; + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = int(ceil(XML->sys.domain_size/8.0)); + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data; + interface_ip.cache_sz = XML->sys.domain_size*data*XML->sys.L2[ithCache].L2_config[0]/XML->sys.L2[ithCache].L2_config[1]; + interface_ip.assoc = 0; + interface_ip.nbanks = 1024; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 0; + interface_ip.throughput = XML->sys.L2[ithCache].L2_config[4]/clockRate; + interface_ip.latency = XML->sys.L2[ithCache].L2_config[5]/clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + strcpy(inv_dir.caches.name,"inv_dir"); + inv_dir.caches.init_cache(&interface_ip); + inv_dir.caches.optimize_array(); + inv_dir.area = inv_dir.caches.local_result.area; } */ - // //pipeline - // interface_ip.pipeline_stages = - // int(ceil(directory.caches.local_result.access_time/directory.caches.local_result.cycle_time)); - // interface_ip.per_stage_vector = directory.caches.l_ip.out_w + - // directory.caches.l_ip.tag_w ; - // pipeLogicDirectory.init_pipeline(is_default, &interface_ip); - // pipeLogicDirectory.compute_pipeline(); - // - // //clock power - // clockNetwork.init_wire_external(is_default, &interface_ip); - // clockNetwork.clk_area =area*1.1;//10% of placement overhead. - // rule of thumb - // clockNetwork.end_wiring_level =5;//toplevel metal - // clockNetwork.start_wiring_level =5;//toplevel metal - // clockNetwork.num_regs = pipeLogicCache.tot_stage_vector + - // pipeLogicDirectory.tot_stage_vector; - // clockNetwork.optimize_wire(); +// //pipeline +// interface_ip.pipeline_stages = int(ceil(directory.caches.local_result.access_time/directory.caches.local_result.cycle_time)); +// interface_ip.per_stage_vector = directory.caches.l_ip.out_w + directory.caches.l_ip.tag_w ; +// pipeLogicDirectory.init_pipeline(is_default, &interface_ip); +// pipeLogicDirectory.compute_pipeline(); +// +// //clock power +// clockNetwork.init_wire_external(is_default, &interface_ip); +// clockNetwork.clk_area =area*1.1;//10% of placement overhead. rule of thumb +// clockNetwork.end_wiring_level =5;//toplevel metal +// clockNetwork.start_wiring_level =5;//toplevel metal +// clockNetwork.num_regs = pipeLogicCache.tot_stage_vector + pipeLogicDirectory.tot_stage_vector; +// clockNetwork.optimize_wire(); + } -void SharedCache::computeEnergy(bool is_tdp) { - double homenode_data_access = (cachep.dir_ty == SBT) ? 0.9 : 1.0; - if (is_tdp) { - if (!((cachep.dir_ty == ST && cacheL == L1Directory) || - (cachep.dir_ty == ST && cacheL == L2Directory))) { - // init stats for Peak - unicache.caches->stats_t.readAc.access = - .67 * unicache.caches->l_ip.num_rw_ports * cachep.duty_cycle * - homenode_data_access; - unicache.caches->stats_t.readAc.miss = 0; - unicache.caches->stats_t.readAc.hit = - unicache.caches->stats_t.readAc.access - - unicache.caches->stats_t.readAc.miss; - unicache.caches->stats_t.writeAc.access = - .33 * unicache.caches->l_ip.num_rw_ports * cachep.duty_cycle * - homenode_data_access; - unicache.caches->stats_t.writeAc.miss = 0; - unicache.caches->stats_t.writeAc.hit = - unicache.caches->stats_t.writeAc.access - - unicache.caches->stats_t.writeAc.miss; - unicache.caches->tdp_stats = unicache.caches->stats_t; - if (cachep.dir_ty == SBT) { - homenode_stats_t.readAc.access = - .67 * unicache.caches->l_ip.num_rw_ports * cachep.dir_duty_cycle * - (1 - homenode_data_access); - homenode_stats_t.readAc.miss = 0; - homenode_stats_t.readAc.hit = - homenode_stats_t.readAc.access - homenode_stats_t.readAc.miss; - homenode_stats_t.writeAc.access = - .67 * unicache.caches->l_ip.num_rw_ports * cachep.dir_duty_cycle * - (1 - homenode_data_access); - homenode_stats_t.writeAc.miss = 0; - homenode_stats_t.writeAc.hit = - homenode_stats_t.writeAc.access - homenode_stats_t.writeAc.miss; - homenode_tdp_stats = homenode_stats_t; - } +void SharedCache::computeEnergy(bool is_tdp) +{ + double homenode_data_access = (cachep.dir_ty==SBT)? 0.9:1.0; + if (is_tdp) + { + if (!((cachep.dir_ty==ST&& cacheL==L1Directory)||(cachep.dir_ty==ST&& cacheL==L2Directory))) + { + //init stats for Peak + unicache.caches->stats_t.readAc.access = .67*unicache.caches->l_ip.num_rw_ports*cachep.duty_cycle*homenode_data_access; + unicache.caches->stats_t.readAc.miss = 0; + unicache.caches->stats_t.readAc.hit = unicache.caches->stats_t.readAc.access - unicache.caches->stats_t.readAc.miss; + unicache.caches->stats_t.writeAc.access = .33*unicache.caches->l_ip.num_rw_ports*cachep.duty_cycle*homenode_data_access; + unicache.caches->stats_t.writeAc.miss = 0; + unicache.caches->stats_t.writeAc.hit = unicache.caches->stats_t.writeAc.access - unicache.caches->stats_t.writeAc.miss; + unicache.caches->tdp_stats = unicache.caches->stats_t; - unicache.missb->stats_t.readAc.access = - unicache.missb->l_ip.num_search_ports; - unicache.missb->stats_t.writeAc.access = - unicache.missb->l_ip.num_search_ports; - unicache.missb->tdp_stats = unicache.missb->stats_t; + if (cachep.dir_ty==SBT) + { + homenode_stats_t.readAc.access = .67*unicache.caches->l_ip.num_rw_ports*cachep.dir_duty_cycle*(1-homenode_data_access); + homenode_stats_t.readAc.miss = 0; + homenode_stats_t.readAc.hit = homenode_stats_t.readAc.access - homenode_stats_t.readAc.miss; + homenode_stats_t.writeAc.access = .67*unicache.caches->l_ip.num_rw_ports*cachep.dir_duty_cycle*(1-homenode_data_access); + homenode_stats_t.writeAc.miss = 0; + homenode_stats_t.writeAc.hit = homenode_stats_t.writeAc.access - homenode_stats_t.writeAc.miss; + homenode_tdp_stats = homenode_stats_t; + } - unicache.ifb->stats_t.readAc.access = unicache.ifb->l_ip.num_search_ports; - unicache.ifb->stats_t.writeAc.access = - unicache.ifb->l_ip.num_search_ports; - unicache.ifb->tdp_stats = unicache.ifb->stats_t; + unicache.missb->stats_t.readAc.access = unicache.missb->l_ip.num_search_ports; + unicache.missb->stats_t.writeAc.access = unicache.missb->l_ip.num_search_ports; + unicache.missb->tdp_stats = unicache.missb->stats_t; - unicache.prefetchb->stats_t.readAc.access = - unicache.prefetchb->l_ip.num_search_ports; - unicache.prefetchb->stats_t.writeAc.access = - unicache.ifb->l_ip.num_search_ports; - unicache.prefetchb->tdp_stats = unicache.prefetchb->stats_t; + unicache.ifb->stats_t.readAc.access = unicache.ifb->l_ip.num_search_ports; + unicache.ifb->stats_t.writeAc.access = unicache.ifb->l_ip.num_search_ports; + unicache.ifb->tdp_stats = unicache.ifb->stats_t; - unicache.wbb->stats_t.readAc.access = unicache.wbb->l_ip.num_search_ports; - unicache.wbb->stats_t.writeAc.access = - unicache.wbb->l_ip.num_search_ports; - unicache.wbb->tdp_stats = unicache.wbb->stats_t; - } else { - unicache.caches->stats_t.readAc.access = - unicache.caches->l_ip.num_search_ports * cachep.duty_cycle; - unicache.caches->stats_t.readAc.miss = 0; - unicache.caches->stats_t.readAc.hit = - unicache.caches->stats_t.readAc.access - - unicache.caches->stats_t.readAc.miss; - unicache.caches->stats_t.writeAc.access = 0; - unicache.caches->stats_t.writeAc.miss = 0; - unicache.caches->stats_t.writeAc.hit = - unicache.caches->stats_t.writeAc.access - - unicache.caches->stats_t.writeAc.miss; - unicache.caches->tdp_stats = unicache.caches->stats_t; - } + unicache.prefetchb->stats_t.readAc.access = unicache.prefetchb->l_ip.num_search_ports; + unicache.prefetchb->stats_t.writeAc.access = unicache.ifb->l_ip.num_search_ports; + unicache.prefetchb->tdp_stats = unicache.prefetchb->stats_t; - } else { - // init stats for runtime power (RTP) - if (cacheL == L2) { - // Copy stats from l1 to L1[0] - XML->sys.L2[ithCache].total_accesses = XML->sys.l2.total_accesses; - XML->sys.L2[ithCache].read_accesses = XML->sys.l2.read_accesses; - XML->sys.L2[ithCache].write_accesses = XML->sys.l2.write_accesses; - XML->sys.L2[ithCache].read_hits = XML->sys.l2.read_hits; - XML->sys.L2[ithCache].read_misses = XML->sys.l2.read_misses; - XML->sys.L2[ithCache].write_hits = XML->sys.l2.write_hits; - XML->sys.L2[ithCache].write_misses = XML->sys.l2.write_misses; + unicache.wbb->stats_t.readAc.access = unicache.wbb->l_ip.num_search_ports; + unicache.wbb->stats_t.writeAc.access = unicache.wbb->l_ip.num_search_ports; + unicache.wbb->tdp_stats = unicache.wbb->stats_t; + } + else + { + unicache.caches->stats_t.readAc.access = unicache.caches->l_ip.num_search_ports*cachep.duty_cycle; + unicache.caches->stats_t.readAc.miss = 0; + unicache.caches->stats_t.readAc.hit = unicache.caches->stats_t.readAc.access - unicache.caches->stats_t.readAc.miss; + unicache.caches->stats_t.writeAc.access = 0; + unicache.caches->stats_t.writeAc.miss = 0; + unicache.caches->stats_t.writeAc.hit = unicache.caches->stats_t.writeAc.access - unicache.caches->stats_t.writeAc.miss; + unicache.caches->tdp_stats = unicache.caches->stats_t; - unicache.caches->stats_t.readAc.access = - XML->sys.L2[ithCache].read_accesses; - unicache.caches->stats_t.readAc.miss = XML->sys.L2[ithCache].read_misses; - unicache.caches->stats_t.readAc.hit = - unicache.caches->stats_t.readAc.access - - unicache.caches->stats_t.readAc.miss; - unicache.caches->stats_t.writeAc.access = - XML->sys.L2[ithCache].write_accesses; - unicache.caches->stats_t.writeAc.miss = - XML->sys.L2[ithCache].write_misses; - unicache.caches->stats_t.writeAc.hit = - unicache.caches->stats_t.writeAc.access - - unicache.caches->stats_t.writeAc.miss; - unicache.caches->rtp_stats = unicache.caches->stats_t; + } - if (cachep.dir_ty == SBT) { - homenode_rtp_stats.readAc.access = - XML->sys.L2[ithCache].homenode_read_accesses; - homenode_rtp_stats.readAc.miss = - XML->sys.L2[ithCache].homenode_read_misses; - homenode_rtp_stats.readAc.hit = - homenode_rtp_stats.readAc.access - homenode_rtp_stats.readAc.miss; - homenode_rtp_stats.writeAc.access = - XML->sys.L2[ithCache].homenode_write_accesses; - homenode_rtp_stats.writeAc.miss = - XML->sys.L2[ithCache].homenode_write_misses; - homenode_rtp_stats.writeAc.hit = - homenode_rtp_stats.writeAc.access - homenode_rtp_stats.writeAc.miss; - } - } else if (cacheL == L3) { - unicache.caches->stats_t.readAc.access = - XML->sys.L3[ithCache].read_accesses; - unicache.caches->stats_t.readAc.miss = XML->sys.L3[ithCache].read_misses; - unicache.caches->stats_t.readAc.hit = - unicache.caches->stats_t.readAc.access - - unicache.caches->stats_t.readAc.miss; - unicache.caches->stats_t.writeAc.access = - XML->sys.L3[ithCache].write_accesses; - unicache.caches->stats_t.writeAc.miss = - XML->sys.L3[ithCache].write_misses; - unicache.caches->stats_t.writeAc.hit = - unicache.caches->stats_t.writeAc.access - - unicache.caches->stats_t.writeAc.miss; - unicache.caches->rtp_stats = unicache.caches->stats_t; + } + else + { + //init stats for runtime power (RTP) + if (cacheL==L2) + { + //Copy stats from l1 to L1[0] + XML->sys.L2[ithCache].total_accesses=XML->sys.l2.total_accesses; + XML->sys.L2[ithCache].read_accesses=XML->sys.l2.read_accesses; + XML->sys.L2[ithCache].write_accesses=XML->sys.l2.write_accesses; + XML->sys.L2[ithCache].read_hits=XML->sys.l2.read_hits; + XML->sys.L2[ithCache].read_misses=XML->sys.l2.read_misses; + XML->sys.L2[ithCache].write_hits=XML->sys.l2.write_hits; + XML->sys.L2[ithCache].write_misses=XML->sys.l2.write_misses; - if (cachep.dir_ty == SBT) { - homenode_rtp_stats.readAc.access = - XML->sys.L3[ithCache].homenode_read_accesses; - homenode_rtp_stats.readAc.miss = - XML->sys.L3[ithCache].homenode_read_misses; - homenode_rtp_stats.readAc.hit = - homenode_rtp_stats.readAc.access - homenode_rtp_stats.readAc.miss; - homenode_rtp_stats.writeAc.access = - XML->sys.L3[ithCache].homenode_write_accesses; - homenode_rtp_stats.writeAc.miss = - XML->sys.L3[ithCache].homenode_write_misses; - homenode_rtp_stats.writeAc.hit = - homenode_rtp_stats.writeAc.access - homenode_rtp_stats.writeAc.miss; - } - } else if (cacheL == L1Directory) { - unicache.caches->stats_t.readAc.access = - XML->sys.L1Directory[ithCache].read_accesses; - unicache.caches->stats_t.readAc.miss = - XML->sys.L1Directory[ithCache].read_misses; - unicache.caches->stats_t.readAc.hit = - unicache.caches->stats_t.readAc.access - - unicache.caches->stats_t.readAc.miss; - unicache.caches->stats_t.writeAc.access = - XML->sys.L1Directory[ithCache].write_accesses; - unicache.caches->stats_t.writeAc.miss = - XML->sys.L1Directory[ithCache].write_misses; - unicache.caches->stats_t.writeAc.hit = - unicache.caches->stats_t.writeAc.access - - unicache.caches->stats_t.writeAc.miss; - unicache.caches->rtp_stats = unicache.caches->stats_t; - } else if (cacheL == L2Directory) { // cout<<"L2 directory"<sys.L2[ithCache].total_accesses=XML->sys.l2.total_accesses; - // XML->sys.L2[ithCache].read_accesses=XML->sys.l2.read_accesses; - // XML->sys.L2[ithCache].write_accesses=XML->sys.l2.write_accesses; - // XML->sys.L2[ithCache].read_hits=XML->sys.l2.read_hits; - // XML->sys.L2[ithCache].read_misses=XML->sys.l2.read_misses; - // XML->sys.L2[ithCache].write_hits=XML->sys.l2.write_hits; - // XML->sys.L2[ithCache].write_misses=XML->sys.l2.write_misses; - unicache.caches->stats_t.readAc.access = - XML->sys.L2Directory[ithCache].read_accesses; - unicache.caches->stats_t.readAc.miss = - XML->sys.L2Directory[ithCache].read_misses; - unicache.caches->stats_t.readAc.hit = - unicache.caches->stats_t.readAc.access - - unicache.caches->stats_t.readAc.miss; - unicache.caches->stats_t.writeAc.access = - XML->sys.L2Directory[ithCache].write_accesses; - unicache.caches->stats_t.writeAc.miss = - XML->sys.L2Directory[ithCache].write_misses; - unicache.caches->stats_t.writeAc.hit = - unicache.caches->stats_t.writeAc.access - - unicache.caches->stats_t.writeAc.miss; - unicache.caches->rtp_stats = unicache.caches->stats_t; - } - if (!((cachep.dir_ty == ST && cacheL == L1Directory) || - (cachep.dir_ty == ST && - cacheL == - L2Directory))) { // Assuming write back and write-allocate cache + unicache.caches->stats_t.readAc.access = XML->sys.L2[ithCache].read_accesses; + unicache.caches->stats_t.readAc.miss = XML->sys.L2[ithCache].read_misses; + unicache.caches->stats_t.readAc.hit = unicache.caches->stats_t.readAc.access - unicache.caches->stats_t.readAc.miss; + unicache.caches->stats_t.writeAc.access = XML->sys.L2[ithCache].write_accesses; + unicache.caches->stats_t.writeAc.miss = XML->sys.L2[ithCache].write_misses; + unicache.caches->stats_t.writeAc.hit = unicache.caches->stats_t.writeAc.access - unicache.caches->stats_t.writeAc.miss; + unicache.caches->rtp_stats = unicache.caches->stats_t; - unicache.missb->stats_t.readAc.access = - unicache.caches->stats_t.writeAc.miss; - unicache.missb->stats_t.writeAc.access = - unicache.caches->stats_t.writeAc.miss; - unicache.missb->rtp_stats = unicache.missb->stats_t; + if (cachep.dir_ty==SBT) + { + homenode_rtp_stats.readAc.access = XML->sys.L2[ithCache].homenode_read_accesses; + homenode_rtp_stats.readAc.miss = XML->sys.L2[ithCache].homenode_read_misses; + homenode_rtp_stats.readAc.hit = homenode_rtp_stats.readAc.access - homenode_rtp_stats.readAc.miss; + homenode_rtp_stats.writeAc.access = XML->sys.L2[ithCache].homenode_write_accesses; + homenode_rtp_stats.writeAc.miss = XML->sys.L2[ithCache].homenode_write_misses; + homenode_rtp_stats.writeAc.hit = homenode_rtp_stats.writeAc.access - homenode_rtp_stats.writeAc.miss; + } + } + else if (cacheL==L3) + { + unicache.caches->stats_t.readAc.access = XML->sys.L3[ithCache].read_accesses; + unicache.caches->stats_t.readAc.miss = XML->sys.L3[ithCache].read_misses; + unicache.caches->stats_t.readAc.hit = unicache.caches->stats_t.readAc.access - unicache.caches->stats_t.readAc.miss; + unicache.caches->stats_t.writeAc.access = XML->sys.L3[ithCache].write_accesses; + unicache.caches->stats_t.writeAc.miss = XML->sys.L3[ithCache].write_misses; + unicache.caches->stats_t.writeAc.hit = unicache.caches->stats_t.writeAc.access - unicache.caches->stats_t.writeAc.miss; + unicache.caches->rtp_stats = unicache.caches->stats_t; - unicache.ifb->stats_t.readAc.access = - unicache.caches->stats_t.writeAc.miss; - unicache.ifb->stats_t.writeAc.access = - unicache.caches->stats_t.writeAc.miss; - unicache.ifb->rtp_stats = unicache.ifb->stats_t; + if (cachep.dir_ty==SBT) + { + homenode_rtp_stats.readAc.access = XML->sys.L3[ithCache].homenode_read_accesses; + homenode_rtp_stats.readAc.miss = XML->sys.L3[ithCache].homenode_read_misses; + homenode_rtp_stats.readAc.hit = homenode_rtp_stats.readAc.access - homenode_rtp_stats.readAc.miss; + homenode_rtp_stats.writeAc.access = XML->sys.L3[ithCache].homenode_write_accesses; + homenode_rtp_stats.writeAc.miss = XML->sys.L3[ithCache].homenode_write_misses; + homenode_rtp_stats.writeAc.hit = homenode_rtp_stats.writeAc.access - homenode_rtp_stats.writeAc.miss; + } + } + else if (cacheL==L1Directory) + { + unicache.caches->stats_t.readAc.access = XML->sys.L1Directory[ithCache].read_accesses; + unicache.caches->stats_t.readAc.miss = XML->sys.L1Directory[ithCache].read_misses; + unicache.caches->stats_t.readAc.hit = unicache.caches->stats_t.readAc.access - unicache.caches->stats_t.readAc.miss; + unicache.caches->stats_t.writeAc.access = XML->sys.L1Directory[ithCache].write_accesses; + unicache.caches->stats_t.writeAc.miss = XML->sys.L1Directory[ithCache].write_misses; + unicache.caches->stats_t.writeAc.hit = unicache.caches->stats_t.writeAc.access - unicache.caches->stats_t.writeAc.miss; + unicache.caches->rtp_stats = unicache.caches->stats_t; + } + else if (cacheL==L2Directory) + { //cout<<"L2 directory"<sys.L2[ithCache].total_accesses=XML->sys.l2.total_accesses; + //XML->sys.L2[ithCache].read_accesses=XML->sys.l2.read_accesses; + //XML->sys.L2[ithCache].write_accesses=XML->sys.l2.write_accesses; + //XML->sys.L2[ithCache].read_hits=XML->sys.l2.read_hits; + //XML->sys.L2[ithCache].read_misses=XML->sys.l2.read_misses; + //XML->sys.L2[ithCache].write_hits=XML->sys.l2.write_hits; + //XML->sys.L2[ithCache].write_misses=XML->sys.l2.write_misses; + unicache.caches->stats_t.readAc.access = XML->sys.L2Directory[ithCache].read_accesses; + unicache.caches->stats_t.readAc.miss = XML->sys.L2Directory[ithCache].read_misses; + unicache.caches->stats_t.readAc.hit = unicache.caches->stats_t.readAc.access - unicache.caches->stats_t.readAc.miss; + unicache.caches->stats_t.writeAc.access = XML->sys.L2Directory[ithCache].write_accesses; + unicache.caches->stats_t.writeAc.miss = XML->sys.L2Directory[ithCache].write_misses; + unicache.caches->stats_t.writeAc.hit = unicache.caches->stats_t.writeAc.access - unicache.caches->stats_t.writeAc.miss; + unicache.caches->rtp_stats = unicache.caches->stats_t; + } + if (!((cachep.dir_ty==ST&& cacheL==L1Directory)||(cachep.dir_ty==ST&& cacheL==L2Directory))) + { //Assuming write back and write-allocate cache - unicache.prefetchb->stats_t.readAc.access = - unicache.caches->stats_t.writeAc.miss; - unicache.prefetchb->stats_t.writeAc.access = - unicache.caches->stats_t.writeAc.miss; - unicache.prefetchb->rtp_stats = unicache.prefetchb->stats_t; + unicache.missb->stats_t.readAc.access = unicache.caches->stats_t.writeAc.miss ; + unicache.missb->stats_t.writeAc.access = unicache.caches->stats_t.writeAc.miss; + unicache.missb->rtp_stats = unicache.missb->stats_t; - unicache.wbb->stats_t.readAc.access = - unicache.caches->stats_t.writeAc.miss; - unicache.wbb->stats_t.writeAc.access = - unicache.caches->stats_t.writeAc.miss; - if (cachep.dir_ty == SBT) { - unicache.missb->stats_t.readAc.access += - homenode_rtp_stats.writeAc.miss; - unicache.missb->stats_t.writeAc.access += - homenode_rtp_stats.writeAc.miss; - unicache.missb->rtp_stats = unicache.missb->stats_t; + unicache.ifb->stats_t.readAc.access = unicache.caches->stats_t.writeAc.miss; + unicache.ifb->stats_t.writeAc.access = unicache.caches->stats_t.writeAc.miss; + unicache.ifb->rtp_stats = unicache.ifb->stats_t; - unicache.missb->stats_t.readAc.access += - homenode_rtp_stats.writeAc.miss; - unicache.missb->stats_t.writeAc.access += - homenode_rtp_stats.writeAc.miss; - unicache.missb->rtp_stats = unicache.missb->stats_t; + unicache.prefetchb->stats_t.readAc.access = unicache.caches->stats_t.writeAc.miss; + unicache.prefetchb->stats_t.writeAc.access = unicache.caches->stats_t.writeAc.miss; + unicache.prefetchb->rtp_stats = unicache.prefetchb->stats_t; - unicache.ifb->stats_t.readAc.access += homenode_rtp_stats.writeAc.miss; - unicache.ifb->stats_t.writeAc.access += homenode_rtp_stats.writeAc.miss; - unicache.ifb->rtp_stats = unicache.ifb->stats_t; + unicache.wbb->stats_t.readAc.access = unicache.caches->stats_t.writeAc.miss; + unicache.wbb->stats_t.writeAc.access = unicache.caches->stats_t.writeAc.miss; + if (cachep.dir_ty==SBT) + { + unicache.missb->stats_t.readAc.access += homenode_rtp_stats.writeAc.miss; + unicache.missb->stats_t.writeAc.access += homenode_rtp_stats.writeAc.miss; + unicache.missb->rtp_stats = unicache.missb->stats_t; - unicache.prefetchb->stats_t.readAc.access += - homenode_rtp_stats.writeAc.miss; - unicache.prefetchb->stats_t.writeAc.access += - homenode_rtp_stats.writeAc.miss; - unicache.prefetchb->rtp_stats = unicache.prefetchb->stats_t; + unicache.missb->stats_t.readAc.access += homenode_rtp_stats.writeAc.miss; + unicache.missb->stats_t.writeAc.access += homenode_rtp_stats.writeAc.miss; + unicache.missb->rtp_stats = unicache.missb->stats_t; - unicache.wbb->stats_t.readAc.access += homenode_rtp_stats.writeAc.miss; - unicache.wbb->stats_t.writeAc.access += homenode_rtp_stats.writeAc.miss; - } - unicache.wbb->rtp_stats = unicache.wbb->stats_t; - } - } + unicache.ifb->stats_t.readAc.access += homenode_rtp_stats.writeAc.miss; + unicache.ifb->stats_t.writeAc.access += homenode_rtp_stats.writeAc.miss; + unicache.ifb->rtp_stats = unicache.ifb->stats_t; - unicache.power_t.reset(); - unicache.rt_power.reset(); - if (!((cachep.dir_ty == ST && cacheL == L1Directory) || - (cachep.dir_ty == ST && cacheL == L2Directory))) { - unicache.power_t.readOp.dynamic += - (unicache.caches->stats_t.readAc.hit * - unicache.caches->local_result.power.readOp.dynamic + - unicache.caches->stats_t.readAc.miss * - unicache.caches->local_result.tag_array2->power.readOp.dynamic + - unicache.caches->stats_t.writeAc.miss * - unicache.caches->local_result.tag_array2->power.writeOp.dynamic + - unicache.caches->stats_t.writeAc.access * - unicache.caches->local_result.power.writeOp - .dynamic); // write miss will also generate a write later + unicache.prefetchb->stats_t.readAc.access += homenode_rtp_stats.writeAc.miss; + unicache.prefetchb->stats_t.writeAc.access += homenode_rtp_stats.writeAc.miss; + unicache.prefetchb->rtp_stats = unicache.prefetchb->stats_t; - if (cachep.dir_ty == SBT) { - unicache.power_t.readOp.dynamic += - homenode_stats_t.readAc.hit * - (unicache.caches->local_result.data_array2->power.readOp.dynamic * - dir_overhead + - unicache.caches->local_result.tag_array2->power.readOp.dynamic) + - homenode_stats_t.readAc.miss * - unicache.caches->local_result.tag_array2->power.readOp.dynamic + - homenode_stats_t.writeAc.miss * - unicache.caches->local_result.tag_array2->power.readOp.dynamic + - homenode_stats_t.writeAc.hit * - (unicache.caches->local_result.data_array2->power.writeOp - .dynamic * - dir_overhead + - unicache.caches->local_result.tag_array2->power.readOp.dynamic + - homenode_stats_t.writeAc.miss * - unicache.caches->local_result.power.writeOp - .dynamic); // write miss on dynamic home node will - // generate a replacement write on whole - // cache block - } + unicache.wbb->stats_t.readAc.access += homenode_rtp_stats.writeAc.miss; + unicache.wbb->stats_t.writeAc.access += homenode_rtp_stats.writeAc.miss; + } + unicache.wbb->rtp_stats = unicache.wbb->stats_t; - unicache.power_t.readOp.dynamic += - unicache.missb->stats_t.readAc.access * - unicache.missb->local_result.power.searchOp.dynamic + - unicache.missb->stats_t.writeAc.access * - unicache.missb->local_result.power.writeOp - .dynamic; // each access to missb involves a CAM and a write - unicache.power_t.readOp.dynamic += - unicache.ifb->stats_t.readAc.access * - unicache.ifb->local_result.power.searchOp.dynamic + - unicache.ifb->stats_t.writeAc.access * - unicache.ifb->local_result.power.writeOp.dynamic; - unicache.power_t.readOp.dynamic += - unicache.prefetchb->stats_t.readAc.access * - unicache.prefetchb->local_result.power.searchOp.dynamic + - unicache.prefetchb->stats_t.writeAc.access * - unicache.prefetchb->local_result.power.writeOp.dynamic; - unicache.power_t.readOp.dynamic += - unicache.wbb->stats_t.readAc.access * - unicache.wbb->local_result.power.searchOp.dynamic + - unicache.wbb->stats_t.writeAc.access * - unicache.wbb->local_result.power.writeOp.dynamic; - } else { - unicache.power_t.readOp.dynamic += - (unicache.caches->stats_t.readAc.access * - unicache.caches->local_result.power.searchOp.dynamic + - unicache.caches->stats_t.writeAc.access * - unicache.caches->local_result.power.writeOp.dynamic); - } + } - if (is_tdp) { - unicache.power = - unicache.power_t + (unicache.caches->local_result.power) * pppm_lkg; - if (!((cachep.dir_ty == ST && cacheL == L1Directory) || - (cachep.dir_ty == ST && cacheL == L2Directory))) { - unicache.power = unicache.power + - (unicache.missb->local_result.power + - unicache.ifb->local_result.power + - unicache.prefetchb->local_result.power + - unicache.wbb->local_result.power) * - pppm_lkg; - } - power = power + unicache.power; - // cout<<"unicache.caches->local_result.power.readOp.dynamic"<local_result.power.readOp.dynamic<local_result.power.writeOp.dynamic"<local_result.power.writeOp.dynamic<local_result.power) * pppm_lkg; - if (!((cachep.dir_ty == ST && cacheL == L1Directory) || - (cachep.dir_ty == ST && cacheL == L2Directory))) { - unicache.rt_power = unicache.rt_power + - (unicache.missb->local_result.power + - unicache.ifb->local_result.power + - unicache.prefetchb->local_result.power + - unicache.wbb->local_result.power) * - pppm_lkg; - } + } - rt_power = rt_power + unicache.rt_power; - } + unicache.power_t.reset(); + unicache.rt_power.reset(); + if (!((cachep.dir_ty==ST&& cacheL==L1Directory)||(cachep.dir_ty==ST&& cacheL==L2Directory))) + { + + unicache.power_t.readOp.dynamic += (unicache.caches->stats_t.readAc.hit*unicache.caches->local_result.power.readOp.dynamic+ + unicache.caches->stats_t.readAc.miss*unicache.caches->local_result.tag_array2->power.readOp.dynamic+ + unicache.caches->stats_t.writeAc.miss*unicache.caches->local_result.tag_array2->power.writeOp.dynamic+ + unicache.caches->stats_t.writeAc.access*unicache.caches->local_result.power.writeOp.dynamic);//write miss will also generate a write later + + if (cachep.dir_ty==SBT) + { + unicache.power_t.readOp.dynamic += homenode_stats_t.readAc.hit * (unicache.caches->local_result.data_array2->power.readOp.dynamic*dir_overhead + + unicache.caches->local_result.tag_array2->power.readOp.dynamic) + + homenode_stats_t.readAc.miss*unicache.caches->local_result.tag_array2->power.readOp.dynamic + + homenode_stats_t.writeAc.miss*unicache.caches->local_result.tag_array2->power.readOp.dynamic + + homenode_stats_t.writeAc.hit*(unicache.caches->local_result.data_array2->power.writeOp.dynamic*dir_overhead + + unicache.caches->local_result.tag_array2->power.readOp.dynamic+ + homenode_stats_t.writeAc.miss*unicache.caches->local_result.power.writeOp.dynamic);//write miss on dynamic home node will generate a replacement write on whole cache block + + + } + + unicache.power_t.readOp.dynamic += unicache.missb->stats_t.readAc.access*unicache.missb->local_result.power.searchOp.dynamic + + unicache.missb->stats_t.writeAc.access*unicache.missb->local_result.power.writeOp.dynamic;//each access to missb involves a CAM and a write + unicache.power_t.readOp.dynamic += unicache.ifb->stats_t.readAc.access*unicache.ifb->local_result.power.searchOp.dynamic + + unicache.ifb->stats_t.writeAc.access*unicache.ifb->local_result.power.writeOp.dynamic; + unicache.power_t.readOp.dynamic += unicache.prefetchb->stats_t.readAc.access*unicache.prefetchb->local_result.power.searchOp.dynamic + + unicache.prefetchb->stats_t.writeAc.access*unicache.prefetchb->local_result.power.writeOp.dynamic; + unicache.power_t.readOp.dynamic += unicache.wbb->stats_t.readAc.access*unicache.wbb->local_result.power.searchOp.dynamic + + unicache.wbb->stats_t.writeAc.access*unicache.wbb->local_result.power.writeOp.dynamic; + } + else + { + unicache.power_t.readOp.dynamic += (unicache.caches->stats_t.readAc.access*unicache.caches->local_result.power.searchOp.dynamic+ + unicache.caches->stats_t.writeAc.access*unicache.caches->local_result.power.writeOp.dynamic); + } + + if (is_tdp) + { + unicache.power = unicache.power_t + (unicache.caches->local_result.power)*pppm_lkg; + if (!((cachep.dir_ty==ST&& cacheL==L1Directory)||(cachep.dir_ty==ST&& cacheL==L2Directory))) + { + unicache.power = unicache.power+ + (unicache.missb->local_result.power + + unicache.ifb->local_result.power + + unicache.prefetchb->local_result.power + + unicache.wbb->local_result.power)*pppm_lkg; + } + power = power + unicache.power; + // cout<<"unicache.caches->local_result.power.readOp.dynamic"<local_result.power.readOp.dynamic<local_result.power.writeOp.dynamic"<local_result.power.writeOp.dynamic<local_result.power)*pppm_lkg; + if (!((cachep.dir_ty==ST&& cacheL==L1Directory)||(cachep.dir_ty==ST&& cacheL==L2Directory))) + { + unicache.rt_power = unicache.rt_power + + (unicache.missb->local_result.power + + unicache.ifb->local_result.power + + unicache.prefetchb->local_result.power + + unicache.wbb->local_result.power)*pppm_lkg; + } + + rt_power = rt_power + unicache.rt_power; + } } -void SharedCache::displayEnergy(uint32_t indent, bool is_tdp) { +void SharedCache::displayEnergy(uint32_t indent,bool is_tdp) +{ string indent_str(indent, ' '); - string indent_str_next(indent + 2, ' '); + string indent_str_next(indent+2, ' '); bool long_channel = XML->sys.longer_channel_device; - if (is_tdp) { - cout << (XML->sys.Private_L2 ? indent_str : "") << cachep.name << endl; - cout << indent_str << "Area = " << area.get_area() * 1e-6 << " mm^2" - << endl; - cout << indent_str - << "Peak Dynamic = " << power.readOp.dynamic * cachep.clockRate << " W" - << endl; - cout << indent_str << "Subthreshold Leakage = " - << (long_channel ? power.readOp.longer_channel_leakage - : power.readOp.leakage) - << " W" << endl; - // cout << indent_str << "Subthreshold Leakage = " << - // power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str << "Gate Leakage = " << power.readOp.gate_leakage << " W" - << endl; - cout << indent_str << "Runtime Dynamic = " - << rt_power.readOp.dynamic / cachep.executionTime << " W" << endl; - cout << endl; - } else { + if (is_tdp) + { + cout << (XML->sys.Private_L2? indent_str:"")<< cachep.name << endl; + cout << indent_str << "Area = " << area.get_area()*1e-6<< " mm^2" << endl; + cout << indent_str << "Peak Dynamic = " << power.readOp.dynamic*cachep.clockRate << " W" << endl; + cout << indent_str << "Subthreshold Leakage = " + << (long_channel? power.readOp.longer_channel_leakage:power.readOp.leakage) <<" W" << endl; + //cout << indent_str << "Subthreshold Leakage = " << power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str << "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl; + cout << indent_str << "Runtime Dynamic = " << rt_power.readOp.dynamic/cachep.executionTime << " W" << endl; + cout <sys.first_level_dir==1) // { -// inv_dir.maxPower = -//inv_dir.caches.local_result.power.searchOp.dynamic*clockRate*XML->sys.domain_size; -// cc.power.readOp.dynamic = -//inv_dir.maxPower*scktRatio*64/XML->sys.domain_size; -// cc.power.readOp.leakage = -//inv_dir.caches.local_result.power.readOp.leakage*inv_dir.caches.l_ip.nbanks*64/XML->sys.domain_size; +// inv_dir.maxPower = inv_dir.caches.local_result.power.searchOp.dynamic*clockRate*XML->sys.domain_size; +// cc.power.readOp.dynamic = inv_dir.maxPower*scktRatio*64/XML->sys.domain_size; +// cc.power.readOp.leakage = inv_dir.caches.local_result.power.readOp.leakage*inv_dir.caches.l_ip.nbanks*64/XML->sys.domain_size; // // cc.area.set_area(inv_dir.area*64/XML->sys.domain_size); // cout<<"CC area="<sys.L2[ithCache].clockrate; - cachep.clockRate *= 1e6; - cachep.executionTime = - XML->sys.total_cycles / (XML->sys.target_core_clockrate * 1e6); - interface_ip.data_arr_ram_cell_tech_type = - XML->sys.L2[ithCache].device_type; // long channel device LSTP - interface_ip.data_arr_peri_global_tech_type = - XML->sys.L2[ithCache].device_type; - interface_ip.tag_arr_ram_cell_tech_type = XML->sys.L2[ithCache].device_type; - interface_ip.tag_arr_peri_global_tech_type = - XML->sys.L2[ithCache].device_type; - cachep.capacity = XML->sys.L2[ithCache].L2_config[0]; - cachep.blockW = XML->sys.L2[ithCache].L2_config[1]; - cachep.assoc = XML->sys.L2[ithCache].L2_config[2]; - cachep.nbanks = XML->sys.L2[ithCache].L2_config[3]; - cachep.throughput = XML->sys.L2[ithCache].L2_config[4] / cachep.clockRate; - cachep.latency = XML->sys.L2[ithCache].L2_config[5] / cachep.clockRate; - cachep.missb_size = XML->sys.L2[ithCache].buffer_sizes[0]; - cachep.fu_size = XML->sys.L2[ithCache].buffer_sizes[1]; - cachep.prefetchb_size = XML->sys.L2[ithCache].buffer_sizes[2]; - cachep.wbb_size = XML->sys.L2[ithCache].buffer_sizes[3]; - cachep.duty_cycle = XML->sys.L2[ithCache].duty_cycle; - if (!XML->sys.L2[ithCache].merged_dir) { - cachep.dir_ty = NonDir; - } else { - cachep.dir_ty = SBT; - cachep.dir_duty_cycle = XML->sys.L2[ithCache].dir_duty_cycle; - } - } else if (cacheL == L3) { - cachep.name = "L3"; - cachep.clockRate = XML->sys.L3[ithCache].clockrate; - cachep.clockRate *= 1e6; - cachep.executionTime = - XML->sys.total_cycles / (XML->sys.target_core_clockrate * 1e6); - interface_ip.data_arr_ram_cell_tech_type = - XML->sys.L3[ithCache].device_type; // long channel device LSTP - interface_ip.data_arr_peri_global_tech_type = - XML->sys.L3[ithCache].device_type; - interface_ip.tag_arr_ram_cell_tech_type = XML->sys.L3[ithCache].device_type; - interface_ip.tag_arr_peri_global_tech_type = - XML->sys.L3[ithCache].device_type; - cachep.capacity = XML->sys.L3[ithCache].L3_config[0]; - cachep.blockW = XML->sys.L3[ithCache].L3_config[1]; - cachep.assoc = XML->sys.L3[ithCache].L3_config[2]; - cachep.nbanks = XML->sys.L3[ithCache].L3_config[3]; - cachep.throughput = XML->sys.L3[ithCache].L3_config[4] / cachep.clockRate; - cachep.latency = XML->sys.L3[ithCache].L3_config[5] / cachep.clockRate; - cachep.missb_size = XML->sys.L3[ithCache].buffer_sizes[0]; - cachep.fu_size = XML->sys.L3[ithCache].buffer_sizes[1]; - cachep.prefetchb_size = XML->sys.L3[ithCache].buffer_sizes[2]; - cachep.wbb_size = XML->sys.L3[ithCache].buffer_sizes[3]; - cachep.duty_cycle = XML->sys.L3[ithCache].duty_cycle; - if (!XML->sys.L2[ithCache].merged_dir) { - cachep.dir_ty = NonDir; - } else { - cachep.dir_ty = SBT; - cachep.dir_duty_cycle = XML->sys.L2[ithCache].dir_duty_cycle; - } - } else if (cacheL == L1Directory) { - cachep.name = "First Level Directory"; - cachep.dir_ty = - (enum Dir_type)XML->sys.L1Directory[ithCache].Directory_type; - cachep.clockRate = XML->sys.L1Directory[ithCache].clockrate; - cachep.clockRate *= 1e6; - cachep.executionTime = - XML->sys.total_cycles / (XML->sys.target_core_clockrate * 1e6); - interface_ip.data_arr_ram_cell_tech_type = - XML->sys.L1Directory[ithCache].device_type; // long channel device LSTP - interface_ip.data_arr_peri_global_tech_type = - XML->sys.L1Directory[ithCache].device_type; - interface_ip.tag_arr_ram_cell_tech_type = - XML->sys.L1Directory[ithCache].device_type; - interface_ip.tag_arr_peri_global_tech_type = - XML->sys.L1Directory[ithCache].device_type; - cachep.capacity = XML->sys.L1Directory[ithCache].Dir_config[0]; - cachep.blockW = XML->sys.L1Directory[ithCache].Dir_config[1]; - cachep.assoc = XML->sys.L1Directory[ithCache].Dir_config[2]; - cachep.nbanks = XML->sys.L1Directory[ithCache].Dir_config[3]; - cachep.throughput = - XML->sys.L1Directory[ithCache].Dir_config[4] / cachep.clockRate; - cachep.latency = - XML->sys.L1Directory[ithCache].Dir_config[5] / cachep.clockRate; - cachep.missb_size = XML->sys.L1Directory[ithCache].buffer_sizes[0]; - cachep.fu_size = XML->sys.L1Directory[ithCache].buffer_sizes[1]; - cachep.prefetchb_size = XML->sys.L1Directory[ithCache].buffer_sizes[2]; - cachep.wbb_size = XML->sys.L1Directory[ithCache].buffer_sizes[3]; - cachep.duty_cycle = XML->sys.L1Directory[ithCache].duty_cycle; - } else if (cacheL == L2Directory) { - cachep.name = "Second Level Directory"; - cachep.dir_ty = - (enum Dir_type)XML->sys.L2Directory[ithCache].Directory_type; - cachep.clockRate = XML->sys.L2Directory[ithCache].clockrate; - cachep.clockRate *= 1e6; - cachep.executionTime = - XML->sys.total_cycles / (XML->sys.target_core_clockrate * 1e6); - interface_ip.data_arr_ram_cell_tech_type = - XML->sys.L2Directory[ithCache].device_type; // long channel device LSTP - interface_ip.data_arr_peri_global_tech_type = - XML->sys.L2Directory[ithCache].device_type; - interface_ip.tag_arr_ram_cell_tech_type = - XML->sys.L2Directory[ithCache].device_type; - interface_ip.tag_arr_peri_global_tech_type = - XML->sys.L2Directory[ithCache].device_type; - cachep.capacity = XML->sys.L2Directory[ithCache].Dir_config[0]; - cachep.blockW = XML->sys.L2Directory[ithCache].Dir_config[1]; - cachep.assoc = XML->sys.L2Directory[ithCache].Dir_config[2]; - cachep.nbanks = XML->sys.L2Directory[ithCache].Dir_config[3]; - cachep.throughput = - XML->sys.L2Directory[ithCache].Dir_config[4] / cachep.clockRate; - cachep.latency = - XML->sys.L2Directory[ithCache].Dir_config[5] / cachep.clockRate; - cachep.missb_size = XML->sys.L2Directory[ithCache].buffer_sizes[0]; - cachep.fu_size = XML->sys.L2Directory[ithCache].buffer_sizes[1]; - cachep.prefetchb_size = XML->sys.L2Directory[ithCache].buffer_sizes[2]; - cachep.wbb_size = XML->sys.L2Directory[ithCache].buffer_sizes[3]; - cachep.duty_cycle = XML->sys.L2Directory[ithCache].duty_cycle; +void SharedCache::set_cache_param() +{ + if (cacheL==L2) + { + cachep.name = "L2"; + cachep.clockRate = XML->sys.L2[ithCache].clockrate; + cachep.clockRate *= 1e6; + cachep.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); + interface_ip.data_arr_ram_cell_tech_type = XML->sys.L2[ithCache].device_type;//long channel device LSTP + interface_ip.data_arr_peri_global_tech_type = XML->sys.L2[ithCache].device_type; + interface_ip.tag_arr_ram_cell_tech_type = XML->sys.L2[ithCache].device_type; + interface_ip.tag_arr_peri_global_tech_type = XML->sys.L2[ithCache].device_type; + cachep.capacity = XML->sys.L2[ithCache].L2_config[0]; + cachep.blockW = XML->sys.L2[ithCache].L2_config[1]; + cachep.assoc = XML->sys.L2[ithCache].L2_config[2]; + cachep.nbanks = XML->sys.L2[ithCache].L2_config[3]; + cachep.throughput = XML->sys.L2[ithCache].L2_config[4]/cachep.clockRate; + cachep.latency = XML->sys.L2[ithCache].L2_config[5]/cachep.clockRate; + cachep.missb_size = XML->sys.L2[ithCache].buffer_sizes[0]; + cachep.fu_size = XML->sys.L2[ithCache].buffer_sizes[1]; + cachep.prefetchb_size= XML->sys.L2[ithCache].buffer_sizes[2]; + cachep.wbb_size = XML->sys.L2[ithCache].buffer_sizes[3]; + cachep.duty_cycle = XML->sys.L2[ithCache].duty_cycle; + if (!XML->sys.L2[ithCache].merged_dir) + { + cachep.dir_ty = NonDir; + } + else + { + cachep.dir_ty = SBT; + cachep.dir_duty_cycle = XML->sys.L2[ithCache].dir_duty_cycle; + } } - // cachep.cache_duty_cycle=cachep.dir_duty_cycle = 0.35; + else if (cacheL==L3) + { + cachep.name = "L3"; + cachep.clockRate = XML->sys.L3[ithCache].clockrate; + cachep.clockRate *= 1e6; + cachep.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); + interface_ip.data_arr_ram_cell_tech_type = XML->sys.L3[ithCache].device_type;//long channel device LSTP + interface_ip.data_arr_peri_global_tech_type = XML->sys.L3[ithCache].device_type; + interface_ip.tag_arr_ram_cell_tech_type = XML->sys.L3[ithCache].device_type; + interface_ip.tag_arr_peri_global_tech_type = XML->sys.L3[ithCache].device_type; + cachep.capacity = XML->sys.L3[ithCache].L3_config[0]; + cachep.blockW = XML->sys.L3[ithCache].L3_config[1]; + cachep.assoc = XML->sys.L3[ithCache].L3_config[2]; + cachep.nbanks = XML->sys.L3[ithCache].L3_config[3]; + cachep.throughput = XML->sys.L3[ithCache].L3_config[4]/cachep.clockRate; + cachep.latency = XML->sys.L3[ithCache].L3_config[5]/cachep.clockRate; + cachep.missb_size = XML->sys.L3[ithCache].buffer_sizes[0]; + cachep.fu_size = XML->sys.L3[ithCache].buffer_sizes[1]; + cachep.prefetchb_size= XML->sys.L3[ithCache].buffer_sizes[2]; + cachep.wbb_size = XML->sys.L3[ithCache].buffer_sizes[3]; + cachep.duty_cycle = XML->sys.L3[ithCache].duty_cycle; + if (!XML->sys.L2[ithCache].merged_dir) + { + cachep.dir_ty = NonDir; + } + else + { + cachep.dir_ty = SBT; + cachep.dir_duty_cycle = XML->sys.L2[ithCache].dir_duty_cycle; + } + } + else if (cacheL==L1Directory) + { + cachep.name = "First Level Directory"; + cachep.dir_ty = (enum Dir_type) XML->sys.L1Directory[ithCache].Directory_type; + cachep.clockRate = XML->sys.L1Directory[ithCache].clockrate; + cachep.clockRate *= 1e6; + cachep.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); + interface_ip.data_arr_ram_cell_tech_type = XML->sys.L1Directory[ithCache].device_type;//long channel device LSTP + interface_ip.data_arr_peri_global_tech_type = XML->sys.L1Directory[ithCache].device_type; + interface_ip.tag_arr_ram_cell_tech_type = XML->sys.L1Directory[ithCache].device_type; + interface_ip.tag_arr_peri_global_tech_type = XML->sys.L1Directory[ithCache].device_type; + cachep.capacity = XML->sys.L1Directory[ithCache].Dir_config[0]; + cachep.blockW = XML->sys.L1Directory[ithCache].Dir_config[1]; + cachep.assoc = XML->sys.L1Directory[ithCache].Dir_config[2]; + cachep.nbanks = XML->sys.L1Directory[ithCache].Dir_config[3]; + cachep.throughput = XML->sys.L1Directory[ithCache].Dir_config[4]/cachep.clockRate; + cachep.latency = XML->sys.L1Directory[ithCache].Dir_config[5]/cachep.clockRate; + cachep.missb_size = XML->sys.L1Directory[ithCache].buffer_sizes[0]; + cachep.fu_size = XML->sys.L1Directory[ithCache].buffer_sizes[1]; + cachep.prefetchb_size= XML->sys.L1Directory[ithCache].buffer_sizes[2]; + cachep.wbb_size = XML->sys.L1Directory[ithCache].buffer_sizes[3]; + cachep.duty_cycle = XML->sys.L1Directory[ithCache].duty_cycle; + } + else if (cacheL==L2Directory) + { + cachep.name = "Second Level Directory"; + cachep.dir_ty = (enum Dir_type) XML->sys.L2Directory[ithCache].Directory_type; + cachep.clockRate = XML->sys.L2Directory[ithCache].clockrate; + cachep.clockRate *= 1e6; + cachep.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); + interface_ip.data_arr_ram_cell_tech_type = XML->sys.L2Directory[ithCache].device_type;//long channel device LSTP + interface_ip.data_arr_peri_global_tech_type = XML->sys.L2Directory[ithCache].device_type; + interface_ip.tag_arr_ram_cell_tech_type = XML->sys.L2Directory[ithCache].device_type; + interface_ip.tag_arr_peri_global_tech_type = XML->sys.L2Directory[ithCache].device_type; + cachep.capacity = XML->sys.L2Directory[ithCache].Dir_config[0]; + cachep.blockW = XML->sys.L2Directory[ithCache].Dir_config[1]; + cachep.assoc = XML->sys.L2Directory[ithCache].Dir_config[2]; + cachep.nbanks = XML->sys.L2Directory[ithCache].Dir_config[3]; + cachep.throughput = XML->sys.L2Directory[ithCache].Dir_config[4]/cachep.clockRate; + cachep.latency = XML->sys.L2Directory[ithCache].Dir_config[5]/cachep.clockRate; + cachep.missb_size = XML->sys.L2Directory[ithCache].buffer_sizes[0]; + cachep.fu_size = XML->sys.L2Directory[ithCache].buffer_sizes[1]; + cachep.prefetchb_size= XML->sys.L2Directory[ithCache].buffer_sizes[2]; + cachep.wbb_size = XML->sys.L2Directory[ithCache].buffer_sizes[3]; + cachep.duty_cycle = XML->sys.L2Directory[ithCache].duty_cycle; + } + //cachep.cache_duty_cycle=cachep.dir_duty_cycle = 0.35; } + diff --git a/src/gpuwattch/sharedcache.h b/src/gpuwattch/sharedcache.h index c5aba19..3041137 100644 --- a/src/gpuwattch/sharedcache.h +++ b/src/gpuwattch/sharedcache.h @@ -31,59 +31,58 @@ #ifndef SHAREDCACHE_H_ #define SHAREDCACHE_H_ -#include #include "XML_Parse.h" -#include "array.h" -#include "basic_components.h" #include "cacti/area.h" #include "cacti/parameter.h" +#include "array.h" #include "logic.h" +#include +#include "basic_components.h" -class SharedCache : public Component { - public: - ParseXML* XML; - int ithCache; - InputParameter interface_ip; - enum cache_level cacheL; - DataCache unicache; // Shared cache - CacheDynParam cachep; - statsDef homenode_tdp_stats; - statsDef homenode_rtp_stats; - statsDef homenode_stats_t; - double dir_overhead; - // cache_processor llCache,directory, directory1, inv_dir; +class SharedCache :public Component{ + public: + ParseXML * XML; + int ithCache; + InputParameter interface_ip; + enum cache_level cacheL; + DataCache unicache;//Shared cache + CacheDynParam cachep; + statsDef homenode_tdp_stats; + statsDef homenode_rtp_stats; + statsDef homenode_stats_t; + double dir_overhead; + // cache_processor llCache,directory, directory1, inv_dir; - // pipeline pipeLogicCache, pipeLogicDirectory; - // clock_network clockNetwork; - double scktRatio, executionTime; - // Component L2Tot, cc, cc1, ccTot; + //pipeline pipeLogicCache, pipeLogicDirectory; + //clock_network clockNetwork; + double scktRatio, executionTime; + // Component L2Tot, cc, cc1, ccTot; - SharedCache(ParseXML* XML_interface, int ithCache_, - InputParameter* interface_ip_, enum cache_level cacheL_ = L2); - void set_cache_param(); - void computeEnergy(bool is_tdp = true); - void displayEnergy(uint32_t indent = 0, bool is_tdp = true); - ~SharedCache(){}; + SharedCache(ParseXML *XML_interface, int ithCache_, InputParameter* interface_ip_,enum cache_level cacheL_ =L2); + void set_cache_param(); + void computeEnergy(bool is_tdp=true); + void displayEnergy(uint32_t indent = 0,bool is_tdp=true); + ~SharedCache(){}; }; -class CCdir : public Component { - public: - ParseXML* XML; - int ithCache; - InputParameter interface_ip; - DataCache dc; // Shared cache - ArrayST* shadow_dir; - // cache_processor llCache,directory, directory1, inv_dir; +class CCdir :public Component{ + public: + ParseXML * XML; + int ithCache; + InputParameter interface_ip; + DataCache dc;//Shared cache + ArrayST * shadow_dir; +// cache_processor llCache,directory, directory1, inv_dir; - // pipeline pipeLogicCache, pipeLogicDirectory; - // clock_network clockNetwork; - double scktRatio, clockRate, executionTime; - Component L2Tot, cc, cc1, ccTot; + //pipeline pipeLogicCache, pipeLogicDirectory; + //clock_network clockNetwork; + double scktRatio, clockRate, executionTime; + Component L2Tot, cc, cc1, ccTot; - CCdir(ParseXML* XML_interface, int ithCache_, InputParameter* interface_ip_); - void computeEnergy(bool is_tdp = true); - void displayEnergy(uint32_t indent = 0, bool is_tdp = true); - ~CCdir(); + CCdir(ParseXML *XML_interface, int ithCache_, InputParameter* interface_ip_); + void computeEnergy(bool is_tdp=true); + void displayEnergy(uint32_t indent = 0,bool is_tdp=true); + ~CCdir(); }; #endif /* SHAREDCACHE_H_ */ diff --git a/src/gpuwattch/technology_xeon_core.cc b/src/gpuwattch/technology_xeon_core.cc index 11bb28e..ef16087 100644 --- a/src/gpuwattch/technology_xeon_core.cc +++ b/src/gpuwattch/technology_xeon_core.cc @@ -29,64 +29,57 @@ * ***************************************************************************/ + #include "basic_circuit.h" #include "parameter.h" -double wire_resistance(double resistivity, double wire_width, - double wire_thickness, double barrier_thickness, - double dishing_thickness, double alpha_scatter) { +double wire_resistance(double resistivity, double wire_width, double wire_thickness, + double barrier_thickness, double dishing_thickness, double alpha_scatter) +{ double resistance; - resistance = alpha_scatter * resistivity / - ((wire_thickness - barrier_thickness - dishing_thickness) * - (wire_width - 2 * barrier_thickness)); - return (resistance); + resistance = alpha_scatter * resistivity /((wire_thickness - barrier_thickness - dishing_thickness)*(wire_width - 2 * barrier_thickness)); + return(resistance); } -double wire_capacitance(double wire_width, double wire_thickness, - double wire_spacing, double ild_thickness, - double miller_value, double horiz_dielectric_constant, - double vert_dielectric_constant, double fringe_cap) { +double wire_capacitance(double wire_width, double wire_thickness, double wire_spacing, + double ild_thickness, double miller_value, double horiz_dielectric_constant, + double vert_dielectric_constant, double fringe_cap) +{ double vertical_cap, sidewall_cap, total_cap; - vertical_cap = 2 * PERMITTIVITY_FREE_SPACE * vert_dielectric_constant * - wire_width / ild_thickness; - sidewall_cap = 2 * PERMITTIVITY_FREE_SPACE * miller_value * - horiz_dielectric_constant * wire_thickness / wire_spacing; + vertical_cap = 2 * PERMITTIVITY_FREE_SPACE * vert_dielectric_constant * wire_width / ild_thickness; + sidewall_cap = 2 * PERMITTIVITY_FREE_SPACE * miller_value * horiz_dielectric_constant * wire_thickness / wire_spacing; total_cap = vertical_cap + sidewall_cap + fringe_cap; - return (total_cap); + return(total_cap); } -void init_tech_params(double technology, bool is_tag) { - int iter, tech, tech_lo, tech_hi; + +void init_tech_params(double technology, bool is_tag) +{ + int iter, tech, tech_lo, tech_hi; double curr_alpha, curr_vpp; - double wire_width, wire_thickness, wire_spacing, fringe_cap, - pmos_to_nmos_sizing_r; - // double aspect_ratio,ild_thickness, miller_value = 1.5, - // horiz_dielectric_constant, vert_dielectric_constant; + double wire_width, wire_thickness, wire_spacing, + fringe_cap, pmos_to_nmos_sizing_r; +// double aspect_ratio,ild_thickness, miller_value = 1.5, horiz_dielectric_constant, vert_dielectric_constant; double barrier_thickness, dishing_thickness, alpha_scatter; - double curr_vdd_dram_cell, curr_v_th_dram_access_transistor, - curr_I_on_dram_cell, curr_c_dram_cell; + double curr_vdd_dram_cell, curr_v_th_dram_access_transistor, curr_I_on_dram_cell, curr_c_dram_cell; - uint32_t ram_cell_tech_type = (is_tag) ? g_ip->tag_arr_ram_cell_tech_type - : g_ip->data_arr_ram_cell_tech_type; - uint32_t peri_global_tech_type = (is_tag) - ? g_ip->tag_arr_peri_global_tech_type - : g_ip->data_arr_peri_global_tech_type; + uint32_t ram_cell_tech_type = (is_tag) ? g_ip->tag_arr_ram_cell_tech_type : g_ip->data_arr_ram_cell_tech_type; + uint32_t peri_global_tech_type = (is_tag) ? g_ip->tag_arr_peri_global_tech_type : g_ip->data_arr_peri_global_tech_type; - technology = technology * 1000.0; // in the unit of nm + technology = technology * 1000.0; // in the unit of nm // initialize parameters g_tp.reset(); double gmp_to_gmn_multiplier_periph_global = 0; double curr_Wmemcella_dram, curr_Wmemcellpmos_dram, curr_Wmemcellnmos_dram, - curr_area_cell_dram, curr_asp_ratio_cell_dram, curr_Wmemcella_sram, - curr_Wmemcellpmos_sram, curr_Wmemcellnmos_sram, curr_area_cell_sram, - curr_asp_ratio_cell_sram, curr_I_off_dram_cell_worst_case_length_temp; - double curr_Wmemcella_cam, curr_Wmemcellpmos_cam, curr_Wmemcellnmos_cam, - curr_area_cell_cam, // Sheng: CAM data - curr_asp_ratio_cell_cam; - double SENSE_AMP_D, SENSE_AMP_P; // J + curr_area_cell_dram, curr_asp_ratio_cell_dram, curr_Wmemcella_sram, + curr_Wmemcellpmos_sram, curr_Wmemcellnmos_sram, curr_area_cell_sram, + curr_asp_ratio_cell_sram, curr_I_off_dram_cell_worst_case_length_temp; + double curr_Wmemcella_cam, curr_Wmemcellpmos_cam, curr_Wmemcellnmos_cam, curr_area_cell_cam,//Sheng: CAM data + curr_asp_ratio_cell_cam; + double SENSE_AMP_D, SENSE_AMP_P; // J double area_cell_dram = 0; double asp_ratio_cell_dram = 0; double area_cell_sram = 0; @@ -98,63 +91,77 @@ void init_tech_params(double technology, bool is_tag) { double nmos_effective_resistance_multiplier; double width_dram_access_transistor; - double curr_logic_scaling_co_eff = - 0; // This is based on the reported numbers of Intel Merom 65nm, - // Penryn45nm and IBM cell 90/65/45 date - double curr_core_tx_density = - 0; // this is density per um^2; 90, ...22nm based on Intel Penryn + double curr_logic_scaling_co_eff = 0;//This is based on the reported numbers of Intel Merom 65nm, Penryn45nm and IBM cell 90/65/45 date + double curr_core_tx_density = 0;//this is density per um^2; 90, ...22nm based on Intel Penryn double curr_chip_layout_overhead = 0; double curr_macro_layout_overhead = 0; double curr_sckt_co_eff = 0; - if (technology < 91 && technology > 89) { + if (technology < 91 && technology > 89) + { tech_lo = 90; tech_hi = 90; - } else if (technology < 66 && technology > 64) { + } + else if (technology < 66 && technology > 64) + { tech_lo = 65; tech_hi = 65; - } else if (technology < 46 && technology > 44) { + } + else if (technology < 46 && technology > 44) + { tech_lo = 45; tech_hi = 45; - } else if (technology < 33 && technology > 31) { + } + else if (technology < 33 && technology > 31) + { tech_lo = 32; tech_hi = 32; - } else if (technology < 23 && technology > 21) { + } + else if (technology < 23 && technology > 21) + { tech_lo = 22; tech_hi = 22; - if (ram_cell_tech_type == 3) { - cout << "current version does not support eDRAM technologies at 22nm" - << endl; - exit(0); + if (ram_cell_tech_type == 3) + { + cout<<"current version does not support eDRAM technologies at 22nm"< 15) - // { - // tech_lo = 16; - // tech_hi = 16; - // } - else if (technology < 90 && technology > 65) { +// else if (technology < 17 && technology > 15) +// { +// tech_lo = 16; +// tech_hi = 16; +// } + else if (technology < 90 && technology > 65) + { tech_lo = 90; tech_hi = 65; - } else if (technology < 65 && technology > 45) { + } + else if (technology < 65 && technology > 45) + { tech_lo = 65; tech_hi = 45; - } else if (technology < 45 && technology > 32) { + } + else if (technology < 45 && technology > 32) + { tech_lo = 45; tech_hi = 32; - } else if (technology < 32 && technology > 22) { - tech_lo = 32; - tech_hi = 22; - } - // else if (technology < 22 && technology > 16) - // { - // tech_lo = 22; - // tech_hi = 16; - // } - else { - cout << "Invalid technology nodes" << endl; - exit(0); } + else if (technology < 32 && technology > 22) + { + tech_lo = 32; + tech_hi = 22; + } +// else if (technology < 22 && technology > 16) +// { +// tech_lo = 22; +// tech_hi = 16; +// } + else + { + cout<<"Invalid technology nodes"<F_sz_um; curr_Wmemcellpmos_sram = 1.23 * g_ip->F_sz_um; curr_Wmemcellnmos_sram = 2.08 * g_ip->F_sz_um; curr_area_cell_sram = 146 * g_ip->F_sz_um * g_ip->F_sz_um; curr_asp_ratio_cell_sram = 1.46; - // CAM cell properties //TODO: data need to be revisited + //CAM cell properties //TODO: data need to be revisited curr_Wmemcella_cam = 1.31 * g_ip->F_sz_um; curr_Wmemcellpmos_cam = 1.23 * g_ip->F_sz_um; curr_Wmemcellnmos_cam = 2.08 * g_ip->F_sz_um; - curr_area_cell_cam = 292 * g_ip->F_sz_um * g_ip->F_sz_um; // 360 - curr_asp_ratio_cell_cam = 2.92; // 2.5 - // Empirical undifferetiated core/FU coefficient - curr_logic_scaling_co_eff = 1; - curr_core_tx_density = 1.25 * 0.7 * 0.7; - curr_sckt_co_eff = 1.1539; - curr_chip_layout_overhead = - 1.2; // die measurement results based on Niagara 1 and 2 - curr_macro_layout_overhead = - 1.1; // EDA placement and routing tool rule of thumb + curr_area_cell_cam = 292 * g_ip->F_sz_um * g_ip->F_sz_um;//360 + curr_asp_ratio_cell_cam = 2.92;//2.5 + //Empirical undifferetiated core/FU coefficient + curr_logic_scaling_co_eff = 1; + curr_core_tx_density = 1.25*0.7*0.7; + curr_sckt_co_eff = 1.1539; + curr_chip_layout_overhead = 1.2;//die measurement results based on Niagara 1 and 2 + curr_macro_layout_overhead = 1.1;//EDA placement and routing tool rule of thumb + + } - if (tech == 65) { // 65nm technology-node. Corresponds to year 2007 in ITRS - // ITRS HP device type - // SENSE_AMP_D = .2e-9; // s - // SENSE_AMP_P = 5.7e-15; // J - // vdd[0] = 1.1; - // Lphy[0] = 0.025; - // Lelec[0] = 0.019; - // t_ox[0] = 1.1e-3; - // v_th[0] = .19491; - // c_ox[0] = 1.88e-14; - // mobility_eff[0] = 436.24 * (1e-2 * 1e6 * 1e-2 * 1e6); - // Vdsat[0] = 7.71e-2; - // c_g_ideal[0] = 4.69e-16; - // c_fringe[0] = 0.077e-15; - // c_junc[0] = 1e-15; - // I_on_n[0] = 1197.2e-6; - // I_on_p[0] = 870.8e-6; - // nmos_effective_resistance_multiplier = 1.50; - // n_to_p_eff_curr_drv_ratio[0] = 2.41; - // gmp_to_gmn_multiplier[0] = 1.38; - // Rnchannelon[0] = nmos_effective_resistance_multiplier * vdd[0] / - // I_on_n[0]; - // Rpchannelon[0] = n_to_p_eff_curr_drv_ratio[0] * Rnchannelon[0]; - // long_channel_leakage_reduction[0] = 1/3.74; - // //Using MASTAR, @380K, increase Lgate until Ion reduces to 90% or - // Lgate increase by 10%, whichever comes first - // //Ioff(Lgate normal)/Ioff(Lgate long)= 3.74. - // I_off_n[0][0] = 1.96e-7; - // I_off_n[0][10] = 2.29e-7; - // I_off_n[0][20] = 2.66e-7; - // I_off_n[0][30] = 3.05e-7; - // I_off_n[0][40] = 3.49e-7; - // I_off_n[0][50] = 3.95e-7; - // I_off_n[0][60] = 4.45e-7; - // I_off_n[0][70] = 4.97e-7; - // I_off_n[0][80] = 5.48e-7; - // I_off_n[0][90] = 5.94e-7; - // I_off_n[0][100] = 6.3e-7; - // I_g_on_n[0][0] = 4.09e-8;//A/micron - // I_g_on_n[0][10] = 4.09e-8; - // I_g_on_n[0][20] = 4.09e-8; - // I_g_on_n[0][30] = 4.09e-8; - // I_g_on_n[0][40] = 4.09e-8; - // I_g_on_n[0][50] = 4.09e-8; - // I_g_on_n[0][60] = 4.09e-8; - // I_g_on_n[0][70] = 4.09e-8; - // I_g_on_n[0][80] = 4.09e-8; - // I_g_on_n[0][90] = 4.09e-8; - // I_g_on_n[0][100] = 4.09e-8; - - SENSE_AMP_D = .2e-9; // s - SENSE_AMP_P = 5.7e-15; // J - vdd[0] = 1.25; - Lphy[0] = 0.025; - Lelec[0] = 0.019; - t_ox[0] = 1.1e-3; - v_th[0] = .12491; - c_ox[0] = 1.88e-14; - mobility_eff[0] = 409.31 * (1e-2 * 1e6 * 1e-2 * 1e6); - Vdsat[0] = 9.08e-2; - c_g_ideal[0] = 4.72e-16; - c_fringe[0] = 0.08e-15; - c_junc[0] = 1e-15; - I_on_n[0] = 1486.4e-6; - I_on_p[0] = 1131.5e-6; - nmos_effective_resistance_multiplier = 1.57; - n_to_p_eff_curr_drv_ratio[0] = 2; - gmp_to_gmn_multiplier[0] = 1.38; - Rnchannelon[0] = - nmos_effective_resistance_multiplier * vdd[0] / I_on_n[0]; - Rpchannelon[0] = n_to_p_eff_curr_drv_ratio[0] * Rnchannelon[0]; - long_channel_leakage_reduction[0] = 1.0 / 4.97; - // Using MASTAR, @380K, increase Lgate until Ion reduces to 90% or Lgate - // increase by 10%, whichever comes first - // Ioff(Lgate normal)/Ioff(Lgate long)= 4.97@Vdd=1.25; (3.74@Vdd=1.1), - // however, Intel paper suggest the reduction factor is 3. - I_off_n[0][0] = 8.62e-7; - I_off_n[0][10] = 9.08e-7; - I_off_n[0][20] = 9.55e-7; - I_off_n[0][30] = 1.00e-6; - I_off_n[0][40] = 1.05e-6; - I_off_n[0][50] = 1.09e-6; - I_off_n[0][60] = 1.14e-6; - I_off_n[0][70] = 1.18e-6; - I_off_n[0][80] = 1.23e-6; - I_off_n[0][90] = 1.27e-6; - I_off_n[0][100] = 1.31e-6; - - I_g_on_n[0][0] = 7.02e-8; // A/micron - I_g_on_n[0][10] = 7.02e-8; - I_g_on_n[0][20] = 7.02e-8; - I_g_on_n[0][30] = 7.02e-8; - I_g_on_n[0][40] = 7.02e-8; - I_g_on_n[0][50] = 7.02e-8; - I_g_on_n[0][60] = 7.02e-8; - I_g_on_n[0][70] = 7.02e-8; - I_g_on_n[0][80] = 7.02e-8; - I_g_on_n[0][90] = 7.02e-8; - I_g_on_n[0][100] = 7.02e-8; - - // ITRS LSTP device type + if (tech == 65) + { //65nm technology-node. Corresponds to year 2007 in ITRS + //ITRS HP device type +// SENSE_AMP_D = .2e-9; // s +// SENSE_AMP_P = 5.7e-15; // J +// vdd[0] = 1.1; +// Lphy[0] = 0.025; +// Lelec[0] = 0.019; +// t_ox[0] = 1.1e-3; +// v_th[0] = .19491; +// c_ox[0] = 1.88e-14; +// mobility_eff[0] = 436.24 * (1e-2 * 1e6 * 1e-2 * 1e6); +// Vdsat[0] = 7.71e-2; +// c_g_ideal[0] = 4.69e-16; +// c_fringe[0] = 0.077e-15; +// c_junc[0] = 1e-15; +// I_on_n[0] = 1197.2e-6; +// I_on_p[0] = 870.8e-6; +// nmos_effective_resistance_multiplier = 1.50; +// n_to_p_eff_curr_drv_ratio[0] = 2.41; +// gmp_to_gmn_multiplier[0] = 1.38; +// Rnchannelon[0] = nmos_effective_resistance_multiplier * vdd[0] / I_on_n[0]; +// Rpchannelon[0] = n_to_p_eff_curr_drv_ratio[0] * Rnchannelon[0]; +// long_channel_leakage_reduction[0] = 1/3.74; +// //Using MASTAR, @380K, increase Lgate until Ion reduces to 90% or Lgate increase by 10%, whichever comes first +// //Ioff(Lgate normal)/Ioff(Lgate long)= 3.74. +// I_off_n[0][0] = 1.96e-7; +// I_off_n[0][10] = 2.29e-7; +// I_off_n[0][20] = 2.66e-7; +// I_off_n[0][30] = 3.05e-7; +// I_off_n[0][40] = 3.49e-7; +// I_off_n[0][50] = 3.95e-7; +// I_off_n[0][60] = 4.45e-7; +// I_off_n[0][70] = 4.97e-7; +// I_off_n[0][80] = 5.48e-7; +// I_off_n[0][90] = 5.94e-7; +// I_off_n[0][100] = 6.3e-7; +// I_g_on_n[0][0] = 4.09e-8;//A/micron +// I_g_on_n[0][10] = 4.09e-8; +// I_g_on_n[0][20] = 4.09e-8; +// I_g_on_n[0][30] = 4.09e-8; +// I_g_on_n[0][40] = 4.09e-8; +// I_g_on_n[0][50] = 4.09e-8; +// I_g_on_n[0][60] = 4.09e-8; +// I_g_on_n[0][70] = 4.09e-8; +// I_g_on_n[0][80] = 4.09e-8; +// I_g_on_n[0][90] = 4.09e-8; +// I_g_on_n[0][100] = 4.09e-8; + + SENSE_AMP_D = .2e-9; // s + SENSE_AMP_P = 5.7e-15; // J + vdd[0] = 1.25; + Lphy[0] = 0.025; + Lelec[0] = 0.019; + t_ox[0] = 1.1e-3; + v_th[0] = .12491; + c_ox[0] = 1.88e-14; + mobility_eff[0] = 409.31 * (1e-2 * 1e6 * 1e-2 * 1e6); + Vdsat[0] = 9.08e-2; + c_g_ideal[0] = 4.72e-16; + c_fringe[0] = 0.08e-15; + c_junc[0] = 1e-15; + I_on_n[0] = 1486.4e-6; + I_on_p[0] = 1131.5e-6; + nmos_effective_resistance_multiplier = 1.57; + n_to_p_eff_curr_drv_ratio[0] = 2; + gmp_to_gmn_multiplier[0] = 1.38; + Rnchannelon[0] = nmos_effective_resistance_multiplier * vdd[0] / I_on_n[0]; + Rpchannelon[0] = n_to_p_eff_curr_drv_ratio[0] * Rnchannelon[0]; + long_channel_leakage_reduction[0] = 1.0/4.97; + //Using MASTAR, @380K, increase Lgate until Ion reduces to 90% or Lgate increase by 10%, whichever comes first + //Ioff(Lgate normal)/Ioff(Lgate long)= 4.97@Vdd=1.25; (3.74@Vdd=1.1), however, Intel paper suggest the reduction factor is 3. + I_off_n[0][0] = 8.62e-7; + I_off_n[0][10] = 9.08e-7; + I_off_n[0][20] = 9.55e-7; + I_off_n[0][30] = 1.00e-6; + I_off_n[0][40] = 1.05e-6; + I_off_n[0][50] = 1.09e-6; + I_off_n[0][60] = 1.14e-6; + I_off_n[0][70] = 1.18e-6; + I_off_n[0][80] = 1.23e-6; + I_off_n[0][90] = 1.27e-6; + I_off_n[0][100] = 1.31e-6; + + + I_g_on_n[0][0] = 7.02e-8;//A/micron + I_g_on_n[0][10] = 7.02e-8; + I_g_on_n[0][20] = 7.02e-8; + I_g_on_n[0][30] = 7.02e-8; + I_g_on_n[0][40] = 7.02e-8; + I_g_on_n[0][50] = 7.02e-8; + I_g_on_n[0][60] = 7.02e-8; + I_g_on_n[0][70] = 7.02e-8; + I_g_on_n[0][80] = 7.02e-8; + I_g_on_n[0][90] = 7.02e-8; + I_g_on_n[0][100] = 7.02e-8; + + //ITRS LSTP device type vdd[1] = 1.2; Lphy[1] = 0.045; Lelec[1] = 0.0298; @@ -573,10 +583,9 @@ void init_tech_params(double technology, bool is_tag) { nmos_effective_resistance_multiplier = 1.96; n_to_p_eff_curr_drv_ratio[1] = 2.23; gmp_to_gmn_multiplier[1] = 0.99; - Rnchannelon[1] = - nmos_effective_resistance_multiplier * vdd[1] / I_on_n[1]; + Rnchannelon[1] = nmos_effective_resistance_multiplier * vdd[1] / I_on_n[1]; Rpchannelon[1] = n_to_p_eff_curr_drv_ratio[1] * Rnchannelon[1]; - long_channel_leakage_reduction[1] = 1 / 2.82; + long_channel_leakage_reduction[1] = 1/2.82; I_off_n[1][0] = 9.12e-12; I_off_n[1][10] = 1.49e-11; I_off_n[1][20] = 2.36e-11; @@ -589,7 +598,7 @@ void init_tech_params(double technology, bool is_tag) { I_off_n[1][90] = 2.62e-10; I_off_n[1][100] = 3.21e-10; - I_g_on_n[1][0] = 1.09e-10; // A/micron + I_g_on_n[1][0] = 1.09e-10;//A/micron I_g_on_n[1][10] = 1.09e-10; I_g_on_n[1][20] = 1.09e-10; I_g_on_n[1][30] = 1.09e-10; @@ -601,7 +610,7 @@ void init_tech_params(double technology, bool is_tag) { I_g_on_n[1][90] = 1.09e-10; I_g_on_n[1][100] = 1.09e-10; - // ITRS LOP device type + //ITRS LOP device type vdd[2] = 0.8; Lphy[2] = 0.032; Lelec[2] = 0.0216; @@ -618,10 +627,9 @@ void init_tech_params(double technology, bool is_tag) { nmos_effective_resistance_multiplier = 1.82; n_to_p_eff_curr_drv_ratio[2] = 2.28; gmp_to_gmn_multiplier[2] = 1.11; - Rnchannelon[2] = - nmos_effective_resistance_multiplier * vdd[2] / I_on_n[2]; + Rnchannelon[2] = nmos_effective_resistance_multiplier * vdd[2] / I_on_n[2]; Rpchannelon[2] = n_to_p_eff_curr_drv_ratio[2] * Rnchannelon[2]; - long_channel_leakage_reduction[2] = 1 / 2.05; + long_channel_leakage_reduction[2] = 1/2.05; I_off_n[2][0] = 4.9e-9; I_off_n[2][10] = 6.49e-9; I_off_n[2][20] = 8.45e-9; @@ -634,7 +642,7 @@ void init_tech_params(double technology, bool is_tag) { I_off_n[2][90] = 3.13e-8; I_off_n[2][100] = 3.42e-8; - I_g_on_n[2][0] = 9.61e-9; // A/micron + I_g_on_n[2][0] = 9.61e-9;//A/micron I_g_on_n[2][10] = 9.61e-9; I_g_on_n[2][20] = 9.61e-9; I_g_on_n[2][30] = 9.61e-9; @@ -646,8 +654,9 @@ void init_tech_params(double technology, bool is_tag) { I_g_on_n[2][90] = 9.61e-9; I_g_on_n[2][100] = 9.61e-9; - if (ram_cell_tech_type == lp_dram) { - // LP-DRAM cell access transistor technology parameters + if (ram_cell_tech_type == lp_dram) + { + //LP-DRAM cell access transistor technology parameters curr_vdd_dram_cell = 1.2; Lphy[3] = 0.12; Lelec[3] = 0.0756; @@ -662,26 +671,25 @@ void init_tech_params(double technology, bool is_tag) { curr_asp_ratio_cell_dram = 1.46; curr_c_dram_cell = 20e-15; - // LP-DRAM wordline transistor parameters + //LP-DRAM wordline transistor parameters curr_vpp = 1.6; t_ox[3] = 2.2e-3; v_th[3] = 0.43806; c_ox[3] = 1.22e-14; - mobility_eff[3] = 328.32 * (1e-2 * 1e6 * 1e-2 * 1e6); + mobility_eff[3] = 328.32 * (1e-2 * 1e6 * 1e-2 * 1e6); Vdsat[3] = 0.43806; c_g_ideal[3] = 1.46e-15; c_fringe[3] = 0.08e-15; - c_junc[3] = 1e-15; + c_junc[3] = 1e-15 ; I_on_n[3] = 399.8e-6; I_on_p[3] = 243.4e-6; nmos_effective_resistance_multiplier = 1.65; n_to_p_eff_curr_drv_ratio[3] = 2.05; gmp_to_gmn_multiplier[3] = 0.90; - Rnchannelon[3] = - nmos_effective_resistance_multiplier * curr_vpp / I_on_n[3]; + Rnchannelon[3] = nmos_effective_resistance_multiplier * curr_vpp / I_on_n[3]; Rpchannelon[3] = n_to_p_eff_curr_drv_ratio[3] * Rnchannelon[3]; long_channel_leakage_reduction[3] = 1; - I_off_n[3][0] = 2.23e-11; + I_off_n[3][0] = 2.23e-11; I_off_n[3][10] = 3.46e-11; I_off_n[3][20] = 5.24e-11; I_off_n[3][30] = 7.75e-11; @@ -692,8 +700,10 @@ void init_tech_params(double technology, bool is_tag) { I_off_n[3][80] = 3.63e-10; I_off_n[3][90] = 4.41e-10; I_off_n[3][100] = 5.36e-10; - } else if (ram_cell_tech_type == comm_dram) { - // COMM-DRAM cell access transistor technology parameters + } + else if (ram_cell_tech_type == comm_dram) + { + //COMM-DRAM cell access transistor technology parameters curr_vdd_dram_cell = 1.3; Lphy[3] = 0.065; Lelec[3] = 0.0426; @@ -704,30 +714,29 @@ void init_tech_params(double technology, bool is_tag) { curr_Wmemcella_dram = width_dram_access_transistor; curr_Wmemcellpmos_dram = 0; curr_Wmemcellnmos_dram = 0; - curr_area_cell_dram = 6 * 0.065 * 0.065; + curr_area_cell_dram = 6*0.065*0.065; curr_asp_ratio_cell_dram = 1.5; curr_c_dram_cell = 30e-15; - // COMM-DRAM wordline transistor parameters + //COMM-DRAM wordline transistor parameters curr_vpp = 3.3; t_ox[3] = 5e-3; v_th[3] = 1.0; c_ox[3] = 6.16e-15; - mobility_eff[3] = 303.44 * (1e-2 * 1e6 * 1e-2 * 1e6); + mobility_eff[3] = 303.44 * (1e-2 * 1e6 * 1e-2 * 1e6); Vdsat[3] = 0.385; c_g_ideal[3] = 4e-16; c_fringe[3] = 0.08e-15; - c_junc[3] = 1e-15; + c_junc[3] = 1e-15 ; I_on_n[3] = 1031e-6; I_on_p[3] = I_on_n[3] / 2; nmos_effective_resistance_multiplier = 1.69; n_to_p_eff_curr_drv_ratio[3] = 2.39; gmp_to_gmn_multiplier[3] = 0.90; - Rnchannelon[3] = - nmos_effective_resistance_multiplier * curr_vpp / I_on_n[3]; + Rnchannelon[3] = nmos_effective_resistance_multiplier * curr_vpp / I_on_n[3]; Rpchannelon[3] = n_to_p_eff_curr_drv_ratio[3] * Rnchannelon[3]; long_channel_leakage_reduction[3] = 1; - I_off_n[3][0] = 1.80e-14; + I_off_n[3][0] = 1.80e-14; I_off_n[3][10] = 3.64e-14; I_off_n[3][20] = 7.03e-14; I_off_n[3][30] = 1.31e-13; @@ -740,32 +749,31 @@ void init_tech_params(double technology, bool is_tag) { I_off_n[3][100] = 3.99e-12; } - // SRAM cell properties + //SRAM cell properties curr_Wmemcella_sram = 1.31 * g_ip->F_sz_um; curr_Wmemcellpmos_sram = 1.23 * g_ip->F_sz_um; curr_Wmemcellnmos_sram = 2.08 * g_ip->F_sz_um; curr_area_cell_sram = 146 * g_ip->F_sz_um * g_ip->F_sz_um; curr_asp_ratio_cell_sram = 1.46; - // CAM cell properties //TODO: data need to be revisited + //CAM cell properties //TODO: data need to be revisited curr_Wmemcella_cam = 1.31 * g_ip->F_sz_um; curr_Wmemcellpmos_cam = 1.23 * g_ip->F_sz_um; curr_Wmemcellnmos_cam = 2.08 * g_ip->F_sz_um; curr_area_cell_cam = 292 * g_ip->F_sz_um * g_ip->F_sz_um; curr_asp_ratio_cell_cam = 2.92; - // Empirical undifferetiated core/FU coefficient + //Empirical undifferetiated core/FU coefficient curr_logic_scaling_co_eff = 0.7; - curr_core_tx_density = 1.25 * 0.7; - curr_sckt_co_eff = 1.1359; - curr_chip_layout_overhead = - 1.2; // die measurement results based on Niagara 1 and 2 - curr_macro_layout_overhead = - 1.1; // EDA placement and routing tool rule of thumb + curr_core_tx_density = 1.25*0.7; + curr_sckt_co_eff = 1.1359; + curr_chip_layout_overhead = 1.2;//die measurement results based on Niagara 1 and 2 + curr_macro_layout_overhead = 1.1;//EDA placement and routing tool rule of thumb } - if (tech == 45) { // 45nm technology-node. Corresponds to year 2010 in ITRS - // ITRS HP device type - SENSE_AMP_D = .04e-9; // s - SENSE_AMP_P = 2.7e-15; // J + if (tech == 45) + { //45nm technology-node. Corresponds to year 2010 in ITRS + //ITRS HP device type + SENSE_AMP_D = .04e-9; // s + SENSE_AMP_P = 2.7e-15; // J vdd[0] = 1.0; Lphy[0] = 0.018; Lelec[0] = 0.01345; @@ -778,20 +786,15 @@ void init_tech_params(double technology, bool is_tag) { c_fringe[0] = 0.05e-15; c_junc[0] = 1e-15; I_on_n[0] = 2046.6e-6; - // There are certain problems with the ITRS PMOS numbers in MASTAR for - // 45nm. So we are using 65nm values of - // n_to_p_eff_curr_drv_ratio and gmp_to_gmn_multiplier for 45nm - I_on_p[0] = I_on_n[0] / 2; // This value is fixed arbitrarily but I_on_p - // is not being used in CACTI + //There are certain problems with the ITRS PMOS numbers in MASTAR for 45nm. So we are using 65nm values of + //n_to_p_eff_curr_drv_ratio and gmp_to_gmn_multiplier for 45nm + I_on_p[0] = I_on_n[0] / 2;//This value is fixed arbitrarily but I_on_p is not being used in CACTI nmos_effective_resistance_multiplier = 1.51; n_to_p_eff_curr_drv_ratio[0] = 2.41; gmp_to_gmn_multiplier[0] = 1.38; - Rnchannelon[0] = - nmos_effective_resistance_multiplier * vdd[0] / I_on_n[0]; + Rnchannelon[0] = nmos_effective_resistance_multiplier * vdd[0] / I_on_n[0]; Rpchannelon[0] = n_to_p_eff_curr_drv_ratio[0] * Rnchannelon[0]; - long_channel_leakage_reduction[0] = - 1 / 3.546; // Using MASTAR, @380K, increase Lgate until Ion reduces - // to 90%, Ioff(Lgate normal)/Ioff(Lgate long)= 3.74 + long_channel_leakage_reduction[0] = 1/3.546;//Using MASTAR, @380K, increase Lgate until Ion reduces to 90%, Ioff(Lgate normal)/Ioff(Lgate long)= 3.74 I_off_n[0][0] = 2.8e-7; I_off_n[0][10] = 3.28e-7; I_off_n[0][20] = 3.81e-7; @@ -804,7 +807,7 @@ void init_tech_params(double technology, bool is_tag) { I_off_n[0][90] = 8.91e-7; I_off_n[0][100] = 9.84e-7; - I_g_on_n[0][0] = 3.59e-8; // A/micron + I_g_on_n[0][0] = 3.59e-8;//A/micron I_g_on_n[0][10] = 3.59e-8; I_g_on_n[0][20] = 3.59e-8; I_g_on_n[0][30] = 3.59e-8; @@ -816,14 +819,14 @@ void init_tech_params(double technology, bool is_tag) { I_g_on_n[0][90] = 3.59e-8; I_g_on_n[0][100] = 3.59e-8; - // ITRS LSTP device type + //ITRS LSTP device type vdd[1] = 1.1; - Lphy[1] = 0.028; + Lphy[1] = 0.028; Lelec[1] = 0.0212; t_ox[1] = 1.4e-3; v_th[1] = 0.50245; c_ox[1] = 2.01e-14; - mobility_eff[1] = 363.96 * (1e-2 * 1e6 * 1e-2 * 1e6); + mobility_eff[1] = 363.96 * (1e-2 * 1e6 * 1e-2 * 1e6); Vdsat[1] = 9.12e-2; c_g_ideal[1] = 5.18e-16; c_fringe[1] = 0.08e-15; @@ -833,10 +836,9 @@ void init_tech_params(double technology, bool is_tag) { nmos_effective_resistance_multiplier = 1.99; n_to_p_eff_curr_drv_ratio[1] = 2.23; gmp_to_gmn_multiplier[1] = 0.99; - Rnchannelon[1] = - nmos_effective_resistance_multiplier * vdd[1] / I_on_n[1]; + Rnchannelon[1] = nmos_effective_resistance_multiplier * vdd[1] / I_on_n[1]; Rpchannelon[1] = n_to_p_eff_curr_drv_ratio[1] * Rnchannelon[1]; - long_channel_leakage_reduction[1] = 1 / 2.08; + long_channel_leakage_reduction[1] = 1/2.08; I_off_n[1][0] = 1.01e-11; I_off_n[1][10] = 1.65e-11; I_off_n[1][20] = 2.62e-11; @@ -849,7 +851,7 @@ void init_tech_params(double technology, bool is_tag) { I_off_n[1][90] = 3.29e-10; I_off_n[1][100] = 4.1e-10; - I_g_on_n[1][0] = 9.47e-12; // A/micron + I_g_on_n[1][0] = 9.47e-12;//A/micron I_g_on_n[1][10] = 9.47e-12; I_g_on_n[1][20] = 9.47e-12; I_g_on_n[1][30] = 9.47e-12; @@ -861,13 +863,13 @@ void init_tech_params(double technology, bool is_tag) { I_g_on_n[1][90] = 9.47e-12; I_g_on_n[1][100] = 9.47e-12; - // ITRS LOP device type + //ITRS LOP device type vdd[2] = 0.7; Lphy[2] = 0.022; Lelec[2] = 0.016; t_ox[2] = 0.9e-3; v_th[2] = 0.22599; - c_ox[2] = 2.82e-14; // F/micron2 + c_ox[2] = 2.82e-14;//F/micron2 mobility_eff[2] = 508.9 * (1e-2 * 1e6 * 1e-2 * 1e6); Vdsat[2] = 5.71e-2; c_g_ideal[2] = 6.2e-16; @@ -878,10 +880,9 @@ void init_tech_params(double technology, bool is_tag) { nmos_effective_resistance_multiplier = 1.76; n_to_p_eff_curr_drv_ratio[2] = 2.28; gmp_to_gmn_multiplier[2] = 1.11; - Rnchannelon[2] = - nmos_effective_resistance_multiplier * vdd[2] / I_on_n[2]; + Rnchannelon[2] = nmos_effective_resistance_multiplier * vdd[2] / I_on_n[2]; Rpchannelon[2] = n_to_p_eff_curr_drv_ratio[2] * Rnchannelon[2]; - long_channel_leakage_reduction[2] = 1 / 1.92; + long_channel_leakage_reduction[2] = 1/1.92; I_off_n[2][0] = 4.03e-9; I_off_n[2][10] = 5.02e-9; I_off_n[2][20] = 6.18e-9; @@ -894,7 +895,7 @@ void init_tech_params(double technology, bool is_tag) { I_off_n[2][90] = 1.84e-8; I_off_n[2][100] = 2.03e-8; - I_g_on_n[2][0] = 3.24e-8; // A/micron + I_g_on_n[2][0] = 3.24e-8;//A/micron I_g_on_n[2][10] = 4.01e-8; I_g_on_n[2][20] = 4.90e-8; I_g_on_n[2][30] = 5.92e-8; @@ -906,29 +907,29 @@ void init_tech_params(double technology, bool is_tag) { I_g_on_n[2][90] = 1.43e-7; I_g_on_n[2][100] = 1.54e-7; - if (ram_cell_tech_type == lp_dram) { - // LP-DRAM cell access transistor technology parameters + if (ram_cell_tech_type == lp_dram) + { + //LP-DRAM cell access transistor technology parameters curr_vdd_dram_cell = 1.1; Lphy[3] = 0.078; - Lelec[3] = 0.0504; // Assume Lelec is 30% lesser than Lphy for DRAM - // access and wordline transistors. + Lelec[3] = 0.0504;// Assume Lelec is 30% lesser than Lphy for DRAM access and wordline transistors. curr_v_th_dram_access_transistor = 0.44559; width_dram_access_transistor = 0.079; - curr_I_on_dram_cell = 36e-6; // A + curr_I_on_dram_cell = 36e-6;//A curr_I_off_dram_cell_worst_case_length_temp = 19.5e-12; curr_Wmemcella_dram = width_dram_access_transistor; curr_Wmemcellpmos_dram = 0; - curr_Wmemcellnmos_dram = 0; + curr_Wmemcellnmos_dram = 0; curr_area_cell_dram = width_dram_access_transistor * Lphy[3] * 10.0; curr_asp_ratio_cell_dram = 1.46; curr_c_dram_cell = 20e-15; - // LP-DRAM wordline transistor parameters + //LP-DRAM wordline transistor parameters curr_vpp = 1.5; t_ox[3] = 2.1e-3; v_th[3] = 0.44559; c_ox[3] = 1.41e-14; - mobility_eff[3] = 426.30 * (1e-2 * 1e6 * 1e-2 * 1e6); + mobility_eff[3] = 426.30 * (1e-2 * 1e6 * 1e-2 * 1e6); Vdsat[3] = 0.181; c_g_ideal[3] = 1.10e-15; c_fringe[3] = 0.08e-15; @@ -938,8 +939,7 @@ void init_tech_params(double technology, bool is_tag) { nmos_effective_resistance_multiplier = 1.65; n_to_p_eff_curr_drv_ratio[3] = 2.05; gmp_to_gmn_multiplier[3] = 0.90; - Rnchannelon[3] = - nmos_effective_resistance_multiplier * curr_vpp / I_on_n[3]; + Rnchannelon[3] = nmos_effective_resistance_multiplier * curr_vpp / I_on_n[3]; Rpchannelon[3] = n_to_p_eff_curr_drv_ratio[3] * Rnchannelon[3]; long_channel_leakage_reduction[3] = 1; I_off_n[3][0] = 2.54e-11; @@ -953,23 +953,25 @@ void init_tech_params(double technology, bool is_tag) { I_off_n[3][80] = 4.26e-10; I_off_n[3][90] = 5.27e-10; I_off_n[3][100] = 6.46e-10; - } else if (ram_cell_tech_type == comm_dram) { - // COMM-DRAM cell access transistor technology parameters + } + else if (ram_cell_tech_type == comm_dram) + { + //COMM-DRAM cell access transistor technology parameters curr_vdd_dram_cell = 1.1; Lphy[3] = 0.045; Lelec[3] = 0.0298; curr_v_th_dram_access_transistor = 1; width_dram_access_transistor = 0.045; - curr_I_on_dram_cell = 20e-6; // A + curr_I_on_dram_cell = 20e-6;//A curr_I_off_dram_cell_worst_case_length_temp = 1e-15; curr_Wmemcella_dram = width_dram_access_transistor; curr_Wmemcellpmos_dram = 0; - curr_Wmemcellnmos_dram = 0; - curr_area_cell_dram = 6 * 0.045 * 0.045; + curr_Wmemcellnmos_dram = 0; + curr_area_cell_dram = 6*0.045*0.045; curr_asp_ratio_cell_dram = 1.5; curr_c_dram_cell = 30e-15; - // COMM-DRAM wordline transistor parameters + //COMM-DRAM wordline transistor parameters curr_vpp = 2.7; t_ox[3] = 4e-3; v_th[3] = 1.0; @@ -984,8 +986,7 @@ void init_tech_params(double technology, bool is_tag) { nmos_effective_resistance_multiplier = 1.69; n_to_p_eff_curr_drv_ratio[3] = 1.95; gmp_to_gmn_multiplier[3] = 0.90; - Rnchannelon[3] = - nmos_effective_resistance_multiplier * curr_vpp / I_on_n[3]; + Rnchannelon[3] = nmos_effective_resistance_multiplier * curr_vpp / I_on_n[3]; Rpchannelon[3] = n_to_p_eff_curr_drv_ratio[3] * Rnchannelon[3]; long_channel_leakage_reduction[3] = 1; I_off_n[3][0] = 1.31e-14; @@ -1001,35 +1002,34 @@ void init_tech_params(double technology, bool is_tag) { I_off_n[3][100] = 3.29e-12; } - // SRAM cell properties + + //SRAM cell properties curr_Wmemcella_sram = 1.31 * g_ip->F_sz_um; curr_Wmemcellpmos_sram = 1.23 * g_ip->F_sz_um; curr_Wmemcellnmos_sram = 2.08 * g_ip->F_sz_um; curr_area_cell_sram = 146 * g_ip->F_sz_um * g_ip->F_sz_um; curr_asp_ratio_cell_sram = 1.46; - // CAM cell properties //TODO: data need to be revisited + //CAM cell properties //TODO: data need to be revisited curr_Wmemcella_cam = 1.31 * g_ip->F_sz_um; curr_Wmemcellpmos_cam = 1.23 * g_ip->F_sz_um; curr_Wmemcellnmos_cam = 2.08 * g_ip->F_sz_um; curr_area_cell_cam = 292 * g_ip->F_sz_um * g_ip->F_sz_um; curr_asp_ratio_cell_cam = 2.92; - // Empirical undifferetiated core/FU coefficient - curr_logic_scaling_co_eff = 0.7 * 0.7; - curr_core_tx_density = 1.25; - curr_sckt_co_eff = 1.1387; - curr_chip_layout_overhead = - 1.2; // die measurement results based on Niagara 1 and 2 - curr_macro_layout_overhead = - 1.1; // EDA placement and routing tool rule of thumb + //Empirical undifferetiated core/FU coefficient + curr_logic_scaling_co_eff = 0.7*0.7; + curr_core_tx_density = 1.25; + curr_sckt_co_eff = 1.1387; + curr_chip_layout_overhead = 1.2;//die measurement results based on Niagara 1 and 2 + curr_macro_layout_overhead = 1.1;//EDA placement and routing tool rule of thumb } - if (tech == 32) { - SENSE_AMP_D = .03e-9; // s - SENSE_AMP_P = 2.16e-15; // J - // For 2013, MPU/ASIC stagger-contacted M1 half-pitch is 32 nm (so this is - // 32 nm - // technology i.e. FEATURESIZE = 0.032). Using the SOI process numbers for - // HP and LSTP. + if (tech == 32) + { + SENSE_AMP_D = .03e-9; // s + SENSE_AMP_P = 2.16e-15; // J + //For 2013, MPU/ASIC stagger-contacted M1 half-pitch is 32 nm (so this is 32 nm + //technology i.e. FEATURESIZE = 0.032). Using the SOI process numbers for + //HP and LSTP. vdd[0] = 0.9; Lphy[0] = 0.013; Lelec[0] = 0.01013; @@ -1041,20 +1041,16 @@ void init_tech_params(double technology, bool is_tag) { c_g_ideal[0] = 5.34e-16; c_fringe[0] = 0.04e-15; c_junc[0] = 1e-15; - I_on_n[0] = 2211.7e-6; + I_on_n[0] = 2211.7e-6; I_on_p[0] = I_on_n[0] / 2; nmos_effective_resistance_multiplier = 1.49; n_to_p_eff_curr_drv_ratio[0] = 2.41; gmp_to_gmn_multiplier[0] = 1.38; - Rnchannelon[0] = nmos_effective_resistance_multiplier * vdd[0] / - I_on_n[0]; // ohm-micron - Rpchannelon[0] = - n_to_p_eff_curr_drv_ratio[0] * Rnchannelon[0]; // ohm-micron - long_channel_leakage_reduction[0] = 1 / 3.706; - // Using MASTAR, @300K (380K does not work in MASTAR), increase Lgate - // until Ion reduces to 95% or Lgate increase by 5% (DG device can only - // increase by 5%), - // whichever comes first + Rnchannelon[0] = nmos_effective_resistance_multiplier * vdd[0] / I_on_n[0];//ohm-micron + Rpchannelon[0] = n_to_p_eff_curr_drv_ratio[0] * Rnchannelon[0];//ohm-micron + long_channel_leakage_reduction[0] = 1/3.706; + //Using MASTAR, @300K (380K does not work in MASTAR), increase Lgate until Ion reduces to 95% or Lgate increase by 5% (DG device can only increase by 5%), + //whichever comes first I_off_n[0][0] = 1.52e-7; I_off_n[0][10] = 1.55e-7; I_off_n[0][20] = 1.59e-7; @@ -1067,7 +1063,7 @@ void init_tech_params(double technology, bool is_tag) { I_off_n[0][90] = 2.73e-6; I_off_n[0][100] = 6.1e-6; - I_g_on_n[0][0] = 6.55e-8; // A/micron + I_g_on_n[0][0] = 6.55e-8;//A/micron I_g_on_n[0][10] = 6.55e-8; I_g_on_n[0][20] = 6.55e-8; I_g_on_n[0][30] = 6.55e-8; @@ -1079,27 +1075,27 @@ void init_tech_params(double technology, bool is_tag) { I_g_on_n[0][90] = 6.55e-8; I_g_on_n[0][100] = 6.55e-8; - // 32 DG - // I_g_on_n[0][0] = 2.71e-9;//A/micron - // I_g_on_n[0][10] = 2.71e-9; - // I_g_on_n[0][20] = 2.71e-9; - // I_g_on_n[0][30] = 2.71e-9; - // I_g_on_n[0][40] = 2.71e-9; - // I_g_on_n[0][50] = 2.71e-9; - // I_g_on_n[0][60] = 2.71e-9; - // I_g_on_n[0][70] = 2.71e-9; - // I_g_on_n[0][80] = 2.71e-9; - // I_g_on_n[0][90] = 2.71e-9; - // I_g_on_n[0][100] = 2.71e-9; - - // LSTP device type +// 32 DG +// I_g_on_n[0][0] = 2.71e-9;//A/micron +// I_g_on_n[0][10] = 2.71e-9; +// I_g_on_n[0][20] = 2.71e-9; +// I_g_on_n[0][30] = 2.71e-9; +// I_g_on_n[0][40] = 2.71e-9; +// I_g_on_n[0][50] = 2.71e-9; +// I_g_on_n[0][60] = 2.71e-9; +// I_g_on_n[0][70] = 2.71e-9; +// I_g_on_n[0][80] = 2.71e-9; +// I_g_on_n[0][90] = 2.71e-9; +// I_g_on_n[0][100] = 2.71e-9; + + //LSTP device type vdd[1] = 1; Lphy[1] = 0.020; Lelec[1] = 0.0173; t_ox[1] = 1.2e-3; v_th[1] = 0.513; c_ox[1] = 2.29e-14; - mobility_eff[1] = 347.46 * (1e-2 * 1e6 * 1e-2 * 1e6); + mobility_eff[1] = 347.46 * (1e-2 * 1e6 * 1e-2 * 1e6); Vdsat[1] = 8.64e-2; c_g_ideal[1] = 4.58e-16; c_fringe[1] = 0.053e-15; @@ -1109,10 +1105,9 @@ void init_tech_params(double technology, bool is_tag) { nmos_effective_resistance_multiplier = 1.99; n_to_p_eff_curr_drv_ratio[1] = 2.23; gmp_to_gmn_multiplier[1] = 0.99; - Rnchannelon[1] = - nmos_effective_resistance_multiplier * vdd[1] / I_on_n[1]; + Rnchannelon[1] = nmos_effective_resistance_multiplier * vdd[1] / I_on_n[1]; Rpchannelon[1] = n_to_p_eff_curr_drv_ratio[1] * Rnchannelon[1]; - long_channel_leakage_reduction[1] = 1 / 1.93; + long_channel_leakage_reduction[1] = 1/1.93; I_off_n[1][0] = 2.06e-11; I_off_n[1][10] = 3.30e-11; I_off_n[1][20] = 5.15e-11; @@ -1125,7 +1120,7 @@ void init_tech_params(double technology, bool is_tag) { I_off_n[1][90] = 5.96e-10; I_off_n[1][100] = 7.44e-10; - I_g_on_n[1][0] = 3.73e-11; // A/micron + I_g_on_n[1][0] = 3.73e-11;//A/micron I_g_on_n[1][10] = 3.73e-11; I_g_on_n[1][20] = 3.73e-11; I_g_on_n[1][30] = 3.73e-11; @@ -1137,14 +1132,15 @@ void init_tech_params(double technology, bool is_tag) { I_g_on_n[1][90] = 3.73e-11; I_g_on_n[1][100] = 3.73e-11; - // LOP device type + + //LOP device type vdd[2] = 0.6; Lphy[2] = 0.016; Lelec[2] = 0.01232; t_ox[2] = 0.9e-3; v_th[2] = 0.24227; c_ox[2] = 2.84e-14; - mobility_eff[2] = 513.52 * (1e-2 * 1e6 * 1e-2 * 1e6); + mobility_eff[2] = 513.52 * (1e-2 * 1e6 * 1e-2 * 1e6); Vdsat[2] = 4.64e-2; c_g_ideal[2] = 4.54e-16; c_fringe[2] = 0.057e-15; @@ -1154,10 +1150,9 @@ void init_tech_params(double technology, bool is_tag) { nmos_effective_resistance_multiplier = 1.73; n_to_p_eff_curr_drv_ratio[2] = 2.28; gmp_to_gmn_multiplier[2] = 1.11; - Rnchannelon[2] = - nmos_effective_resistance_multiplier * vdd[2] / I_on_n[2]; + Rnchannelon[2] = nmos_effective_resistance_multiplier * vdd[2] / I_on_n[2]; Rpchannelon[2] = n_to_p_eff_curr_drv_ratio[2] * Rnchannelon[2]; - long_channel_leakage_reduction[2] = 1 / 1.89; + long_channel_leakage_reduction[2] = 1/1.89; I_off_n[2][0] = 5.94e-8; I_off_n[2][10] = 7.23e-8; I_off_n[2][20] = 8.7e-8; @@ -1170,7 +1165,7 @@ void init_tech_params(double technology, bool is_tag) { I_off_n[2][90] = 2.39e-7; I_off_n[2][100] = 2.63e-7; - I_g_on_n[2][0] = 2.93e-9; // A/micron + I_g_on_n[2][0] = 2.93e-9;//A/micron I_g_on_n[2][10] = 2.93e-9; I_g_on_n[2][20] = 2.93e-9; I_g_on_n[2][30] = 2.93e-9; @@ -1182,12 +1177,12 @@ void init_tech_params(double technology, bool is_tag) { I_g_on_n[2][90] = 2.93e-9; I_g_on_n[2][100] = 2.93e-9; - if (ram_cell_tech_type == lp_dram) { - // LP-DRAM cell access transistor technology parameters + if (ram_cell_tech_type == lp_dram) + { + //LP-DRAM cell access transistor technology parameters curr_vdd_dram_cell = 1.0; Lphy[3] = 0.056; - Lelec[3] = 0.0419; // Assume Lelec is 30% lesser than Lphy for DRAM - // access and wordline transistors. + Lelec[3] = 0.0419;//Assume Lelec is 30% lesser than Lphy for DRAM access and wordline transistors. curr_v_th_dram_access_transistor = 0.44129; width_dram_access_transistor = 0.056; curr_I_on_dram_cell = 36e-6; @@ -1199,12 +1194,12 @@ void init_tech_params(double technology, bool is_tag) { curr_asp_ratio_cell_dram = 1.46; curr_c_dram_cell = 20e-15; - // LP-DRAM wordline transistor parameters + //LP-DRAM wordline transistor parameters curr_vpp = 1.5; t_ox[3] = 2e-3; v_th[3] = 0.44467; c_ox[3] = 1.48e-14; - mobility_eff[3] = 408.12 * (1e-2 * 1e6 * 1e-2 * 1e6); + mobility_eff[3] = 408.12 * (1e-2 * 1e6 * 1e-2 * 1e6); Vdsat[3] = 0.174; c_g_ideal[3] = 7.45e-16; c_fringe[3] = 0.053e-15; @@ -1214,11 +1209,10 @@ void init_tech_params(double technology, bool is_tag) { nmos_effective_resistance_multiplier = 1.65; n_to_p_eff_curr_drv_ratio[3] = 2.05; gmp_to_gmn_multiplier[3] = 0.90; - Rnchannelon[3] = - nmos_effective_resistance_multiplier * curr_vpp / I_on_n[3]; + Rnchannelon[3] = nmos_effective_resistance_multiplier * curr_vpp / I_on_n[3]; Rpchannelon[3] = n_to_p_eff_curr_drv_ratio[3] * Rnchannelon[3]; long_channel_leakage_reduction[3] = 1; - I_off_n[3][0] = 3.57e-11; + I_off_n[3][0] = 3.57e-11; I_off_n[3][10] = 5.51e-11; I_off_n[3][20] = 8.27e-11; I_off_n[3][30] = 1.21e-10; @@ -1229,12 +1223,13 @@ void init_tech_params(double technology, bool is_tag) { I_off_n[3][80] = 5.87e-10; I_off_n[3][90] = 7.29e-10; I_off_n[3][100] = 8.87e-10; - } else if (ram_cell_tech_type == comm_dram) { - // COMM-DRAM cell access transistor technology parameters + } + else if (ram_cell_tech_type == comm_dram) + { + //COMM-DRAM cell access transistor technology parameters curr_vdd_dram_cell = 1.0; Lphy[3] = 0.032; - Lelec[3] = 0.0205; // Assume Lelec is 30% lesser than Lphy for DRAM - // access and wordline transistors. + Lelec[3] = 0.0205;//Assume Lelec is 30% lesser than Lphy for DRAM access and wordline transistors. curr_v_th_dram_access_transistor = 1; width_dram_access_transistor = 0.032; curr_I_on_dram_cell = 20e-6; @@ -1242,16 +1237,16 @@ void init_tech_params(double technology, bool is_tag) { curr_Wmemcella_dram = width_dram_access_transistor; curr_Wmemcellpmos_dram = 0; curr_Wmemcellnmos_dram = 0; - curr_area_cell_dram = 6 * 0.032 * 0.032; + curr_area_cell_dram = 6*0.032*0.032; curr_asp_ratio_cell_dram = 1.5; curr_c_dram_cell = 30e-15; - // COMM-DRAM wordline transistor parameters + //COMM-DRAM wordline transistor parameters curr_vpp = 2.6; t_ox[3] = 4e-3; v_th[3] = 1.0; c_ox[3] = 7.99e-15; - mobility_eff[3] = 380.76 * (1e-2 * 1e6 * 1e-2 * 1e6); + mobility_eff[3] = 380.76 * (1e-2 * 1e6 * 1e-2 * 1e6); Vdsat[3] = 0.129; c_g_ideal[3] = 2.56e-16; c_fringe[3] = 0.053e-15; @@ -1261,11 +1256,10 @@ void init_tech_params(double technology, bool is_tag) { nmos_effective_resistance_multiplier = 1.69; n_to_p_eff_curr_drv_ratio[3] = 1.95; gmp_to_gmn_multiplier[3] = 0.90; - Rnchannelon[3] = - nmos_effective_resistance_multiplier * curr_vpp / I_on_n[3]; + Rnchannelon[3] = nmos_effective_resistance_multiplier * curr_vpp / I_on_n[3]; Rpchannelon[3] = n_to_p_eff_curr_drv_ratio[3] * Rnchannelon[3]; long_channel_leakage_reduction[3] = 1; - I_off_n[3][0] = 3.63e-14; + I_off_n[3][0] = 3.63e-14; I_off_n[3][10] = 7.18e-14; I_off_n[3][20] = 1.36e-13; I_off_n[3][30] = 2.49e-13; @@ -1278,620 +1272,550 @@ void init_tech_params(double technology, bool is_tag) { I_off_n[3][100] = 7.16e-12; } - // SRAM cell properties - curr_Wmemcella_sram = 1.31 * g_ip->F_sz_um; - curr_Wmemcellpmos_sram = 1.23 * g_ip->F_sz_um; - curr_Wmemcellnmos_sram = 2.08 * g_ip->F_sz_um; - curr_area_cell_sram = 146 * g_ip->F_sz_um * g_ip->F_sz_um; - curr_asp_ratio_cell_sram = 1.46; - // CAM cell properties //TODO: data need to be revisited - curr_Wmemcella_cam = 1.31 * g_ip->F_sz_um; - curr_Wmemcellpmos_cam = 1.23 * g_ip->F_sz_um; - curr_Wmemcellnmos_cam = 2.08 * g_ip->F_sz_um; - curr_area_cell_cam = 292 * g_ip->F_sz_um * g_ip->F_sz_um; - curr_asp_ratio_cell_cam = 2.92; - // Empirical undifferetiated core/FU coefficient - curr_logic_scaling_co_eff = 0.7 * 0.7 * 0.7; - curr_core_tx_density = 1.25 / 0.7; - curr_sckt_co_eff = 1.1111; - curr_chip_layout_overhead = - 1.2; // die measurement results based on Niagara 1 and 2 - curr_macro_layout_overhead = - 1.1; // EDA placement and routing tool rule of thumb - } - - if (tech == 22) { - // For 2016, MPU/ASIC stagger-contacted M1 half-pitch is 22 nm (so this is - // 22 nm - // technology i.e. FEATURESIZE = 0.022). Using the DG process numbers for - // HP. - // 22 nm HP - vdd[0] = 0.8; - Lphy[0] = 0.009; // Lphy is the physical gate-length. - Lelec[0] = 0.00468; // Lelec is the electrical gate-length. - t_ox[0] = 0.55e-3; // micron - v_th[0] = 0.1395; // V - c_ox[0] = 3.63e-14; // F/micron2 - mobility_eff[0] = 426.07 * (1e-2 * 1e6 * 1e-2 * 1e6); // micron2 / Vs - Vdsat[0] = 2.33e-2; // V/micron - c_g_ideal[0] = 3.27e-16; // F/micron - c_fringe[0] = 0.06e-15; // F/micron - c_junc[0] = 0; // F/micron2 - I_on_n[0] = 2626.4e-6; // A/micron - I_on_p[0] = I_on_n[0] / - 2; // A/micron //This value for I_on_p is not really used. - nmos_effective_resistance_multiplier = 1.45; - n_to_p_eff_curr_drv_ratio[0] = - 2; // Wpmos/Wnmos = 2 in 2007 MASTAR. Look in - //"Dynamic" tab of Device workspace. - gmp_to_gmn_multiplier[0] = 1.38; // Just using the 32nm SOI value. - Rnchannelon[0] = nmos_effective_resistance_multiplier * vdd[0] / - I_on_n[0]; // ohm-micron - Rpchannelon[0] = - n_to_p_eff_curr_drv_ratio[0] * Rnchannelon[0]; // ohm-micron - long_channel_leakage_reduction[0] = 1 / 3.274; - I_off_n[0][0] = 1.52e-7 / 1.5 * 1.2; // From 22nm, leakage current are - // directly from ITRS report rather - // than MASTAR, since MASTAR has - // serious bugs there. - I_off_n[0][10] = 1.55e-7 / 1.5 * 1.2; - I_off_n[0][20] = 1.59e-7 / 1.5 * 1.2; - I_off_n[0][30] = 1.68e-7 / 1.5 * 1.2; - I_off_n[0][40] = 1.90e-7 / 1.5 * 1.2; - I_off_n[0][50] = 2.69e-7 / 1.5 * 1.2; - I_off_n[0][60] = 5.32e-7 / 1.5 * 1.2; - I_off_n[0][70] = 1.02e-6 / 1.5 * 1.2; - I_off_n[0][80] = 1.62e-6 / 1.5 * 1.2; - I_off_n[0][90] = 2.73e-6 / 1.5 * 1.2; - I_off_n[0][100] = 6.1e-6 / 1.5 * 1.2; - // for 22nm DG HP - I_g_on_n[0][0] = 1.81e-9; // A/micron - I_g_on_n[0][10] = 1.81e-9; - I_g_on_n[0][20] = 1.81e-9; - I_g_on_n[0][30] = 1.81e-9; - I_g_on_n[0][40] = 1.81e-9; - I_g_on_n[0][50] = 1.81e-9; - I_g_on_n[0][60] = 1.81e-9; - I_g_on_n[0][70] = 1.81e-9; - I_g_on_n[0][80] = 1.81e-9; - I_g_on_n[0][90] = 1.81e-9; - I_g_on_n[0][100] = 1.81e-9; - - // 22 nm LSTP DG - vdd[1] = 0.8; - Lphy[1] = 0.014; - Lelec[1] = 0.008; // Lelec is the electrical gate-length. - t_ox[1] = 1.1e-3; // micron - v_th[1] = 0.40126; // V - c_ox[1] = 2.30e-14; // F/micron2 - mobility_eff[1] = 738.09 * (1e-2 * 1e6 * 1e-2 * 1e6); // micron2 / Vs - Vdsat[1] = 6.64e-2; // V/micron - c_g_ideal[1] = 3.22e-16; // F/micron - c_fringe[1] = 0.08e-15; - c_junc[1] = 0; // F/micron2 - I_on_n[1] = 727.6e-6; // A/micron - I_on_p[1] = I_on_n[1] / 2; - nmos_effective_resistance_multiplier = 1.99; - n_to_p_eff_curr_drv_ratio[1] = 2; - gmp_to_gmn_multiplier[1] = 0.99; - Rnchannelon[1] = nmos_effective_resistance_multiplier * vdd[1] / - I_on_n[1]; // ohm-micron - Rpchannelon[1] = - n_to_p_eff_curr_drv_ratio[1] * Rnchannelon[1]; // ohm-micron - long_channel_leakage_reduction[1] = 1 / 1.89; - I_off_n[1][0] = 2.43e-11; - I_off_n[1][10] = 4.85e-11; - I_off_n[1][20] = 9.68e-11; - I_off_n[1][30] = 1.94e-10; - I_off_n[1][40] = 3.87e-10; - I_off_n[1][50] = 7.73e-10; - I_off_n[1][60] = 3.55e-10; - I_off_n[1][70] = 3.09e-9; - I_off_n[1][80] = 6.19e-9; - I_off_n[1][90] = 1.24e-8; - I_off_n[1][100] = 2.48e-8; - - I_g_on_n[1][0] = 4.51e-10; // A/micron - I_g_on_n[1][10] = 4.51e-10; - I_g_on_n[1][20] = 4.51e-10; - I_g_on_n[1][30] = 4.51e-10; - I_g_on_n[1][40] = 4.51e-10; - I_g_on_n[1][50] = 4.51e-10; - I_g_on_n[1][60] = 4.51e-10; - I_g_on_n[1][70] = 4.51e-10; - I_g_on_n[1][80] = 4.51e-10; - I_g_on_n[1][90] = 4.51e-10; - I_g_on_n[1][100] = 4.51e-10; - - // 22 nm LOP - vdd[2] = 0.6; - Lphy[2] = 0.011; - Lelec[2] = 0.00604; // Lelec is the electrical gate-length. - t_ox[2] = 0.8e-3; // micron - v_th[2] = 0.2315; // V - c_ox[2] = 2.87e-14; // F/micron2 - mobility_eff[2] = 698.37 * (1e-2 * 1e6 * 1e-2 * 1e6); // micron2 / Vs - Vdsat[2] = 1.81e-2; // V/micron - c_g_ideal[2] = 3.16e-16; // F/micron - c_fringe[2] = 0.08e-15; - c_junc[2] = - 0; // F/micron2 This is Cj0 not Cjunc in MASTAR results->Dynamic Tab - I_on_n[2] = 916.1e-6; // A/micron - I_on_p[2] = I_on_n[2] / 2; - nmos_effective_resistance_multiplier = 1.73; - n_to_p_eff_curr_drv_ratio[2] = 2; - gmp_to_gmn_multiplier[2] = 1.11; - Rnchannelon[2] = nmos_effective_resistance_multiplier * vdd[2] / - I_on_n[2]; // ohm-micron - Rpchannelon[2] = - n_to_p_eff_curr_drv_ratio[2] * Rnchannelon[2]; // ohm-micron - long_channel_leakage_reduction[2] = 1 / 2.38; - - I_off_n[2][0] = 1.31e-8; - I_off_n[2][10] = 2.60e-8; - I_off_n[2][20] = 5.14e-8; - I_off_n[2][30] = 1.02e-7; - I_off_n[2][40] = 2.02e-7; - I_off_n[2][50] = 3.99e-7; - I_off_n[2][60] = 7.91e-7; - I_off_n[2][70] = 1.09e-6; - I_off_n[2][80] = 2.09e-6; - I_off_n[2][90] = 4.04e-6; - I_off_n[2][100] = 4.48e-6; - - I_g_on_n[2][0] = 2.74e-9; // A/micron - I_g_on_n[2][10] = 2.74e-9; - I_g_on_n[2][20] = 2.74e-9; - I_g_on_n[2][30] = 2.74e-9; - I_g_on_n[2][40] = 2.74e-9; - I_g_on_n[2][50] = 2.74e-9; - I_g_on_n[2][60] = 2.74e-9; - I_g_on_n[2][70] = 2.74e-9; - I_g_on_n[2][80] = 2.74e-9; - I_g_on_n[2][90] = 2.74e-9; - I_g_on_n[2][100] = 2.74e-9; - - if (ram_cell_tech_type == 3) { - } else if (ram_cell_tech_type == 4) { - // 22 nm commodity DRAM cell access transistor technology parameters. - // parameters - curr_vdd_dram_cell = 0.9; // 0.45;//This value has reduced greatly in - // 2007 ITRS for all technology nodes. In - // 2005 ITRS, the value was about twice the value in 2007 ITRS - Lphy[3] = 0.022; // micron - Lelec[3] = 0.0181; // micron. - curr_v_th_dram_access_transistor = 1; // V - width_dram_access_transistor = 0.022; // micron - curr_I_on_dram_cell = - 20e-6; // This is a typical value that I have always - // kept constant. In reality this could perhaps be lower - curr_I_off_dram_cell_worst_case_length_temp = 1e-15; // A - curr_Wmemcella_dram = width_dram_access_transistor; - curr_Wmemcellpmos_dram = 0; - curr_Wmemcellnmos_dram = 0; - curr_area_cell_dram = 6 * 0.022 * 0.022; // micron2. - curr_asp_ratio_cell_dram = 0.667; - curr_c_dram_cell = 30e-15; // This is a typical value that I have - // alwaus - // kept constant. - - // 22 nm commodity DRAM wordline transistor parameters obtained using - // MASTAR. - curr_vpp = 2.3; // vpp. V - t_ox[3] = 3.5e-3; // micron - v_th[3] = 1.0; // V - c_ox[3] = 9.06e-15; // F/micron2 - mobility_eff[3] = 367.29 * (1e-2 * 1e6 * 1e-2 * 1e6); // micron2 / Vs - Vdsat[3] = 0.0972; // V/micron - c_g_ideal[3] = 1.99e-16; // F/micron - c_fringe[3] = 0.053e-15; // F/micron - c_junc[3] = 1e-15; // F/micron2 - I_on_n[3] = 910.5e-6; // A/micron - I_on_p[3] = I_on_n[3] / 2; // This value for I_on_p is not really used. - nmos_effective_resistance_multiplier = - 1.69; // Using the value from 32nm. - // - n_to_p_eff_curr_drv_ratio[3] = 1.95; // Using the value from 32nm - gmp_to_gmn_multiplier[3] = 0.90; - Rnchannelon[3] = nmos_effective_resistance_multiplier * curr_vpp / - I_on_n[3]; // ohm-micron - Rpchannelon[3] = - n_to_p_eff_curr_drv_ratio[3] * Rnchannelon[3]; // ohm-micron - long_channel_leakage_reduction[3] = 1; - I_off_n[3][0] = 1.1e-13; // A/micron - I_off_n[3][10] = 2.11e-13; - I_off_n[3][20] = 3.88e-13; - I_off_n[3][30] = 6.9e-13; - I_off_n[3][40] = 1.19e-12; - I_off_n[3][50] = 1.98e-12; - I_off_n[3][60] = 3.22e-12; - I_off_n[3][70] = 5.09e-12; - I_off_n[3][80] = 7.85e-12; - I_off_n[3][90] = 1.18e-11; - I_off_n[3][100] = 1.72e-11; - - } else { - // some error handler - } - - // SRAM cell properties - curr_Wmemcella_sram = 1.31 * g_ip->F_sz_um; - curr_Wmemcellpmos_sram = 1.23 * g_ip->F_sz_um; - curr_Wmemcellnmos_sram = 2.08 * g_ip->F_sz_um; - curr_area_cell_sram = 146 * g_ip->F_sz_um * g_ip->F_sz_um; - curr_asp_ratio_cell_sram = 1.46; - // CAM cell properties //TODO: data need to be revisited - curr_Wmemcella_cam = 1.31 * g_ip->F_sz_um; - curr_Wmemcellpmos_cam = 1.23 * g_ip->F_sz_um; - curr_Wmemcellnmos_cam = 2.08 * g_ip->F_sz_um; - curr_area_cell_cam = 292 * g_ip->F_sz_um * g_ip->F_sz_um; - curr_asp_ratio_cell_cam = 2.92; - // Empirical undifferetiated core/FU coefficient - curr_logic_scaling_co_eff = 0.7 * 0.7 * 0.7 * 0.7; - curr_core_tx_density = 1.25 / 0.7 / 0.7; - curr_sckt_co_eff = 1.1296; - curr_chip_layout_overhead = - 1.2; // die measurement results based on Niagara 1 and 2 - curr_macro_layout_overhead = - 1.1; // EDA placement and routing tool rule of thumb - } - - if (tech == 16) { - // For 2019, MPU/ASIC stagger-contacted M1 half-pitch is 16 nm (so this is - // 16 nm - // technology i.e. FEATURESIZE = 0.016). Using the DG process numbers for - // HP. - // 16 nm HP - vdd[0] = 0.7; - Lphy[0] = 0.006; // Lphy is the physical gate-length. - Lelec[0] = 0.00315; // Lelec is the electrical gate-length. - t_ox[0] = 0.5e-3; // micron - v_th[0] = 0.1489; // V - c_ox[0] = 3.83e-14; // F/micron2 Cox_elec in MASTAR - mobility_eff[0] = 476.15 * (1e-2 * 1e6 * 1e-2 * 1e6); // micron2 / Vs - Vdsat[0] = 1.42e-2; // V/micron calculated in spreadsheet - c_g_ideal[0] = 2.30e-16; // F/micron - c_fringe[0] = 0.06e-15; // F/micron MASTAR inputdynamic/3 - c_junc[0] = 0; // F/micron2 MASTAR result dynamic - I_on_n[0] = 2768.4e-6; // A/micron - I_on_p[0] = I_on_n[0] / - 2; // A/micron //This value for I_on_p is not really used. - nmos_effective_resistance_multiplier = - 1.48; // nmos_effective_resistance_multiplier is the ratio of Ieff - // to Idsat where Ieff is the effective NMOS current and Idsat - // is the saturation current. - n_to_p_eff_curr_drv_ratio[0] = - 2; // Wpmos/Wnmos = 2 in 2007 MASTAR. Look in - //"Dynamic" tab of Device workspace. - gmp_to_gmn_multiplier[0] = 1.38; // Just using the 32nm SOI value. - Rnchannelon[0] = nmos_effective_resistance_multiplier * vdd[0] / - I_on_n[0]; // ohm-micron - Rpchannelon[0] = - n_to_p_eff_curr_drv_ratio[0] * Rnchannelon[0]; // ohm-micron - long_channel_leakage_reduction[0] = 1 / 2.655; - I_off_n[0][0] = 1.52e-7 / 1.5 * 1.2 * 1.07; - I_off_n[0][10] = 1.55e-7 / 1.5 * 1.2 * 1.07; - I_off_n[0][20] = 1.59e-7 / 1.5 * 1.2 * 1.07; - I_off_n[0][30] = 1.68e-7 / 1.5 * 1.2 * 1.07; - I_off_n[0][40] = 1.90e-7 / 1.5 * 1.2 * 1.07; - I_off_n[0][50] = 2.69e-7 / 1.5 * 1.2 * 1.07; - I_off_n[0][60] = 5.32e-7 / 1.5 * 1.2 * 1.07; - I_off_n[0][70] = 1.02e-6 / 1.5 * 1.2 * 1.07; - I_off_n[0][80] = 1.62e-6 / 1.5 * 1.2 * 1.07; - I_off_n[0][90] = 2.73e-6 / 1.5 * 1.2 * 1.07; - I_off_n[0][100] = 6.1e-6 / 1.5 * 1.2 * 1.07; - // for 16nm DG HP - I_g_on_n[0][0] = 1.07e-9; // A/micron - I_g_on_n[0][10] = 1.07e-9; - I_g_on_n[0][20] = 1.07e-9; - I_g_on_n[0][30] = 1.07e-9; - I_g_on_n[0][40] = 1.07e-9; - I_g_on_n[0][50] = 1.07e-9; - I_g_on_n[0][60] = 1.07e-9; - I_g_on_n[0][70] = 1.07e-9; - I_g_on_n[0][80] = 1.07e-9; - I_g_on_n[0][90] = 1.07e-9; - I_g_on_n[0][100] = 1.07e-9; - - // //16 nm LSTP DG - // vdd[1] = 0.8; - // Lphy[1] = 0.014; - // Lelec[1] = 0.008;//Lelec is the electrical gate-length. - // t_ox[1] = 1.1e-3;//micron - // v_th[1] = 0.40126;//V - // c_ox[1] = 2.30e-14;//F/micron2 - // mobility_eff[1] = 738.09 * (1e-2 * 1e6 * 1e-2 * 1e6); //micron2 - // / Vs - // Vdsat[1] = 6.64e-2; //V/micron - // c_g_ideal[1] = 3.22e-16;//F/micron - // c_fringe[1] = 0.008e-15; - // c_junc[1] = 0;//F/micron2 - // I_on_n[1] = 727.6e-6;//A/micron - // I_on_p[1] = I_on_n[1] / 2; - // nmos_effective_resistance_multiplier = 1.99; - // n_to_p_eff_curr_drv_ratio[1] = 2; - // gmp_to_gmn_multiplier[1] = 0.99; - // Rnchannelon[1] = nmos_effective_resistance_multiplier * vdd[1] / - // I_on_n[1];//ohm-micron - // Rpchannelon[1] = n_to_p_eff_curr_drv_ratio[1] * - // Rnchannelon[1];//ohm-micron - // I_off_n[1][0] = 2.43e-11; - // I_off_n[1][10] = 4.85e-11; - // I_off_n[1][20] = 9.68e-11; - // I_off_n[1][30] = 1.94e-10; - // I_off_n[1][40] = 3.87e-10; - // I_off_n[1][50] = 7.73e-10; - // I_off_n[1][60] = 3.55e-10; - // I_off_n[1][70] = 3.09e-9; - // I_off_n[1][80] = 6.19e-9; - // I_off_n[1][90] = 1.24e-8; - // I_off_n[1][100]= 2.48e-8; - // - // // for 22nm LSTP HP - // I_g_on_n[1][0] = 4.51e-10;//A/micron - // I_g_on_n[1][10] = 4.51e-10; - // I_g_on_n[1][20] = 4.51e-10; - // I_g_on_n[1][30] = 4.51e-10; - // I_g_on_n[1][40] = 4.51e-10; - // I_g_on_n[1][50] = 4.51e-10; - // I_g_on_n[1][60] = 4.51e-10; - // I_g_on_n[1][70] = 4.51e-10; - // I_g_on_n[1][80] = 4.51e-10; - // I_g_on_n[1][90] = 4.51e-10; - // I_g_on_n[1][100] = 4.51e-10; - - if (ram_cell_tech_type == 3) { - } else if (ram_cell_tech_type == 4) { - // 22 nm commodity DRAM cell access transistor technology parameters. - // parameters - curr_vdd_dram_cell = 0.9; // 0.45;//This value has reduced greatly in - // 2007 ITRS for all technology nodes. In - // 2005 ITRS, the value was about twice the value in 2007 ITRS - Lphy[3] = 0.022; // micron - Lelec[3] = 0.0181; // micron. - curr_v_th_dram_access_transistor = 1; // V - width_dram_access_transistor = 0.022; // micron - curr_I_on_dram_cell = - 20e-6; // This is a typical value that I have always - // kept constant. In reality this could perhaps be lower - curr_I_off_dram_cell_worst_case_length_temp = 1e-15; // A - curr_Wmemcella_dram = width_dram_access_transistor; - curr_Wmemcellpmos_dram = 0; - curr_Wmemcellnmos_dram = 0; - curr_area_cell_dram = 6 * 0.022 * 0.022; // micron2. - curr_asp_ratio_cell_dram = 0.667; - curr_c_dram_cell = 30e-15; // This is a typical value that I have - // alwaus - // kept constant. - - // 22 nm commodity DRAM wordline transistor parameters obtained using - // MASTAR. - curr_vpp = 2.3; // vpp. V - t_ox[3] = 3.5e-3; // micron - v_th[3] = 1.0; // V - c_ox[3] = 9.06e-15; // F/micron2 - mobility_eff[3] = 367.29 * (1e-2 * 1e6 * 1e-2 * 1e6); // micron2 / Vs - Vdsat[3] = 0.0972; // V/micron - c_g_ideal[3] = 1.99e-16; // F/micron - c_fringe[3] = 0.053e-15; // F/micron - c_junc[3] = 1e-15; // F/micron2 - I_on_n[3] = 910.5e-6; // A/micron - I_on_p[3] = I_on_n[3] / 2; // This value for I_on_p is not really used. - nmos_effective_resistance_multiplier = - 1.69; // Using the value from 32nm. - // - n_to_p_eff_curr_drv_ratio[3] = 1.95; // Using the value from 32nm - gmp_to_gmn_multiplier[3] = 0.90; - Rnchannelon[3] = nmos_effective_resistance_multiplier * curr_vpp / - I_on_n[3]; // ohm-micron - Rpchannelon[3] = - n_to_p_eff_curr_drv_ratio[3] * Rnchannelon[3]; // ohm-micron - long_channel_leakage_reduction[3] = 1; - I_off_n[3][0] = 1.1e-13; // A/micron - I_off_n[3][10] = 2.11e-13; - I_off_n[3][20] = 3.88e-13; - I_off_n[3][30] = 6.9e-13; - I_off_n[3][40] = 1.19e-12; - I_off_n[3][50] = 1.98e-12; - I_off_n[3][60] = 3.22e-12; - I_off_n[3][70] = 5.09e-12; - I_off_n[3][80] = 7.85e-12; - I_off_n[3][90] = 1.18e-11; - I_off_n[3][100] = 1.72e-11; - - } else { - // some error handler - } - - // SRAM cell properties - curr_Wmemcella_sram = 1.31 * g_ip->F_sz_um; + //SRAM cell properties + curr_Wmemcella_sram = 1.31 * g_ip->F_sz_um; curr_Wmemcellpmos_sram = 1.23 * g_ip->F_sz_um; curr_Wmemcellnmos_sram = 2.08 * g_ip->F_sz_um; - curr_area_cell_sram = 146 * g_ip->F_sz_um * g_ip->F_sz_um; + curr_area_cell_sram = 146 * g_ip->F_sz_um * g_ip->F_sz_um; curr_asp_ratio_cell_sram = 1.46; - // CAM cell properties //TODO: data need to be revisited + //CAM cell properties //TODO: data need to be revisited curr_Wmemcella_cam = 1.31 * g_ip->F_sz_um; curr_Wmemcellpmos_cam = 1.23 * g_ip->F_sz_um; curr_Wmemcellnmos_cam = 2.08 * g_ip->F_sz_um; curr_area_cell_cam = 292 * g_ip->F_sz_um * g_ip->F_sz_um; curr_asp_ratio_cell_cam = 2.92; - // Empirical undifferetiated core/FU coefficient - curr_logic_scaling_co_eff = 0.7 * 0.7 * 0.7 * 0.7 * 0.7; - curr_core_tx_density = 1.25 / 0.7 / 0.7 / 0.7; - curr_sckt_co_eff = 1.1296; - curr_chip_layout_overhead = - 1.2; // die measurement results based on Niagara 1 and 2 - curr_macro_layout_overhead = - 1.1; // EDA placement and routing tool rule of thumb + //Empirical undifferetiated core/FU coefficient + curr_logic_scaling_co_eff = 0.7*0.7*0.7; + curr_core_tx_density = 1.25/0.7; + curr_sckt_co_eff = 1.1111; + curr_chip_layout_overhead = 1.2;//die measurement results based on Niagara 1 and 2 + curr_macro_layout_overhead = 1.1;//EDA placement and routing tool rule of thumb } - g_tp.peri_global.Vdd += curr_alpha * vdd[peri_global_tech_type]; - g_tp.peri_global.t_ox += curr_alpha * t_ox[peri_global_tech_type]; - g_tp.peri_global.Vth += curr_alpha * v_th[peri_global_tech_type]; - g_tp.peri_global.C_ox += curr_alpha * c_ox[peri_global_tech_type]; + if(tech == 22){ + //For 2016, MPU/ASIC stagger-contacted M1 half-pitch is 22 nm (so this is 22 nm + //technology i.e. FEATURESIZE = 0.022). Using the DG process numbers for HP. + //22 nm HP + vdd[0] = 0.8; + Lphy[0] = 0.009;//Lphy is the physical gate-length. + Lelec[0] = 0.00468;//Lelec is the electrical gate-length. + t_ox[0] = 0.55e-3;//micron + v_th[0] = 0.1395;//V + c_ox[0] = 3.63e-14;//F/micron2 + mobility_eff[0] = 426.07 * (1e-2 * 1e6 * 1e-2 * 1e6); //micron2 / Vs + Vdsat[0] = 2.33e-2; //V/micron + c_g_ideal[0] = 3.27e-16;//F/micron + c_fringe[0] = 0.06e-15;//F/micron + c_junc[0] = 0;//F/micron2 + I_on_n[0] = 2626.4e-6;//A/micron + I_on_p[0] = I_on_n[0] / 2;//A/micron //This value for I_on_p is not really used. + nmos_effective_resistance_multiplier = 1.45; + n_to_p_eff_curr_drv_ratio[0] = 2; //Wpmos/Wnmos = 2 in 2007 MASTAR. Look in + //"Dynamic" tab of Device workspace. + gmp_to_gmn_multiplier[0] = 1.38; //Just using the 32nm SOI value. + Rnchannelon[0] = nmos_effective_resistance_multiplier * vdd[0] / I_on_n[0];//ohm-micron + Rpchannelon[0] = n_to_p_eff_curr_drv_ratio[0] * Rnchannelon[0];//ohm-micron + long_channel_leakage_reduction[0] = 1/3.274; + I_off_n[0][0] = 1.52e-7/1.5*1.2;//From 22nm, leakage current are directly from ITRS report rather than MASTAR, since MASTAR has serious bugs there. + I_off_n[0][10] = 1.55e-7/1.5*1.2; + I_off_n[0][20] = 1.59e-7/1.5*1.2; + I_off_n[0][30] = 1.68e-7/1.5*1.2; + I_off_n[0][40] = 1.90e-7/1.5*1.2; + I_off_n[0][50] = 2.69e-7/1.5*1.2; + I_off_n[0][60] = 5.32e-7/1.5*1.2; + I_off_n[0][70] = 1.02e-6/1.5*1.2; + I_off_n[0][80] = 1.62e-6/1.5*1.2; + I_off_n[0][90] = 2.73e-6/1.5*1.2; + I_off_n[0][100] = 6.1e-6/1.5*1.2; + //for 22nm DG HP + I_g_on_n[0][0] = 1.81e-9;//A/micron + I_g_on_n[0][10] = 1.81e-9; + I_g_on_n[0][20] = 1.81e-9; + I_g_on_n[0][30] = 1.81e-9; + I_g_on_n[0][40] = 1.81e-9; + I_g_on_n[0][50] = 1.81e-9; + I_g_on_n[0][60] = 1.81e-9; + I_g_on_n[0][70] = 1.81e-9; + I_g_on_n[0][80] = 1.81e-9; + I_g_on_n[0][90] = 1.81e-9; + I_g_on_n[0][100] = 1.81e-9; + + //22 nm LSTP DG + vdd[1] = 0.8; + Lphy[1] = 0.014; + Lelec[1] = 0.008;//Lelec is the electrical gate-length. + t_ox[1] = 1.1e-3;//micron + v_th[1] = 0.40126;//V + c_ox[1] = 2.30e-14;//F/micron2 + mobility_eff[1] = 738.09 * (1e-2 * 1e6 * 1e-2 * 1e6); //micron2 / Vs + Vdsat[1] = 6.64e-2; //V/micron + c_g_ideal[1] = 3.22e-16;//F/micron + c_fringe[1] = 0.08e-15; + c_junc[1] = 0;//F/micron2 + I_on_n[1] = 727.6e-6;//A/micron + I_on_p[1] = I_on_n[1] / 2; + nmos_effective_resistance_multiplier = 1.99; + n_to_p_eff_curr_drv_ratio[1] = 2; + gmp_to_gmn_multiplier[1] = 0.99; + Rnchannelon[1] = nmos_effective_resistance_multiplier * vdd[1] / I_on_n[1];//ohm-micron + Rpchannelon[1] = n_to_p_eff_curr_drv_ratio[1] * Rnchannelon[1];//ohm-micron + long_channel_leakage_reduction[1] = 1/1.89; + I_off_n[1][0] = 2.43e-11; + I_off_n[1][10] = 4.85e-11; + I_off_n[1][20] = 9.68e-11; + I_off_n[1][30] = 1.94e-10; + I_off_n[1][40] = 3.87e-10; + I_off_n[1][50] = 7.73e-10; + I_off_n[1][60] = 3.55e-10; + I_off_n[1][70] = 3.09e-9; + I_off_n[1][80] = 6.19e-9; + I_off_n[1][90] = 1.24e-8; + I_off_n[1][100]= 2.48e-8; + + I_g_on_n[1][0] = 4.51e-10;//A/micron + I_g_on_n[1][10] = 4.51e-10; + I_g_on_n[1][20] = 4.51e-10; + I_g_on_n[1][30] = 4.51e-10; + I_g_on_n[1][40] = 4.51e-10; + I_g_on_n[1][50] = 4.51e-10; + I_g_on_n[1][60] = 4.51e-10; + I_g_on_n[1][70] = 4.51e-10; + I_g_on_n[1][80] = 4.51e-10; + I_g_on_n[1][90] = 4.51e-10; + I_g_on_n[1][100] = 4.51e-10; + + //22 nm LOP + vdd[2] = 0.6; + Lphy[2] = 0.011; + Lelec[2] = 0.00604;//Lelec is the electrical gate-length. + t_ox[2] = 0.8e-3;//micron + v_th[2] = 0.2315;//V + c_ox[2] = 2.87e-14;//F/micron2 + mobility_eff[2] = 698.37 * (1e-2 * 1e6 * 1e-2 * 1e6); //micron2 / Vs + Vdsat[2] = 1.81e-2; //V/micron + c_g_ideal[2] = 3.16e-16;//F/micron + c_fringe[2] = 0.08e-15; + c_junc[2] = 0;//F/micron2 This is Cj0 not Cjunc in MASTAR results->Dynamic Tab + I_on_n[2] = 916.1e-6;//A/micron + I_on_p[2] = I_on_n[2] / 2; + nmos_effective_resistance_multiplier = 1.73; + n_to_p_eff_curr_drv_ratio[2] = 2; + gmp_to_gmn_multiplier[2] = 1.11; + Rnchannelon[2] = nmos_effective_resistance_multiplier * vdd[2] / I_on_n[2];//ohm-micron + Rpchannelon[2] = n_to_p_eff_curr_drv_ratio[2] * Rnchannelon[2];//ohm-micron + long_channel_leakage_reduction[2] = 1/2.38; + + I_off_n[2][0] = 1.31e-8; + I_off_n[2][10] = 2.60e-8; + I_off_n[2][20] = 5.14e-8; + I_off_n[2][30] = 1.02e-7; + I_off_n[2][40] = 2.02e-7; + I_off_n[2][50] = 3.99e-7; + I_off_n[2][60] = 7.91e-7; + I_off_n[2][70] = 1.09e-6; + I_off_n[2][80] = 2.09e-6; + I_off_n[2][90] = 4.04e-6; + I_off_n[2][100]= 4.48e-6; + + I_g_on_n[2][0] = 2.74e-9;//A/micron + I_g_on_n[2][10] = 2.74e-9; + I_g_on_n[2][20] = 2.74e-9; + I_g_on_n[2][30] = 2.74e-9; + I_g_on_n[2][40] = 2.74e-9; + I_g_on_n[2][50] = 2.74e-9; + I_g_on_n[2][60] = 2.74e-9; + I_g_on_n[2][70] = 2.74e-9; + I_g_on_n[2][80] = 2.74e-9; + I_g_on_n[2][90] = 2.74e-9; + I_g_on_n[2][100] = 2.74e-9; + + + + if (ram_cell_tech_type == 3) + {} + else if (ram_cell_tech_type == 4) + { + //22 nm commodity DRAM cell access transistor technology parameters. + //parameters + curr_vdd_dram_cell = 0.9;//0.45;//This value has reduced greatly in 2007 ITRS for all technology nodes. In + //2005 ITRS, the value was about twice the value in 2007 ITRS + Lphy[3] = 0.022;//micron + Lelec[3] = 0.0181;//micron. + curr_v_th_dram_access_transistor = 1;//V + width_dram_access_transistor = 0.022;//micron + curr_I_on_dram_cell = 20e-6; //This is a typical value that I have always + //kept constant. In reality this could perhaps be lower + curr_I_off_dram_cell_worst_case_length_temp = 1e-15;//A + curr_Wmemcella_dram = width_dram_access_transistor; + curr_Wmemcellpmos_dram = 0; + curr_Wmemcellnmos_dram = 0; + curr_area_cell_dram = 6*0.022*0.022;//micron2. + curr_asp_ratio_cell_dram = 0.667; + curr_c_dram_cell = 30e-15;//This is a typical value that I have alwaus + //kept constant. + + //22 nm commodity DRAM wordline transistor parameters obtained using MASTAR. + curr_vpp = 2.3;//vpp. V + t_ox[3] = 3.5e-3;//micron + v_th[3] = 1.0;//V + c_ox[3] = 9.06e-15;//F/micron2 + mobility_eff[3] = 367.29 * (1e-2 * 1e6 * 1e-2 * 1e6);//micron2 / Vs + Vdsat[3] = 0.0972; //V/micron + c_g_ideal[3] = 1.99e-16;//F/micron + c_fringe[3] = 0.053e-15;//F/micron + c_junc[3] = 1e-15;//F/micron2 + I_on_n[3] = 910.5e-6;//A/micron + I_on_p[3] = I_on_n[3] / 2;//This value for I_on_p is not really used. + nmos_effective_resistance_multiplier = 1.69;//Using the value from 32nm. + // + n_to_p_eff_curr_drv_ratio[3] = 1.95;//Using the value from 32nm + gmp_to_gmn_multiplier[3] = 0.90; + Rnchannelon[3] = nmos_effective_resistance_multiplier * curr_vpp / I_on_n[3];//ohm-micron + Rpchannelon[3] = n_to_p_eff_curr_drv_ratio[3] * Rnchannelon[3];//ohm-micron + long_channel_leakage_reduction[3] = 1; + I_off_n[3][0] = 1.1e-13; //A/micron + I_off_n[3][10] = 2.11e-13; + I_off_n[3][20] = 3.88e-13; + I_off_n[3][30] = 6.9e-13; + I_off_n[3][40] = 1.19e-12; + I_off_n[3][50] = 1.98e-12; + I_off_n[3][60] = 3.22e-12; + I_off_n[3][70] = 5.09e-12; + I_off_n[3][80] = 7.85e-12; + I_off_n[3][90] = 1.18e-11; + I_off_n[3][100] = 1.72e-11; + + } + else + { + //some error handler + } + + //SRAM cell properties + curr_Wmemcella_sram = 1.31 * g_ip->F_sz_um; + curr_Wmemcellpmos_sram = 1.23 * g_ip->F_sz_um; + curr_Wmemcellnmos_sram = 2.08 * g_ip->F_sz_um; + curr_area_cell_sram = 146 * g_ip->F_sz_um * g_ip->F_sz_um; + curr_asp_ratio_cell_sram = 1.46; + //CAM cell properties //TODO: data need to be revisited + curr_Wmemcella_cam = 1.31 * g_ip->F_sz_um; + curr_Wmemcellpmos_cam = 1.23 * g_ip->F_sz_um; + curr_Wmemcellnmos_cam = 2.08 * g_ip->F_sz_um; + curr_area_cell_cam = 292 * g_ip->F_sz_um * g_ip->F_sz_um; + curr_asp_ratio_cell_cam = 2.92; + //Empirical undifferetiated core/FU coefficient + curr_logic_scaling_co_eff = 0.7*0.7*0.7*0.7; + curr_core_tx_density = 1.25/0.7/0.7; + curr_sckt_co_eff = 1.1296; + curr_chip_layout_overhead = 1.2;//die measurement results based on Niagara 1 and 2 + curr_macro_layout_overhead = 1.1;//EDA placement and routing tool rule of thumb + } + + if(tech == 16){ + //For 2019, MPU/ASIC stagger-contacted M1 half-pitch is 16 nm (so this is 16 nm + //technology i.e. FEATURESIZE = 0.016). Using the DG process numbers for HP. + //16 nm HP + vdd[0] = 0.7; + Lphy[0] = 0.006;//Lphy is the physical gate-length. + Lelec[0] = 0.00315;//Lelec is the electrical gate-length. + t_ox[0] = 0.5e-3;//micron + v_th[0] = 0.1489;//V + c_ox[0] = 3.83e-14;//F/micron2 Cox_elec in MASTAR + mobility_eff[0] = 476.15 * (1e-2 * 1e6 * 1e-2 * 1e6); //micron2 / Vs + Vdsat[0] = 1.42e-2; //V/micron calculated in spreadsheet + c_g_ideal[0] = 2.30e-16;//F/micron + c_fringe[0] = 0.06e-15;//F/micron MASTAR inputdynamic/3 + c_junc[0] = 0;//F/micron2 MASTAR result dynamic + I_on_n[0] = 2768.4e-6;//A/micron + I_on_p[0] = I_on_n[0] / 2;//A/micron //This value for I_on_p is not really used. + nmos_effective_resistance_multiplier = 1.48;//nmos_effective_resistance_multiplier is the ratio of Ieff to Idsat where Ieff is the effective NMOS current and Idsat is the saturation current. + n_to_p_eff_curr_drv_ratio[0] = 2; //Wpmos/Wnmos = 2 in 2007 MASTAR. Look in + //"Dynamic" tab of Device workspace. + gmp_to_gmn_multiplier[0] = 1.38; //Just using the 32nm SOI value. + Rnchannelon[0] = nmos_effective_resistance_multiplier * vdd[0] / I_on_n[0];//ohm-micron + Rpchannelon[0] = n_to_p_eff_curr_drv_ratio[0] * Rnchannelon[0];//ohm-micron + long_channel_leakage_reduction[0] = 1/2.655; + I_off_n[0][0] = 1.52e-7/1.5*1.2*1.07; + I_off_n[0][10] = 1.55e-7/1.5*1.2*1.07; + I_off_n[0][20] = 1.59e-7/1.5*1.2*1.07; + I_off_n[0][30] = 1.68e-7/1.5*1.2*1.07; + I_off_n[0][40] = 1.90e-7/1.5*1.2*1.07; + I_off_n[0][50] = 2.69e-7/1.5*1.2*1.07; + I_off_n[0][60] = 5.32e-7/1.5*1.2*1.07; + I_off_n[0][70] = 1.02e-6/1.5*1.2*1.07; + I_off_n[0][80] = 1.62e-6/1.5*1.2*1.07; + I_off_n[0][90] = 2.73e-6/1.5*1.2*1.07; + I_off_n[0][100] = 6.1e-6/1.5*1.2*1.07; + //for 16nm DG HP + I_g_on_n[0][0] = 1.07e-9;//A/micron + I_g_on_n[0][10] = 1.07e-9; + I_g_on_n[0][20] = 1.07e-9; + I_g_on_n[0][30] = 1.07e-9; + I_g_on_n[0][40] = 1.07e-9; + I_g_on_n[0][50] = 1.07e-9; + I_g_on_n[0][60] = 1.07e-9; + I_g_on_n[0][70] = 1.07e-9; + I_g_on_n[0][80] = 1.07e-9; + I_g_on_n[0][90] = 1.07e-9; + I_g_on_n[0][100] = 1.07e-9; + +// //16 nm LSTP DG +// vdd[1] = 0.8; +// Lphy[1] = 0.014; +// Lelec[1] = 0.008;//Lelec is the electrical gate-length. +// t_ox[1] = 1.1e-3;//micron +// v_th[1] = 0.40126;//V +// c_ox[1] = 2.30e-14;//F/micron2 +// mobility_eff[1] = 738.09 * (1e-2 * 1e6 * 1e-2 * 1e6); //micron2 / Vs +// Vdsat[1] = 6.64e-2; //V/micron +// c_g_ideal[1] = 3.22e-16;//F/micron +// c_fringe[1] = 0.008e-15; +// c_junc[1] = 0;//F/micron2 +// I_on_n[1] = 727.6e-6;//A/micron +// I_on_p[1] = I_on_n[1] / 2; +// nmos_effective_resistance_multiplier = 1.99; +// n_to_p_eff_curr_drv_ratio[1] = 2; +// gmp_to_gmn_multiplier[1] = 0.99; +// Rnchannelon[1] = nmos_effective_resistance_multiplier * vdd[1] / I_on_n[1];//ohm-micron +// Rpchannelon[1] = n_to_p_eff_curr_drv_ratio[1] * Rnchannelon[1];//ohm-micron +// I_off_n[1][0] = 2.43e-11; +// I_off_n[1][10] = 4.85e-11; +// I_off_n[1][20] = 9.68e-11; +// I_off_n[1][30] = 1.94e-10; +// I_off_n[1][40] = 3.87e-10; +// I_off_n[1][50] = 7.73e-10; +// I_off_n[1][60] = 3.55e-10; +// I_off_n[1][70] = 3.09e-9; +// I_off_n[1][80] = 6.19e-9; +// I_off_n[1][90] = 1.24e-8; +// I_off_n[1][100]= 2.48e-8; +// +// // for 22nm LSTP HP +// I_g_on_n[1][0] = 4.51e-10;//A/micron +// I_g_on_n[1][10] = 4.51e-10; +// I_g_on_n[1][20] = 4.51e-10; +// I_g_on_n[1][30] = 4.51e-10; +// I_g_on_n[1][40] = 4.51e-10; +// I_g_on_n[1][50] = 4.51e-10; +// I_g_on_n[1][60] = 4.51e-10; +// I_g_on_n[1][70] = 4.51e-10; +// I_g_on_n[1][80] = 4.51e-10; +// I_g_on_n[1][90] = 4.51e-10; +// I_g_on_n[1][100] = 4.51e-10; + + + if (ram_cell_tech_type == 3) + {} + else if (ram_cell_tech_type == 4) + { + //22 nm commodity DRAM cell access transistor technology parameters. + //parameters + curr_vdd_dram_cell = 0.9;//0.45;//This value has reduced greatly in 2007 ITRS for all technology nodes. In + //2005 ITRS, the value was about twice the value in 2007 ITRS + Lphy[3] = 0.022;//micron + Lelec[3] = 0.0181;//micron. + curr_v_th_dram_access_transistor = 1;//V + width_dram_access_transistor = 0.022;//micron + curr_I_on_dram_cell = 20e-6; //This is a typical value that I have always + //kept constant. In reality this could perhaps be lower + curr_I_off_dram_cell_worst_case_length_temp = 1e-15;//A + curr_Wmemcella_dram = width_dram_access_transistor; + curr_Wmemcellpmos_dram = 0; + curr_Wmemcellnmos_dram = 0; + curr_area_cell_dram = 6*0.022*0.022;//micron2. + curr_asp_ratio_cell_dram = 0.667; + curr_c_dram_cell = 30e-15;//This is a typical value that I have alwaus + //kept constant. + + //22 nm commodity DRAM wordline transistor parameters obtained using MASTAR. + curr_vpp = 2.3;//vpp. V + t_ox[3] = 3.5e-3;//micron + v_th[3] = 1.0;//V + c_ox[3] = 9.06e-15;//F/micron2 + mobility_eff[3] = 367.29 * (1e-2 * 1e6 * 1e-2 * 1e6);//micron2 / Vs + Vdsat[3] = 0.0972; //V/micron + c_g_ideal[3] = 1.99e-16;//F/micron + c_fringe[3] = 0.053e-15;//F/micron + c_junc[3] = 1e-15;//F/micron2 + I_on_n[3] = 910.5e-6;//A/micron + I_on_p[3] = I_on_n[3] / 2;//This value for I_on_p is not really used. + nmos_effective_resistance_multiplier = 1.69;//Using the value from 32nm. + // + n_to_p_eff_curr_drv_ratio[3] = 1.95;//Using the value from 32nm + gmp_to_gmn_multiplier[3] = 0.90; + Rnchannelon[3] = nmos_effective_resistance_multiplier * curr_vpp / I_on_n[3];//ohm-micron + Rpchannelon[3] = n_to_p_eff_curr_drv_ratio[3] * Rnchannelon[3];//ohm-micron + long_channel_leakage_reduction[3] = 1; + I_off_n[3][0] = 1.1e-13; //A/micron + I_off_n[3][10] = 2.11e-13; + I_off_n[3][20] = 3.88e-13; + I_off_n[3][30] = 6.9e-13; + I_off_n[3][40] = 1.19e-12; + I_off_n[3][50] = 1.98e-12; + I_off_n[3][60] = 3.22e-12; + I_off_n[3][70] = 5.09e-12; + I_off_n[3][80] = 7.85e-12; + I_off_n[3][90] = 1.18e-11; + I_off_n[3][100] = 1.72e-11; + + } + else + { + //some error handler + } + + //SRAM cell properties + curr_Wmemcella_sram = 1.31 * g_ip->F_sz_um; + curr_Wmemcellpmos_sram = 1.23 * g_ip->F_sz_um; + curr_Wmemcellnmos_sram = 2.08 * g_ip->F_sz_um; + curr_area_cell_sram = 146 * g_ip->F_sz_um * g_ip->F_sz_um; + curr_asp_ratio_cell_sram = 1.46; + //CAM cell properties //TODO: data need to be revisited + curr_Wmemcella_cam = 1.31 * g_ip->F_sz_um; + curr_Wmemcellpmos_cam = 1.23 * g_ip->F_sz_um; + curr_Wmemcellnmos_cam = 2.08 * g_ip->F_sz_um; + curr_area_cell_cam = 292 * g_ip->F_sz_um * g_ip->F_sz_um; + curr_asp_ratio_cell_cam = 2.92; + //Empirical undifferetiated core/FU coefficient + curr_logic_scaling_co_eff = 0.7*0.7*0.7*0.7*0.7; + curr_core_tx_density = 1.25/0.7/0.7/0.7; + curr_sckt_co_eff = 1.1296; + curr_chip_layout_overhead = 1.2;//die measurement results based on Niagara 1 and 2 + curr_macro_layout_overhead = 1.1;//EDA placement and routing tool rule of thumb + } + + + g_tp.peri_global.Vdd += curr_alpha * vdd[peri_global_tech_type]; + g_tp.peri_global.t_ox += curr_alpha * t_ox[peri_global_tech_type]; + g_tp.peri_global.Vth += curr_alpha * v_th[peri_global_tech_type]; + g_tp.peri_global.C_ox += curr_alpha * c_ox[peri_global_tech_type]; g_tp.peri_global.C_g_ideal += curr_alpha * c_g_ideal[peri_global_tech_type]; - g_tp.peri_global.C_fringe += curr_alpha * c_fringe[peri_global_tech_type]; - g_tp.peri_global.C_junc += curr_alpha * c_junc[peri_global_tech_type]; + g_tp.peri_global.C_fringe += curr_alpha * c_fringe[peri_global_tech_type]; + g_tp.peri_global.C_junc += curr_alpha * c_junc[peri_global_tech_type]; g_tp.peri_global.C_junc_sidewall = 0.25e-15; // F/micron - g_tp.peri_global.l_phy += curr_alpha * Lphy[peri_global_tech_type]; - g_tp.peri_global.l_elec += curr_alpha * Lelec[peri_global_tech_type]; - g_tp.peri_global.I_on_n += curr_alpha * I_on_n[peri_global_tech_type]; - g_tp.peri_global.R_nch_on += - curr_alpha * Rnchannelon[peri_global_tech_type]; - g_tp.peri_global.R_pch_on += - curr_alpha * Rpchannelon[peri_global_tech_type]; - g_tp.peri_global.n_to_p_eff_curr_drv_ratio += - curr_alpha * n_to_p_eff_curr_drv_ratio[peri_global_tech_type]; - g_tp.peri_global.long_channel_leakage_reduction += - curr_alpha * long_channel_leakage_reduction[peri_global_tech_type]; - g_tp.peri_global.I_off_n += - curr_alpha * I_off_n[peri_global_tech_type][g_ip->temp - 300]; - g_tp.peri_global.I_off_p += - curr_alpha * I_off_n[peri_global_tech_type][g_ip->temp - 300]; - g_tp.peri_global.I_g_on_n += - curr_alpha * I_g_on_n[peri_global_tech_type][g_ip->temp - 300]; - g_tp.peri_global.I_g_on_p += - curr_alpha * I_g_on_n[peri_global_tech_type][g_ip->temp - 300]; - gmp_to_gmn_multiplier_periph_global += - curr_alpha * gmp_to_gmn_multiplier[peri_global_tech_type]; - - g_tp.sram_cell.Vdd += curr_alpha * vdd[ram_cell_tech_type]; - g_tp.sram_cell.l_phy += curr_alpha * Lphy[ram_cell_tech_type]; - g_tp.sram_cell.l_elec += curr_alpha * Lelec[ram_cell_tech_type]; - g_tp.sram_cell.t_ox += curr_alpha * t_ox[ram_cell_tech_type]; - g_tp.sram_cell.Vth += curr_alpha * v_th[ram_cell_tech_type]; + g_tp.peri_global.l_phy += curr_alpha * Lphy[peri_global_tech_type]; + g_tp.peri_global.l_elec += curr_alpha * Lelec[peri_global_tech_type]; + g_tp.peri_global.I_on_n += curr_alpha * I_on_n[peri_global_tech_type]; + g_tp.peri_global.R_nch_on += curr_alpha * Rnchannelon[peri_global_tech_type]; + g_tp.peri_global.R_pch_on += curr_alpha * Rpchannelon[peri_global_tech_type]; + g_tp.peri_global.n_to_p_eff_curr_drv_ratio + += curr_alpha * n_to_p_eff_curr_drv_ratio[peri_global_tech_type]; + g_tp.peri_global.long_channel_leakage_reduction + += curr_alpha * long_channel_leakage_reduction[peri_global_tech_type]; + g_tp.peri_global.I_off_n += curr_alpha * I_off_n[peri_global_tech_type][g_ip->temp - 300]; + g_tp.peri_global.I_off_p += curr_alpha * I_off_n[peri_global_tech_type][g_ip->temp - 300]; + g_tp.peri_global.I_g_on_n += curr_alpha * I_g_on_n[peri_global_tech_type][g_ip->temp - 300]; + g_tp.peri_global.I_g_on_p += curr_alpha * I_g_on_n[peri_global_tech_type][g_ip->temp - 300]; + gmp_to_gmn_multiplier_periph_global += curr_alpha * gmp_to_gmn_multiplier[peri_global_tech_type]; + + g_tp.sram_cell.Vdd += curr_alpha * vdd[ram_cell_tech_type]; + g_tp.sram_cell.l_phy += curr_alpha * Lphy[ram_cell_tech_type]; + g_tp.sram_cell.l_elec += curr_alpha * Lelec[ram_cell_tech_type]; + g_tp.sram_cell.t_ox += curr_alpha * t_ox[ram_cell_tech_type]; + g_tp.sram_cell.Vth += curr_alpha * v_th[ram_cell_tech_type]; g_tp.sram_cell.C_g_ideal += curr_alpha * c_g_ideal[ram_cell_tech_type]; - g_tp.sram_cell.C_fringe += curr_alpha * c_fringe[ram_cell_tech_type]; - g_tp.sram_cell.C_junc += curr_alpha * c_junc[ram_cell_tech_type]; + g_tp.sram_cell.C_fringe += curr_alpha * c_fringe[ram_cell_tech_type]; + g_tp.sram_cell.C_junc += curr_alpha * c_junc[ram_cell_tech_type]; g_tp.sram_cell.C_junc_sidewall = 0.25e-15; // F/micron - g_tp.sram_cell.I_on_n += curr_alpha * I_on_n[ram_cell_tech_type]; - g_tp.sram_cell.R_nch_on += curr_alpha * Rnchannelon[ram_cell_tech_type]; - g_tp.sram_cell.R_pch_on += curr_alpha * Rpchannelon[ram_cell_tech_type]; - g_tp.sram_cell.n_to_p_eff_curr_drv_ratio += - curr_alpha * n_to_p_eff_curr_drv_ratio[ram_cell_tech_type]; - g_tp.sram_cell.long_channel_leakage_reduction += - curr_alpha * long_channel_leakage_reduction[ram_cell_tech_type]; - g_tp.sram_cell.I_off_n += - curr_alpha * I_off_n[ram_cell_tech_type][g_ip->temp - 300]; - g_tp.sram_cell.I_off_p += - curr_alpha * I_off_n[ram_cell_tech_type][g_ip->temp - 300]; - g_tp.sram_cell.I_g_on_n += - curr_alpha * I_g_on_n[ram_cell_tech_type][g_ip->temp - 300]; - g_tp.sram_cell.I_g_on_p += - curr_alpha * I_g_on_n[ram_cell_tech_type][g_ip->temp - 300]; - - g_tp.dram_cell_Vdd += curr_alpha * curr_vdd_dram_cell; - g_tp.dram_acc.Vth += curr_alpha * curr_v_th_dram_access_transistor; - g_tp.dram_acc.l_phy += curr_alpha * Lphy[dram_cell_tech_flavor]; - g_tp.dram_acc.l_elec += curr_alpha * Lelec[dram_cell_tech_flavor]; + g_tp.sram_cell.I_on_n += curr_alpha * I_on_n[ram_cell_tech_type]; + g_tp.sram_cell.R_nch_on += curr_alpha * Rnchannelon[ram_cell_tech_type]; + g_tp.sram_cell.R_pch_on += curr_alpha * Rpchannelon[ram_cell_tech_type]; + g_tp.sram_cell.n_to_p_eff_curr_drv_ratio += curr_alpha * n_to_p_eff_curr_drv_ratio[ram_cell_tech_type]; + g_tp.sram_cell.long_channel_leakage_reduction += curr_alpha * long_channel_leakage_reduction[ram_cell_tech_type]; + g_tp.sram_cell.I_off_n += curr_alpha * I_off_n[ram_cell_tech_type][g_ip->temp - 300]; + g_tp.sram_cell.I_off_p += curr_alpha * I_off_n[ram_cell_tech_type][g_ip->temp - 300]; + g_tp.sram_cell.I_g_on_n += curr_alpha * I_g_on_n[ram_cell_tech_type][g_ip->temp - 300]; + g_tp.sram_cell.I_g_on_p += curr_alpha * I_g_on_n[ram_cell_tech_type][g_ip->temp - 300]; + + g_tp.dram_cell_Vdd += curr_alpha * curr_vdd_dram_cell; + g_tp.dram_acc.Vth += curr_alpha * curr_v_th_dram_access_transistor; + g_tp.dram_acc.l_phy += curr_alpha * Lphy[dram_cell_tech_flavor]; + g_tp.dram_acc.l_elec += curr_alpha * Lelec[dram_cell_tech_flavor]; g_tp.dram_acc.C_g_ideal += curr_alpha * c_g_ideal[dram_cell_tech_flavor]; - g_tp.dram_acc.C_fringe += curr_alpha * c_fringe[dram_cell_tech_flavor]; - g_tp.dram_acc.C_junc += curr_alpha * c_junc[dram_cell_tech_flavor]; + g_tp.dram_acc.C_fringe += curr_alpha * c_fringe[dram_cell_tech_flavor]; + g_tp.dram_acc.C_junc += curr_alpha * c_junc[dram_cell_tech_flavor]; g_tp.dram_acc.C_junc_sidewall = 0.25e-15; // F/micron - g_tp.dram_cell_I_on += curr_alpha * curr_I_on_dram_cell; - g_tp.dram_cell_I_off_worst_case_len_temp += - curr_alpha * curr_I_off_dram_cell_worst_case_length_temp; - g_tp.dram_acc.I_on_n += curr_alpha * I_on_n[dram_cell_tech_flavor]; - g_tp.dram_cell_C += curr_alpha * curr_c_dram_cell; - g_tp.vpp += curr_alpha * curr_vpp; - g_tp.dram_wl.l_phy += curr_alpha * Lphy[dram_cell_tech_flavor]; - g_tp.dram_wl.l_elec += curr_alpha * Lelec[dram_cell_tech_flavor]; - g_tp.dram_wl.C_g_ideal += curr_alpha * c_g_ideal[dram_cell_tech_flavor]; - g_tp.dram_wl.C_fringe += curr_alpha * c_fringe[dram_cell_tech_flavor]; - g_tp.dram_wl.C_junc += curr_alpha * c_junc[dram_cell_tech_flavor]; + g_tp.dram_cell_I_on += curr_alpha * curr_I_on_dram_cell; + g_tp.dram_cell_I_off_worst_case_len_temp += curr_alpha * curr_I_off_dram_cell_worst_case_length_temp; + g_tp.dram_acc.I_on_n += curr_alpha * I_on_n[dram_cell_tech_flavor]; + g_tp.dram_cell_C += curr_alpha * curr_c_dram_cell; + g_tp.vpp += curr_alpha * curr_vpp; + g_tp.dram_wl.l_phy += curr_alpha * Lphy[dram_cell_tech_flavor]; + g_tp.dram_wl.l_elec += curr_alpha * Lelec[dram_cell_tech_flavor]; + g_tp.dram_wl.C_g_ideal += curr_alpha * c_g_ideal[dram_cell_tech_flavor]; + g_tp.dram_wl.C_fringe += curr_alpha * c_fringe[dram_cell_tech_flavor]; + g_tp.dram_wl.C_junc += curr_alpha * c_junc[dram_cell_tech_flavor]; g_tp.dram_wl.C_junc_sidewall = 0.25e-15; // F/micron - g_tp.dram_wl.I_on_n += curr_alpha * I_on_n[dram_cell_tech_flavor]; - g_tp.dram_wl.R_nch_on += curr_alpha * Rnchannelon[dram_cell_tech_flavor]; - g_tp.dram_wl.R_pch_on += curr_alpha * Rpchannelon[dram_cell_tech_flavor]; - g_tp.dram_wl.n_to_p_eff_curr_drv_ratio += - curr_alpha * n_to_p_eff_curr_drv_ratio[dram_cell_tech_flavor]; - g_tp.dram_wl.long_channel_leakage_reduction += - curr_alpha * long_channel_leakage_reduction[dram_cell_tech_flavor]; - g_tp.dram_wl.I_off_n += - curr_alpha * I_off_n[dram_cell_tech_flavor][g_ip->temp - 300]; - g_tp.dram_wl.I_off_p += - curr_alpha * I_off_n[dram_cell_tech_flavor][g_ip->temp - 300]; - - g_tp.cam_cell.Vdd += curr_alpha * vdd[ram_cell_tech_type]; - g_tp.cam_cell.l_phy += curr_alpha * Lphy[ram_cell_tech_type]; - g_tp.cam_cell.l_elec += curr_alpha * Lelec[ram_cell_tech_type]; - g_tp.cam_cell.t_ox += curr_alpha * t_ox[ram_cell_tech_type]; - g_tp.cam_cell.Vth += curr_alpha * v_th[ram_cell_tech_type]; + g_tp.dram_wl.I_on_n += curr_alpha * I_on_n[dram_cell_tech_flavor]; + g_tp.dram_wl.R_nch_on += curr_alpha * Rnchannelon[dram_cell_tech_flavor]; + g_tp.dram_wl.R_pch_on += curr_alpha * Rpchannelon[dram_cell_tech_flavor]; + g_tp.dram_wl.n_to_p_eff_curr_drv_ratio += curr_alpha * n_to_p_eff_curr_drv_ratio[dram_cell_tech_flavor]; + g_tp.dram_wl.long_channel_leakage_reduction += curr_alpha * long_channel_leakage_reduction[dram_cell_tech_flavor]; + g_tp.dram_wl.I_off_n += curr_alpha * I_off_n[dram_cell_tech_flavor][g_ip->temp - 300]; + g_tp.dram_wl.I_off_p += curr_alpha * I_off_n[dram_cell_tech_flavor][g_ip->temp - 300]; + + g_tp.cam_cell.Vdd += curr_alpha * vdd[ram_cell_tech_type]; + g_tp.cam_cell.l_phy += curr_alpha * Lphy[ram_cell_tech_type]; + g_tp.cam_cell.l_elec += curr_alpha * Lelec[ram_cell_tech_type]; + g_tp.cam_cell.t_ox += curr_alpha * t_ox[ram_cell_tech_type]; + g_tp.cam_cell.Vth += curr_alpha * v_th[ram_cell_tech_type]; g_tp.cam_cell.C_g_ideal += curr_alpha * c_g_ideal[ram_cell_tech_type]; - g_tp.cam_cell.C_fringe += curr_alpha * c_fringe[ram_cell_tech_type]; - g_tp.cam_cell.C_junc += curr_alpha * c_junc[ram_cell_tech_type]; + g_tp.cam_cell.C_fringe += curr_alpha * c_fringe[ram_cell_tech_type]; + g_tp.cam_cell.C_junc += curr_alpha * c_junc[ram_cell_tech_type]; g_tp.cam_cell.C_junc_sidewall = 0.25e-15; // F/micron - g_tp.cam_cell.I_on_n += curr_alpha * I_on_n[ram_cell_tech_type]; - g_tp.cam_cell.R_nch_on += curr_alpha * Rnchannelon[ram_cell_tech_type]; - g_tp.cam_cell.R_pch_on += curr_alpha * Rpchannelon[ram_cell_tech_type]; - g_tp.cam_cell.n_to_p_eff_curr_drv_ratio += - curr_alpha * n_to_p_eff_curr_drv_ratio[ram_cell_tech_type]; - g_tp.cam_cell.long_channel_leakage_reduction += - curr_alpha * long_channel_leakage_reduction[ram_cell_tech_type]; - g_tp.cam_cell.I_off_n += - curr_alpha * I_off_n[ram_cell_tech_type][g_ip->temp - 300]; - g_tp.cam_cell.I_off_p += - curr_alpha * I_off_n[ram_cell_tech_type][g_ip->temp - 300]; - g_tp.cam_cell.I_g_on_n += - curr_alpha * I_g_on_n[ram_cell_tech_type][g_ip->temp - 300]; - g_tp.cam_cell.I_g_on_p += - curr_alpha * I_g_on_n[ram_cell_tech_type][g_ip->temp - 300]; - - g_tp.dram.cell_a_w += curr_alpha * curr_Wmemcella_dram; + g_tp.cam_cell.I_on_n += curr_alpha * I_on_n[ram_cell_tech_type]; + g_tp.cam_cell.R_nch_on += curr_alpha * Rnchannelon[ram_cell_tech_type]; + g_tp.cam_cell.R_pch_on += curr_alpha * Rpchannelon[ram_cell_tech_type]; + g_tp.cam_cell.n_to_p_eff_curr_drv_ratio += curr_alpha * n_to_p_eff_curr_drv_ratio[ram_cell_tech_type]; + g_tp.cam_cell.long_channel_leakage_reduction += curr_alpha * long_channel_leakage_reduction[ram_cell_tech_type]; + g_tp.cam_cell.I_off_n += curr_alpha * I_off_n[ram_cell_tech_type][g_ip->temp - 300]; + g_tp.cam_cell.I_off_p += curr_alpha * I_off_n[ram_cell_tech_type][g_ip->temp - 300]; + g_tp.cam_cell.I_g_on_n += curr_alpha * I_g_on_n[ram_cell_tech_type][g_ip->temp - 300]; + g_tp.cam_cell.I_g_on_p += curr_alpha * I_g_on_n[ram_cell_tech_type][g_ip->temp - 300]; + + g_tp.dram.cell_a_w += curr_alpha * curr_Wmemcella_dram; g_tp.dram.cell_pmos_w += curr_alpha * curr_Wmemcellpmos_dram; g_tp.dram.cell_nmos_w += curr_alpha * curr_Wmemcellnmos_dram; - area_cell_dram += curr_alpha * curr_area_cell_dram; - asp_ratio_cell_dram += curr_alpha * curr_asp_ratio_cell_dram; + area_cell_dram += curr_alpha * curr_area_cell_dram; + asp_ratio_cell_dram += curr_alpha * curr_asp_ratio_cell_dram; - g_tp.sram.cell_a_w += curr_alpha * curr_Wmemcella_sram; + g_tp.sram.cell_a_w += curr_alpha * curr_Wmemcella_sram; g_tp.sram.cell_pmos_w += curr_alpha * curr_Wmemcellpmos_sram; g_tp.sram.cell_nmos_w += curr_alpha * curr_Wmemcellnmos_sram; area_cell_sram += curr_alpha * curr_area_cell_sram; asp_ratio_cell_sram += curr_alpha * curr_asp_ratio_cell_sram; - g_tp.cam.cell_a_w += curr_alpha * curr_Wmemcella_cam; // sheng + g_tp.cam.cell_a_w += curr_alpha * curr_Wmemcella_cam;//sheng g_tp.cam.cell_pmos_w += curr_alpha * curr_Wmemcellpmos_cam; g_tp.cam.cell_nmos_w += curr_alpha * curr_Wmemcellnmos_cam; area_cell_cam += curr_alpha * curr_area_cell_cam; asp_ratio_cell_cam += curr_alpha * curr_asp_ratio_cell_cam; - // Sense amplifier latch Gm calculation - mobility_eff_periph_global += - curr_alpha * mobility_eff[peri_global_tech_type]; + //Sense amplifier latch Gm calculation + mobility_eff_periph_global += curr_alpha * mobility_eff[peri_global_tech_type]; Vdsat_periph_global += curr_alpha * Vdsat[peri_global_tech_type]; - // Empirical undifferetiated core/FU coefficient - g_tp.scaling_factor.logic_scaling_co_eff += - curr_alpha * curr_logic_scaling_co_eff; + //Empirical undifferetiated core/FU coefficient + g_tp.scaling_factor.logic_scaling_co_eff += curr_alpha * curr_logic_scaling_co_eff; g_tp.scaling_factor.core_tx_density += curr_alpha * curr_core_tx_density; - g_tp.chip_layout_overhead += curr_alpha * curr_chip_layout_overhead; + g_tp.chip_layout_overhead += curr_alpha * curr_chip_layout_overhead; g_tp.macro_layout_overhead += curr_alpha * curr_macro_layout_overhead; - g_tp.sckt_co_eff += curr_alpha * curr_sckt_co_eff; + g_tp.sckt_co_eff += curr_alpha * curr_sckt_co_eff; } - // Currently we are not modeling the resistance/capacitance of poly anywhere. - // Continuous function (or date have been processed) does not need linear - // interpolation - g_tp.w_comp_inv_p1 = - 12.5 * g_ip->F_sz_um; // this was 10 micron for the 0.8 micron process - g_tp.w_comp_inv_n1 = - 7.5 * g_ip->F_sz_um; // this was 6 micron for the 0.8 micron process - g_tp.w_comp_inv_p2 = - 25 * g_ip->F_sz_um; // this was 20 micron for the 0.8 micron process - g_tp.w_comp_inv_n2 = - 15 * g_ip->F_sz_um; // this was 12 micron for the 0.8 micron process - g_tp.w_comp_inv_p3 = - 50 * g_ip->F_sz_um; // this was 40 micron for the 0.8 micron process - g_tp.w_comp_inv_n3 = - 30 * g_ip->F_sz_um; // this was 24 micron for the 0.8 micron process - g_tp.w_eval_inv_p = - 100 * g_ip->F_sz_um; // this was 80 micron for the 0.8 micron process - g_tp.w_eval_inv_n = - 50 * g_ip->F_sz_um; // this was 40 micron for the 0.8 micron process - g_tp.w_comp_n = - 12.5 * g_ip->F_sz_um; // this was 10 micron for the 0.8 micron process - g_tp.w_comp_p = - 37.5 * g_ip->F_sz_um; // this was 30 micron for the 0.8 micron process + + //Currently we are not modeling the resistance/capacitance of poly anywhere. + //Continuous function (or date have been processed) does not need linear interpolation + g_tp.w_comp_inv_p1 = 12.5 * g_ip->F_sz_um;//this was 10 micron for the 0.8 micron process + g_tp.w_comp_inv_n1 = 7.5 * g_ip->F_sz_um;//this was 6 micron for the 0.8 micron process + g_tp.w_comp_inv_p2 = 25 * g_ip->F_sz_um;//this was 20 micron for the 0.8 micron process + g_tp.w_comp_inv_n2 = 15 * g_ip->F_sz_um;//this was 12 micron for the 0.8 micron process + g_tp.w_comp_inv_p3 = 50 * g_ip->F_sz_um;//this was 40 micron for the 0.8 micron process + g_tp.w_comp_inv_n3 = 30 * g_ip->F_sz_um;//this was 24 micron for the 0.8 micron process + g_tp.w_eval_inv_p = 100 * g_ip->F_sz_um;//this was 80 micron for the 0.8 micron process + g_tp.w_eval_inv_n = 50 * g_ip->F_sz_um;//this was 40 micron for the 0.8 micron process + g_tp.w_comp_n = 12.5 * g_ip->F_sz_um;//this was 10 micron for the 0.8 micron process + g_tp.w_comp_p = 37.5 * g_ip->F_sz_um;//this was 30 micron for the 0.8 micron process g_tp.MIN_GAP_BET_P_AND_N_DIFFS = 5 * g_ip->F_sz_um; g_tp.MIN_GAP_BET_SAME_TYPE_DIFFS = 1.5 * g_ip->F_sz_um; @@ -1904,264 +1828,255 @@ void init_tech_params(double technology, bool is_tag) { g_tp.min_w_nmos_ = 3 * g_ip->F_sz_um / 2; g_tp.max_w_nmos_ = 100 * g_ip->F_sz_um; - g_tp.w_iso = 12.5 * g_ip->F_sz_um; // was 10 micron for the 0.8 micron - // process - g_tp.w_sense_n = 3.75 * g_ip->F_sz_um; // sense amplifier N-trans; was 3 - // micron for the 0.8 micron process - g_tp.w_sense_p = 7.5 * g_ip->F_sz_um; // sense amplifier P-trans; was 6 - // micron for the 0.8 micron process - g_tp.w_sense_en = 5 * g_ip->F_sz_um; // Sense enable transistor of the sense - // amplifier; was 4 micron for the 0.8 - // micron process - g_tp.w_nmos_b_mux = 6 * g_tp.min_w_nmos_; + g_tp.w_iso = 12.5*g_ip->F_sz_um;//was 10 micron for the 0.8 micron process + g_tp.w_sense_n = 3.75*g_ip->F_sz_um; // sense amplifier N-trans; was 3 micron for the 0.8 micron process + g_tp.w_sense_p = 7.5*g_ip->F_sz_um; // sense amplifier P-trans; was 6 micron for the 0.8 micron process + g_tp.w_sense_en = 5*g_ip->F_sz_um; // Sense enable transistor of the sense amplifier; was 4 micron for the 0.8 micron process + g_tp.w_nmos_b_mux = 6 * g_tp.min_w_nmos_; g_tp.w_nmos_sa_mux = 6 * g_tp.min_w_nmos_; - if (ram_cell_tech_type == comm_dram) { + if (ram_cell_tech_type == comm_dram) + { g_tp.max_w_nmos_dec = 8 * g_ip->F_sz_um; - g_tp.h_dec = 8; // in the unit of memory cell height - } else { + g_tp.h_dec = 8; // in the unit of memory cell height + } + else + { g_tp.max_w_nmos_dec = g_tp.max_w_nmos_; - g_tp.h_dec = 4; // in the unit of memory cell height + g_tp.h_dec = 4; // in the unit of memory cell height } g_tp.peri_global.C_overlap = 0.2 * g_tp.peri_global.C_g_ideal; - g_tp.sram_cell.C_overlap = 0.2 * g_tp.sram_cell.C_g_ideal; - g_tp.cam_cell.C_overlap = 0.2 * g_tp.cam_cell.C_g_ideal; + g_tp.sram_cell.C_overlap = 0.2 * g_tp.sram_cell.C_g_ideal; + g_tp.cam_cell.C_overlap = 0.2 * g_tp.cam_cell.C_g_ideal; g_tp.dram_acc.C_overlap = 0.2 * g_tp.dram_acc.C_g_ideal; g_tp.dram_acc.R_nch_on = g_tp.dram_cell_Vdd / g_tp.dram_acc.I_on_n; - // g_tp.dram_acc.R_pch_on = g_tp.dram_cell_Vdd / g_tp.dram_acc.I_on_p; + //g_tp.dram_acc.R_pch_on = g_tp.dram_cell_Vdd / g_tp.dram_acc.I_on_p; g_tp.dram_wl.C_overlap = 0.2 * g_tp.dram_wl.C_g_ideal; - double gmn_sense_amp_latch = - (mobility_eff_periph_global / 2) * g_tp.peri_global.C_ox * - (g_tp.w_sense_n / g_tp.peri_global.l_elec) * Vdsat_periph_global; - double gmp_sense_amp_latch = - gmp_to_gmn_multiplier_periph_global * gmn_sense_amp_latch; + double gmn_sense_amp_latch = (mobility_eff_periph_global / 2) * g_tp.peri_global.C_ox * (g_tp.w_sense_n / g_tp.peri_global.l_elec) * Vdsat_periph_global; + double gmp_sense_amp_latch = gmp_to_gmn_multiplier_periph_global * gmn_sense_amp_latch; g_tp.gm_sense_amp_latch = gmn_sense_amp_latch + gmp_sense_amp_latch; g_tp.dram.b_w = sqrt(area_cell_dram / (asp_ratio_cell_dram)); g_tp.dram.b_h = asp_ratio_cell_dram * g_tp.dram.b_w; g_tp.sram.b_w = sqrt(area_cell_sram / (asp_ratio_cell_sram)); g_tp.sram.b_h = asp_ratio_cell_sram * g_tp.sram.b_w; - g_tp.cam.b_w = sqrt(area_cell_cam / (asp_ratio_cell_cam)); // Sheng + g_tp.cam.b_w = sqrt(area_cell_cam / (asp_ratio_cell_cam));//Sheng g_tp.cam.b_h = asp_ratio_cell_cam * g_tp.cam.b_w; g_tp.dram.Vbitpre = g_tp.dram_cell_Vdd; g_tp.sram.Vbitpre = vdd[ram_cell_tech_type]; - g_tp.cam.Vbitpre = vdd[ram_cell_tech_type]; // Sheng + g_tp.cam.Vbitpre = vdd[ram_cell_tech_type];//Sheng pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio(); g_tp.w_pmos_bl_precharge = 6 * pmos_to_nmos_sizing_r * g_tp.min_w_nmos_; g_tp.w_pmos_bl_eq = pmos_to_nmos_sizing_r * g_tp.min_w_nmos_; - double wire_pitch[NUMBER_INTERCONNECT_PROJECTION_TYPES][NUMBER_WIRE_TYPES], - wire_r_per_micron[NUMBER_INTERCONNECT_PROJECTION_TYPES] - [NUMBER_WIRE_TYPES], - wire_c_per_micron[NUMBER_INTERCONNECT_PROJECTION_TYPES] - [NUMBER_WIRE_TYPES], - horiz_dielectric_constant[NUMBER_INTERCONNECT_PROJECTION_TYPES] - [NUMBER_WIRE_TYPES], - vert_dielectric_constant[NUMBER_INTERCONNECT_PROJECTION_TYPES] - [NUMBER_WIRE_TYPES], - aspect_ratio[NUMBER_INTERCONNECT_PROJECTION_TYPES][NUMBER_WIRE_TYPES], - miller_value[NUMBER_INTERCONNECT_PROJECTION_TYPES][NUMBER_WIRE_TYPES], - ild_thickness[NUMBER_INTERCONNECT_PROJECTION_TYPES][NUMBER_WIRE_TYPES]; - - for (iter = 0; iter <= 1; ++iter) { + + double wire_pitch [NUMBER_INTERCONNECT_PROJECTION_TYPES][NUMBER_WIRE_TYPES], + wire_r_per_micron[NUMBER_INTERCONNECT_PROJECTION_TYPES][NUMBER_WIRE_TYPES], + wire_c_per_micron[NUMBER_INTERCONNECT_PROJECTION_TYPES][NUMBER_WIRE_TYPES], + horiz_dielectric_constant[NUMBER_INTERCONNECT_PROJECTION_TYPES][NUMBER_WIRE_TYPES], + vert_dielectric_constant[NUMBER_INTERCONNECT_PROJECTION_TYPES][NUMBER_WIRE_TYPES], + aspect_ratio[NUMBER_INTERCONNECT_PROJECTION_TYPES][NUMBER_WIRE_TYPES], + miller_value[NUMBER_INTERCONNECT_PROJECTION_TYPES][NUMBER_WIRE_TYPES], + ild_thickness[NUMBER_INTERCONNECT_PROJECTION_TYPES][NUMBER_WIRE_TYPES]; + + for (iter=0; iter<=1; ++iter) + { // linear interpolation - if (iter == 0) { + if (iter == 0) + { tech = tech_lo; - if (tech_lo == tech_hi) { + if (tech_lo == tech_hi) + { curr_alpha = 1; - } else { - curr_alpha = (technology - tech_hi) / (tech_lo - tech_hi); } - } else { + else + { + curr_alpha = (technology - tech_hi)/(tech_lo - tech_hi); + } + } + else + { tech = tech_hi; - if (tech_lo == tech_hi) { + if (tech_lo == tech_hi) + { break; - } else { - curr_alpha = (tech_lo - technology) / (tech_lo - tech_hi); + } + else + { + curr_alpha = (tech_lo - technology)/(tech_lo - tech_hi); } } - if (tech == 90) { - // Aggressive projections - wire_pitch[0][0] = 2.5 * g_ip->F_sz_um; // micron + if (tech == 90) + { + //Aggressive projections + wire_pitch[0][0] = 2.5 * g_ip->F_sz_um;//micron aspect_ratio[0][0] = 2.4; - wire_width = wire_pitch[0][0] / 2; // micron - wire_thickness = aspect_ratio[0][0] * wire_width; // micron - wire_spacing = wire_pitch[0][0] - wire_width; // micron - barrier_thickness = 0.01; // micron - dishing_thickness = 0; // micron + wire_width = wire_pitch[0][0] / 2; //micron + wire_thickness = aspect_ratio[0][0] * wire_width;//micron + wire_spacing = wire_pitch[0][0] - wire_width;//micron + barrier_thickness = 0.01;//micron + dishing_thickness = 0;//micron alpha_scatter = 1; - wire_r_per_micron[0][0] = wire_resistance( - CU_RESISTIVITY, wire_width, wire_thickness, barrier_thickness, - dishing_thickness, alpha_scatter); // ohm/micron - ild_thickness[0][0] = 0.48; // micron + wire_r_per_micron[0][0] = wire_resistance(CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter);//ohm/micron + ild_thickness[0][0] = 0.48;//micron miller_value[0][0] = 1.5; horiz_dielectric_constant[0][0] = 2.709; vert_dielectric_constant[0][0] = 3.9; - fringe_cap = 0.115e-15; // F/micron - wire_c_per_micron[0][0] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[0][0], - miller_value[0][0], horiz_dielectric_constant[0][0], + fringe_cap = 0.115e-15; //F/micron + wire_c_per_micron[0][0] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[0][0], miller_value[0][0], horiz_dielectric_constant[0][0], vert_dielectric_constant[0][0], - fringe_cap); // F/micron. + fringe_cap);//F/micron. wire_pitch[0][1] = 4 * g_ip->F_sz_um; wire_width = wire_pitch[0][1] / 2; aspect_ratio[0][1] = 2.4; wire_thickness = aspect_ratio[0][1] * wire_width; wire_spacing = wire_pitch[0][1] - wire_width; - wire_r_per_micron[0][1] = - wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[0][1] = 0.48; // micron + wire_r_per_micron[0][1] = wire_resistance(CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[0][1] = 0.48;//micron miller_value[0][1] = 1.5; horiz_dielectric_constant[0][1] = 2.709; vert_dielectric_constant[0][1] = 3.9; - wire_c_per_micron[0][1] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[0][1], - miller_value[0][1], horiz_dielectric_constant[0][1], - vert_dielectric_constant[0][1], fringe_cap); + wire_c_per_micron[0][1] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[0][1], miller_value[0][1], horiz_dielectric_constant[0][1], + vert_dielectric_constant[0][1], + fringe_cap); wire_pitch[0][2] = 8 * g_ip->F_sz_um; aspect_ratio[0][2] = 2.7; wire_width = wire_pitch[0][2] / 2; wire_thickness = aspect_ratio[0][2] * wire_width; wire_spacing = wire_pitch[0][2] - wire_width; - wire_r_per_micron[0][2] = - wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); + wire_r_per_micron[0][2] = wire_resistance(CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[0][2] = 0.96; miller_value[0][2] = 1.5; horiz_dielectric_constant[0][2] = 2.709; vert_dielectric_constant[0][2] = 3.9; - wire_c_per_micron[0][2] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[0][2], - miller_value[0][2], horiz_dielectric_constant[0][2], - vert_dielectric_constant[0][2], fringe_cap); + wire_c_per_micron[0][2] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[0][2], miller_value[0][2], horiz_dielectric_constant[0][2], vert_dielectric_constant[0][2], + fringe_cap); - // Conservative projections + //Conservative projections wire_pitch[1][0] = 2.5 * g_ip->F_sz_um; - aspect_ratio[1][0] = 2.0; + aspect_ratio[1][0] = 2.0; wire_width = wire_pitch[1][0] / 2; wire_thickness = aspect_ratio[1][0] * wire_width; wire_spacing = wire_pitch[1][0] - wire_width; barrier_thickness = 0.008; dishing_thickness = 0; alpha_scatter = 1; - wire_r_per_micron[1][0] = - wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[1][0] = 0.48; - miller_value[1][0] = 1.5; - horiz_dielectric_constant[1][0] = 3.038; - vert_dielectric_constant[1][0] = 3.9; + wire_r_per_micron[1][0] = wire_resistance(CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[1][0] = 0.48; + miller_value[1][0] = 1.5; + horiz_dielectric_constant[1][0] = 3.038; + vert_dielectric_constant[1][0] = 3.9; fringe_cap = 0.115e-15; - wire_c_per_micron[1][0] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[1][0], - miller_value[1][0], horiz_dielectric_constant[1][0], - vert_dielectric_constant[1][0], fringe_cap); + wire_c_per_micron[1][0] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[1][0], miller_value[1][0], horiz_dielectric_constant[1][0], + vert_dielectric_constant[1][0], + fringe_cap); wire_pitch[1][1] = 4 * g_ip->F_sz_um; wire_width = wire_pitch[1][1] / 2; aspect_ratio[1][1] = 2.0; wire_thickness = aspect_ratio[1][1] * wire_width; wire_spacing = wire_pitch[1][1] - wire_width; - wire_r_per_micron[1][1] = - wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[1][1] = 0.48; - miller_value[1][1] = 1.5; - horiz_dielectric_constant[1][1] = 3.038; - vert_dielectric_constant[1][1] = 3.9; - wire_c_per_micron[1][1] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[1][1], - miller_value[1][1], horiz_dielectric_constant[1][1], - vert_dielectric_constant[1][1], fringe_cap); + wire_r_per_micron[1][1] = wire_resistance(CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[1][1] = 0.48; + miller_value[1][1] = 1.5; + horiz_dielectric_constant[1][1] = 3.038; + vert_dielectric_constant[1][1] = 3.9; + wire_c_per_micron[1][1] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[1][1], miller_value[1][1], horiz_dielectric_constant[1][1], + vert_dielectric_constant[1][1], + fringe_cap); wire_pitch[1][2] = 8 * g_ip->F_sz_um; - aspect_ratio[1][2] = 2.2; + aspect_ratio[1][2] = 2.2; wire_width = wire_pitch[1][2] / 2; wire_thickness = aspect_ratio[1][2] * wire_width; wire_spacing = wire_pitch[1][2] - wire_width; - dishing_thickness = 0.1 * wire_thickness; - wire_r_per_micron[1][2] = - wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[1][2] = 1.1; - miller_value[1][2] = 1.5; - horiz_dielectric_constant[1][2] = 3.038; - vert_dielectric_constant[1][2] = 3.9; - wire_c_per_micron[1][2] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[1][2], - miller_value[1][2], horiz_dielectric_constant[1][2], - vert_dielectric_constant[1][2], fringe_cap); - // Nominal projections for commodity DRAM wordline/bitline + dishing_thickness = 0.1 * wire_thickness; + wire_r_per_micron[1][2] = wire_resistance(CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[1][2] = 1.1; + miller_value[1][2] = 1.5; + horiz_dielectric_constant[1][2] = 3.038; + vert_dielectric_constant[1][2] = 3.9; + wire_c_per_micron[1][2] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[1][2] , miller_value[1][2], horiz_dielectric_constant[1][2], vert_dielectric_constant[1][2], + fringe_cap); + //Nominal projections for commodity DRAM wordline/bitline wire_pitch[1][3] = 2 * 0.09; wire_c_per_micron[1][3] = 60e-15 / (256 * 2 * 0.09); wire_r_per_micron[1][3] = 12 / 0.09; - } else if (tech == 65) { - // Aggressive projections + } + else if (tech == 65) + { + //Aggressive projections wire_pitch[0][0] = 2.5 * g_ip->F_sz_um; - aspect_ratio[0][0] = 2.7; + aspect_ratio[0][0] = 2.7; wire_width = wire_pitch[0][0] / 2; - wire_thickness = aspect_ratio[0][0] * wire_width; + wire_thickness = aspect_ratio[0][0] * wire_width; wire_spacing = wire_pitch[0][0] - wire_width; barrier_thickness = 0; dishing_thickness = 0; alpha_scatter = 1; - wire_r_per_micron[0][0] = - wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[0][0] = 0.405; - miller_value[0][0] = 1.5; - horiz_dielectric_constant[0][0] = 2.303; - vert_dielectric_constant[0][0] = 3.9; + wire_r_per_micron[0][0] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[0][0] = 0.405; + miller_value[0][0] = 1.5; + horiz_dielectric_constant[0][0] = 2.303; + vert_dielectric_constant[0][0] = 3.9; fringe_cap = 0.115e-15; - wire_c_per_micron[0][0] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[0][0], - miller_value[0][0], horiz_dielectric_constant[0][0], - vert_dielectric_constant[0][0], fringe_cap); + wire_c_per_micron[0][0] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[0][0] , miller_value[0][0] , horiz_dielectric_constant[0][0] , vert_dielectric_constant[0][0] , + fringe_cap); wire_pitch[0][1] = 4 * g_ip->F_sz_um; wire_width = wire_pitch[0][1] / 2; - aspect_ratio[0][1] = 2.7; - wire_thickness = aspect_ratio[0][1] * wire_width; + aspect_ratio[0][1] = 2.7; + wire_thickness = aspect_ratio[0][1] * wire_width; wire_spacing = wire_pitch[0][1] - wire_width; - wire_r_per_micron[0][1] = - wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[0][1] = 0.405; - miller_value[0][1] = 1.5; - horiz_dielectric_constant[0][1] = 2.303; - vert_dielectric_constant[0][1] = 3.9; - wire_c_per_micron[0][1] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[0][1], - miller_value[0][1], horiz_dielectric_constant[0][1], - vert_dielectric_constant[0][1], fringe_cap); + wire_r_per_micron[0][1] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[0][1] = 0.405; + miller_value[0][1] = 1.5; + horiz_dielectric_constant[0][1] = 2.303; + vert_dielectric_constant[0][1] = 3.9; + wire_c_per_micron[0][1] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[0][1], miller_value[0][1], horiz_dielectric_constant[0][1], + vert_dielectric_constant[0][1], + fringe_cap); wire_pitch[0][2] = 8 * g_ip->F_sz_um; aspect_ratio[0][2] = 2.8; wire_width = wire_pitch[0][2] / 2; wire_thickness = aspect_ratio[0][2] * wire_width; wire_spacing = wire_pitch[0][2] - wire_width; - wire_r_per_micron[0][2] = - wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); + wire_r_per_micron[0][2] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[0][2] = 0.81; - miller_value[0][2] = 1.5; - horiz_dielectric_constant[0][2] = 2.303; - vert_dielectric_constant[0][2] = 3.9; - wire_c_per_micron[0][2] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[0][2], - miller_value[0][2], horiz_dielectric_constant[0][2], - vert_dielectric_constant[0][2], fringe_cap); - - // Conservative projections + miller_value[0][2] = 1.5; + horiz_dielectric_constant[0][2] = 2.303; + vert_dielectric_constant[0][2] = 3.9; + wire_c_per_micron[0][2] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[0][2], miller_value[0][2], horiz_dielectric_constant[0][2], vert_dielectric_constant[0][2], + fringe_cap); + + //Conservative projections wire_pitch[1][0] = 2.5 * g_ip->F_sz_um; aspect_ratio[1][0] = 2.0; wire_width = wire_pitch[1][0] / 2; @@ -2170,115 +2085,105 @@ void init_tech_params(double technology, bool is_tag) { barrier_thickness = 0.006; dishing_thickness = 0; alpha_scatter = 1; - wire_r_per_micron[1][0] = - wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); + wire_r_per_micron[1][0] = wire_resistance(CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[1][0] = 0.405; miller_value[1][0] = 1.5; horiz_dielectric_constant[1][0] = 2.734; vert_dielectric_constant[1][0] = 3.9; fringe_cap = 0.115e-15; - wire_c_per_micron[1][0] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[1][0], - miller_value[1][0], horiz_dielectric_constant[1][0], - vert_dielectric_constant[1][0], fringe_cap); + wire_c_per_micron[1][0] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[1][0], miller_value[1][0], horiz_dielectric_constant[1][0], vert_dielectric_constant[1][0], + fringe_cap); wire_pitch[1][1] = 4 * g_ip->F_sz_um; wire_width = wire_pitch[1][1] / 2; aspect_ratio[1][1] = 2.0; wire_thickness = aspect_ratio[1][1] * wire_width; wire_spacing = wire_pitch[1][1] - wire_width; - wire_r_per_micron[1][1] = - wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); + wire_r_per_micron[1][1] = wire_resistance(CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[1][1] = 0.405; miller_value[1][1] = 1.5; horiz_dielectric_constant[1][1] = 2.734; vert_dielectric_constant[1][1] = 3.9; - wire_c_per_micron[1][1] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[1][1], - miller_value[1][1], horiz_dielectric_constant[1][1], - vert_dielectric_constant[1][1], fringe_cap); + wire_c_per_micron[1][1] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[1][1], miller_value[1][1], horiz_dielectric_constant[1][1], vert_dielectric_constant[1][1], + fringe_cap); wire_pitch[1][2] = 8 * g_ip->F_sz_um; aspect_ratio[1][2] = 2.2; wire_width = wire_pitch[1][2] / 2; wire_thickness = aspect_ratio[1][2] * wire_width; wire_spacing = wire_pitch[1][2] - wire_width; - dishing_thickness = 0.1 * wire_thickness; - wire_r_per_micron[1][2] = - wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); + dishing_thickness = 0.1 * wire_thickness; + wire_r_per_micron[1][2] = wire_resistance(CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[1][2] = 0.77; miller_value[1][2] = 1.5; horiz_dielectric_constant[1][2] = 2.734; vert_dielectric_constant[1][2] = 3.9; - wire_c_per_micron[1][2] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[1][2], - miller_value[1][2], horiz_dielectric_constant[1][2], - vert_dielectric_constant[1][2], fringe_cap); - // Nominal projections for commodity DRAM wordline/bitline + wire_c_per_micron[1][2] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[1][2], miller_value[1][2], horiz_dielectric_constant[1][2], vert_dielectric_constant[1][2], + fringe_cap); + //Nominal projections for commodity DRAM wordline/bitline wire_pitch[1][3] = 2 * 0.065; wire_c_per_micron[1][3] = 52.5e-15 / (256 * 2 * 0.065); wire_r_per_micron[1][3] = 12 / 0.065; - } else if (tech == 45) { - // Aggressive projections. + } + else if (tech == 45) + { + //Aggressive projections. wire_pitch[0][0] = 2.5 * g_ip->F_sz_um; - aspect_ratio[0][0] = 3.0; + aspect_ratio[0][0] = 3.0; wire_width = wire_pitch[0][0] / 2; - wire_thickness = aspect_ratio[0][0] * wire_width; + wire_thickness = aspect_ratio[0][0] * wire_width; wire_spacing = wire_pitch[0][0] - wire_width; barrier_thickness = 0; dishing_thickness = 0; alpha_scatter = 1; - wire_r_per_micron[0][0] = - wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[0][0] = 0.315; - miller_value[0][0] = 1.5; - horiz_dielectric_constant[0][0] = 1.958; - vert_dielectric_constant[0][0] = 3.9; + wire_r_per_micron[0][0] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[0][0] = 0.315; + miller_value[0][0] = 1.5; + horiz_dielectric_constant[0][0] = 1.958; + vert_dielectric_constant[0][0] = 3.9; fringe_cap = 0.115e-15; - wire_c_per_micron[0][0] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[0][0], - miller_value[0][0], horiz_dielectric_constant[0][0], - vert_dielectric_constant[0][0], fringe_cap); + wire_c_per_micron[0][0] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[0][0] , miller_value[0][0] , horiz_dielectric_constant[0][0] , vert_dielectric_constant[0][0] , + fringe_cap); wire_pitch[0][1] = 4 * g_ip->F_sz_um; wire_width = wire_pitch[0][1] / 2; - aspect_ratio[0][1] = 3.0; + aspect_ratio[0][1] = 3.0; wire_thickness = aspect_ratio[0][1] * wire_width; wire_spacing = wire_pitch[0][1] - wire_width; - wire_r_per_micron[0][1] = - wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[0][1] = 0.315; - miller_value[0][1] = 1.5; - horiz_dielectric_constant[0][1] = 1.958; - vert_dielectric_constant[0][1] = 3.9; - wire_c_per_micron[0][1] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[0][1], - miller_value[0][1], horiz_dielectric_constant[0][1], - vert_dielectric_constant[0][1], fringe_cap); + wire_r_per_micron[0][1] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[0][1] = 0.315; + miller_value[0][1] = 1.5; + horiz_dielectric_constant[0][1] = 1.958; + vert_dielectric_constant[0][1] = 3.9; + wire_c_per_micron[0][1] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[0][1], miller_value[0][1], horiz_dielectric_constant[0][1], vert_dielectric_constant[0][1], + fringe_cap); wire_pitch[0][2] = 8 * g_ip->F_sz_um; aspect_ratio[0][2] = 3.0; wire_width = wire_pitch[0][2] / 2; wire_thickness = aspect_ratio[0][2] * wire_width; wire_spacing = wire_pitch[0][2] - wire_width; - wire_r_per_micron[0][2] = - wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); + wire_r_per_micron[0][2] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[0][2] = 0.63; - miller_value[0][2] = 1.5; - horiz_dielectric_constant[0][2] = 1.958; - vert_dielectric_constant[0][2] = 3.9; - wire_c_per_micron[0][2] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[0][2], - miller_value[0][2], horiz_dielectric_constant[0][2], - vert_dielectric_constant[0][2], fringe_cap); - - // Conservative projections + miller_value[0][2] = 1.5; + horiz_dielectric_constant[0][2] = 1.958; + vert_dielectric_constant[0][2] = 3.9; + wire_c_per_micron[0][2] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[0][2], miller_value[0][2], horiz_dielectric_constant[0][2], vert_dielectric_constant[0][2], + fringe_cap); + + //Conservative projections wire_pitch[1][0] = 2.5 * g_ip->F_sz_um; aspect_ratio[1][0] = 2.0; wire_width = wire_pitch[1][0] / 2; @@ -2287,36 +2192,32 @@ void init_tech_params(double technology, bool is_tag) { barrier_thickness = 0.004; dishing_thickness = 0; alpha_scatter = 1; - wire_r_per_micron[1][0] = - wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); + wire_r_per_micron[1][0] = wire_resistance(CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[1][0] = 0.315; miller_value[1][0] = 1.5; horiz_dielectric_constant[1][0] = 2.46; vert_dielectric_constant[1][0] = 3.9; fringe_cap = 0.115e-15; - wire_c_per_micron[1][0] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[1][0], - miller_value[1][0], horiz_dielectric_constant[1][0], - vert_dielectric_constant[1][0], fringe_cap); + wire_c_per_micron[1][0] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[1][0], miller_value[1][0], horiz_dielectric_constant[1][0], vert_dielectric_constant[1][0], + fringe_cap); wire_pitch[1][1] = 4 * g_ip->F_sz_um; wire_width = wire_pitch[1][1] / 2; aspect_ratio[1][1] = 2.0; wire_thickness = aspect_ratio[1][1] * wire_width; wire_spacing = wire_pitch[1][1] - wire_width; - wire_r_per_micron[1][1] = - wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); + wire_r_per_micron[1][1] = wire_resistance(CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[1][1] = 0.315; miller_value[1][1] = 1.5; horiz_dielectric_constant[1][1] = 2.46; vert_dielectric_constant[1][1] = 3.9; fringe_cap = 0.115e-15; - wire_c_per_micron[1][1] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[1][1], - miller_value[1][1], horiz_dielectric_constant[1][1], - vert_dielectric_constant[1][1], fringe_cap); + wire_c_per_micron[1][1] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[1][1], miller_value[1][1], horiz_dielectric_constant[1][1], vert_dielectric_constant[1][1], + fringe_cap); wire_pitch[1][2] = 8 * g_ip->F_sz_um; aspect_ratio[1][2] = 2.2; @@ -2324,23 +2225,23 @@ void init_tech_params(double technology, bool is_tag) { wire_thickness = aspect_ratio[1][2] * wire_width; wire_spacing = wire_pitch[1][2] - wire_width; dishing_thickness = 0.1 * wire_thickness; - wire_r_per_micron[1][2] = - wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); + wire_r_per_micron[1][2] = wire_resistance(CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[1][2] = 0.55; miller_value[1][2] = 1.5; horiz_dielectric_constant[1][2] = 2.46; vert_dielectric_constant[1][2] = 3.9; - wire_c_per_micron[1][2] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[1][2], - miller_value[1][2], horiz_dielectric_constant[1][2], - vert_dielectric_constant[1][2], fringe_cap); - // Nominal projections for commodity DRAM wordline/bitline + wire_c_per_micron[1][2] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[1][2], miller_value[1][2], horiz_dielectric_constant[1][2], vert_dielectric_constant[1][2], + fringe_cap); + //Nominal projections for commodity DRAM wordline/bitline wire_pitch[1][3] = 2 * 0.045; wire_c_per_micron[1][3] = 37.5e-15 / (256 * 2 * 0.045); wire_r_per_micron[1][3] = 12 / 0.045; - } else if (tech == 32) { - // Aggressive projections. + } + else if (tech == 32) + { + //Aggressive projections. wire_pitch[0][0] = 2.5 * g_ip->F_sz_um; aspect_ratio[0][0] = 3.0; wire_width = wire_pitch[0][0] / 2; @@ -2349,54 +2250,48 @@ void init_tech_params(double technology, bool is_tag) { barrier_thickness = 0; dishing_thickness = 0; alpha_scatter = 1; - wire_r_per_micron[0][0] = - wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); + wire_r_per_micron[0][0] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[0][0] = 0.21; miller_value[0][0] = 1.5; horiz_dielectric_constant[0][0] = 1.664; vert_dielectric_constant[0][0] = 3.9; fringe_cap = 0.115e-15; - wire_c_per_micron[0][0] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[0][0], - miller_value[0][0], horiz_dielectric_constant[0][0], - vert_dielectric_constant[0][0], fringe_cap); + wire_c_per_micron[0][0] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[0][0], miller_value[0][0], horiz_dielectric_constant[0][0], vert_dielectric_constant[0][0], + fringe_cap); wire_pitch[0][1] = 4 * g_ip->F_sz_um; wire_width = wire_pitch[0][1] / 2; aspect_ratio[0][1] = 3.0; wire_thickness = aspect_ratio[0][1] * wire_width; wire_spacing = wire_pitch[0][1] - wire_width; - wire_r_per_micron[0][1] = - wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); + wire_r_per_micron[0][1] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[0][1] = 0.21; miller_value[0][1] = 1.5; horiz_dielectric_constant[0][1] = 1.664; vert_dielectric_constant[0][1] = 3.9; - wire_c_per_micron[0][1] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[0][1], - miller_value[0][1], horiz_dielectric_constant[0][1], - vert_dielectric_constant[0][1], fringe_cap); + wire_c_per_micron[0][1] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[0][1], miller_value[0][1], horiz_dielectric_constant[0][1], vert_dielectric_constant[0][1], + fringe_cap); wire_pitch[0][2] = 8 * g_ip->F_sz_um; aspect_ratio[0][2] = 3.0; wire_width = wire_pitch[0][2] / 2; wire_thickness = aspect_ratio[0][2] * wire_width; wire_spacing = wire_pitch[0][2] - wire_width; - wire_r_per_micron[0][2] = - wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); + wire_r_per_micron[0][2] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[0][2] = 0.42; miller_value[0][2] = 1.5; horiz_dielectric_constant[0][2] = 1.664; vert_dielectric_constant[0][2] = 3.9; - wire_c_per_micron[0][2] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[0][2], - miller_value[0][2], horiz_dielectric_constant[0][2], - vert_dielectric_constant[0][2], fringe_cap); + wire_c_per_micron[0][2] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[0][2], miller_value[0][2], horiz_dielectric_constant[0][2], vert_dielectric_constant[0][2], + fringe_cap); - // Conservative projections + //Conservative projections wire_pitch[1][0] = 2.5 * g_ip->F_sz_um; aspect_ratio[1][0] = 2.0; wire_width = wire_pitch[1][0] / 2; @@ -2405,579 +2300,460 @@ void init_tech_params(double technology, bool is_tag) { barrier_thickness = 0.003; dishing_thickness = 0; alpha_scatter = 1; - wire_r_per_micron[1][0] = - wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); + wire_r_per_micron[1][0] = wire_resistance(CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[1][0] = 0.21; miller_value[1][0] = 1.5; horiz_dielectric_constant[1][0] = 2.214; vert_dielectric_constant[1][0] = 3.9; fringe_cap = 0.115e-15; - wire_c_per_micron[1][0] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[1][0], - miller_value[1][0], horiz_dielectric_constant[1][0], - vert_dielectric_constant[1][0], fringe_cap); + wire_c_per_micron[1][0] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[1][0], miller_value[1][0], horiz_dielectric_constant[1][0], vert_dielectric_constant[1][0], + fringe_cap); wire_pitch[1][1] = 4 * g_ip->F_sz_um; aspect_ratio[1][1] = 2.0; wire_width = wire_pitch[1][1] / 2; wire_thickness = aspect_ratio[1][1] * wire_width; wire_spacing = wire_pitch[1][1] - wire_width; - wire_r_per_micron[1][1] = - wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); + wire_r_per_micron[1][1] = wire_resistance(CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[1][1] = 0.21; miller_value[1][1] = 1.5; horiz_dielectric_constant[1][1] = 2.214; vert_dielectric_constant[1][1] = 3.9; - wire_c_per_micron[1][1] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[1][1], - miller_value[1][1], horiz_dielectric_constant[1][1], - vert_dielectric_constant[1][1], fringe_cap); + wire_c_per_micron[1][1] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[1][1], miller_value[1][1], horiz_dielectric_constant[1][1], vert_dielectric_constant[1][1], + fringe_cap); wire_pitch[1][2] = 8 * g_ip->F_sz_um; aspect_ratio[1][2] = 2.2; wire_width = wire_pitch[1][2] / 2; wire_thickness = aspect_ratio[1][2] * wire_width; wire_spacing = wire_pitch[1][2] - wire_width; - dishing_thickness = 0.1 * wire_thickness; - wire_r_per_micron[1][2] = - wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); + dishing_thickness = 0.1 * wire_thickness; + wire_r_per_micron[1][2] = wire_resistance(CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[1][2] = 0.385; miller_value[1][2] = 1.5; horiz_dielectric_constant[1][2] = 2.214; vert_dielectric_constant[1][2] = 3.9; - wire_c_per_micron[1][2] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[1][2], - miller_value[1][2], horiz_dielectric_constant[1][2], - vert_dielectric_constant[1][2], fringe_cap); - // Nominal projections for commodity DRAM wordline/bitline - wire_pitch[1][3] = 2 * 0.032; // micron - wire_c_per_micron[1][3] = 31e-15 / (256 * 2 * 0.032); // F/micron - wire_r_per_micron[1][3] = 12 / 0.032; // ohm/micron - } else if (tech == 22) { - // Aggressive projections. - wire_pitch[0][0] = 2.5 * g_ip->F_sz_um; // local - aspect_ratio[0][0] = 3.0; - wire_width = wire_pitch[0][0] / 2; - wire_thickness = aspect_ratio[0][0] * wire_width; - wire_spacing = wire_pitch[0][0] - wire_width; - barrier_thickness = 0; - dishing_thickness = 0; - alpha_scatter = 1; - wire_r_per_micron[0][0] = - wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[0][0] = 0.15; - miller_value[0][0] = 1.5; - horiz_dielectric_constant[0][0] = 1.414; - vert_dielectric_constant[0][0] = 3.9; - fringe_cap = 0.115e-15; - wire_c_per_micron[0][0] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[0][0], - miller_value[0][0], horiz_dielectric_constant[0][0], - vert_dielectric_constant[0][0], fringe_cap); - - wire_pitch[0][1] = 4 * g_ip->F_sz_um; // semi-global - wire_width = wire_pitch[0][1] / 2; - aspect_ratio[0][1] = 3.0; - wire_thickness = aspect_ratio[0][1] * wire_width; - wire_spacing = wire_pitch[0][1] - wire_width; - wire_r_per_micron[0][1] = - wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[0][1] = 0.15; - miller_value[0][1] = 1.5; - horiz_dielectric_constant[0][1] = 1.414; - vert_dielectric_constant[0][1] = 3.9; - wire_c_per_micron[0][1] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[0][1], - miller_value[0][1], horiz_dielectric_constant[0][1], - vert_dielectric_constant[0][1], fringe_cap); - - wire_pitch[0][2] = 8 * g_ip->F_sz_um; // global - aspect_ratio[0][2] = 3.0; - wire_width = wire_pitch[0][2] / 2; - wire_thickness = aspect_ratio[0][2] * wire_width; - wire_spacing = wire_pitch[0][2] - wire_width; - wire_r_per_micron[0][2] = - wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[0][2] = 0.3; - miller_value[0][2] = 1.5; - horiz_dielectric_constant[0][2] = 1.414; - vert_dielectric_constant[0][2] = 3.9; - wire_c_per_micron[0][2] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[0][2], - miller_value[0][2], horiz_dielectric_constant[0][2], - vert_dielectric_constant[0][2], fringe_cap); - - // //************************* - // wire_pitch[0][4] = 16 * g_ip.F_sz_um;//global - // aspect_ratio = 3.0; - // wire_width = wire_pitch[0][4] / 2; - // wire_thickness = aspect_ratio * wire_width; - // wire_spacing = wire_pitch[0][4] - wire_width; - // wire_r_per_micron[0][4] = wire_resistance(BULK_CU_RESISTIVITY, - // wire_width, - // wire_thickness, barrier_thickness, - // dishing_thickness, alpha_scatter); - // ild_thickness = 0.3; - // wire_c_per_micron[0][4] = wire_capacitance(wire_width, - // wire_thickness, wire_spacing, - // ild_thickness, miller_value, - // horiz_dielectric_constant, vert_dielectric_constant, - // fringe_cap); - // - // wire_pitch[0][5] = 24 * g_ip.F_sz_um;//global - // aspect_ratio = 3.0; - // wire_width = wire_pitch[0][5] / 2; - // wire_thickness = aspect_ratio * wire_width; - // wire_spacing = wire_pitch[0][5] - wire_width; - // wire_r_per_micron[0][5] = wire_resistance(BULK_CU_RESISTIVITY, - // wire_width, - // wire_thickness, barrier_thickness, - // dishing_thickness, alpha_scatter); - // ild_thickness = 0.3; - // wire_c_per_micron[0][5] = wire_capacitance(wire_width, - // wire_thickness, wire_spacing, - // ild_thickness, miller_value, - // horiz_dielectric_constant, vert_dielectric_constant, - // fringe_cap); - // - // wire_pitch[0][6] = 32 * g_ip.F_sz_um;//global - // aspect_ratio = 3.0; - // wire_width = wire_pitch[0][6] / 2; - // wire_thickness = aspect_ratio * wire_width; - // wire_spacing = wire_pitch[0][6] - wire_width; - // wire_r_per_micron[0][6] = wire_resistance(BULK_CU_RESISTIVITY, - // wire_width, - // wire_thickness, barrier_thickness, - // dishing_thickness, alpha_scatter); - // ild_thickness = 0.3; - // wire_c_per_micron[0][6] = wire_capacitance(wire_width, - // wire_thickness, wire_spacing, - // ild_thickness, miller_value, - // horiz_dielectric_constant, vert_dielectric_constant, - // fringe_cap); - //************************* - - // Conservative projections - wire_pitch[1][0] = 2.5 * g_ip->F_sz_um; - aspect_ratio[1][0] = 2.0; - wire_width = wire_pitch[1][0] / 2; - wire_thickness = aspect_ratio[1][0] * wire_width; - wire_spacing = wire_pitch[1][0] - wire_width; - barrier_thickness = 0.003; - dishing_thickness = 0; - alpha_scatter = 1.05; - wire_r_per_micron[1][0] = - wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[1][0] = 0.15; - miller_value[1][0] = 1.5; - horiz_dielectric_constant[1][0] = 2.104; - vert_dielectric_constant[1][0] = 3.9; - fringe_cap = 0.115e-15; - wire_c_per_micron[1][0] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[1][0], - miller_value[1][0], horiz_dielectric_constant[1][0], - vert_dielectric_constant[1][0], fringe_cap); - - wire_pitch[1][1] = 4 * g_ip->F_sz_um; - wire_width = wire_pitch[1][1] / 2; - aspect_ratio[1][1] = 2.0; - wire_thickness = aspect_ratio[1][1] * wire_width; - wire_spacing = wire_pitch[1][1] - wire_width; - wire_r_per_micron[1][1] = - wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[1][1] = 0.15; - miller_value[1][1] = 1.5; - horiz_dielectric_constant[1][1] = 2.104; - vert_dielectric_constant[1][1] = 3.9; - wire_c_per_micron[1][1] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[1][1], - miller_value[1][1], horiz_dielectric_constant[1][1], - vert_dielectric_constant[1][1], fringe_cap); - - wire_pitch[1][2] = 8 * g_ip->F_sz_um; - aspect_ratio[1][2] = 2.2; - wire_width = wire_pitch[1][2] / 2; - wire_thickness = aspect_ratio[1][2] * wire_width; - wire_spacing = wire_pitch[1][2] - wire_width; - dishing_thickness = 0.1 * wire_thickness; - wire_r_per_micron[1][2] = - wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[1][2] = 0.275; - miller_value[1][2] = 1.5; - horiz_dielectric_constant[1][2] = 2.104; - vert_dielectric_constant[1][2] = 3.9; - wire_c_per_micron[1][2] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[1][2], - miller_value[1][2], horiz_dielectric_constant[1][2], - vert_dielectric_constant[1][2], fringe_cap); - // Nominal projections for commodity DRAM wordline/bitline - wire_pitch[1][3] = 2 * 0.022; // micron - wire_c_per_micron[1][3] = 31e-15 / (256 * 2 * 0.022); // F/micron - wire_r_per_micron[1][3] = 12 / 0.022; // ohm/micron - - //****************** - // wire_pitch[1][4] = 16 * g_ip.F_sz_um; - // aspect_ratio = 2.2; - // wire_width = wire_pitch[1][4] / 2; - // wire_thickness = aspect_ratio * wire_width; - // wire_spacing = wire_pitch[1][4] - wire_width; - // dishing_thickness = 0.1 * wire_thickness; - // wire_r_per_micron[1][4] = wire_resistance(CU_RESISTIVITY, - // wire_width, - // wire_thickness, barrier_thickness, - // dishing_thickness, alpha_scatter); - // ild_thickness = 0.275; - // wire_c_per_micron[1][4] = wire_capacitance(wire_width, - // wire_thickness, wire_spacing, - // ild_thickness, miller_value, - // horiz_dielectric_constant, vert_dielectric_constant, - // fringe_cap); - // - // wire_pitch[1][5] = 24 * g_ip.F_sz_um; - // aspect_ratio = 2.2; - // wire_width = wire_pitch[1][5] / 2; - // wire_thickness = aspect_ratio * wire_width; - // wire_spacing = wire_pitch[1][5] - wire_width; - // dishing_thickness = 0.1 * wire_thickness; - // wire_r_per_micron[1][5] = wire_resistance(CU_RESISTIVITY, - // wire_width, - // wire_thickness, barrier_thickness, - // dishing_thickness, alpha_scatter); - // ild_thickness = 0.275; - // wire_c_per_micron[1][5] = wire_capacitance(wire_width, - // wire_thickness, wire_spacing, - // ild_thickness, miller_value, - // horiz_dielectric_constant, vert_dielectric_constant, - // fringe_cap); - // - // wire_pitch[1][6] = 32 * g_ip.F_sz_um; - // aspect_ratio = 2.2; - // wire_width = wire_pitch[1][6] / 2; - // wire_thickness = aspect_ratio * wire_width; - // wire_spacing = wire_pitch[1][6] - wire_width; - // dishing_thickness = 0.1 * wire_thickness; - // wire_r_per_micron[1][6] = wire_resistance(CU_RESISTIVITY, - // wire_width, - // wire_thickness, barrier_thickness, - // dishing_thickness, alpha_scatter); - // ild_thickness = 0.275; - // wire_c_per_micron[1][6] = wire_capacitance(wire_width, - // wire_thickness, wire_spacing, - // ild_thickness, miller_value, - // horiz_dielectric_constant, vert_dielectric_constant, - // fringe_cap); + wire_c_per_micron[1][2] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[1][2], miller_value[1][2], horiz_dielectric_constant[1][2], vert_dielectric_constant[1][2], + fringe_cap); + //Nominal projections for commodity DRAM wordline/bitline + wire_pitch[1][3] = 2 * 0.032;//micron + wire_c_per_micron[1][3] = 31e-15 / (256 * 2 * 0.032);//F/micron + wire_r_per_micron[1][3] = 12 / 0.032;//ohm/micron } + else if (tech == 22) + { + //Aggressive projections. + wire_pitch[0][0] = 2.5 * g_ip->F_sz_um;//local + aspect_ratio[0][0] = 3.0; + wire_width = wire_pitch[0][0] / 2; + wire_thickness = aspect_ratio[0][0] * wire_width; + wire_spacing = wire_pitch[0][0] - wire_width; + barrier_thickness = 0; + dishing_thickness = 0; + alpha_scatter = 1; + wire_r_per_micron[0][0] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[0][0] = 0.15; + miller_value[0][0] = 1.5; + horiz_dielectric_constant[0][0] = 1.414; + vert_dielectric_constant[0][0] = 3.9; + fringe_cap = 0.115e-15; + wire_c_per_micron[0][0] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[0][0], miller_value[0][0], horiz_dielectric_constant[0][0], vert_dielectric_constant[0][0], + fringe_cap); + + wire_pitch[0][1] = 4 * g_ip->F_sz_um;//semi-global + wire_width = wire_pitch[0][1] / 2; + aspect_ratio[0][1] = 3.0; + wire_thickness = aspect_ratio[0][1] * wire_width; + wire_spacing = wire_pitch[0][1] - wire_width; + wire_r_per_micron[0][1] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[0][1] = 0.15; + miller_value[0][1] = 1.5; + horiz_dielectric_constant[0][1] = 1.414; + vert_dielectric_constant[0][1] = 3.9; + wire_c_per_micron[0][1] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[0][1], miller_value[0][1], horiz_dielectric_constant[0][1], vert_dielectric_constant[0][1], + fringe_cap); + + wire_pitch[0][2] = 8 * g_ip->F_sz_um;//global + aspect_ratio[0][2] = 3.0; + wire_width = wire_pitch[0][2] / 2; + wire_thickness = aspect_ratio[0][2] * wire_width; + wire_spacing = wire_pitch[0][2] - wire_width; + wire_r_per_micron[0][2] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[0][2] = 0.3; + miller_value[0][2] = 1.5; + horiz_dielectric_constant[0][2] = 1.414; + vert_dielectric_constant[0][2] = 3.9; + wire_c_per_micron[0][2] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[0][2], miller_value[0][2], horiz_dielectric_constant[0][2], vert_dielectric_constant[0][2], + fringe_cap); + +// //************************* +// wire_pitch[0][4] = 16 * g_ip.F_sz_um;//global +// aspect_ratio = 3.0; +// wire_width = wire_pitch[0][4] / 2; +// wire_thickness = aspect_ratio * wire_width; +// wire_spacing = wire_pitch[0][4] - wire_width; +// wire_r_per_micron[0][4] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, +// wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); +// ild_thickness = 0.3; +// wire_c_per_micron[0][4] = wire_capacitance(wire_width, wire_thickness, wire_spacing, +// ild_thickness, miller_value, horiz_dielectric_constant, vert_dielectric_constant, +// fringe_cap); +// +// wire_pitch[0][5] = 24 * g_ip.F_sz_um;//global +// aspect_ratio = 3.0; +// wire_width = wire_pitch[0][5] / 2; +// wire_thickness = aspect_ratio * wire_width; +// wire_spacing = wire_pitch[0][5] - wire_width; +// wire_r_per_micron[0][5] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, +// wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); +// ild_thickness = 0.3; +// wire_c_per_micron[0][5] = wire_capacitance(wire_width, wire_thickness, wire_spacing, +// ild_thickness, miller_value, horiz_dielectric_constant, vert_dielectric_constant, +// fringe_cap); +// +// wire_pitch[0][6] = 32 * g_ip.F_sz_um;//global +// aspect_ratio = 3.0; +// wire_width = wire_pitch[0][6] / 2; +// wire_thickness = aspect_ratio * wire_width; +// wire_spacing = wire_pitch[0][6] - wire_width; +// wire_r_per_micron[0][6] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, +// wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); +// ild_thickness = 0.3; +// wire_c_per_micron[0][6] = wire_capacitance(wire_width, wire_thickness, wire_spacing, +// ild_thickness, miller_value, horiz_dielectric_constant, vert_dielectric_constant, +// fringe_cap); + //************************* + + //Conservative projections + wire_pitch[1][0] = 2.5 * g_ip->F_sz_um; + aspect_ratio[1][0] = 2.0; + wire_width = wire_pitch[1][0] / 2; + wire_thickness = aspect_ratio[1][0] * wire_width; + wire_spacing = wire_pitch[1][0] - wire_width; + barrier_thickness = 0.003; + dishing_thickness = 0; + alpha_scatter = 1.05; + wire_r_per_micron[1][0] = wire_resistance(CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[1][0] = 0.15; + miller_value[1][0] = 1.5; + horiz_dielectric_constant[1][0] = 2.104; + vert_dielectric_constant[1][0] = 3.9; + fringe_cap = 0.115e-15; + wire_c_per_micron[1][0] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[1][0], miller_value[1][0], horiz_dielectric_constant[1][0], vert_dielectric_constant[1][0], + fringe_cap); + + wire_pitch[1][1] = 4 * g_ip->F_sz_um; + wire_width = wire_pitch[1][1] / 2; + aspect_ratio[1][1] = 2.0; + wire_thickness = aspect_ratio[1][1] * wire_width; + wire_spacing = wire_pitch[1][1] - wire_width; + wire_r_per_micron[1][1] = wire_resistance(CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[1][1] = 0.15; + miller_value[1][1] = 1.5; + horiz_dielectric_constant[1][1] = 2.104; + vert_dielectric_constant[1][1] = 3.9; + wire_c_per_micron[1][1] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[1][1], miller_value[1][1], horiz_dielectric_constant[1][1], vert_dielectric_constant[1][1], + fringe_cap); + + wire_pitch[1][2] = 8 * g_ip->F_sz_um; + aspect_ratio[1][2] = 2.2; + wire_width = wire_pitch[1][2] / 2; + wire_thickness = aspect_ratio[1][2] * wire_width; + wire_spacing = wire_pitch[1][2] - wire_width; + dishing_thickness = 0.1 * wire_thickness; + wire_r_per_micron[1][2] = wire_resistance(CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[1][2] = 0.275; + miller_value[1][2] = 1.5; + horiz_dielectric_constant[1][2] = 2.104; + vert_dielectric_constant[1][2] = 3.9; + wire_c_per_micron[1][2] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[1][2], miller_value[1][2], horiz_dielectric_constant[1][2], vert_dielectric_constant[1][2], + fringe_cap); + //Nominal projections for commodity DRAM wordline/bitline + wire_pitch[1][3] = 2 * 0.022;//micron + wire_c_per_micron[1][3] = 31e-15 / (256 * 2 * 0.022);//F/micron + wire_r_per_micron[1][3] = 12 / 0.022;//ohm/micron + + //****************** +// wire_pitch[1][4] = 16 * g_ip.F_sz_um; +// aspect_ratio = 2.2; +// wire_width = wire_pitch[1][4] / 2; +// wire_thickness = aspect_ratio * wire_width; +// wire_spacing = wire_pitch[1][4] - wire_width; +// dishing_thickness = 0.1 * wire_thickness; +// wire_r_per_micron[1][4] = wire_resistance(CU_RESISTIVITY, wire_width, +// wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); +// ild_thickness = 0.275; +// wire_c_per_micron[1][4] = wire_capacitance(wire_width, wire_thickness, wire_spacing, +// ild_thickness, miller_value, horiz_dielectric_constant, vert_dielectric_constant, +// fringe_cap); +// +// wire_pitch[1][5] = 24 * g_ip.F_sz_um; +// aspect_ratio = 2.2; +// wire_width = wire_pitch[1][5] / 2; +// wire_thickness = aspect_ratio * wire_width; +// wire_spacing = wire_pitch[1][5] - wire_width; +// dishing_thickness = 0.1 * wire_thickness; +// wire_r_per_micron[1][5] = wire_resistance(CU_RESISTIVITY, wire_width, +// wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); +// ild_thickness = 0.275; +// wire_c_per_micron[1][5] = wire_capacitance(wire_width, wire_thickness, wire_spacing, +// ild_thickness, miller_value, horiz_dielectric_constant, vert_dielectric_constant, +// fringe_cap); +// +// wire_pitch[1][6] = 32 * g_ip.F_sz_um; +// aspect_ratio = 2.2; +// wire_width = wire_pitch[1][6] / 2; +// wire_thickness = aspect_ratio * wire_width; +// wire_spacing = wire_pitch[1][6] - wire_width; +// dishing_thickness = 0.1 * wire_thickness; +// wire_r_per_micron[1][6] = wire_resistance(CU_RESISTIVITY, wire_width, +// wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); +// ild_thickness = 0.275; +// wire_c_per_micron[1][6] = wire_capacitance(wire_width, wire_thickness, wire_spacing, +// ild_thickness, miller_value, horiz_dielectric_constant, vert_dielectric_constant, +// fringe_cap); + } + + else if (tech == 16) + { + //Aggressive projections. + wire_pitch[0][0] = 2.5 * g_ip->F_sz_um;//local + aspect_ratio[0][0] = 3.0; + wire_width = wire_pitch[0][0] / 2; + wire_thickness = aspect_ratio[0][0] * wire_width; + wire_spacing = wire_pitch[0][0] - wire_width; + barrier_thickness = 0; + dishing_thickness = 0; + alpha_scatter = 1; + wire_r_per_micron[0][0] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[0][0] = 0.108; + miller_value[0][0] = 1.5; + horiz_dielectric_constant[0][0] = 1.202; + vert_dielectric_constant[0][0] = 3.9; + fringe_cap = 0.115e-15; + wire_c_per_micron[0][0] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[0][0], miller_value[0][0], horiz_dielectric_constant[0][0], vert_dielectric_constant[0][0], + fringe_cap); + + wire_pitch[0][1] = 4 * g_ip->F_sz_um;//semi-global + aspect_ratio[0][1] = 3.0; + wire_width = wire_pitch[0][1] / 2; + wire_thickness = aspect_ratio[0][1] * wire_width; + wire_spacing = wire_pitch[0][1] - wire_width; + wire_r_per_micron[0][1] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[0][1] = 0.108; + miller_value[0][1] = 1.5; + horiz_dielectric_constant[0][1] = 1.202; + vert_dielectric_constant[0][1] = 3.9; + wire_c_per_micron[0][1] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[0][1], miller_value[0][1], horiz_dielectric_constant[0][1], vert_dielectric_constant[0][1], + fringe_cap); + + wire_pitch[0][2] = 8 * g_ip->F_sz_um;//global + aspect_ratio[0][2] = 3.0; + wire_width = wire_pitch[0][2] / 2; + wire_thickness = aspect_ratio[0][2] * wire_width; + wire_spacing = wire_pitch[0][2] - wire_width; + wire_r_per_micron[0][2] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[0][2] = 0.216; + miller_value[0][2] = 1.5; + horiz_dielectric_constant[0][2] = 1.202; + vert_dielectric_constant[0][2] = 3.9; + wire_c_per_micron[0][2] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[0][2], miller_value[0][2], horiz_dielectric_constant[0][2], vert_dielectric_constant[0][2], + fringe_cap); + +// //************************* +// wire_pitch[0][4] = 16 * g_ip.F_sz_um;//global +// aspect_ratio = 3.0; +// wire_width = wire_pitch[0][4] / 2; +// wire_thickness = aspect_ratio * wire_width; +// wire_spacing = wire_pitch[0][4] - wire_width; +// wire_r_per_micron[0][4] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, +// wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); +// ild_thickness = 0.3; +// wire_c_per_micron[0][4] = wire_capacitance(wire_width, wire_thickness, wire_spacing, +// ild_thickness, miller_value, horiz_dielectric_constant, vert_dielectric_constant, +// fringe_cap); +// +// wire_pitch[0][5] = 24 * g_ip.F_sz_um;//global +// aspect_ratio = 3.0; +// wire_width = wire_pitch[0][5] / 2; +// wire_thickness = aspect_ratio * wire_width; +// wire_spacing = wire_pitch[0][5] - wire_width; +// wire_r_per_micron[0][5] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, +// wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); +// ild_thickness = 0.3; +// wire_c_per_micron[0][5] = wire_capacitance(wire_width, wire_thickness, wire_spacing, +// ild_thickness, miller_value, horiz_dielectric_constant, vert_dielectric_constant, +// fringe_cap); +// +// wire_pitch[0][6] = 32 * g_ip.F_sz_um;//global +// aspect_ratio = 3.0; +// wire_width = wire_pitch[0][6] / 2; +// wire_thickness = aspect_ratio * wire_width; +// wire_spacing = wire_pitch[0][6] - wire_width; +// wire_r_per_micron[0][6] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, +// wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); +// ild_thickness = 0.3; +// wire_c_per_micron[0][6] = wire_capacitance(wire_width, wire_thickness, wire_spacing, +// ild_thickness, miller_value, horiz_dielectric_constant, vert_dielectric_constant, +// fringe_cap); + //************************* + + //Conservative projections + wire_pitch[1][0] = 2.5 * g_ip->F_sz_um; + aspect_ratio[1][0] = 2.0; + wire_width = wire_pitch[1][0] / 2; + wire_thickness = aspect_ratio[1][0] * wire_width; + wire_spacing = wire_pitch[1][0] - wire_width; + barrier_thickness = 0.002; + dishing_thickness = 0; + alpha_scatter = 1.05; + wire_r_per_micron[1][0] = wire_resistance(CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[1][0] = 0.108; + miller_value[1][0] = 1.5; + horiz_dielectric_constant[1][0] = 1.998; + vert_dielectric_constant[1][0] = 3.9; + fringe_cap = 0.115e-15; + wire_c_per_micron[1][0] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[1][0], miller_value[1][0], horiz_dielectric_constant[1][0], vert_dielectric_constant[1][0], + fringe_cap); + + wire_pitch[1][1] = 4 * g_ip->F_sz_um; + wire_width = wire_pitch[1][1] / 2; + aspect_ratio[1][1] = 2.0; + wire_thickness = aspect_ratio[1][1] * wire_width; + wire_spacing = wire_pitch[1][1] - wire_width; + wire_r_per_micron[1][1] = wire_resistance(CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[1][1] = 0.108; + miller_value[1][1] = 1.5; + horiz_dielectric_constant[1][1] = 1.998; + vert_dielectric_constant[1][1] = 3.9; + wire_c_per_micron[1][1] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[1][1], miller_value[1][1], horiz_dielectric_constant[1][1], vert_dielectric_constant[1][1], + fringe_cap); + + wire_pitch[1][2] = 8 * g_ip->F_sz_um; + aspect_ratio[1][2] = 2.2; + wire_width = wire_pitch[1][2] / 2; + wire_thickness = aspect_ratio[1][2] * wire_width; + wire_spacing = wire_pitch[1][2] - wire_width; + dishing_thickness = 0.1 * wire_thickness; + wire_r_per_micron[1][2] = wire_resistance(CU_RESISTIVITY, wire_width, + wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[1][2] = 0.198; + miller_value[1][2] = 1.5; + horiz_dielectric_constant[1][2] = 1.998; + vert_dielectric_constant[1][2] = 3.9; + wire_c_per_micron[1][2] = wire_capacitance(wire_width, wire_thickness, wire_spacing, + ild_thickness[1][2], miller_value[1][2], horiz_dielectric_constant[1][2], vert_dielectric_constant[1][2], + fringe_cap); + //Nominal projections for commodity DRAM wordline/bitline + wire_pitch[1][3] = 2 * 0.016;//micron + wire_c_per_micron[1][3] = 31e-15 / (256 * 2 * 0.016);//F/micron + wire_r_per_micron[1][3] = 12 / 0.016;//ohm/micron + + //****************** +// wire_pitch[1][4] = 16 * g_ip.F_sz_um; +// aspect_ratio = 2.2; +// wire_width = wire_pitch[1][4] / 2; +// wire_thickness = aspect_ratio * wire_width; +// wire_spacing = wire_pitch[1][4] - wire_width; +// dishing_thickness = 0.1 * wire_thickness; +// wire_r_per_micron[1][4] = wire_resistance(CU_RESISTIVITY, wire_width, +// wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); +// ild_thickness = 0.275; +// wire_c_per_micron[1][4] = wire_capacitance(wire_width, wire_thickness, wire_spacing, +// ild_thickness, miller_value, horiz_dielectric_constant, vert_dielectric_constant, +// fringe_cap); +// +// wire_pitch[1][5] = 24 * g_ip.F_sz_um; +// aspect_ratio = 2.2; +// wire_width = wire_pitch[1][5] / 2; +// wire_thickness = aspect_ratio * wire_width; +// wire_spacing = wire_pitch[1][5] - wire_width; +// dishing_thickness = 0.1 * wire_thickness; +// wire_r_per_micron[1][5] = wire_resistance(CU_RESISTIVITY, wire_width, +// wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); +// ild_thickness = 0.275; +// wire_c_per_micron[1][5] = wire_capacitance(wire_width, wire_thickness, wire_spacing, +// ild_thickness, miller_value, horiz_dielectric_constant, vert_dielectric_constant, +// fringe_cap); +// +// wire_pitch[1][6] = 32 * g_ip.F_sz_um; +// aspect_ratio = 2.2; +// wire_width = wire_pitch[1][6] / 2; +// wire_thickness = aspect_ratio * wire_width; +// wire_spacing = wire_pitch[1][6] - wire_width; +// dishing_thickness = 0.1 * wire_thickness; +// wire_r_per_micron[1][6] = wire_resistance(CU_RESISTIVITY, wire_width, +// wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); +// ild_thickness = 0.275; +// wire_c_per_micron[1][6] = wire_capacitance(wire_width, wire_thickness, wire_spacing, +// ild_thickness, miller_value, horiz_dielectric_constant, vert_dielectric_constant, +// fringe_cap); + } + g_tp.wire_local.pitch += curr_alpha * wire_pitch[g_ip->ic_proj_type][(ram_cell_tech_type == comm_dram)?3:0]; + g_tp.wire_local.R_per_um += curr_alpha * wire_r_per_micron[g_ip->ic_proj_type][(ram_cell_tech_type == comm_dram)?3:0]; + g_tp.wire_local.C_per_um += curr_alpha * wire_c_per_micron[g_ip->ic_proj_type][(ram_cell_tech_type == comm_dram)?3:0]; + g_tp.wire_local.aspect_ratio += curr_alpha * aspect_ratio[g_ip->ic_proj_type][(ram_cell_tech_type == comm_dram)?3:0]; + g_tp.wire_local.ild_thickness += curr_alpha * ild_thickness[g_ip->ic_proj_type][(ram_cell_tech_type == comm_dram)?3:0]; + g_tp.wire_local.miller_value += curr_alpha * miller_value[g_ip->ic_proj_type][(ram_cell_tech_type == comm_dram)?3:0]; + g_tp.wire_local.horiz_dielectric_constant += curr_alpha* horiz_dielectric_constant[g_ip->ic_proj_type][(ram_cell_tech_type == comm_dram)?3:0]; + g_tp.wire_local.vert_dielectric_constant += curr_alpha* vert_dielectric_constant [g_ip->ic_proj_type][(ram_cell_tech_type == comm_dram)?3:0]; + + g_tp.wire_inside_mat.pitch += curr_alpha * wire_pitch[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; + g_tp.wire_inside_mat.R_per_um += curr_alpha* wire_r_per_micron[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; + g_tp.wire_inside_mat.C_per_um += curr_alpha* wire_c_per_micron[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; + g_tp.wire_inside_mat.aspect_ratio += curr_alpha * aspect_ratio[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; + g_tp.wire_inside_mat.ild_thickness += curr_alpha * ild_thickness[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; + g_tp.wire_inside_mat.miller_value += curr_alpha * miller_value[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; + g_tp.wire_inside_mat.horiz_dielectric_constant += curr_alpha* horiz_dielectric_constant[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; + g_tp.wire_inside_mat.vert_dielectric_constant += curr_alpha* vert_dielectric_constant [g_ip->ic_proj_type][g_ip->wire_is_mat_type]; + + g_tp.wire_outside_mat.pitch += curr_alpha * wire_pitch[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; + g_tp.wire_outside_mat.R_per_um += curr_alpha*wire_r_per_micron[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; + g_tp.wire_outside_mat.C_per_um += curr_alpha*wire_c_per_micron[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; + g_tp.wire_outside_mat.aspect_ratio += curr_alpha * aspect_ratio[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; + g_tp.wire_outside_mat.ild_thickness += curr_alpha * ild_thickness[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; + g_tp.wire_outside_mat.miller_value += curr_alpha * miller_value[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; + g_tp.wire_outside_mat.horiz_dielectric_constant += curr_alpha* horiz_dielectric_constant[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; + g_tp.wire_outside_mat.vert_dielectric_constant += curr_alpha* vert_dielectric_constant [g_ip->ic_proj_type][g_ip->wire_os_mat_type]; + + g_tp.unit_len_wire_del = g_tp.wire_inside_mat.R_per_um * g_tp.wire_inside_mat.C_per_um / 2; + + g_tp.sense_delay += curr_alpha *SENSE_AMP_D; + g_tp.sense_dy_power += curr_alpha *SENSE_AMP_P; +// g_tp.horiz_dielectric_constant += horiz_dielectric_constant; +// g_tp.vert_dielectric_constant += vert_dielectric_constant; +// g_tp.aspect_ratio += aspect_ratio; +// g_tp.miller_value += miller_value; +// g_tp.ild_thickness += ild_thickness; - else if (tech == 16) { - // Aggressive projections. - wire_pitch[0][0] = 2.5 * g_ip->F_sz_um; // local - aspect_ratio[0][0] = 3.0; - wire_width = wire_pitch[0][0] / 2; - wire_thickness = aspect_ratio[0][0] * wire_width; - wire_spacing = wire_pitch[0][0] - wire_width; - barrier_thickness = 0; - dishing_thickness = 0; - alpha_scatter = 1; - wire_r_per_micron[0][0] = - wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[0][0] = 0.108; - miller_value[0][0] = 1.5; - horiz_dielectric_constant[0][0] = 1.202; - vert_dielectric_constant[0][0] = 3.9; - fringe_cap = 0.115e-15; - wire_c_per_micron[0][0] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[0][0], - miller_value[0][0], horiz_dielectric_constant[0][0], - vert_dielectric_constant[0][0], fringe_cap); - - wire_pitch[0][1] = 4 * g_ip->F_sz_um; // semi-global - aspect_ratio[0][1] = 3.0; - wire_width = wire_pitch[0][1] / 2; - wire_thickness = aspect_ratio[0][1] * wire_width; - wire_spacing = wire_pitch[0][1] - wire_width; - wire_r_per_micron[0][1] = - wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[0][1] = 0.108; - miller_value[0][1] = 1.5; - horiz_dielectric_constant[0][1] = 1.202; - vert_dielectric_constant[0][1] = 3.9; - wire_c_per_micron[0][1] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[0][1], - miller_value[0][1], horiz_dielectric_constant[0][1], - vert_dielectric_constant[0][1], fringe_cap); - - wire_pitch[0][2] = 8 * g_ip->F_sz_um; // global - aspect_ratio[0][2] = 3.0; - wire_width = wire_pitch[0][2] / 2; - wire_thickness = aspect_ratio[0][2] * wire_width; - wire_spacing = wire_pitch[0][2] - wire_width; - wire_r_per_micron[0][2] = - wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[0][2] = 0.216; - miller_value[0][2] = 1.5; - horiz_dielectric_constant[0][2] = 1.202; - vert_dielectric_constant[0][2] = 3.9; - wire_c_per_micron[0][2] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[0][2], - miller_value[0][2], horiz_dielectric_constant[0][2], - vert_dielectric_constant[0][2], fringe_cap); - - // //************************* - // wire_pitch[0][4] = 16 * g_ip.F_sz_um;//global - // aspect_ratio = 3.0; - // wire_width = wire_pitch[0][4] / 2; - // wire_thickness = aspect_ratio * wire_width; - // wire_spacing = wire_pitch[0][4] - wire_width; - // wire_r_per_micron[0][4] = wire_resistance(BULK_CU_RESISTIVITY, - // wire_width, - // wire_thickness, barrier_thickness, - // dishing_thickness, alpha_scatter); - // ild_thickness = 0.3; - // wire_c_per_micron[0][4] = wire_capacitance(wire_width, - // wire_thickness, wire_spacing, - // ild_thickness, miller_value, - // horiz_dielectric_constant, vert_dielectric_constant, - // fringe_cap); - // - // wire_pitch[0][5] = 24 * g_ip.F_sz_um;//global - // aspect_ratio = 3.0; - // wire_width = wire_pitch[0][5] / 2; - // wire_thickness = aspect_ratio * wire_width; - // wire_spacing = wire_pitch[0][5] - wire_width; - // wire_r_per_micron[0][5] = wire_resistance(BULK_CU_RESISTIVITY, - // wire_width, - // wire_thickness, barrier_thickness, - // dishing_thickness, alpha_scatter); - // ild_thickness = 0.3; - // wire_c_per_micron[0][5] = wire_capacitance(wire_width, - // wire_thickness, wire_spacing, - // ild_thickness, miller_value, - // horiz_dielectric_constant, vert_dielectric_constant, - // fringe_cap); - // - // wire_pitch[0][6] = 32 * g_ip.F_sz_um;//global - // aspect_ratio = 3.0; - // wire_width = wire_pitch[0][6] / 2; - // wire_thickness = aspect_ratio * wire_width; - // wire_spacing = wire_pitch[0][6] - wire_width; - // wire_r_per_micron[0][6] = wire_resistance(BULK_CU_RESISTIVITY, - // wire_width, - // wire_thickness, barrier_thickness, - // dishing_thickness, alpha_scatter); - // ild_thickness = 0.3; - // wire_c_per_micron[0][6] = wire_capacitance(wire_width, - // wire_thickness, wire_spacing, - // ild_thickness, miller_value, - // horiz_dielectric_constant, vert_dielectric_constant, - // fringe_cap); - //************************* - - // Conservative projections - wire_pitch[1][0] = 2.5 * g_ip->F_sz_um; - aspect_ratio[1][0] = 2.0; - wire_width = wire_pitch[1][0] / 2; - wire_thickness = aspect_ratio[1][0] * wire_width; - wire_spacing = wire_pitch[1][0] - wire_width; - barrier_thickness = 0.002; - dishing_thickness = 0; - alpha_scatter = 1.05; - wire_r_per_micron[1][0] = - wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[1][0] = 0.108; - miller_value[1][0] = 1.5; - horiz_dielectric_constant[1][0] = 1.998; - vert_dielectric_constant[1][0] = 3.9; - fringe_cap = 0.115e-15; - wire_c_per_micron[1][0] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[1][0], - miller_value[1][0], horiz_dielectric_constant[1][0], - vert_dielectric_constant[1][0], fringe_cap); - - wire_pitch[1][1] = 4 * g_ip->F_sz_um; - wire_width = wire_pitch[1][1] / 2; - aspect_ratio[1][1] = 2.0; - wire_thickness = aspect_ratio[1][1] * wire_width; - wire_spacing = wire_pitch[1][1] - wire_width; - wire_r_per_micron[1][1] = - wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[1][1] = 0.108; - miller_value[1][1] = 1.5; - horiz_dielectric_constant[1][1] = 1.998; - vert_dielectric_constant[1][1] = 3.9; - wire_c_per_micron[1][1] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[1][1], - miller_value[1][1], horiz_dielectric_constant[1][1], - vert_dielectric_constant[1][1], fringe_cap); - - wire_pitch[1][2] = 8 * g_ip->F_sz_um; - aspect_ratio[1][2] = 2.2; - wire_width = wire_pitch[1][2] / 2; - wire_thickness = aspect_ratio[1][2] * wire_width; - wire_spacing = wire_pitch[1][2] - wire_width; - dishing_thickness = 0.1 * wire_thickness; - wire_r_per_micron[1][2] = - wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, - barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[1][2] = 0.198; - miller_value[1][2] = 1.5; - horiz_dielectric_constant[1][2] = 1.998; - vert_dielectric_constant[1][2] = 3.9; - wire_c_per_micron[1][2] = wire_capacitance( - wire_width, wire_thickness, wire_spacing, ild_thickness[1][2], - miller_value[1][2], horiz_dielectric_constant[1][2], - vert_dielectric_constant[1][2], fringe_cap); - // Nominal projections for commodity DRAM wordline/bitline - wire_pitch[1][3] = 2 * 0.016; // micron - wire_c_per_micron[1][3] = 31e-15 / (256 * 2 * 0.016); // F/micron - wire_r_per_micron[1][3] = 12 / 0.016; // ohm/micron - - //****************** - // wire_pitch[1][4] = 16 * g_ip.F_sz_um; - // aspect_ratio = 2.2; - // wire_width = wire_pitch[1][4] / 2; - // wire_thickness = aspect_ratio * wire_width; - // wire_spacing = wire_pitch[1][4] - wire_width; - // dishing_thickness = 0.1 * wire_thickness; - // wire_r_per_micron[1][4] = wire_resistance(CU_RESISTIVITY, - // wire_width, - // wire_thickness, barrier_thickness, - // dishing_thickness, alpha_scatter); - // ild_thickness = 0.275; - // wire_c_per_micron[1][4] = wire_capacitance(wire_width, - // wire_thickness, wire_spacing, - // ild_thickness, miller_value, - // horiz_dielectric_constant, vert_dielectric_constant, - // fringe_cap); - // - // wire_pitch[1][5] = 24 * g_ip.F_sz_um; - // aspect_ratio = 2.2; - // wire_width = wire_pitch[1][5] / 2; - // wire_thickness = aspect_ratio * wire_width; - // wire_spacing = wire_pitch[1][5] - wire_width; - // dishing_thickness = 0.1 * wire_thickness; - // wire_r_per_micron[1][5] = wire_resistance(CU_RESISTIVITY, - // wire_width, - // wire_thickness, barrier_thickness, - // dishing_thickness, alpha_scatter); - // ild_thickness = 0.275; - // wire_c_per_micron[1][5] = wire_capacitance(wire_width, - // wire_thickness, wire_spacing, - // ild_thickness, miller_value, - // horiz_dielectric_constant, vert_dielectric_constant, - // fringe_cap); - // - // wire_pitch[1][6] = 32 * g_ip.F_sz_um; - // aspect_ratio = 2.2; - // wire_width = wire_pitch[1][6] / 2; - // wire_thickness = aspect_ratio * wire_width; - // wire_spacing = wire_pitch[1][6] - wire_width; - // dishing_thickness = 0.1 * wire_thickness; - // wire_r_per_micron[1][6] = wire_resistance(CU_RESISTIVITY, - // wire_width, - // wire_thickness, barrier_thickness, - // dishing_thickness, alpha_scatter); - // ild_thickness = 0.275; - // wire_c_per_micron[1][6] = wire_capacitance(wire_width, - // wire_thickness, wire_spacing, - // ild_thickness, miller_value, - // horiz_dielectric_constant, vert_dielectric_constant, - // fringe_cap); - } - g_tp.wire_local.pitch += - curr_alpha * wire_pitch[g_ip->ic_proj_type] - [(ram_cell_tech_type == comm_dram) ? 3 : 0]; - g_tp.wire_local.R_per_um += - curr_alpha * - wire_r_per_micron[g_ip->ic_proj_type] - [(ram_cell_tech_type == comm_dram) ? 3 : 0]; - g_tp.wire_local.C_per_um += - curr_alpha * - wire_c_per_micron[g_ip->ic_proj_type] - [(ram_cell_tech_type == comm_dram) ? 3 : 0]; - g_tp.wire_local.aspect_ratio += - curr_alpha * aspect_ratio[g_ip->ic_proj_type] - [(ram_cell_tech_type == comm_dram) ? 3 : 0]; - g_tp.wire_local.ild_thickness += - curr_alpha * ild_thickness[g_ip->ic_proj_type] - [(ram_cell_tech_type == comm_dram) ? 3 : 0]; - g_tp.wire_local.miller_value += - curr_alpha * miller_value[g_ip->ic_proj_type] - [(ram_cell_tech_type == comm_dram) ? 3 : 0]; - g_tp.wire_local.horiz_dielectric_constant += - curr_alpha * - horiz_dielectric_constant[g_ip->ic_proj_type] - [(ram_cell_tech_type == comm_dram) ? 3 : 0]; - g_tp.wire_local.vert_dielectric_constant += - curr_alpha * - vert_dielectric_constant[g_ip->ic_proj_type] - [(ram_cell_tech_type == comm_dram) ? 3 : 0]; - - g_tp.wire_inside_mat.pitch += - curr_alpha * wire_pitch[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; - g_tp.wire_inside_mat.R_per_um += - curr_alpha * - wire_r_per_micron[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; - g_tp.wire_inside_mat.C_per_um += - curr_alpha * - wire_c_per_micron[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; - g_tp.wire_inside_mat.aspect_ratio += - curr_alpha * aspect_ratio[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; - g_tp.wire_inside_mat.ild_thickness += - curr_alpha * ild_thickness[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; - g_tp.wire_inside_mat.miller_value += - curr_alpha * miller_value[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; - g_tp.wire_inside_mat.horiz_dielectric_constant += - curr_alpha * - horiz_dielectric_constant[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; - g_tp.wire_inside_mat.vert_dielectric_constant += - curr_alpha * - vert_dielectric_constant[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; - - g_tp.wire_outside_mat.pitch += - curr_alpha * wire_pitch[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; - g_tp.wire_outside_mat.R_per_um += - curr_alpha * - wire_r_per_micron[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; - g_tp.wire_outside_mat.C_per_um += - curr_alpha * - wire_c_per_micron[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; - g_tp.wire_outside_mat.aspect_ratio += - curr_alpha * aspect_ratio[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; - g_tp.wire_outside_mat.ild_thickness += - curr_alpha * ild_thickness[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; - g_tp.wire_outside_mat.miller_value += - curr_alpha * miller_value[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; - g_tp.wire_outside_mat.horiz_dielectric_constant += - curr_alpha * - horiz_dielectric_constant[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; - g_tp.wire_outside_mat.vert_dielectric_constant += - curr_alpha * - vert_dielectric_constant[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; - - g_tp.unit_len_wire_del = - g_tp.wire_inside_mat.R_per_um * g_tp.wire_inside_mat.C_per_um / 2; - - g_tp.sense_delay += curr_alpha * SENSE_AMP_D; - g_tp.sense_dy_power += curr_alpha * SENSE_AMP_P; - // g_tp.horiz_dielectric_constant += horiz_dielectric_constant; - // g_tp.vert_dielectric_constant += vert_dielectric_constant; - // g_tp.aspect_ratio += aspect_ratio; - // g_tp.miller_value += miller_value; - // g_tp.ild_thickness += ild_thickness; } g_tp.fringe_cap = fringe_cap; @@ -2988,9 +2764,9 @@ void init_tech_params(double technology, bool is_tag) { g_tp.kinv = horowitz(0, tf, 0.5, 0.5, RISE); double KLOAD = 1; c_load = KLOAD * (drain_C_(g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def) + - drain_C_(g_tp.min_w_nmos_ * p_to_n_sizing_r, PCH, 1, 1, - g_tp.cell_h_def) + + drain_C_(g_tp.min_w_nmos_ * p_to_n_sizing_r, PCH, 1, 1, g_tp.cell_h_def) + gate_C(g_tp.min_w_nmos_ * 4 * (1 + p_to_n_sizing_r), 0.0)); tf = rd * c_load; g_tp.FO4 = horowitz(0, tf, 0.5, 0.5, RISE); } + diff --git a/src/gpuwattch/version.h b/src/gpuwattch/version.h index 41bd5b9..76d8c75 100644 --- a/src/gpuwattch/version.h +++ b/src/gpuwattch/version.h @@ -32,9 +32,9 @@ #ifndef VERSION_H_ #define VERSION_H_ -#define VER_MAJOR 0 /* beta release */ -#define VER_MINOR 8 +#define VER_MAJOR 0 /* beta release */ +#define VER_MINOR 8 -#define VER_UPDATE "Aug, 2010" +#define VER_UPDATE "Aug, 2010" #endif /* VERSION_H_ */ diff --git a/src/gpuwattch/xmlParser.cc b/src/gpuwattch/xmlParser.cc index 810e6fb..968658a 100644 --- a/src/gpuwattch/xmlParser.cc +++ b/src/gpuwattch/xmlParser.cc @@ -37,26 +37,22 @@ * * NOTE: * - * If you add "#define _XMLPARSER_NO_MESSAGEBOX_" on the first line of this - *file + * If you add "#define _XMLPARSER_NO_MESSAGEBOX_" on the first line of this file * the "openFileHelper" function will always display error messages inside the * console instead of inside a message-box-window. Message-box-windows are * available on windows 9x/NT/2000/XP/Vista only. * - * The following license terms for the "XMLParser library from Business-Insight" - *apply to projects + * The following license terms for the "XMLParser library from Business-Insight" apply to projects * that are in some way related to * the "mcpat project", including applications * using "mcpat project" and tools developed * for enhancing "mcpat project". All other projects - * (not related to "mcpat project") have to use the "XMLParser library from - *Business-Insight" + * (not related to "mcpat project") have to use the "XMLParser library from Business-Insight" * code under the Aladdin Free Public License (AFPL) * See the file "AFPL-license.txt" for more informations about the AFPL license. * (see http://www.artifex.com/downloads/doc/Public.htm for detailed AFPL terms) * - * Redistribution and use of the "XMLParser library from Business-Insight" in - *source and binary forms, with or without + * Redistribution and use of the "XMLParser library from Business-Insight" in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. @@ -94,360 +90,267 @@ //#include //#endif #define WIN32_LEAN_AND_MEAN -#include // to have IsTextUnicode, MultiByteToWideChar, WideCharToMultiByte to handle unicode files -// to have "MessageBoxA" to display error messages for openFilHelper +#include // to have IsTextUnicode, MultiByteToWideChar, WideCharToMultiByte to handle unicode files + // to have "MessageBoxA" to display error messages for openFilHelper #endif -#include #include +#include #include -#include #include +#include XMLCSTR XMLNode::getVersion() { return _CXML("v2.39"); } -void freeXMLString(XMLSTR t) { - if (t) free(t); -} +void freeXMLString(XMLSTR t){if(t)free(t);} -static XMLNode::XMLCharEncoding characterEncoding = XMLNode::char_encoding_UTF8; -static char guessWideCharChars = 1, dropWhiteSpace = 1, - removeCommentsInMiddleOfText = 1; +static XMLNode::XMLCharEncoding characterEncoding=XMLNode::char_encoding_UTF8; +static char guessWideCharChars=1, dropWhiteSpace=1, removeCommentsInMiddleOfText=1; -inline int mmin(const int t1, const int t2) { return t1 < t2 ? t1 : t2; } +inline int mmin( const int t1, const int t2 ) { return t1 < t2 ? t1 : t2; } // You can modify the initialization of the variable "XMLClearTags" below // to change the clearTags that are currently recognized by the library. // The number on the second columns is the length of the string inside the // first column. The "")}, - {_CXML("")}, - {_CXML("")}, - {_CXML("
"), 5, _CXML("
")}, - // { _CXML("")}, - {NULL, 0, NULL}}; +typedef struct { XMLCSTR lpszOpen; int openTagLen; XMLCSTR lpszClose;} ALLXMLClearTag; +static ALLXMLClearTag XMLClearTags[] = +{ + { _CXML("") }, + { _CXML("") }, + { _CXML("") }, + { _CXML("
")    ,5,  _CXML("
") }, +// { _CXML("")}, + { NULL ,0, NULL } +}; // You can modify the initialization of the variable "XMLEntities" below -// to change the character entities that are currently recognized by the -// library. +// to change the character entities that are currently recognized by the library. // The number on the second columns is the length of the string inside the -// first column. Additionally, the syntaxes " " and " " are -// recognized. -typedef struct { - XMLCSTR s; - int l; - XMLCHAR c; -} XMLCharacterEntity; -static XMLCharacterEntity XMLEntities[] = { - {_CXML("&"), 5, _CXML('&')}, {_CXML("<"), 4, _CXML('<')}, - {_CXML(">"), 4, _CXML('>')}, {_CXML("""), 6, _CXML('\"')}, - {_CXML("'"), 6, _CXML('\'')}, {NULL, 0, '\0'}}; - -// When rendering the XMLNode to a string (using the "createXMLString" -// function), +// first column. Additionally, the syntaxes " " and " " are recognized. +typedef struct { XMLCSTR s; int l; XMLCHAR c;} XMLCharacterEntity; +static XMLCharacterEntity XMLEntities[] = +{ + { _CXML("&" ), 5, _CXML('&' )}, + { _CXML("<" ), 4, _CXML('<' )}, + { _CXML(">" ), 4, _CXML('>' )}, + { _CXML("""), 6, _CXML('\"')}, + { _CXML("'"), 6, _CXML('\'')}, + { NULL , 0, '\0' } +}; + +// When rendering the XMLNode to a string (using the "createXMLString" function), // you can ask for a beautiful formatting. This formatting is using the // following indentation character: #define INDENTCHAR _CXML('\t') // The following function parses the XML errors into a user friendly string. -// You can edit this to change the output language of the library to something -// else. -XMLCSTR XMLNode::getError(XMLError xerror) { - switch (xerror) { - case eXMLErrorNone: - return _CXML("No error"); - case eXMLErrorMissingEndTag: - return _CXML("Warning: Unmatched end tag"); - case eXMLErrorNoXMLTagFound: - return _CXML("Warning: No XML tag found"); - case eXMLErrorEmpty: - return _CXML("Error: No XML data"); - case eXMLErrorMissingTagName: - return _CXML("Error: Missing start tag name"); - case eXMLErrorMissingEndTagName: - return _CXML("Error: Missing end tag name"); - case eXMLErrorUnmatchedEndTag: - return _CXML("Error: Unmatched end tag"); - case eXMLErrorUnmatchedEndClearTag: - return _CXML("Error: Unmatched clear tag end"); - case eXMLErrorUnexpectedToken: - return _CXML("Error: Unexpected token found"); - case eXMLErrorNoElements: - return _CXML("Error: No elements found"); - case eXMLErrorFileNotFound: - return _CXML("Error: File not found"); - case eXMLErrorFirstTagNotFound: - return _CXML("Error: First Tag not found"); - case eXMLErrorUnknownCharacterEntity: - return _CXML("Error: Unknown character entity"); - case eXMLErrorCharacterCodeAbove255: - return _CXML( - "Error: Character code above 255 is forbidden in MultiByte char " - "mode."); - case eXMLErrorCharConversionError: - return _CXML( - "Error: unable to convert between WideChar and MultiByte chars"); - case eXMLErrorCannotOpenWriteFile: - return _CXML("Error: unable to open file for writing"); - case eXMLErrorCannotWriteFile: - return _CXML("Error: cannot write into file"); - - case eXMLErrorBase64DataSizeIsNotMultipleOf4: - return _CXML("Warning: Base64-string length is not a multiple of 4"); - case eXMLErrorBase64DecodeTruncatedData: - return _CXML("Warning: Base64-string is truncated"); - case eXMLErrorBase64DecodeIllegalCharacter: - return _CXML("Error: Base64-string contains an illegal character"); - case eXMLErrorBase64DecodeBufferTooSmall: - return _CXML("Error: Base64 decode output buffer is too small"); - }; - return _CXML("Unknown"); +// You can edit this to change the output language of the library to something else. +XMLCSTR XMLNode::getError(XMLError xerror) +{ + switch (xerror) + { + case eXMLErrorNone: return _CXML("No error"); + case eXMLErrorMissingEndTag: return _CXML("Warning: Unmatched end tag"); + case eXMLErrorNoXMLTagFound: return _CXML("Warning: No XML tag found"); + case eXMLErrorEmpty: return _CXML("Error: No XML data"); + case eXMLErrorMissingTagName: return _CXML("Error: Missing start tag name"); + case eXMLErrorMissingEndTagName: return _CXML("Error: Missing end tag name"); + case eXMLErrorUnmatchedEndTag: return _CXML("Error: Unmatched end tag"); + case eXMLErrorUnmatchedEndClearTag: return _CXML("Error: Unmatched clear tag end"); + case eXMLErrorUnexpectedToken: return _CXML("Error: Unexpected token found"); + case eXMLErrorNoElements: return _CXML("Error: No elements found"); + case eXMLErrorFileNotFound: return _CXML("Error: File not found"); + case eXMLErrorFirstTagNotFound: return _CXML("Error: First Tag not found"); + case eXMLErrorUnknownCharacterEntity:return _CXML("Error: Unknown character entity"); + case eXMLErrorCharacterCodeAbove255: return _CXML("Error: Character code above 255 is forbidden in MultiByte char mode."); + case eXMLErrorCharConversionError: return _CXML("Error: unable to convert between WideChar and MultiByte chars"); + case eXMLErrorCannotOpenWriteFile: return _CXML("Error: unable to open file for writing"); + case eXMLErrorCannotWriteFile: return _CXML("Error: cannot write into file"); + + case eXMLErrorBase64DataSizeIsNotMultipleOf4: return _CXML("Warning: Base64-string length is not a multiple of 4"); + case eXMLErrorBase64DecodeTruncatedData: return _CXML("Warning: Base64-string is truncated"); + case eXMLErrorBase64DecodeIllegalCharacter: return _CXML("Error: Base64-string contains an illegal character"); + case eXMLErrorBase64DecodeBufferTooSmall: return _CXML("Error: Base64 decode output buffer is too small"); + }; + return _CXML("Unknown"); } ///////////////////////////////////////////////////////////////////////// // Here start the abstraction layer to be OS-independent // ///////////////////////////////////////////////////////////////////////// -// Here is an abstraction layer to access some common string manipulation -// functions. -// The abstraction layer is currently working for gcc, Microsoft Visual Studio -// 6.0, +// Here is an abstraction layer to access some common string manipulation functions. +// The abstraction layer is currently working for gcc, Microsoft Visual Studio 6.0, // Microsoft Visual Studio .NET, CC (sun compiler) and Borland C++. -// If you plan to "port" the library to a new system/compiler, all you have to -// do is +// If you plan to "port" the library to a new system/compiler, all you have to do is // to edit the following lines. #ifdef XML_NO_WIDE_CHAR char myIsTextWideChar(const void *b, int len) { return FALSE; } #else -#if defined(UNDER_CE) || !defined(_XMLWINDOWS) -char myIsTextWideChar(const void *b, - int len) // inspired by the Wine API: RtlIsTextUnicode -{ + #if defined (UNDER_CE) || !defined(_XMLWINDOWS) + char myIsTextWideChar(const void *b, int len) // inspired by the Wine API: RtlIsTextUnicode + { #ifdef sun - // for SPARC processors: wchar_t* buffers must always be alligned, otherwise - // it's a char* buffer. - if ((((unsigned long)b) % sizeof(wchar_t)) != 0) return FALSE; + // for SPARC processors: wchar_t* buffers must always be alligned, otherwise it's a char* buffer. + if ((((unsigned long)b)%sizeof(wchar_t))!=0) return FALSE; #endif - const wchar_t *s = (const wchar_t *)b; + const wchar_t *s=(const wchar_t*)b; - // buffer too small: - if (len < (int)sizeof(wchar_t)) return FALSE; + // buffer too small: + if (len<(int)sizeof(wchar_t)) return FALSE; - // odd length test - if (len & 1) return FALSE; + // odd length test + if (len&1) return FALSE; - /* only checks the first 256 characters */ - len = mmin(256, len / sizeof(wchar_t)); + /* only checks the first 256 characters */ + len=mmin(256,len/sizeof(wchar_t)); - // Check for the special byte order: - if (*((unsigned short *)s) == 0xFFFE) - return TRUE; // IS_TEXT_UNICODE_REVERSE_SIGNATURE; - if (*((unsigned short *)s) == 0xFEFF) - return TRUE; // IS_TEXT_UNICODE_SIGNATURE + // Check for the special byte order: + if (*((unsigned short*)s) == 0xFFFE) return TRUE; // IS_TEXT_UNICODE_REVERSE_SIGNATURE; + if (*((unsigned short*)s) == 0xFEFF) return TRUE; // IS_TEXT_UNICODE_SIGNATURE - // checks for ASCII characters in the UNICODE stream - int i, stats = 0; - for (i = 0; i < len; i++) - if (s[i] <= (unsigned short)255) stats++; - if (stats > len / 2) return TRUE; + // checks for ASCII characters in the UNICODE stream + int i,stats=0; + for (i=0; ilen/2) return TRUE; - // Check for UNICODE NULL chars - for (i = 0; i < len; i++) - if (!s[i]) return TRUE; + // Check for UNICODE NULL chars + for (i=0; i -static inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l) { - return wsncasecmp(c1, c2, l); -} -static inline int xstrncmp(XMLCSTR c1, XMLCSTR c2, int l) { - return wsncmp(c1, c2, l); -} -static inline int xstricmp(XMLCSTR c1, XMLCSTR c2) { return wscasecmp(c1, c2); } -#else -// for gcc -static inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l) { - return wcsncasecmp(c1, c2, l); -} -static inline int xstrncmp(XMLCSTR c1, XMLCSTR c2, int l) { - return wcsncmp(c1, c2, l); -} -static inline int xstricmp(XMLCSTR c1, XMLCSTR c2) { - return wcscasecmp(c1, c2); -} -#endif -static inline XMLSTR xstrstr(XMLCSTR c1, XMLCSTR c2) { - return (XMLSTR)wcsstr(c1, c2); -} -static inline XMLSTR xstrcpy(XMLSTR c1, XMLCSTR c2) { - return (XMLSTR)wcscpy(c1, c2); -} -static inline FILE *xfopen(XMLCSTR filename, XMLCSTR mode) { - char *filenameAscii = myWideCharToMultiByte(filename); - FILE *f; - if (mode[0] == _CXML('r')) - f = fopen(filenameAscii, "rb"); - else - f = fopen(filenameAscii, "wb"); - free(filenameAscii); - return f; -} -#else -static inline FILE *xfopen(XMLCSTR filename, XMLCSTR mode) { - return fopen(filename, mode); -} -static inline int xstrlen(XMLCSTR c) { return strlen(c); } -static inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l) { - return strncasecmp(c1, c2, l); -} -static inline int xstrncmp(XMLCSTR c1, XMLCSTR c2, int l) { - return strncmp(c1, c2, l); -} -static inline int xstricmp(XMLCSTR c1, XMLCSTR c2) { - return strcasecmp(c1, c2); -} -static inline XMLSTR xstrstr(XMLCSTR c1, XMLCSTR c2) { - return (XMLSTR)strstr(c1, c2); -} -static inline XMLSTR xstrcpy(XMLSTR c1, XMLCSTR c2) { - return (XMLSTR)strcpy(c1, c2); -} -#endif -static inline int _strnicmp(const char *c1, const char *c2, int l) { - return strncasecmp(c1, c2, l); -} + #ifdef XML_NO_WIDE_CHAR + char *myWideCharToMultiByte(const wchar_t *s) { return NULL; } + #else + char *myWideCharToMultiByte(const wchar_t *s) + { + const wchar_t *ss=s; + int i=(int)wcsrtombs(NULL,&ss,0,NULL); + if (i<0) return NULL; + char *d=(char *)malloc(i+1); + wcsrtombs(d,&s,i,NULL); + d[i]=0; + return d; + } + #endif + #ifdef _XMLWIDECHAR + wchar_t *myMultiByteToWideChar(const char *s, XMLNode::XMLCharEncoding ce) + { + const char *ss=s; + int i=(int)mbsrtowcs(NULL,&ss,0,NULL); + if (i<0) return NULL; + wchar_t *d=(wchar_t *)malloc((i+1)*sizeof(wchar_t)); + mbsrtowcs(d,&s,i,NULL); + d[i]=0; + return d; + } + int xstrlen(XMLCSTR c) { return wcslen(c); } + #ifdef sun + // for CC + #include + static inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l) { return wsncasecmp(c1,c2,l);} + static inline int xstrncmp(XMLCSTR c1, XMLCSTR c2, int l) { return wsncmp(c1,c2,l);} + static inline int xstricmp(XMLCSTR c1, XMLCSTR c2) { return wscasecmp(c1,c2); } + #else + // for gcc + static inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l) { return wcsncasecmp(c1,c2,l);} + static inline int xstrncmp(XMLCSTR c1, XMLCSTR c2, int l) { return wcsncmp(c1,c2,l);} + static inline int xstricmp(XMLCSTR c1, XMLCSTR c2) { return wcscasecmp(c1,c2); } + #endif + static inline XMLSTR xstrstr(XMLCSTR c1, XMLCSTR c2) { return (XMLSTR)wcsstr(c1,c2); } + static inline XMLSTR xstrcpy(XMLSTR c1, XMLCSTR c2) { return (XMLSTR)wcscpy(c1,c2); } + static inline FILE *xfopen(XMLCSTR filename,XMLCSTR mode) + { + char *filenameAscii=myWideCharToMultiByte(filename); + FILE *f; + if (mode[0]==_CXML('r')) f=fopen(filenameAscii,"rb"); + else f=fopen(filenameAscii,"wb"); + free(filenameAscii); + return f; + } + #else + static inline FILE *xfopen(XMLCSTR filename,XMLCSTR mode) { return fopen(filename,mode); } + static inline int xstrlen(XMLCSTR c) { return strlen(c); } + static inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l) { return strncasecmp(c1,c2,l);} + static inline int xstrncmp(XMLCSTR c1, XMLCSTR c2, int l) { return strncmp(c1,c2,l);} + static inline int xstricmp(XMLCSTR c1, XMLCSTR c2) { return strcasecmp(c1,c2); } + static inline XMLSTR xstrstr(XMLCSTR c1, XMLCSTR c2) { return (XMLSTR)strstr(c1,c2); } + static inline XMLSTR xstrcpy(XMLSTR c1, XMLCSTR c2) { return (XMLSTR)strcpy(c1,c2); } + #endif + static inline int _strnicmp(const char *c1,const char *c2, int l) { return strncasecmp(c1,c2,l);} #endif + /////////////////////////////////////////////////////////////////////////////// // the "xmltoc,xmltob,xmltoi,xmltol,xmltof,xmltoa" functions // /////////////////////////////////////////////////////////////////////////////// @@ -455,145 +358,82 @@ static inline int _strnicmp(const char *c1, const char *c2, int l) { // There are only here as "convenience" functions for the user. // If you don't need them, you can delete them without any trouble. #ifdef _XMLWIDECHAR -#ifdef _XMLWINDOWS -// for Microsoft Visual Studio 6.0 and Microsoft Visual Studio .NET and Borland -// C++ Builder 6.0 -char xmltob(XMLCSTR t, int v) { - if (t && (*t)) return (char)_wtoi(t); - return v; -} -int xmltoi(XMLCSTR t, int v) { - if (t && (*t)) return _wtoi(t); - return v; -} -long xmltol(XMLCSTR t, long v) { - if (t && (*t)) return _wtol(t); - return v; -} -double xmltof(XMLCSTR t, double v) { - if (t && (*t)) wscanf(t, "%f", &v); /*v=_wtof(t);*/ - return v; -} + #ifdef _XMLWINDOWS + // for Microsoft Visual Studio 6.0 and Microsoft Visual Studio .NET and Borland C++ Builder 6.0 + char xmltob(XMLCSTR t,int v){ if (t&&(*t)) return (char)_wtoi(t); return v; } + int xmltoi(XMLCSTR t,int v){ if (t&&(*t)) return _wtoi(t); return v; } + long xmltol(XMLCSTR t,long v){ if (t&&(*t)) return _wtol(t); return v; } + double xmltof(XMLCSTR t,double v){ if (t&&(*t)) wscanf(t, "%f", &v); /*v=_wtof(t);*/ return v; } + #else + #ifdef sun + // for CC + #include + char xmltob(XMLCSTR t,int v){ if (t) return (char)wstol(t,NULL,10); return v; } + int xmltoi(XMLCSTR t,int v){ if (t) return (int)wstol(t,NULL,10); return v; } + long xmltol(XMLCSTR t,long v){ if (t) return wstol(t,NULL,10); return v; } + #else + // for gcc + char xmltob(XMLCSTR t,int v){ if (t) return (char)wcstol(t,NULL,10); return v; } + int xmltoi(XMLCSTR t,int v){ if (t) return (int)wcstol(t,NULL,10); return v; } + long xmltol(XMLCSTR t,long v){ if (t) return wcstol(t,NULL,10); return v; } + #endif + double xmltof(XMLCSTR t,double v){ if (t&&(*t)) wscanf(t, "%f", &v); /*v=_wtof(t);*/ return v; } + #endif #else -#ifdef sun -// for CC -#include -char xmltob(XMLCSTR t, int v) { - if (t) return (char)wstol(t, NULL, 10); - return v; -} -int xmltoi(XMLCSTR t, int v) { - if (t) return (int)wstol(t, NULL, 10); - return v; -} -long xmltol(XMLCSTR t, long v) { - if (t) return wstol(t, NULL, 10); - return v; -} -#else -// for gcc -char xmltob(XMLCSTR t, int v) { - if (t) return (char)wcstol(t, NULL, 10); - return v; -} -int xmltoi(XMLCSTR t, int v) { - if (t) return (int)wcstol(t, NULL, 10); - return v; -} -long xmltol(XMLCSTR t, long v) { - if (t) return wcstol(t, NULL, 10); - return v; -} -#endif -double xmltof(XMLCSTR t, double v) { - if (t && (*t)) wscanf(t, "%f", &v); /*v=_wtof(t);*/ - return v; -} -#endif -#else -char xmltob(XMLCSTR t, char v) { - if (t && (*t)) return (char)atoi(t); - return v; -} -int xmltoi(XMLCSTR t, int v) { - if (t && (*t)) return atoi(t); - return v; -} -long xmltol(XMLCSTR t, long v) { - if (t && (*t)) return atol(t); - return v; -} -double xmltof(XMLCSTR t, double v) { - if (t && (*t)) return atof(t); - return v; -} + char xmltob(XMLCSTR t,char v){ if (t&&(*t)) return (char)atoi(t); return v; } + int xmltoi(XMLCSTR t,int v){ if (t&&(*t)) return atoi(t); return v; } + long xmltol(XMLCSTR t,long v){ if (t&&(*t)) return atol(t); return v; } + double xmltof(XMLCSTR t,double v){ if (t&&(*t)) return atof(t); return v; } #endif -XMLCSTR xmltoa(XMLCSTR t, XMLCSTR v) { - if (t) return t; - return v; -} -XMLCHAR xmltoc(XMLCSTR t, XMLCHAR v) { - if (t && (*t)) return *t; - return v; -} - +XMLCSTR xmltoa(XMLCSTR t,XMLCSTR v){ if (t) return t; return v; } +XMLCHAR xmltoc(XMLCSTR t,XMLCHAR v){ if (t&&(*t)) return *t; return v; } + ///////////////////////////////////////////////////////////////////////// // the "openFileHelper" function // ///////////////////////////////////////////////////////////////////////// -// Since each application has its own way to report and deal with errors, you -// should modify & rewrite -// the following "openFileHelper" function to get an "error reporting mechanism" -// tailored to your needs. -XMLNode XMLNode::openFileHelper(XMLCSTR filename, XMLCSTR tag) { - // guess the value of the global parameter "characterEncoding" - // (the guess is based on the first 200 bytes of the file). - FILE *f = xfopen(filename, _CXML("rb")); - if (f) { - char bb[205]; - int l = (int)fread(bb, 1, 200, f); - setGlobalOptions(guessCharEncoding(bb, l), guessWideCharChars, - dropWhiteSpace, removeCommentsInMiddleOfText); - fclose(f); - } - - // parse the file - XMLResults pResults; - XMLNode xnode = XMLNode::parseFile(filename, tag, &pResults); - - // display error message (if any) - if (pResults.error != eXMLErrorNone) { - // create message - char message[2000], *s1 = (char *)"", *s3 = (char *)""; - XMLCSTR s2 = _CXML(""); - if (pResults.error == eXMLErrorFirstTagNotFound) { - s1 = (char *)"First Tag should be '"; - s2 = tag; - s3 = (char *)"'.\n"; +// Since each application has its own way to report and deal with errors, you should modify & rewrite +// the following "openFileHelper" function to get an "error reporting mechanism" tailored to your needs. +XMLNode XMLNode::openFileHelper(XMLCSTR filename, XMLCSTR tag) +{ + // guess the value of the global parameter "characterEncoding" + // (the guess is based on the first 200 bytes of the file). + FILE *f=xfopen(filename,_CXML("rb")); + if (f) + { + char bb[205]; + int l=(int)fread(bb,1,200,f); + setGlobalOptions(guessCharEncoding(bb,l),guessWideCharChars,dropWhiteSpace,removeCommentsInMiddleOfText); + fclose(f); } - sprintf(message, + + // parse the file + XMLResults pResults; + XMLNode xnode=XMLNode::parseFile(filename,tag,&pResults); + + // display error message (if any) + if (pResults.error != eXMLErrorNone) + { + // create message + char message[2000],*s1=(char*)"",*s3=(char*)""; XMLCSTR s2=_CXML(""); + if (pResults.error==eXMLErrorFirstTagNotFound) { s1=(char*)"First Tag should be '"; s2=tag; s3=(char*)"'.\n"; } + sprintf(message, #ifdef _XMLWIDECHAR - "XML Parsing error inside file '%S'.\n%S\nAt line %i, column " - "%i.\n%s%S%s" + "XML Parsing error inside file '%S'.\n%S\nAt line %i, column %i.\n%s%S%s" #else - "XML Parsing error inside file '%s'.\n%s\nAt line %i, column " - "%i.\n%s%s%s" + "XML Parsing error inside file '%s'.\n%s\nAt line %i, column %i.\n%s%s%s" #endif - , - filename, XMLNode::getError(pResults.error), pResults.nLine, - pResults.nColumn, s1, s2, s3); - -// display message -#if defined(_XMLWINDOWS) && !defined(UNDER_CE) && \ - !defined(_XMLPARSER_NO_MESSAGEBOX_) - MessageBoxA(NULL, message, "XML Parsing error", - MB_OK | MB_ICONERROR | MB_TOPMOST); + ,filename,XMLNode::getError(pResults.error),pResults.nLine,pResults.nColumn,s1,s2,s3); + + // display message +#if defined(_XMLWINDOWS) && !defined(UNDER_CE) && !defined(_XMLPARSER_NO_MESSAGEBOX_) + MessageBoxA(NULL,message,"XML Parsing error",MB_OK|MB_ICONERROR|MB_TOPMOST); #else - printf("%s", message); + printf("%s",message); #endif - exit(255); - } - return xnode; + exit(255); + } + return xnode; } ///////////////////////////////////////////////////////////////////////// @@ -603,496 +443,400 @@ XMLNode XMLNode::openFileHelper(XMLCSTR filename, XMLCSTR tag) { // You should normally not change anything below this point. #ifndef _XMLWIDECHAR -// If "characterEncoding=ascii" then we assume that all characters have the same -// length of 1 byte. -// If "characterEncoding=UTF8" then the characters have different lengths (from -// 1 byte to 4 bytes). -// If "characterEncoding=ShiftJIS" then the characters have different lengths -// (from 1 byte to 2 bytes). -// This table is used as lookup-table to know the length of a character (in -// byte) based on the +// If "characterEncoding=ascii" then we assume that all characters have the same length of 1 byte. +// If "characterEncoding=UTF8" then the characters have different lengths (from 1 byte to 4 bytes). +// If "characterEncoding=ShiftJIS" then the characters have different lengths (from 1 byte to 2 bytes). +// This table is used as lookup-table to know the length of a character (in byte) based on the // content of the first byte of the character. // (note: if you modify this, you must always have XML_utf8ByteTable[0]=0 ). -static const char XML_utf8ByteTable[256] = { +static const char XML_utf8ByteTable[256] = +{ // 0 1 2 3 4 5 6 7 8 9 a b c d e f - 0, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 End of ASCII range - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 0x80 to 0xc1 invalid - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x90 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0 - 1, 1, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 0xc2 to 0xdf 2 byte - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0 - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, // 0xe0 0xe0 to 0xef 3 byte - 4, 4, 4, 4, 4, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid + 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x00 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x10 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x20 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x30 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x40 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x50 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x60 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x70 End of ASCII range + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x80 0x80 to 0xc1 invalid + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x90 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0xa0 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0xb0 + 1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xc0 0xc2 to 0xdf 2 byte + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xd0 + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,// 0xe0 0xe0 to 0xef 3 byte + 4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid }; -static const char XML_legacyByteTable[256] = { - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; -static const char XML_sjisByteTable[256] = { - // 0 1 2 3 4 5 6 7 8 9 a b c d e f - 0, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 - 1, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, // 0x80 0x81 to 0x9F 2 bytes - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, // 0x90 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0xc0 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0xd0 - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, // 0xe0 0xe0 to 0xef 2 bytes - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 +static const char XML_legacyByteTable[256] = +{ + 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }; -static const char XML_gb2312ByteTable[256] = { +static const char XML_sjisByteTable[256] = +{ // 0 1 2 3 4 5 6 7 8 9 a b c d e f - 0, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x90 - 1, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, // 0xa0 0xa1 to 0xf7 2 bytes - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, // 0xb0 - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0 - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, // 0xe0 - 2, 2, 2, 2, 2, 2, 2, 2, - 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 + 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x00 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x10 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x20 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x30 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x40 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x50 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x60 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x70 + 1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0x80 0x81 to 0x9F 2 bytes + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0x90 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0xa0 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0xb0 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0xc0 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0xd0 + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xe0 0xe0 to 0xef 2 bytes + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 // 0xf0 }; -static const char XML_gbk_big5_ByteTable[256] = { +static const char XML_gb2312ByteTable[256] = +{ +// 0 1 2 3 4 5 6 7 8 9 a b c d e f + 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x00 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x10 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x20 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x30 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x40 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x50 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x60 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x70 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x80 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x90 + 1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xa0 0xa1 to 0xf7 2 bytes + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xb0 + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xc0 + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xd0 + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xe0 + 2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1 // 0xf0 +}; +static const char XML_gbk_big5_ByteTable[256] = +{ // 0 1 2 3 4 5 6 7 8 9 a b c d e f - 0, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 - 1, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, // 0x80 0x81 to 0xfe 2 bytes - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, // 0x90 - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, // 0xa0 - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, // 0xb0 - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0 - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, // 0xe0 - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 1 // 0xf0 + 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x00 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x10 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x20 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x30 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x40 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x50 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x60 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x70 + 1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0x80 0x81 to 0xfe 2 bytes + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0x90 + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xa0 + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xb0 + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xc0 + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xd0 + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xe0 + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1 // 0xf0 }; -static const char *XML_ByteTable = (const char *) - XML_utf8ByteTable; // the default is - // "characterEncoding=XMLNode::encoding_UTF8" +static const char *XML_ByteTable=(const char *)XML_utf8ByteTable; // the default is "characterEncoding=XMLNode::encoding_UTF8" #endif + XMLNode XMLNode::emptyXMLNode; -XMLClear XMLNode::emptyXMLClear = {NULL, NULL, NULL}; -XMLAttribute XMLNode::emptyXMLAttribute = {NULL, NULL}; +XMLClear XMLNode::emptyXMLClear={ NULL, NULL, NULL}; +XMLAttribute XMLNode::emptyXMLAttribute={ NULL, NULL}; // Enumeration used to decipher what type a token is -typedef enum XMLTokenTypeTag { - eTokenText = 0, - eTokenQuotedText, - eTokenTagStart, /* "<" */ - eTokenTagEnd, /* "" */ - eTokenEquals, /* "=" */ - eTokenDeclaration, /* "" */ - eTokenClear, - eTokenError +typedef enum XMLTokenTypeTag +{ + eTokenText = 0, + eTokenQuotedText, + eTokenTagStart, /* "<" */ + eTokenTagEnd, /* "" */ + eTokenEquals, /* "=" */ + eTokenDeclaration, /* "" */ + eTokenClear, + eTokenError } XMLTokenType; // Main structure used for parsing XML -typedef struct XML { - XMLCSTR lpXML; - XMLCSTR lpszText; - int nIndex, nIndexMissigEndTag; - enum XMLError error; - XMLCSTR lpEndTag; - int cbEndTag; - XMLCSTR lpNewElement; - int cbNewElement; - int nFirst; +typedef struct XML +{ + XMLCSTR lpXML; + XMLCSTR lpszText; + int nIndex,nIndexMissigEndTag; + enum XMLError error; + XMLCSTR lpEndTag; + int cbEndTag; + XMLCSTR lpNewElement; + int cbNewElement; + int nFirst; } XML; -typedef struct { - ALLXMLClearTag *pClr; - XMLCSTR pStr; +typedef struct +{ + ALLXMLClearTag *pClr; + XMLCSTR pStr; } NextToken; // Enumeration used when parsing attributes -typedef enum Attrib { eAttribName = 0, eAttribEquals, eAttribValue } Attrib; +typedef enum Attrib +{ + eAttribName = 0, + eAttribEquals, + eAttribValue +} Attrib; // Enumeration used when parsing elements to dictate whether we are currently // inside a tag -typedef enum Status { eInsideTag = 0, eOutsideTag } Status; +typedef enum Status +{ + eInsideTag = 0, + eOutsideTag +} Status; -XMLError XMLNode::writeToFile(XMLCSTR filename, const char *encoding, - char nFormat) const { - if (!d) return eXMLErrorNone; - FILE *f = xfopen(filename, _CXML("wb")); - if (!f) return eXMLErrorCannotOpenWriteFile; +XMLError XMLNode::writeToFile(XMLCSTR filename, const char *encoding, char nFormat) const +{ + if (!d) return eXMLErrorNone; + FILE *f=xfopen(filename,_CXML("wb")); + if (!f) return eXMLErrorCannotOpenWriteFile; #ifdef _XMLWIDECHAR - unsigned char h[2] = {0xFF, 0xFE}; - if (!fwrite(h, 2, 1, f)) return eXMLErrorCannotWriteFile; - if ((!isDeclaration()) && - ((d->lpszName) || (!getChildNode().isDeclaration()))) { - if (!fwrite(L"\n", - sizeof(wchar_t) * 40, 1, f)) - return eXMLErrorCannotWriteFile; - } + unsigned char h[2]={ 0xFF, 0xFE }; + if (!fwrite(h,2,1,f)) return eXMLErrorCannotWriteFile; + if ((!isDeclaration())&&((d->lpszName)||(!getChildNode().isDeclaration()))) + { + if (!fwrite(L"\n",sizeof(wchar_t)*40,1,f)) + return eXMLErrorCannotWriteFile; + } #else - if ((!isDeclaration()) && - ((d->lpszName) || (!getChildNode().isDeclaration()))) { - if (characterEncoding == char_encoding_UTF8) { - // header so that windows recognize the file as UTF-8: - unsigned char h[3] = {0xEF, 0xBB, 0xBF}; - if (!fwrite(h, 3, 1, f)) return eXMLErrorCannotWriteFile; - encoding = "utf-8"; - } else if (characterEncoding == char_encoding_ShiftJIS) - encoding = "SHIFT-JIS"; - - if (!encoding) encoding = "ISO-8859-1"; - if (fprintf(f, "\n", encoding) < 0) - return eXMLErrorCannotWriteFile; - } else { - if (characterEncoding == char_encoding_UTF8) { - unsigned char h[3] = {0xEF, 0xBB, 0xBF}; - if (!fwrite(h, 3, 1, f)) return eXMLErrorCannotWriteFile; + if ((!isDeclaration())&&((d->lpszName)||(!getChildNode().isDeclaration()))) + { + if (characterEncoding==char_encoding_UTF8) + { + // header so that windows recognize the file as UTF-8: + unsigned char h[3]={0xEF,0xBB,0xBF}; if (!fwrite(h,3,1,f)) return eXMLErrorCannotWriteFile; + encoding="utf-8"; + } else if (characterEncoding==char_encoding_ShiftJIS) encoding="SHIFT-JIS"; + + if (!encoding) encoding="ISO-8859-1"; + if (fprintf(f,"\n",encoding)<0) return eXMLErrorCannotWriteFile; + } else + { + if (characterEncoding==char_encoding_UTF8) + { + unsigned char h[3]={0xEF,0xBB,0xBF}; if (!fwrite(h,3,1,f)) return eXMLErrorCannotWriteFile; + } } - } #endif - int i; - XMLSTR t = createXMLString(nFormat, &i); - if (!fwrite(t, sizeof(XMLCHAR) * i, 1, f)) return eXMLErrorCannotWriteFile; - if (fclose(f) != 0) return eXMLErrorCannotWriteFile; - free(t); - return eXMLErrorNone; + int i; + XMLSTR t=createXMLString(nFormat,&i); + if (!fwrite(t,sizeof(XMLCHAR)*i,1,f)) return eXMLErrorCannotWriteFile; + if (fclose(f)!=0) return eXMLErrorCannotWriteFile; + free(t); + return eXMLErrorNone; } // Duplicate a given string. -XMLSTR stringDup(XMLCSTR lpszData, int cbData) { - if (lpszData == NULL) return NULL; - - XMLSTR lpszNew; - if (cbData == -1) cbData = (int)xstrlen(lpszData); - lpszNew = (XMLSTR)malloc((cbData + 1) * sizeof(XMLCHAR)); - if (lpszNew) { - memcpy(lpszNew, lpszData, (cbData) * sizeof(XMLCHAR)); - lpszNew[cbData] = (XMLCHAR)NULL; - } - return lpszNew; -} - -XMLSTR ToXMLStringTool::toXMLUnSafe(XMLSTR dest, XMLCSTR source) { - XMLSTR dd = dest; - XMLCHAR ch; - XMLCharacterEntity *entity; - while ((ch = *source)) { - entity = XMLEntities; - do { - if (ch == entity->c) { - xstrcpy(dest, entity->s); - dest += entity->l; - source++; - goto out_of_loop1; - } - entity++; - } while (entity->s); +XMLSTR stringDup(XMLCSTR lpszData, int cbData) +{ + if (lpszData==NULL) return NULL; + + XMLSTR lpszNew; + if (cbData==-1) cbData=(int)xstrlen(lpszData); + lpszNew = (XMLSTR)malloc((cbData+1) * sizeof(XMLCHAR)); + if (lpszNew) + { + memcpy(lpszNew, lpszData, (cbData) * sizeof(XMLCHAR)); + lpszNew[cbData] = (XMLCHAR)NULL; + } + return lpszNew; +} + +XMLSTR ToXMLStringTool::toXMLUnSafe(XMLSTR dest,XMLCSTR source) +{ + XMLSTR dd=dest; + XMLCHAR ch; + XMLCharacterEntity *entity; + while ((ch=*source)) + { + entity=XMLEntities; + do + { + if (ch==entity->c) {xstrcpy(dest,entity->s); dest+=entity->l; source++; goto out_of_loop1; } + entity++; + } while(entity->s); #ifdef _XMLWIDECHAR - *(dest++) = *(source++); + *(dest++)=*(source++); #else - switch (XML_ByteTable[(unsigned char)ch]) { - case 4: - *(dest++) = *(source++); - case 3: - *(dest++) = *(source++); - case 2: - *(dest++) = *(source++); - case 1: - *(dest++) = *(source++); - } + switch(XML_ByteTable[(unsigned char)ch]) + { + case 4: *(dest++)=*(source++); + case 3: *(dest++)=*(source++); + case 2: *(dest++)=*(source++); + case 1: *(dest++)=*(source++); + } #endif - out_of_loop1:; - } - *dest = 0; - return dd; +out_of_loop1: + ; + } + *dest=0; + return dd; } // private (used while rendering): -int ToXMLStringTool::lengthXMLString(XMLCSTR source) { - int r = 0; - XMLCharacterEntity *entity; - XMLCHAR ch; - while ((ch = *source)) { - entity = XMLEntities; - do { - if (ch == entity->c) { - r += entity->l; - source++; - goto out_of_loop1; - } - entity++; - } while (entity->s); +int ToXMLStringTool::lengthXMLString(XMLCSTR source) +{ + int r=0; + XMLCharacterEntity *entity; + XMLCHAR ch; + while ((ch=*source)) + { + entity=XMLEntities; + do + { + if (ch==entity->c) { r+=entity->l; source++; goto out_of_loop1; } + entity++; + } while(entity->s); #ifdef _XMLWIDECHAR - r++; - source++; + r++; source++; #else - ch = XML_ByteTable[(unsigned char)ch]; - r += ch; - source += ch; + ch=XML_ByteTable[(unsigned char)ch]; r+=ch; source+=ch; #endif - out_of_loop1:; - } - return r; +out_of_loop1: + ; + } + return r; } -ToXMLStringTool::~ToXMLStringTool() { freeBuffer(); } -void ToXMLStringTool::freeBuffer() { - if (buf) free(buf); - buf = NULL; - buflen = 0; -} -XMLSTR ToXMLStringTool::toXML(XMLCSTR source) { - int l = lengthXMLString(source) + 1; - if (l > buflen) { - buflen = l; - buf = (XMLSTR)realloc(buf, l * sizeof(XMLCHAR)); - } - return toXMLUnSafe(buf, source); +ToXMLStringTool::~ToXMLStringTool(){ freeBuffer(); } +void ToXMLStringTool::freeBuffer(){ if (buf) free(buf); buf=NULL; buflen=0; } +XMLSTR ToXMLStringTool::toXML(XMLCSTR source) +{ + int l=lengthXMLString(source)+1; + if (l>buflen) { buflen=l; buf=(XMLSTR)realloc(buf,l*sizeof(XMLCHAR)); } + return toXMLUnSafe(buf,source); } // private: -XMLSTR fromXMLString(XMLCSTR s, int lo, XML *pXML) { - // This function is the opposite of the function "toXMLString". It decodes the - // escape - // sequences &, ", ', <, > and replace them by the - // characters - // &,",',<,>. This function is used internally by the XML Parser. All the - // calls to - // the XML library will always gives you back "decoded" strings. - // - // in: string (s) and length (lo) of string - // out: new allocated string converted from xml - if (!s) return NULL; - - int ll = 0, j; - XMLSTR d; - XMLCSTR ss = s; - XMLCharacterEntity *entity; - while ((lo > 0) && (*s)) { - if (*s == _CXML('&')) { - if ((lo > 2) && (s[1] == _CXML('#'))) { - s += 2; - lo -= 2; - if ((*s == _CXML('X')) || (*s == _CXML('x'))) { - s++; - lo--; - } - while ((*s) && (*s != _CXML(';')) && ((lo--) > 0)) s++; - if (*s != _CXML(';')) { - pXML->error = eXMLErrorUnknownCharacterEntity; - return NULL; - } - s++; - lo--; - } else { - entity = XMLEntities; - do { - if ((lo >= entity->l) && (xstrnicmp(s, entity->s, entity->l) == 0)) { - s += entity->l; - lo -= entity->l; - break; - } - entity++; - } while (entity->s); - if (!entity->s) { - pXML->error = eXMLErrorUnknownCharacterEntity; - return NULL; - } - } - } else { +XMLSTR fromXMLString(XMLCSTR s, int lo, XML *pXML) +{ + // This function is the opposite of the function "toXMLString". It decodes the escape + // sequences &, ", ', <, > and replace them by the characters + // &,",',<,>. This function is used internally by the XML Parser. All the calls to + // the XML library will always gives you back "decoded" strings. + // + // in: string (s) and length (lo) of string + // out: new allocated string converted from xml + if (!s) return NULL; + + int ll=0,j; + XMLSTR d; + XMLCSTR ss=s; + XMLCharacterEntity *entity; + while ((lo>0)&&(*s)) + { + if (*s==_CXML('&')) + { + if ((lo>2)&&(s[1]==_CXML('#'))) + { + s+=2; lo-=2; + if ((*s==_CXML('X'))||(*s==_CXML('x'))) { s++; lo--; } + while ((*s)&&(*s!=_CXML(';'))&&((lo--)>0)) s++; + if (*s!=_CXML(';')) + { + pXML->error=eXMLErrorUnknownCharacterEntity; + return NULL; + } + s++; lo--; + } else + { + entity=XMLEntities; + do + { + if ((lo>=entity->l)&&(xstrnicmp(s,entity->s,entity->l)==0)) { s+=entity->l; lo-=entity->l; break; } + entity++; + } while(entity->s); + if (!entity->s) + { + pXML->error=eXMLErrorUnknownCharacterEntity; + return NULL; + } + } + } else + { #ifdef _XMLWIDECHAR - s++; - lo--; + s++; lo--; #else - j = XML_ByteTable[(unsigned char)*s]; - s += j; - lo -= j; - ll += j - 1; + j=XML_ByteTable[(unsigned char)*s]; s+=j; lo-=j; ll+=j-1; #endif - } - ll++; - } - - d = (XMLSTR)malloc((ll + 1) * sizeof(XMLCHAR)); - s = d; - while (ll-- > 0) { - if (*ss == _CXML('&')) { - if (ss[1] == _CXML('#')) { - ss += 2; - j = 0; - if ((*ss == _CXML('X')) || (*ss == _CXML('x'))) { - ss++; - while (*ss != _CXML(';')) { - if ((*ss >= _CXML('0')) && (*ss <= _CXML('9'))) - j = (j << 4) + *ss - _CXML('0'); - else if ((*ss >= _CXML('A')) && (*ss <= _CXML('F'))) - j = (j << 4) + *ss - _CXML('A') + 10; - else if ((*ss >= _CXML('a')) && (*ss <= _CXML('f'))) - j = (j << 4) + *ss - _CXML('a') + 10; - else { - free((void *)s); - pXML->error = eXMLErrorUnknownCharacterEntity; - return NULL; - } - ss++; - } - } else { - while (*ss != _CXML(';')) { - if ((*ss >= _CXML('0')) && (*ss <= _CXML('9'))) - j = (j * 10) + *ss - _CXML('0'); - else { - free((void *)s); - pXML->error = eXMLErrorUnknownCharacterEntity; - return NULL; - } - ss++; - } } + ll++; + } + + d=(XMLSTR)malloc((ll+1)*sizeof(XMLCHAR)); + s=d; + while (ll-->0) + { + if (*ss==_CXML('&')) + { + if (ss[1]==_CXML('#')) + { + ss+=2; j=0; + if ((*ss==_CXML('X'))||(*ss==_CXML('x'))) + { + ss++; + while (*ss!=_CXML(';')) + { + if ((*ss>=_CXML('0'))&&(*ss<=_CXML('9'))) j=(j<<4)+*ss-_CXML('0'); + else if ((*ss>=_CXML('A'))&&(*ss<=_CXML('F'))) j=(j<<4)+*ss-_CXML('A')+10; + else if ((*ss>=_CXML('a'))&&(*ss<=_CXML('f'))) j=(j<<4)+*ss-_CXML('a')+10; + else { free((void*)s); pXML->error=eXMLErrorUnknownCharacterEntity;return NULL;} + ss++; + } + } else + { + while (*ss!=_CXML(';')) + { + if ((*ss>=_CXML('0'))&&(*ss<=_CXML('9'))) j=(j*10)+*ss-_CXML('0'); + else { free((void*)s); pXML->error=eXMLErrorUnknownCharacterEntity;return NULL;} + ss++; + } + } #ifndef _XMLWIDECHAR - if (j > 255) { - free((void *)s); - pXML->error = eXMLErrorCharacterCodeAbove255; - return NULL; - } + if (j>255) { free((void*)s); pXML->error=eXMLErrorCharacterCodeAbove255;return NULL;} #endif - (*d++) = (XMLCHAR)j; - ss++; - } else { - entity = XMLEntities; - do { - if (xstrnicmp(ss, entity->s, entity->l) == 0) { - *(d++) = entity->c; - ss += entity->l; - break; - } - entity++; - } while (entity->s); - } - } else { + (*d++)=(XMLCHAR)j; ss++; + } else + { + entity=XMLEntities; + do + { + if (xstrnicmp(ss,entity->s,entity->l)==0) { *(d++)=entity->c; ss+=entity->l; break; } + entity++; + } while(entity->s); + } + } else + { #ifdef _XMLWIDECHAR - *(d++) = *(ss++); + *(d++)=*(ss++); #else - switch (XML_ByteTable[(unsigned char)*ss]) { - case 4: - *(d++) = *(ss++); - ll--; - case 3: - *(d++) = *(ss++); - ll--; - case 2: - *(d++) = *(ss++); - ll--; - case 1: - *(d++) = *(ss++); - } + switch(XML_ByteTable[(unsigned char)*ss]) + { + case 4: *(d++)=*(ss++); ll--; + case 3: *(d++)=*(ss++); ll--; + case 2: *(d++)=*(ss++); ll--; + case 1: *(d++)=*(ss++); + } #endif + } } - } - *d = 0; - return (XMLSTR)s; + *d=0; + return (XMLSTR)s; } -#define XML_isSPACECHAR(ch) \ - ((ch == _CXML('\n')) || (ch == _CXML(' ')) || (ch == _CXML('\t')) || \ - (ch == _CXML('\r'))) +#define XML_isSPACECHAR(ch) ((ch==_CXML('\n'))||(ch==_CXML(' '))||(ch== _CXML('\t'))||(ch==_CXML('\r'))) // private: char myTagCompare(XMLCSTR cclose, XMLCSTR copen) @@ -1100,1259 +844,1233 @@ char myTagCompare(XMLCSTR cclose, XMLCSTR copen) // return 0 if equals // return 1 if different { - if (!cclose) return 1; - int l = (int)xstrlen(cclose); - if (xstrnicmp(cclose, copen, l) != 0) return 1; - const XMLCHAR c = copen[l]; - if (XML_isSPACECHAR(c) || (c == _CXML('/')) || (c == _CXML('<')) || - (c == _CXML('>')) || (c == _CXML('='))) - return 0; - return 1; + if (!cclose) return 1; + int l=(int)xstrlen(cclose); + if (xstrnicmp(cclose, copen, l)!=0) return 1; + const XMLCHAR c=copen[l]; + if (XML_isSPACECHAR(c)|| + (c==_CXML('/' ))|| + (c==_CXML('<' ))|| + (c==_CXML('>' ))|| + (c==_CXML('=' ))) return 0; + return 1; } // Obtain the next character from the string. -static inline XMLCHAR getNextChar(XML *pXML) { - XMLCHAR ch = pXML->lpXML[pXML->nIndex]; +static inline XMLCHAR getNextChar(XML *pXML) +{ + XMLCHAR ch = pXML->lpXML[pXML->nIndex]; #ifdef _XMLWIDECHAR - if (ch != 0) pXML->nIndex++; + if (ch!=0) pXML->nIndex++; #else - pXML->nIndex += XML_ByteTable[(unsigned char)ch]; + pXML->nIndex+=XML_ByteTable[(unsigned char)ch]; #endif - return ch; + return ch; } // Find the next token in a string. // pcbToken contains the number of characters that have been read. -static NextToken GetNextToken(XML *pXML, int *pcbToken, - enum XMLTokenTypeTag *pType) { - NextToken result; - XMLCHAR ch; - XMLCHAR chTemp; - int indexStart, nFoundMatch, nIsText = FALSE; - result.pClr = NULL; // prevent warning - - // Find next non-white space character - do { - indexStart = pXML->nIndex; - ch = getNextChar(pXML); - } while XML_isSPACECHAR(ch); - - if (ch) { - // Cache the current string pointer - result.pStr = &pXML->lpXML[indexStart]; - - // First check whether the token is in the clear tag list (meaning it - // does not need formatting). - ALLXMLClearTag *ctag = XMLClearTags; - do { - if (xstrncmp(ctag->lpszOpen, result.pStr, ctag->openTagLen) == 0) { - result.pClr = ctag; - pXML->nIndex += ctag->openTagLen - 1; - *pType = eTokenClear; - return result; - } - ctag++; - } while (ctag->lpszOpen); - - // If we didn't find a clear tag then check for standard tokens - switch (ch) { - // Check for quotes - case _CXML('\''): - case _CXML('\"'): - // Type of token - *pType = eTokenQuotedText; - chTemp = ch; - - // Set the size - nFoundMatch = FALSE; - - // Search through the string to find a matching quote - while ((ch = getNextChar(pXML))) { - if (ch == chTemp) { - nFoundMatch = TRUE; - break; - } - if (ch == _CXML('<')) break; - } +static NextToken GetNextToken(XML *pXML, int *pcbToken, enum XMLTokenTypeTag *pType) +{ + NextToken result; + XMLCHAR ch; + XMLCHAR chTemp; + int indexStart,nFoundMatch,nIsText=FALSE; + result.pClr=NULL; // prevent warning + + // Find next non-white space character + do { indexStart=pXML->nIndex; ch=getNextChar(pXML); } while XML_isSPACECHAR(ch); + + if (ch) + { + // Cache the current string pointer + result.pStr = &pXML->lpXML[indexStart]; + + // First check whether the token is in the clear tag list (meaning it + // does not need formatting). + ALLXMLClearTag *ctag=XMLClearTags; + do + { + if (xstrncmp(ctag->lpszOpen, result.pStr, ctag->openTagLen)==0) + { + result.pClr=ctag; + pXML->nIndex+=ctag->openTagLen-1; + *pType=eTokenClear; + return result; + } + ctag++; + } while(ctag->lpszOpen); + + // If we didn't find a clear tag then check for standard tokens + switch(ch) + { + // Check for quotes + case _CXML('\''): + case _CXML('\"'): + // Type of token + *pType = eTokenQuotedText; + chTemp = ch; + + // Set the size + nFoundMatch = FALSE; + + // Search through the string to find a matching quote + while((ch = getNextChar(pXML))) + { + if (ch==chTemp) { nFoundMatch = TRUE; break; } + if (ch==_CXML('<')) break; + } - // If we failed to find a matching quote - if (nFoundMatch == FALSE) { - pXML->nIndex = indexStart + 1; - nIsText = TRUE; - break; - } + // If we failed to find a matching quote + if (nFoundMatch == FALSE) + { + pXML->nIndex=indexStart+1; + nIsText=TRUE; + break; + } - // 4.02.2002 - // if (FindNonWhiteSpace(pXML)) pXML->nIndex--; +// 4.02.2002 +// if (FindNonWhiteSpace(pXML)) pXML->nIndex--; - break; + break; - // Equals (used with attribute values) - case _CXML('='): - *pType = eTokenEquals; - break; + // Equals (used with attribute values) + case _CXML('='): + *pType = eTokenEquals; + break; - // Close tag - case _CXML('>'): - *pType = eTokenCloseTag; - break; + // Close tag + case _CXML('>'): + *pType = eTokenCloseTag; + break; - // Check for tag start and tag end - case _CXML('<'): + // Check for tag start and tag end + case _CXML('<'): - // Peek at the next character to see if we have an end tag 'lpXML[pXML->nIndex]; + // Peek at the next character to see if we have an end tag 'lpXML[pXML->nIndex]; - // If we have a tag end... - if (chTemp == _CXML('/')) { - // Set the type and ensure we point at the next character - getNextChar(pXML); - *pType = eTokenTagEnd; - } + // If we have a tag end... + if (chTemp == _CXML('/')) + { + // Set the type and ensure we point at the next character + getNextChar(pXML); + *pType = eTokenTagEnd; + } - // If we have an XML declaration tag - else if (chTemp == _CXML('?')) { - // Set the type and ensure we point at the next character - getNextChar(pXML); - *pType = eTokenDeclaration; - } + // If we have an XML declaration tag + else if (chTemp == _CXML('?')) + { - // Otherwise we must have a start tag - else { - *pType = eTokenTagStart; - } - break; + // Set the type and ensure we point at the next character + getNextChar(pXML); + *pType = eTokenDeclaration; + } - // Check to see if we have a short hand type end tag ('/>'). - case _CXML('/'): + // Otherwise we must have a start tag + else + { + *pType = eTokenTagStart; + } + break; - // Peek at the next character to see if we have a short end tag '/>' - chTemp = pXML->lpXML[pXML->nIndex]; + // Check to see if we have a short hand type end tag ('/>'). + case _CXML('/'): - // If we have a short hand end tag... - if (chTemp == _CXML('>')) { - // Set the type and ensure we point at the next character - getNextChar(pXML); - *pType = eTokenShortHandClose; - break; - } + // Peek at the next character to see if we have a short end tag '/>' + chTemp = pXML->lpXML[pXML->nIndex]; - // If we haven't found a short hand closing tag then drop into the - // text process + // If we have a short hand end tag... + if (chTemp == _CXML('>')) + { + // Set the type and ensure we point at the next character + getNextChar(pXML); + *pType = eTokenShortHandClose; + break; + } - // Other characters - default: - nIsText = TRUE; - } + // If we haven't found a short hand closing tag then drop into the + // text process - // If this is a TEXT node - if (nIsText) { - // Indicate we are dealing with text - *pType = eTokenText; - while ((ch = getNextChar(pXML))) { - if - XML_isSPACECHAR(ch) { - indexStart++; - break; - } - else if (ch == _CXML('/')) { - // If we find a slash then this maybe text or a short hand end tag - // Peek at the next character to see it we have short hand end tag - ch = pXML->lpXML[pXML->nIndex]; - // If we found a short hand end tag then we need to exit the loop - if (ch == _CXML('>')) { - pXML->nIndex--; - break; - } + // Other characters + default: + nIsText = TRUE; + } - } else if ((ch == _CXML('<')) || (ch == _CXML('>')) || - (ch == _CXML('='))) { - pXML->nIndex--; - break; + // If this is a TEXT node + if (nIsText) + { + // Indicate we are dealing with text + *pType = eTokenText; + while((ch = getNextChar(pXML))) + { + if XML_isSPACECHAR(ch) + { + indexStart++; break; + + } else if (ch==_CXML('/')) + { + // If we find a slash then this maybe text or a short hand end tag + // Peek at the next character to see it we have short hand end tag + ch=pXML->lpXML[pXML->nIndex]; + // If we found a short hand end tag then we need to exit the loop + if (ch==_CXML('>')) { pXML->nIndex--; break; } + + } else if ((ch==_CXML('<'))||(ch==_CXML('>'))||(ch==_CXML('='))) + { + pXML->nIndex--; break; + } + } } - } + *pcbToken = pXML->nIndex-indexStart; + } else + { + // If we failed to obtain a valid character + *pcbToken = 0; + *pType = eTokenError; + result.pStr=NULL; } - *pcbToken = pXML->nIndex - indexStart; - } else { - // If we failed to obtain a valid character - *pcbToken = 0; - *pType = eTokenError; - result.pStr = NULL; - } - return result; + return result; } -XMLCSTR XMLNode::updateName_WOSD(XMLSTR lpszName) { - if (!d) { - free(lpszName); - return NULL; - } - if (d->lpszName && (lpszName != d->lpszName)) free((void *)d->lpszName); - d->lpszName = lpszName; - return lpszName; +XMLCSTR XMLNode::updateName_WOSD(XMLSTR lpszName) +{ + if (!d) { free(lpszName); return NULL; } + if (d->lpszName&&(lpszName!=d->lpszName)) free((void*)d->lpszName); + d->lpszName=lpszName; + return lpszName; } // private: -XMLNode::XMLNode(struct XMLNodeDataTag *p) { - d = p; - (p->ref_count)++; -} -XMLNode::XMLNode(XMLNodeData *pParent, XMLSTR lpszName, char isDeclaration) { - d = (XMLNodeData *)malloc(sizeof(XMLNodeData)); - d->ref_count = 1; +XMLNode::XMLNode(struct XMLNodeDataTag *p){ d=p; (p->ref_count)++; } +XMLNode::XMLNode(XMLNodeData *pParent, XMLSTR lpszName, char isDeclaration) +{ + d=(XMLNodeData*)malloc(sizeof(XMLNodeData)); + d->ref_count=1; - d->lpszName = NULL; - d->nChild = 0; - d->nText = 0; - d->nClear = 0; - d->nAttribute = 0; + d->lpszName=NULL; + d->nChild= 0; + d->nText = 0; + d->nClear = 0; + d->nAttribute = 0; - d->isDeclaration = isDeclaration; + d->isDeclaration = isDeclaration; - d->pParent = pParent; - d->pChild = NULL; - d->pText = NULL; - d->pClear = NULL; - d->pAttribute = NULL; - d->pOrder = NULL; + d->pParent = pParent; + d->pChild= NULL; + d->pText= NULL; + d->pClear= NULL; + d->pAttribute= NULL; + d->pOrder= NULL; - updateName_WOSD(lpszName); + updateName_WOSD(lpszName); } -XMLNode XMLNode::createXMLTopNode_WOSD(XMLSTR lpszName, char isDeclaration) { - return XMLNode(NULL, lpszName, isDeclaration); -} -XMLNode XMLNode::createXMLTopNode(XMLCSTR lpszName, char isDeclaration) { - return XMLNode(NULL, stringDup(lpszName), isDeclaration); -} +XMLNode XMLNode::createXMLTopNode_WOSD(XMLSTR lpszName, char isDeclaration) { return XMLNode(NULL,lpszName,isDeclaration); } +XMLNode XMLNode::createXMLTopNode(XMLCSTR lpszName, char isDeclaration) { return XMLNode(NULL,stringDup(lpszName),isDeclaration); } #define MEMORYINCREASE 50 -static inline void myFree(void *p) { - if (p) free(p); -} -static inline void *myRealloc(void *p, int newsize, int memInc, - int sizeofElem) { - if (p == NULL) { - if (memInc) return malloc(memInc * sizeofElem); - return malloc(sizeofElem); - } - if ((memInc == 0) || ((newsize % memInc) == 0)) - p = realloc(p, (newsize + memInc) * sizeofElem); - // if (!p) - // { - // printf("XMLParser Error: Not enough memory! Aborting...\n"); - // exit(220); - // } - return p; +static inline void myFree(void *p) { if (p) free(p); } +static inline void *myRealloc(void *p, int newsize, int memInc, int sizeofElem) +{ + if (p==NULL) { if (memInc) return malloc(memInc*sizeofElem); return malloc(sizeofElem); } + if ((memInc==0)||((newsize%memInc)==0)) p=realloc(p,(newsize+memInc)*sizeofElem); +// if (!p) +// { +// printf("XMLParser Error: Not enough memory! Aborting...\n"); exit(220); +// } + return p; } // private: -XMLElementPosition XMLNode::findPosition(XMLNodeData *d, int index, - XMLElementType xxtype) { - if (index < 0) return -1; - int i = 0, j = (int)((index << 2) + xxtype), *o = d->pOrder; - while (o[i] != j) i++; - return i; +XMLElementPosition XMLNode::findPosition(XMLNodeData *d, int index, XMLElementType xxtype) +{ + if (index<0) return -1; + int i=0,j=(int)((index<<2)+xxtype),*o=d->pOrder; while (o[i]!=j) i++; return i; } // private: // update "order" information when deleting a content of a XMLNode -int XMLNode::removeOrderElement(XMLNodeData *d, XMLElementType t, int index) { - int n = d->nChild + d->nText + d->nClear, *o = d->pOrder, - i = findPosition(d, index, t); - memmove(o + i, o + i + 1, (n - i) * sizeof(int)); - for (; i < n; i++) - if ((o[i] & 3) == (int)t) o[i] -= 4; - // We should normally do: - // d->pOrder=(int)realloc(d->pOrder,n*sizeof(int)); - // but we skip reallocation because it's too time consuming. - // Anyway, at the end, it will be free'd completely at once. - return i; -} - -void *XMLNode::addToOrder(int memoryIncrease, int *_pos, int nc, void *p, - int size, XMLElementType xtype) { - // in: *_pos is the position inside d->pOrder ("-1" means "EndOf") - // out: *_pos is the index inside p - p = myRealloc(p, (nc + 1), memoryIncrease, size); - int n = d->nChild + d->nText + d->nClear; - d->pOrder = - (int *)myRealloc(d->pOrder, n + 1, memoryIncrease * 3, sizeof(int)); - int pos = *_pos, *o = d->pOrder; - - if ((pos < 0) || (pos >= n)) { - *_pos = nc; - o[n] = (int)((nc << 2) + xtype); - return p; - } +int XMLNode::removeOrderElement(XMLNodeData *d, XMLElementType t, int index) +{ + int n=d->nChild+d->nText+d->nClear, *o=d->pOrder,i=findPosition(d,index,t); + memmove(o+i, o+i+1, (n-i)*sizeof(int)); + for (;ipOrder=(int)realloc(d->pOrder,n*sizeof(int)); + // but we skip reallocation because it's too time consuming. + // Anyway, at the end, it will be free'd completely at once. + return i; +} + +void *XMLNode::addToOrder(int memoryIncrease,int *_pos, int nc, void *p, int size, XMLElementType xtype) +{ + // in: *_pos is the position inside d->pOrder ("-1" means "EndOf") + // out: *_pos is the index inside p + p=myRealloc(p,(nc+1),memoryIncrease,size); + int n=d->nChild+d->nText+d->nClear; + d->pOrder=(int*)myRealloc(d->pOrder,n+1,memoryIncrease*3,sizeof(int)); + int pos=*_pos,*o=d->pOrder; - int i = pos; - memmove(o + i + 1, o + i, (n - i) * sizeof(int)); + if ((pos<0)||(pos>=n)) { *_pos=nc; o[n]=(int)((nc<<2)+xtype); return p; } - while ((pos < n) && ((o[pos] & 3) != (int)xtype)) pos++; - if (pos == n) { - *_pos = nc; - o[n] = (int)((nc << 2) + xtype); - return p; - } + int i=pos; + memmove(o+i+1, o+i, (n-i)*sizeof(int)); + + while ((pos> 2; - memmove(((char *)p) + (pos + 1) * size, ((char *)p) + pos * size, - (nc - pos) * size); + *_pos=pos=o[pos]>>2; + memmove(((char*)p)+(pos+1)*size,((char*)p)+pos*size,(nc-pos)*size); - return p; + return p; } // Add a child node to the given element. -XMLNode XMLNode::addChild_priv(int memoryIncrease, XMLSTR lpszName, - char isDeclaration, int pos) { - if (!lpszName) return emptyXMLNode; - d->pChild = (XMLNode *)addToOrder(memoryIncrease, &pos, d->nChild, d->pChild, - sizeof(XMLNode), eNodeChild); - d->pChild[pos].d = NULL; - d->pChild[pos] = XMLNode(d, lpszName, isDeclaration); - d->nChild++; - return d->pChild[pos]; +XMLNode XMLNode::addChild_priv(int memoryIncrease, XMLSTR lpszName, char isDeclaration, int pos) +{ + if (!lpszName) return emptyXMLNode; + d->pChild=(XMLNode*)addToOrder(memoryIncrease,&pos,d->nChild,d->pChild,sizeof(XMLNode),eNodeChild); + d->pChild[pos].d=NULL; + d->pChild[pos]=XMLNode(d,lpszName,isDeclaration); + d->nChild++; + return d->pChild[pos]; } // Add an attribute to an element. -XMLAttribute *XMLNode::addAttribute_priv(int memoryIncrease, XMLSTR lpszName, - XMLSTR lpszValuev) { - if (!lpszName) return &emptyXMLAttribute; - if (!d) { - myFree(lpszName); - myFree(lpszValuev); - return &emptyXMLAttribute; - } - int nc = d->nAttribute; - d->pAttribute = (XMLAttribute *)myRealloc( - d->pAttribute, (nc + 1), memoryIncrease, sizeof(XMLAttribute)); - XMLAttribute *pAttr = d->pAttribute + nc; - pAttr->lpszName = lpszName; - pAttr->lpszValue = lpszValuev; - d->nAttribute++; - return pAttr; +XMLAttribute *XMLNode::addAttribute_priv(int memoryIncrease,XMLSTR lpszName, XMLSTR lpszValuev) +{ + if (!lpszName) return &emptyXMLAttribute; + if (!d) { myFree(lpszName); myFree(lpszValuev); return &emptyXMLAttribute; } + int nc=d->nAttribute; + d->pAttribute=(XMLAttribute*)myRealloc(d->pAttribute,(nc+1),memoryIncrease,sizeof(XMLAttribute)); + XMLAttribute *pAttr=d->pAttribute+nc; + pAttr->lpszName = lpszName; + pAttr->lpszValue = lpszValuev; + d->nAttribute++; + return pAttr; } // Add text to the element. -XMLCSTR XMLNode::addText_priv(int memoryIncrease, XMLSTR lpszValue, int pos) { - if (!lpszValue) return NULL; - if (!d) { - myFree(lpszValue); - return NULL; - } - d->pText = (XMLCSTR *)addToOrder(memoryIncrease, &pos, d->nText, d->pText, - sizeof(XMLSTR), eNodeText); - d->pText[pos] = lpszValue; - d->nText++; - return lpszValue; +XMLCSTR XMLNode::addText_priv(int memoryIncrease, XMLSTR lpszValue, int pos) +{ + if (!lpszValue) return NULL; + if (!d) { myFree(lpszValue); return NULL; } + d->pText=(XMLCSTR*)addToOrder(memoryIncrease,&pos,d->nText,d->pText,sizeof(XMLSTR),eNodeText); + d->pText[pos]=lpszValue; + d->nText++; + return lpszValue; } // Add clear (unformatted) text to the element. -XMLClear *XMLNode::addClear_priv(int memoryIncrease, XMLSTR lpszValue, - XMLCSTR lpszOpen, XMLCSTR lpszClose, int pos) { - if (!lpszValue) return &emptyXMLClear; - if (!d) { - myFree(lpszValue); - return &emptyXMLClear; - } - d->pClear = (XMLClear *)addToOrder(memoryIncrease, &pos, d->nClear, d->pClear, - sizeof(XMLClear), eNodeClear); - XMLClear *pNewClear = d->pClear + pos; - pNewClear->lpszValue = lpszValue; - if (!lpszOpen) lpszOpen = XMLClearTags->lpszOpen; - if (!lpszClose) lpszClose = XMLClearTags->lpszClose; - pNewClear->lpszOpenTag = lpszOpen; - pNewClear->lpszCloseTag = lpszClose; - d->nClear++; - return pNewClear; +XMLClear *XMLNode::addClear_priv(int memoryIncrease, XMLSTR lpszValue, XMLCSTR lpszOpen, XMLCSTR lpszClose, int pos) +{ + if (!lpszValue) return &emptyXMLClear; + if (!d) { myFree(lpszValue); return &emptyXMLClear; } + d->pClear=(XMLClear *)addToOrder(memoryIncrease,&pos,d->nClear,d->pClear,sizeof(XMLClear),eNodeClear); + XMLClear *pNewClear=d->pClear+pos; + pNewClear->lpszValue = lpszValue; + if (!lpszOpen) lpszOpen=XMLClearTags->lpszOpen; + if (!lpszClose) lpszClose=XMLClearTags->lpszClose; + pNewClear->lpszOpenTag = lpszOpen; + pNewClear->lpszCloseTag = lpszClose; + d->nClear++; + return pNewClear; } // private: // Parse a clear (unformatted) type node. -char XMLNode::parseClearTag(void *px, void *_pClear) { - XML *pXML = (XML *)px; - ALLXMLClearTag pClear = *((ALLXMLClearTag *)_pClear); - int cbTemp = 0; - XMLCSTR lpszTemp = NULL; - XMLCSTR lpXML = &pXML->lpXML[pXML->nIndex]; - static XMLCSTR docTypeEnd = _CXML("]>"); - - // Find the closing tag - // Seems the ')) { - lpszTemp = pCh; - break; - } +char XMLNode::parseClearTag(void *px, void *_pClear) +{ + XML *pXML=(XML *)px; + ALLXMLClearTag pClear=*((ALLXMLClearTag*)_pClear); + int cbTemp=0; + XMLCSTR lpszTemp=NULL; + XMLCSTR lpXML=&pXML->lpXML[pXML->nIndex]; + static XMLCSTR docTypeEnd=_CXML("]>"); + + // Find the closing tag + // Seems the ')) { lpszTemp=pCh; break; } #ifdef _XMLWIDECHAR - pCh++; + pCh++; #else - pCh += XML_ByteTable[(unsigned char)(*pCh)]; + pCh+=XML_ByteTable[(unsigned char)(*pCh)]; #endif - } - } else - lpszTemp = xstrstr(lpXML, pClear.lpszClose); + } + } else lpszTemp=xstrstr(lpXML, pClear.lpszClose); - if (lpszTemp) { - // Cache the size and increment the index - cbTemp = (int)(lpszTemp - lpXML); + if (lpszTemp) + { + // Cache the size and increment the index + cbTemp = (int)(lpszTemp - lpXML); - pXML->nIndex += cbTemp + (int)xstrlen(pClear.lpszClose); + pXML->nIndex += cbTemp+(int)xstrlen(pClear.lpszClose); - // Add the clear node to the current element - addClear_priv(MEMORYINCREASE, stringDup(lpXML, cbTemp), pClear.lpszOpen, - pClear.lpszClose, -1); - return 0; - } - - // If we failed to find the end tag - pXML->error = eXMLErrorUnmatchedEndClearTag; - return 1; -} - -void XMLNode::exactMemory(XMLNodeData *d) { - if (d->pOrder) - d->pOrder = (int *)realloc( - d->pOrder, (d->nChild + d->nText + d->nClear) * sizeof(int)); - if (d->pChild) - d->pChild = (XMLNode *)realloc(d->pChild, d->nChild * sizeof(XMLNode)); - if (d->pAttribute) - d->pAttribute = (XMLAttribute *)realloc( - d->pAttribute, d->nAttribute * sizeof(XMLAttribute)); - if (d->pText) - d->pText = (XMLCSTR *)realloc(d->pText, d->nText * sizeof(XMLSTR)); - if (d->pClear) - d->pClear = (XMLClear *)realloc(d->pClear, d->nClear * sizeof(XMLClear)); -} - -char XMLNode::maybeAddTxT(void *pa, XMLCSTR tokenPStr) { - XML *pXML = (XML *)pa; - XMLCSTR lpszText = pXML->lpszText; - if (!lpszText) return 0; - if (dropWhiteSpace) - while (XML_isSPACECHAR(*lpszText) && (lpszText != tokenPStr)) lpszText++; - int cbText = (int)(tokenPStr - lpszText); - if (!cbText) { - pXML->lpszText = NULL; - return 0; - } - if (dropWhiteSpace) { - cbText--; - while ((cbText) && XML_isSPACECHAR(lpszText[cbText])) cbText--; - cbText++; - } - if (!cbText) { - pXML->lpszText = NULL; - return 0; - } - XMLSTR lpt = fromXMLString(lpszText, cbText, pXML); - if (!lpt) return 1; - pXML->lpszText = NULL; - if (removeCommentsInMiddleOfText && d->nText && d->nClear) { - // if the previous insertion was a comment () AND - // if the previous previous insertion was a text then, delete the comment - // and append the text - int n = d->nChild + d->nText + d->nClear - 1, *o = d->pOrder; - if (((o[n] & 3) == eNodeClear) && ((o[n - 1] & 3) == eNodeText)) { - int i = o[n] >> 2; - if (d->pClear[i].lpszOpenTag == XMLClearTags[2].lpszOpen) { - deleteClear(i); - i = o[n - 1] >> 2; - n = xstrlen(d->pText[i]); - int n2 = xstrlen(lpt) + 1; - d->pText[i] = - (XMLSTR)realloc((void *)d->pText[i], (n + n2) * sizeof(XMLCHAR)); - if (!d->pText[i]) return 1; - memcpy((void *)(d->pText[i] + n), lpt, n2 * sizeof(XMLCHAR)); - free(lpt); + // Add the clear node to the current element + addClear_priv(MEMORYINCREASE,stringDup(lpXML,cbTemp), pClear.lpszOpen, pClear.lpszClose,-1); return 0; - } } - } - addText_priv(MEMORYINCREASE, lpt, -1); - return 0; + + // If we failed to find the end tag + pXML->error = eXMLErrorUnmatchedEndClearTag; + return 1; +} + +void XMLNode::exactMemory(XMLNodeData *d) +{ + if (d->pOrder) d->pOrder=(int*)realloc(d->pOrder,(d->nChild+d->nText+d->nClear)*sizeof(int)); + if (d->pChild) d->pChild=(XMLNode*)realloc(d->pChild,d->nChild*sizeof(XMLNode)); + if (d->pAttribute) d->pAttribute=(XMLAttribute*)realloc(d->pAttribute,d->nAttribute*sizeof(XMLAttribute)); + if (d->pText) d->pText=(XMLCSTR*)realloc(d->pText,d->nText*sizeof(XMLSTR)); + if (d->pClear) d->pClear=(XMLClear *)realloc(d->pClear,d->nClear*sizeof(XMLClear)); +} + +char XMLNode::maybeAddTxT(void *pa, XMLCSTR tokenPStr) +{ + XML *pXML=(XML *)pa; + XMLCSTR lpszText=pXML->lpszText; + if (!lpszText) return 0; + if (dropWhiteSpace) while (XML_isSPACECHAR(*lpszText)&&(lpszText!=tokenPStr)) lpszText++; + int cbText = (int)(tokenPStr - lpszText); + if (!cbText) { pXML->lpszText=NULL; return 0; } + if (dropWhiteSpace) { cbText--; while ((cbText)&&XML_isSPACECHAR(lpszText[cbText])) cbText--; cbText++; } + if (!cbText) { pXML->lpszText=NULL; return 0; } + XMLSTR lpt=fromXMLString(lpszText,cbText,pXML); + if (!lpt) return 1; + pXML->lpszText=NULL; + if (removeCommentsInMiddleOfText && d->nText && d->nClear) + { + // if the previous insertion was a comment () AND + // if the previous previous insertion was a text then, delete the comment and append the text + int n=d->nChild+d->nText+d->nClear-1,*o=d->pOrder; + if (((o[n]&3)==eNodeClear)&&((o[n-1]&3)==eNodeText)) + { + int i=o[n]>>2; + if (d->pClear[i].lpszOpenTag==XMLClearTags[2].lpszOpen) + { + deleteClear(i); + i=o[n-1]>>2; + n=xstrlen(d->pText[i]); + int n2=xstrlen(lpt)+1; + d->pText[i]=(XMLSTR)realloc((void*)d->pText[i],(n+n2)*sizeof(XMLCHAR)); + if (!d->pText[i]) return 1; + memcpy((void*)(d->pText[i]+n),lpt,n2*sizeof(XMLCHAR)); + free(lpt); + return 0; + } + } + } + addText_priv(MEMORYINCREASE,lpt,-1); + return 0; } // private: // Recursively parse an XML element. -int XMLNode::ParseXMLElement(void *pa) { - XML *pXML = (XML *)pa; - int cbToken; - enum XMLTokenTypeTag xtype; - NextToken token; - XMLCSTR lpszTemp = NULL; - int cbTemp = 0; - char nDeclaration; - XMLNode pNew; - enum Status status; // inside or outside a tag - enum Attrib attrib = eAttribName; - - assert(pXML); - - // If this is the first call to the function - if (pXML->nFirst) { - // Assume we are outside of a tag definition - pXML->nFirst = FALSE; - status = eOutsideTag; - } else { - // If this is not the first call then we should only be called when inside a - // tag. - status = eInsideTag; - } - - // Iterate through the tokens in the document - for (;;) { - // Obtain the next token - token = GetNextToken(pXML, &cbToken, &xtype); - - if (xtype != eTokenError) { - // Check the current status - switch (status) { - // If we are outside of a tag definition - case eOutsideTag: - - // Check what type of token we obtained - switch (xtype) { - // If we have found text or quoted text - case eTokenText: - case eTokenCloseTag: /* '>' */ - case eTokenShortHandClose: /* '/>' */ - case eTokenQuotedText: - case eTokenEquals: - break; - - // If we found a start tag '<' and declarations 'error = eXMLErrorMissingTagName; - return FALSE; - } - -// If we found a new element which is the same as this -// element then we need to pass this back to the caller.. +int XMLNode::ParseXMLElement(void *pa) +{ + XML *pXML=(XML *)pa; + int cbToken; + enum XMLTokenTypeTag xtype; + NextToken token; + XMLCSTR lpszTemp=NULL; + int cbTemp=0; + char nDeclaration; + XMLNode pNew; + enum Status status; // inside or outside a tag + enum Attrib attrib = eAttribName; + + assert(pXML); + + // If this is the first call to the function + if (pXML->nFirst) + { + // Assume we are outside of a tag definition + pXML->nFirst = FALSE; + status = eOutsideTag; + } else + { + // If this is not the first call then we should only be called when inside a tag. + status = eInsideTag; + } + + // Iterate through the tokens in the document + for(;;) + { + // Obtain the next token + token = GetNextToken(pXML, &cbToken, &xtype); + + if (xtype != eTokenError) + { + // Check the current status + switch(status) + { + + // If we are outside of a tag definition + case eOutsideTag: + + // Check what type of token we obtained + switch(xtype) + { + // If we have found text or quoted text + case eTokenText: + case eTokenCloseTag: /* '>' */ + case eTokenShortHandClose: /* '/>' */ + case eTokenQuotedText: + case eTokenEquals: + break; + + // If we found a start tag '<' and declarations 'error = eXMLErrorMissingTagName; + return FALSE; + } + + // If we found a new element which is the same as this + // element then we need to pass this back to the caller.. #ifdef APPROXIMATE_PARSING - if (d->lpszName && myTagCompare(d->lpszName, token.pStr) == 0) { - // Indicate to the caller that it needs to create a - // new element. - pXML->lpNewElement = token.pStr; - pXML->cbNewElement = cbToken; - return TRUE; - } else + if (d->lpszName && + myTagCompare(d->lpszName, token.pStr) == 0) + { + // Indicate to the caller that it needs to create a + // new element. + pXML->lpNewElement = token.pStr; + pXML->cbNewElement = cbToken; + return TRUE; + } else #endif - { - // If the name of the new element differs from the name of - // the current element we need to add the new element to - // the current one and recurse - pNew = addChild_priv(MEMORYINCREASE, - stringDup(token.pStr, cbToken), - nDeclaration, -1); - - while (!pNew.isEmpty()) { - // Callself to process the new node. If we return - // FALSE this means we dont have any more - // processing to do... - - if (!pNew.ParseXMLElement(pXML)) - return FALSE; - else { - // If the call to recurse this function - // evented in a end tag specified in XML then - // we need to unwind the calls to this - // function until we find the appropriate node - // (the element name and end tag name must - // match) - if (pXML->cbEndTag) { - // If we are back at the root node then we - // have an unmatched end tag - if (!d->lpszName) { - pXML->error = eXMLErrorUnmatchedEndTag; - return FALSE; - } + { + // If the name of the new element differs from the name of + // the current element we need to add the new element to + // the current one and recurse + pNew = addChild_priv(MEMORYINCREASE,stringDup(token.pStr,cbToken), nDeclaration,-1); + + while (!pNew.isEmpty()) + { + // Callself to process the new node. If we return + // FALSE this means we dont have any more + // processing to do... + + if (!pNew.ParseXMLElement(pXML)) return FALSE; + else + { + // If the call to recurse this function + // evented in a end tag specified in XML then + // we need to unwind the calls to this + // function until we find the appropriate node + // (the element name and end tag name must + // match) + if (pXML->cbEndTag) + { + // If we are back at the root node then we + // have an unmatched end tag + if (!d->lpszName) + { + pXML->error=eXMLErrorUnmatchedEndTag; + return FALSE; + } + + // If the end tag matches the name of this + // element then we only need to unwind + // once more... + + if (myTagCompare(d->lpszName, pXML->lpEndTag)==0) + { + pXML->cbEndTag = 0; + } + + return TRUE; + } else + if (pXML->cbNewElement) + { + // If the call indicated a new element is to + // be created on THIS element. + + // If the name of this element matches the + // name of the element we need to create + // then we need to return to the caller + // and let it process the element. + + if (myTagCompare(d->lpszName, pXML->lpNewElement)==0) + { + return TRUE; + } + + // Add the new element and recurse + pNew = addChild_priv(MEMORYINCREASE,stringDup(pXML->lpNewElement,pXML->cbNewElement),0,-1); + pXML->cbNewElement = 0; + } + else + { + // If we didn't have a new element to create + pNew = emptyXMLNode; + + } + } + } + } + break; - // If the end tag matches the name of this - // element then we only need to unwind - // once more... + // If we found an end tag + case eTokenTagEnd: - if (myTagCompare(d->lpszName, pXML->lpEndTag) == 0) { - pXML->cbEndTag = 0; - } + // If we have node text then add this to the element + if (maybeAddTxT(pXML,token.pStr)) return FALSE; - return TRUE; - } else if (pXML->cbNewElement) { - // If the call indicated a new element is to - // be created on THIS element. + // Find the name of the end tag + token = GetNextToken(pXML, &cbTemp, &xtype); - // If the name of this element matches the - // name of the element we need to create - // then we need to return to the caller - // and let it process the element. + // The end tag should be text + if (xtype != eTokenText) + { + pXML->error = eXMLErrorMissingEndTagName; + return FALSE; + } + lpszTemp = token.pStr; - if (myTagCompare(d->lpszName, pXML->lpNewElement) == 0) { - return TRUE; - } - - // Add the new element and recurse - pNew = addChild_priv( - MEMORYINCREASE, - stringDup(pXML->lpNewElement, pXML->cbNewElement), 0, - -1); - pXML->cbNewElement = 0; - } else { - // If we didn't have a new element to create - pNew = emptyXMLNode; + // After the end tag we should find a closing tag + token = GetNextToken(pXML, &cbToken, &xtype); + if (xtype != eTokenCloseTag) + { + pXML->error = eXMLErrorMissingEndTagName; + return FALSE; } - } - } - } - break; - - // If we found an end tag - case eTokenTagEnd: - - // If we have node text then add this to the element - if (maybeAddTxT(pXML, token.pStr)) return FALSE; - - // Find the name of the end tag - token = GetNextToken(pXML, &cbTemp, &xtype); - - // The end tag should be text - if (xtype != eTokenText) { - pXML->error = eXMLErrorMissingEndTagName; - return FALSE; - } - lpszTemp = token.pStr; - - // After the end tag we should find a closing tag - token = GetNextToken(pXML, &cbToken, &xtype); - if (xtype != eTokenCloseTag) { - pXML->error = eXMLErrorMissingEndTagName; - return FALSE; - } - pXML->lpszText = pXML->lpXML + pXML->nIndex; - - // We need to return to the previous caller. If the name - // of the tag cannot be found we need to keep returning to - // caller until we find a match - if (myTagCompare(d->lpszName, lpszTemp) != 0) + pXML->lpszText=pXML->lpXML+pXML->nIndex; + + // We need to return to the previous caller. If the name + // of the tag cannot be found we need to keep returning to + // caller until we find a match + if (myTagCompare(d->lpszName, lpszTemp) != 0) #ifdef STRICT_PARSING - { - pXML->error = eXMLErrorUnmatchedEndTag; - pXML->nIndexMissigEndTag = pXML->nIndex; - return FALSE; - } + { + pXML->error=eXMLErrorUnmatchedEndTag; + pXML->nIndexMissigEndTag=pXML->nIndex; + return FALSE; + } #else - { - pXML->error = eXMLErrorMissingEndTag; - pXML->nIndexMissigEndTag = pXML->nIndex; - pXML->lpEndTag = lpszTemp; - pXML->cbEndTag = cbTemp; - } + { + pXML->error=eXMLErrorMissingEndTag; + pXML->nIndexMissigEndTag=pXML->nIndex; + pXML->lpEndTag = lpszTemp; + pXML->cbEndTag = cbTemp; + } #endif - // Return to the caller - exactMemory(d); - return TRUE; - - // If we found a clear (unformatted) token - case eTokenClear: - // If we have node text then add this to the element - if (maybeAddTxT(pXML, token.pStr)) return FALSE; - if (parseClearTag(pXML, token.pClr)) return FALSE; - pXML->lpszText = pXML->lpXML + pXML->nIndex; - break; - - default: - break; - } - break; - - // If we are inside a tag definition we need to search for attributes - case eInsideTag: - - // Check what part of the attribute (name, equals, value) we - // are looking for. - switch (attrib) { - // If we are looking for a new attribute - case eAttribName: - - // Check what the current token type is - switch (xtype) { - // If the current type is text... - // Eg. 'attribute' - case eTokenText: - // Cache the token then indicate that we are next to - // look for the equals - lpszTemp = token.pStr; - cbTemp = cbToken; - attrib = eAttribEquals; - break; - - // If we found a closing tag... - // Eg. '>' - case eTokenCloseTag: - // We are now outside the tag - status = eOutsideTag; - pXML->lpszText = pXML->lpXML + pXML->nIndex; - break; - - // If we found a short hand '/>' closing tag then we can - // return to the caller - case eTokenShortHandClose: - exactMemory(d); - pXML->lpszText = pXML->lpXML + pXML->nIndex; - return TRUE; - - // Errors... - case eTokenQuotedText: /* '"SomeText"' */ - case eTokenTagStart: /* '<' */ - case eTokenTagEnd: /* 'error = eXMLErrorUnexpectedToken; - return FALSE; - default: - break; - } - break; - - // If we are looking for an equals - case eAttribEquals: - // Check what the current token type is - switch (xtype) { - // If the current type is text... - // Eg. 'Attribute AnotherAttribute' - case eTokenText: - // Add the unvalued attribute to the list - addAttribute_priv(MEMORYINCREASE, stringDup(lpszTemp, cbTemp), - NULL); - // Cache the token then indicate. We are next to - // look for the equals attribute - lpszTemp = token.pStr; - cbTemp = cbToken; - break; - - // If we found a closing tag 'Attribute >' or a short hand - // closing tag 'Attribute />' - case eTokenShortHandClose: - case eTokenCloseTag: - // If we are a declaration element 'lpszText = pXML->lpXML + pXML->nIndex; - - if (d->isDeclaration && - (lpszTemp[cbTemp - 1]) == _CXML('?')) { - cbTemp--; - if (d->pParent && d->pParent->pParent) - xtype = eTokenShortHandClose; - } - - if (cbTemp) { - // Add the unvalued attribute to the list - addAttribute_priv(MEMORYINCREASE, - stringDup(lpszTemp, cbTemp), NULL); - } - - // If this is the end of the tag then return to the caller - if (xtype == eTokenShortHandClose) { + // Return to the caller exactMemory(d); return TRUE; - } - - // We are now outside the tag - status = eOutsideTag; - break; - // If we found the equals token... - // Eg. 'Attribute =' - case eTokenEquals: - // Indicate that we next need to search for the value - // for the attribute - attrib = eAttribValue; - break; - - // Errors... - case eTokenQuotedText: /* 'Attribute "InvalidAttr"'*/ - case eTokenTagStart: /* 'Attribute <' */ - case eTokenTagEnd: /* 'Attribute error = eXMLErrorUnexpectedToken; - return FALSE; + // If we have node text then add this to the element + if (maybeAddTxT(pXML,token.pStr)) return FALSE; + if (parseClearTag(pXML, token.pClr)) return FALSE; + pXML->lpszText=pXML->lpXML+pXML->nIndex; + break; + default: - break; - } - break; - - // If we are looking for an attribute value - case eAttribValue: - // Check what the current token type is - switch (xtype) { - // If the current type is text or quoted text... - // Eg. 'Attribute = "Value"' or 'Attribute = Value' or - // 'Attribute = 'Value''. - case eTokenText: - case eTokenQuotedText: - // If we are a declaration element 'isDeclaration && - (token.pStr[cbToken - 1]) == _CXML('?')) { - cbToken--; - } - - if (cbTemp) { - // Add the valued attribute to the list - if (xtype == eTokenQuotedText) { - token.pStr++; - cbToken -= 2; + break; + } + break; + + // If we are inside a tag definition we need to search for attributes + case eInsideTag: + + // Check what part of the attribute (name, equals, value) we + // are looking for. + switch(attrib) + { + // If we are looking for a new attribute + case eAttribName: + + // Check what the current token type is + switch(xtype) + { + // If the current type is text... + // Eg. 'attribute' + case eTokenText: + // Cache the token then indicate that we are next to + // look for the equals + lpszTemp = token.pStr; + cbTemp = cbToken; + attrib = eAttribEquals; + break; + + // If we found a closing tag... + // Eg. '>' + case eTokenCloseTag: + // We are now outside the tag + status = eOutsideTag; + pXML->lpszText=pXML->lpXML+pXML->nIndex; + break; + + // If we found a short hand '/>' closing tag then we can + // return to the caller + case eTokenShortHandClose: + exactMemory(d); + pXML->lpszText=pXML->lpXML+pXML->nIndex; + return TRUE; + + // Errors... + case eTokenQuotedText: /* '"SomeText"' */ + case eTokenTagStart: /* '<' */ + case eTokenTagEnd: /* 'error = eXMLErrorUnexpectedToken; + return FALSE; + default: break; } - XMLSTR attrVal = (XMLSTR)token.pStr; - if (attrVal) { - attrVal = fromXMLString(attrVal, cbToken, pXML); - if (!attrVal) return FALSE; + break; + + // If we are looking for an equals + case eAttribEquals: + // Check what the current token type is + switch(xtype) + { + // If the current type is text... + // Eg. 'Attribute AnotherAttribute' + case eTokenText: + // Add the unvalued attribute to the list + addAttribute_priv(MEMORYINCREASE,stringDup(lpszTemp,cbTemp), NULL); + // Cache the token then indicate. We are next to + // look for the equals attribute + lpszTemp = token.pStr; + cbTemp = cbToken; + break; + + // If we found a closing tag 'Attribute >' or a short hand + // closing tag 'Attribute />' + case eTokenShortHandClose: + case eTokenCloseTag: + // If we are a declaration element 'lpszText=pXML->lpXML+pXML->nIndex; + + if (d->isDeclaration && + (lpszTemp[cbTemp-1]) == _CXML('?')) + { + cbTemp--; + if (d->pParent && d->pParent->pParent) xtype = eTokenShortHandClose; + } + + if (cbTemp) + { + // Add the unvalued attribute to the list + addAttribute_priv(MEMORYINCREASE,stringDup(lpszTemp,cbTemp), NULL); + } + + // If this is the end of the tag then return to the caller + if (xtype == eTokenShortHandClose) + { + exactMemory(d); + return TRUE; + } + + // We are now outside the tag + status = eOutsideTag; + break; + + // If we found the equals token... + // Eg. 'Attribute =' + case eTokenEquals: + // Indicate that we next need to search for the value + // for the attribute + attrib = eAttribValue; + break; + + // Errors... + case eTokenQuotedText: /* 'Attribute "InvalidAttr"'*/ + case eTokenTagStart: /* 'Attribute <' */ + case eTokenTagEnd: /* 'Attribute error = eXMLErrorUnexpectedToken; + return FALSE; + default: break; } - addAttribute_priv(MEMORYINCREASE, - stringDup(lpszTemp, cbTemp), attrVal); - } - - // Indicate we are searching for a new attribute - attrib = eAttribName; - break; - - // Errors... - case eTokenTagStart: /* 'Attr = <' */ - case eTokenTagEnd: /* 'Attr = ' */ - case eTokenShortHandClose: /* "Attr = />" */ - case eTokenEquals: /* 'Attr = =' */ - case eTokenDeclaration: /* 'Attr = error = eXMLErrorUnexpectedToken; - return FALSE; - break; - default: - break; - } - } - } - } - // If we failed to obtain the next token - else { - if ((!d->isDeclaration) && (d->pParent)) { + break; + + // If we are looking for an attribute value + case eAttribValue: + // Check what the current token type is + switch(xtype) + { + // If the current type is text or quoted text... + // Eg. 'Attribute = "Value"' or 'Attribute = Value' or + // 'Attribute = 'Value''. + case eTokenText: + case eTokenQuotedText: + // If we are a declaration element 'isDeclaration && + (token.pStr[cbToken-1]) == _CXML('?')) + { + cbToken--; + } + + if (cbTemp) + { + // Add the valued attribute to the list + if (xtype==eTokenQuotedText) { token.pStr++; cbToken-=2; } + XMLSTR attrVal=(XMLSTR)token.pStr; + if (attrVal) + { + attrVal=fromXMLString(attrVal,cbToken,pXML); + if (!attrVal) return FALSE; + } + addAttribute_priv(MEMORYINCREASE,stringDup(lpszTemp,cbTemp),attrVal); + } + + // Indicate we are searching for a new attribute + attrib = eAttribName; + break; + + // Errors... + case eTokenTagStart: /* 'Attr = <' */ + case eTokenTagEnd: /* 'Attr = ' */ + case eTokenShortHandClose: /* "Attr = />" */ + case eTokenEquals: /* 'Attr = =' */ + case eTokenDeclaration: /* 'Attr = error = eXMLErrorUnexpectedToken; + return FALSE; + break; + default: break; + } + } + } + } + // If we failed to obtain the next token + else + { + if ((!d->isDeclaration)&&(d->pParent)) + { #ifdef STRICT_PARSING - pXML->error = eXMLErrorUnmatchedEndTag; + pXML->error=eXMLErrorUnmatchedEndTag; #else - pXML->error = eXMLErrorMissingEndTag; + pXML->error=eXMLErrorMissingEndTag; #endif - pXML->nIndexMissigEndTag = pXML->nIndex; - } - maybeAddTxT(pXML, pXML->lpXML + pXML->nIndex); - return FALSE; + pXML->nIndexMissigEndTag=pXML->nIndex; + } + maybeAddTxT(pXML,pXML->lpXML+pXML->nIndex); + return FALSE; + } } - } } // Count the number of lines and columns in an XML string. -static void CountLinesAndColumns(XMLCSTR lpXML, int nUpto, - XMLResults *pResults) { - XMLCHAR ch; - assert(lpXML); - assert(pResults); - - struct XML xml = {lpXML, lpXML, 0, 0, eXMLErrorNone, NULL, 0, NULL, 0, TRUE}; - - pResults->nLine = 1; - pResults->nColumn = 1; - while (xml.nIndex < nUpto) { - ch = getNextChar(&xml); - if (ch != _CXML('\n')) - pResults->nColumn++; - else { - pResults->nLine++; - pResults->nColumn = 1; +static void CountLinesAndColumns(XMLCSTR lpXML, int nUpto, XMLResults *pResults) +{ + XMLCHAR ch; + assert(lpXML); + assert(pResults); + + struct XML xml={ lpXML,lpXML, 0, 0, eXMLErrorNone, NULL, 0, NULL, 0, TRUE }; + + pResults->nLine = 1; + pResults->nColumn = 1; + while (xml.nIndexnColumn++; + else + { + pResults->nLine++; + pResults->nColumn=1; + } } - } } // Parse XML and return the root element. -XMLNode XMLNode::parseString(XMLCSTR lpszXML, XMLCSTR tag, - XMLResults *pResults) { - if (!lpszXML) { - if (pResults) { - pResults->error = eXMLErrorNoElements; - pResults->nLine = 0; - pResults->nColumn = 0; - } - return emptyXMLNode; - } - - XMLNode xnode(NULL, NULL, FALSE); - struct XML xml = {lpszXML, lpszXML, 0, 0, eXMLErrorNone, - NULL, 0, NULL, 0, TRUE}; - - // Create header element - xnode.ParseXMLElement(&xml); - enum XMLError error = xml.error; - if (!xnode.nChildNode()) error = eXMLErrorNoXMLTagFound; - if ((xnode.nChildNode() == 1) && (xnode.nElement() == 1)) - xnode = xnode.getChildNode(); // skip the empty node - - // If no error occurred - if ((error == eXMLErrorNone) || (error == eXMLErrorMissingEndTag) || - (error == eXMLErrorNoXMLTagFound)) { - XMLCSTR name = xnode.getName(); - if (tag && (*tag) && ((!name) || (xstricmp(name, tag)))) { - xnode = xnode.getChildNode(tag); - if (xnode.isEmpty()) { - if (pResults) { - pResults->error = eXMLErrorFirstTagNotFound; - pResults->nLine = 0; - pResults->nColumn = 0; +XMLNode XMLNode::parseString(XMLCSTR lpszXML, XMLCSTR tag, XMLResults *pResults) +{ + if (!lpszXML) + { + if (pResults) + { + pResults->error=eXMLErrorNoElements; + pResults->nLine=0; + pResults->nColumn=0; } return emptyXMLNode; - } } - } else { - // Cleanup: this will destroy all the nodes - xnode = emptyXMLNode; - } - - // If we have been given somewhere to place results - if (pResults) { - pResults->error = error; - - // If we have an error - if (error != eXMLErrorNone) { - if (error == eXMLErrorMissingEndTag) xml.nIndex = xml.nIndexMissigEndTag; - // Find which line and column it starts on. - CountLinesAndColumns(xml.lpXML, xml.nIndex, pResults); + + XMLNode xnode(NULL,NULL,FALSE); + struct XML xml={ lpszXML, lpszXML, 0, 0, eXMLErrorNone, NULL, 0, NULL, 0, TRUE }; + + // Create header element + xnode.ParseXMLElement(&xml); + enum XMLError error = xml.error; + if (!xnode.nChildNode()) error=eXMLErrorNoXMLTagFound; + if ((xnode.nChildNode()==1)&&(xnode.nElement()==1)) xnode=xnode.getChildNode(); // skip the empty node + + // If no error occurred + if ((error==eXMLErrorNone)||(error==eXMLErrorMissingEndTag)||(error==eXMLErrorNoXMLTagFound)) + { + XMLCSTR name=xnode.getName(); + if (tag&&(*tag)&&((!name)||(xstricmp(name,tag)))) + { + xnode=xnode.getChildNode(tag); + if (xnode.isEmpty()) + { + if (pResults) + { + pResults->error=eXMLErrorFirstTagNotFound; + pResults->nLine=0; + pResults->nColumn=0; + } + return emptyXMLNode; + } + } + } else + { + // Cleanup: this will destroy all the nodes + xnode = emptyXMLNode; } - } - return xnode; -} - -XMLNode XMLNode::parseFile(XMLCSTR filename, XMLCSTR tag, - XMLResults *pResults) { - if (pResults) { - pResults->nLine = 0; - pResults->nColumn = 0; - } - FILE *f = xfopen(filename, _CXML("rb")); - if (f == NULL) { - if (pResults) pResults->error = eXMLErrorFileNotFound; - return emptyXMLNode; - } - fseek(f, 0, SEEK_END); - int l = ftell(f), headerSz = 0; - if (!l) { - if (pResults) pResults->error = eXMLErrorEmpty; + + + // If we have been given somewhere to place results + if (pResults) + { + pResults->error = error; + + // If we have an error + if (error!=eXMLErrorNone) + { + if (error==eXMLErrorMissingEndTag) xml.nIndex=xml.nIndexMissigEndTag; + // Find which line and column it starts on. + CountLinesAndColumns(xml.lpXML, xml.nIndex, pResults); + } + } + return xnode; +} + +XMLNode XMLNode::parseFile(XMLCSTR filename, XMLCSTR tag, XMLResults *pResults) +{ + if (pResults) { pResults->nLine=0; pResults->nColumn=0; } + FILE *f=xfopen(filename,_CXML("rb")); + if (f==NULL) { if (pResults) pResults->error=eXMLErrorFileNotFound; return emptyXMLNode; } + fseek(f,0,SEEK_END); + int l=ftell(f),headerSz=0; + if (!l) { if (pResults) pResults->error=eXMLErrorEmpty; fclose(f); return emptyXMLNode; } + fseek(f,0,SEEK_SET); + unsigned char *buf=(unsigned char*)malloc(l+4); + l=fread(buf,1,l,f); fclose(f); - return emptyXMLNode; - } - fseek(f, 0, SEEK_SET); - unsigned char *buf = (unsigned char *)malloc(l + 4); - l = fread(buf, 1, l, f); - fclose(f); - buf[l] = 0; - buf[l + 1] = 0; - buf[l + 2] = 0; - buf[l + 3] = 0; + buf[l]=0;buf[l+1]=0;buf[l+2]=0;buf[l+3]=0; #ifdef _XMLWIDECHAR - if (guessWideCharChars) { - if (!myIsTextWideChar(buf, l)) { - XMLNode::XMLCharEncoding ce = XMLNode::char_encoding_legacy; - if ((buf[0] == 0xef) && (buf[1] == 0xbb) && (buf[2] == 0xbf)) { - headerSz = 3; - ce = XMLNode::char_encoding_UTF8; - } - XMLSTR b2 = myMultiByteToWideChar((const char *)(buf + headerSz), ce); - free(buf); - buf = (unsigned char *)b2; - headerSz = 0; - } else { - if ((buf[0] == 0xef) && (buf[1] == 0xff)) headerSz = 2; - if ((buf[0] == 0xff) && (buf[1] == 0xfe)) headerSz = 2; + if (guessWideCharChars) + { + if (!myIsTextWideChar(buf,l)) + { + XMLNode::XMLCharEncoding ce=XMLNode::char_encoding_legacy; + if ((buf[0]==0xef)&&(buf[1]==0xbb)&&(buf[2]==0xbf)) { headerSz=3; ce=XMLNode::char_encoding_UTF8; } + XMLSTR b2=myMultiByteToWideChar((const char*)(buf+headerSz),ce); + free(buf); buf=(unsigned char*)b2; headerSz=0; + } else + { + if ((buf[0]==0xef)&&(buf[1]==0xff)) headerSz=2; + if ((buf[0]==0xff)&&(buf[1]==0xfe)) headerSz=2; + } } - } #else - if (guessWideCharChars) { - if (myIsTextWideChar(buf, l)) { - if ((buf[0] == 0xef) && (buf[1] == 0xff)) headerSz = 2; - if ((buf[0] == 0xff) && (buf[1] == 0xfe)) headerSz = 2; - char *b2 = myWideCharToMultiByte((const wchar_t *)(buf + headerSz)); - free(buf); - buf = (unsigned char *)b2; - headerSz = 0; - } else { - if ((buf[0] == 0xef) && (buf[1] == 0xbb) && (buf[2] == 0xbf)) - headerSz = 3; + if (guessWideCharChars) + { + if (myIsTextWideChar(buf,l)) + { + if ((buf[0]==0xef)&&(buf[1]==0xff)) headerSz=2; + if ((buf[0]==0xff)&&(buf[1]==0xfe)) headerSz=2; + char *b2=myWideCharToMultiByte((const wchar_t*)(buf+headerSz)); + free(buf); buf=(unsigned char*)b2; headerSz=0; + } else + { + if ((buf[0]==0xef)&&(buf[1]==0xbb)&&(buf[2]==0xbf)) headerSz=3; + } } - } #endif - if (!buf) { - if (pResults) pResults->error = eXMLErrorCharConversionError; - return emptyXMLNode; - } - XMLNode x = parseString((XMLSTR)(buf + headerSz), tag, pResults); - free(buf); - return x; + if (!buf) { if (pResults) pResults->error=eXMLErrorCharConversionError; return emptyXMLNode; } + XMLNode x=parseString((XMLSTR)(buf+headerSz),tag,pResults); + free(buf); + return x; } -static inline void charmemset(XMLSTR dest, XMLCHAR c, int l) { - while (l--) *(dest++) = c; -} +static inline void charmemset(XMLSTR dest,XMLCHAR c,int l) { while (l--) *(dest++)=c; } // private: // Creates an user friendly XML string from a given element with // appropriate white space and carriage returns. // // This recurses through all subnodes then adds contents of the nodes to the // string. -int XMLNode::CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, - int nFormat) { - int nResult = 0; - int cb = nFormat < 0 ? 0 : nFormat; - int cbElement; - int nChildFormat = -1; - int nElementI = pEntry->nChild + pEntry->nText + pEntry->nClear; - int i, j; - if ((nFormat >= 0) && (nElementI == 1) && (pEntry->nText == 1) && - (!pEntry->isDeclaration)) - nFormat = -2; - - assert(pEntry); +int XMLNode::CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, int nFormat) +{ + int nResult = 0; + int cb=nFormat<0?0:nFormat; + int cbElement; + int nChildFormat=-1; + int nElementI=pEntry->nChild+pEntry->nText+pEntry->nClear; + int i,j; + if ((nFormat>=0)&&(nElementI==1)&&(pEntry->nText==1)&&(!pEntry->isDeclaration)) nFormat=-2; + + assert(pEntry); #define LENSTR(lpsz) (lpsz ? xstrlen(lpsz) : 0) - // If the element has no name then assume this is the head node. - cbElement = (int)LENSTR(pEntry->lpszName); - - if (cbElement) { - // "isDeclaration) lpszMarker[nResult++] = _CXML('?'); - xstrcpy(&lpszMarker[nResult], pEntry->lpszName); - nResult += cbElement; - lpszMarker[nResult++] = _CXML(' '); - - } else { - nResult += cbElement + 2 + cb; - if (pEntry->isDeclaration) nResult++; - } + // If the element has no name then assume this is the head node. + cbElement = (int)LENSTR(pEntry->lpszName); + + if (cbElement) + { + // "isDeclaration) lpszMarker[nResult++]=_CXML('?'); + xstrcpy(&lpszMarker[nResult], pEntry->lpszName); + nResult+=cbElement; + lpszMarker[nResult++]=_CXML(' '); + + } else + { + nResult+=cbElement+2+cb; + if (pEntry->isDeclaration) nResult++; + } - // Enumerate attributes and add them to the string - XMLAttribute *pAttr = pEntry->pAttribute; - for (i = 0; i < pEntry->nAttribute; i++) { - // "Attrib - cb = (int)LENSTR(pAttr->lpszName); - if (cb) { - if (lpszMarker) xstrcpy(&lpszMarker[nResult], pAttr->lpszName); - nResult += cb; - // "Attrib=Value " - if (pAttr->lpszValue) { - cb = (int)ToXMLStringTool::lengthXMLString(pAttr->lpszValue); - if (lpszMarker) { - lpszMarker[nResult] = _CXML('='); - lpszMarker[nResult + 1] = _CXML('"'); + // Enumerate attributes and add them to the string + XMLAttribute *pAttr=pEntry->pAttribute; + for (i=0; inAttribute; i++) + { + // "Attrib + cb = (int)LENSTR(pAttr->lpszName); if (cb) - ToXMLStringTool::toXMLUnSafe(&lpszMarker[nResult + 2], - pAttr->lpszValue); - lpszMarker[nResult + cb + 2] = _CXML('"'); - } - nResult += cb + 3; + { + if (lpszMarker) xstrcpy(&lpszMarker[nResult], pAttr->lpszName); + nResult += cb; + // "Attrib=Value " + if (pAttr->lpszValue) + { + cb=(int)ToXMLStringTool::lengthXMLString(pAttr->lpszValue); + if (lpszMarker) + { + lpszMarker[nResult]=_CXML('='); + lpszMarker[nResult+1]=_CXML('"'); + if (cb) ToXMLStringTool::toXMLUnSafe(&lpszMarker[nResult+2],pAttr->lpszValue); + lpszMarker[nResult+cb+2]=_CXML('"'); + } + nResult+=cb+3; + } + if (lpszMarker) lpszMarker[nResult] = _CXML(' '); + nResult++; + } + pAttr++; } - if (lpszMarker) lpszMarker[nResult] = _CXML(' '); - nResult++; - } - pAttr++; - } - if (pEntry->isDeclaration) { - if (lpszMarker) { - lpszMarker[nResult - 1] = _CXML('?'); - lpszMarker[nResult] = _CXML('>'); - } - nResult++; - if (nFormat != -1) { - if (lpszMarker) lpszMarker[nResult] = _CXML('\n'); - nResult++; - } - } else - // If there are child nodes we need to terminate the start tag - if (nElementI) { - if (lpszMarker) lpszMarker[nResult - 1] = _CXML('>'); - if (nFormat >= 0) { - if (lpszMarker) lpszMarker[nResult] = _CXML('\n'); - nResult++; - } - } else - nResult--; - } - - // Calculate the child format for when we recurse. This is used to - // determine the number of spaces used for prefixes. - if (nFormat != -1) { - if (cbElement && (!pEntry->isDeclaration)) - nChildFormat = nFormat + 1; - else - nChildFormat = nFormat; - } - - // Enumerate through remaining children - for (i = 0; i < nElementI; i++) { - j = pEntry->pOrder[i]; - switch ((XMLElementType)(j & 3)) { - // Text nodes - case eNodeText: { - // "Text" - XMLCSTR pChild = pEntry->pText[j >> 2]; - cb = (int)ToXMLStringTool::lengthXMLString(pChild); - if (cb) { - if (nFormat >= 0) { - if (lpszMarker) { - charmemset(&lpszMarker[nResult], INDENTCHAR, nFormat + 1); - ToXMLStringTool::toXMLUnSafe(&lpszMarker[nResult + nFormat + 1], - pChild); - lpszMarker[nResult + nFormat + 1 + cb] = _CXML('\n'); - } - nResult += cb + nFormat + 2; - } else { + if (pEntry->isDeclaration) + { if (lpszMarker) - ToXMLStringTool::toXMLUnSafe(&lpszMarker[nResult], pChild); - nResult += cb; - } - } - break; - } - - // Clear type nodes - case eNodeClear: { - XMLClear *pChild = pEntry->pClear + (j >> 2); - // "OpenTag" - cb = (int)LENSTR(pChild->lpszOpenTag); - if (cb) { - if (nFormat != -1) { - if (lpszMarker) { - charmemset(&lpszMarker[nResult], INDENTCHAR, nFormat + 1); - xstrcpy(&lpszMarker[nResult + nFormat + 1], pChild->lpszOpenTag); + { + lpszMarker[nResult-1]=_CXML('?'); + lpszMarker[nResult]=_CXML('>'); } - nResult += cb + nFormat + 1; - } else { - if (lpszMarker) xstrcpy(&lpszMarker[nResult], pChild->lpszOpenTag); - nResult += cb; - } - } + nResult++; + if (nFormat!=-1) + { + if (lpszMarker) lpszMarker[nResult]=_CXML('\n'); + nResult++; + } + } else + // If there are child nodes we need to terminate the start tag + if (nElementI) + { + if (lpszMarker) lpszMarker[nResult-1]=_CXML('>'); + if (nFormat>=0) + { + if (lpszMarker) lpszMarker[nResult]=_CXML('\n'); + nResult++; + } + } else nResult--; + } - // "OpenTag Value" - cb = (int)LENSTR(pChild->lpszValue); - if (cb) { - if (lpszMarker) xstrcpy(&lpszMarker[nResult], pChild->lpszValue); - nResult += cb; - } + // Calculate the child format for when we recurse. This is used to + // determine the number of spaces used for prefixes. + if (nFormat!=-1) + { + if (cbElement&&(!pEntry->isDeclaration)) nChildFormat=nFormat+1; + else nChildFormat=nFormat; + } - // "OpenTag Value CloseTag" - cb = (int)LENSTR(pChild->lpszCloseTag); - if (cb) { - if (lpszMarker) xstrcpy(&lpszMarker[nResult], pChild->lpszCloseTag); - nResult += cb; - } + // Enumerate through remaining children + for (i=0; ipOrder[i]; + switch((XMLElementType)(j&3)) + { + // Text nodes + case eNodeText: + { + // "Text" + XMLCSTR pChild=pEntry->pText[j>>2]; + cb = (int)ToXMLStringTool::lengthXMLString(pChild); + if (cb) + { + if (nFormat>=0) + { + if (lpszMarker) + { + charmemset(&lpszMarker[nResult],INDENTCHAR,nFormat+1); + ToXMLStringTool::toXMLUnSafe(&lpszMarker[nResult+nFormat+1],pChild); + lpszMarker[nResult+nFormat+1+cb]=_CXML('\n'); + } + nResult+=cb+nFormat+2; + } else + { + if (lpszMarker) ToXMLStringTool::toXMLUnSafe(&lpszMarker[nResult], pChild); + nResult += cb; + } + } + break; + } + + // Clear type nodes + case eNodeClear: + { + XMLClear *pChild=pEntry->pClear+(j>>2); + // "OpenTag" + cb = (int)LENSTR(pChild->lpszOpenTag); + if (cb) + { + if (nFormat!=-1) + { + if (lpszMarker) + { + charmemset(&lpszMarker[nResult], INDENTCHAR, nFormat+1); + xstrcpy(&lpszMarker[nResult+nFormat+1], pChild->lpszOpenTag); + } + nResult+=cb+nFormat+1; + } + else + { + if (lpszMarker)xstrcpy(&lpszMarker[nResult], pChild->lpszOpenTag); + nResult += cb; + } + } - if (nFormat != -1) { - if (lpszMarker) lpszMarker[nResult] = _CXML('\n'); - nResult++; + // "OpenTag Value" + cb = (int)LENSTR(pChild->lpszValue); + if (cb) + { + if (lpszMarker) xstrcpy(&lpszMarker[nResult], pChild->lpszValue); + nResult += cb; + } + + // "OpenTag Value CloseTag" + cb = (int)LENSTR(pChild->lpszCloseTag); + if (cb) + { + if (lpszMarker) xstrcpy(&lpszMarker[nResult], pChild->lpszCloseTag); + nResult += cb; + } + + if (nFormat!=-1) + { + if (lpszMarker) lpszMarker[nResult] = _CXML('\n'); + nResult++; + } + break; + } + + // Element nodes + case eNodeChild: + { + // Recursively add child nodes + nResult += CreateXMLStringR(pEntry->pChild[j>>2].d, lpszMarker ? lpszMarker + nResult : 0, nChildFormat); + break; + } + default: break; } - break; - } - - // Element nodes - case eNodeChild: { - // Recursively add child nodes - nResult += CreateXMLStringR(pEntry->pChild[j >> 2].d, - lpszMarker ? lpszMarker + nResult : 0, - nChildFormat); - break; - } - default: - break; } - } - - if ((cbElement) && (!pEntry->isDeclaration)) { - // If we have child entries we need to use long XML notation for - // closing the element - "blah blah blah" - if (nElementI) { - // "\0" - if (lpszMarker) { - if (nFormat >= 0) { - charmemset(&lpszMarker[nResult], INDENTCHAR, nFormat); - nResult += nFormat; - } - lpszMarker[nResult] = _CXML('<'); - lpszMarker[nResult + 1] = _CXML('/'); - nResult += 2; - xstrcpy(&lpszMarker[nResult], pEntry->lpszName); - nResult += cbElement; - - lpszMarker[nResult] = _CXML('>'); - if (nFormat == -1) - nResult++; - else { - lpszMarker[nResult + 1] = _CXML('\n'); - nResult += 2; + if ((cbElement)&&(!pEntry->isDeclaration)) + { + // If we have child entries we need to use long XML notation for + // closing the element - "blah blah blah" + if (nElementI) + { + // "\0" + if (lpszMarker) + { + if (nFormat >=0) + { + charmemset(&lpszMarker[nResult], INDENTCHAR,nFormat); + nResult+=nFormat; + } + + lpszMarker[nResult]=_CXML('<'); lpszMarker[nResult+1]=_CXML('/'); + nResult += 2; + xstrcpy(&lpszMarker[nResult], pEntry->lpszName); + nResult += cbElement; + + lpszMarker[nResult]=_CXML('>'); + if (nFormat == -1) nResult++; + else + { + lpszMarker[nResult+1]=_CXML('\n'); + nResult+=2; + } + } else + { + if (nFormat>=0) nResult+=cbElement+4+nFormat; + else if (nFormat==-1) nResult+=cbElement+3; + else nResult+=cbElement+4; + } + } else + { + // If there are no children we can use shorthand XML notation - + // "" + // "/>\0" + if (lpszMarker) + { + lpszMarker[nResult]=_CXML('/'); lpszMarker[nResult+1]=_CXML('>'); + if (nFormat != -1) lpszMarker[nResult+2]=_CXML('\n'); + } + nResult += nFormat == -1 ? 2 : 3; } - } else { - if (nFormat >= 0) - nResult += cbElement + 4 + nFormat; - else if (nFormat == -1) - nResult += cbElement + 3; - else - nResult += cbElement + 4; - } - } else { - // If there are no children we can use shorthand XML notation - - // "" - // "/>\0" - if (lpszMarker) { - lpszMarker[nResult] = _CXML('/'); - lpszMarker[nResult + 1] = _CXML('>'); - if (nFormat != -1) lpszMarker[nResult + 2] = _CXML('\n'); - } - nResult += nFormat == -1 ? 2 : 3; } - } - return nResult; + return nResult; } #undef LENSTR @@ -2366,832 +2084,638 @@ int XMLNode::CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, // NULL terminator. // @return XMLSTR - Allocated XML string, you must free // this with free(). -XMLSTR XMLNode::createXMLString(int nFormat, int *pnSize) const { - if (!d) { - if (pnSize) *pnSize = 0; - return NULL; - } - - XMLSTR lpszResult = NULL; - int cbStr; - - // Recursively Calculate the size of the XML string - if (!dropWhiteSpace) nFormat = 0; - nFormat = nFormat ? 0 : -1; - cbStr = CreateXMLStringR(d, 0, nFormat); - // Alllocate memory for the XML string + the NULL terminator and - // create the recursively XML string. - lpszResult = (XMLSTR)malloc((cbStr + 1) * sizeof(XMLCHAR)); - CreateXMLStringR(d, lpszResult, nFormat); - lpszResult[cbStr] = _CXML('\0'); - if (pnSize) *pnSize = cbStr; - return lpszResult; -} - -int XMLNode::detachFromParent(XMLNodeData *d) { - XMLNode *pa = d->pParent->pChild; - int i = 0; - while (((void *)(pa[i].d)) != ((void *)d)) i++; - d->pParent->nChild--; - if (d->pParent->nChild) - memmove(pa + i, pa + i + 1, (d->pParent->nChild - i) * sizeof(XMLNode)); - else { - free(pa); - d->pParent->pChild = NULL; - } - return removeOrderElement(d->pParent, eNodeChild, i); -} - -XMLNode::~XMLNode() { - if (!d) return; - d->ref_count--; - emptyTheNode(0); -} -void XMLNode::deleteNodeContent() { - if (!d) return; - if (d->pParent) { - detachFromParent(d); - d->pParent = NULL; +XMLSTR XMLNode::createXMLString(int nFormat, int *pnSize) const +{ + if (!d) { if (pnSize) *pnSize=0; return NULL; } + + XMLSTR lpszResult = NULL; + int cbStr; + + // Recursively Calculate the size of the XML string + if (!dropWhiteSpace) nFormat=0; + nFormat = nFormat ? 0 : -1; + cbStr = CreateXMLStringR(d, 0, nFormat); + // Alllocate memory for the XML string + the NULL terminator and + // create the recursively XML string. + lpszResult=(XMLSTR)malloc((cbStr+1)*sizeof(XMLCHAR)); + CreateXMLStringR(d, lpszResult, nFormat); + lpszResult[cbStr]=_CXML('\0'); + if (pnSize) *pnSize = cbStr; + return lpszResult; +} + +int XMLNode::detachFromParent(XMLNodeData *d) +{ + XMLNode *pa=d->pParent->pChild; + int i=0; + while (((void*)(pa[i].d))!=((void*)d)) i++; + d->pParent->nChild--; + if (d->pParent->nChild) memmove(pa+i,pa+i+1,(d->pParent->nChild-i)*sizeof(XMLNode)); + else { free(pa); d->pParent->pChild=NULL; } + return removeOrderElement(d->pParent,eNodeChild,i); +} + +XMLNode::~XMLNode() +{ + if (!d) return; d->ref_count--; - } - emptyTheNode(1); + emptyTheNode(0); } -void XMLNode::emptyTheNode(char force) { - XMLNodeData *dd = d; // warning: must stay this way! - if ((dd->ref_count == 0) || force) { - if (d->pParent) detachFromParent(d); - int i; - XMLNode *pc; - for (i = 0; i < dd->nChild; i++) { - pc = dd->pChild + i; - pc->d->pParent = NULL; - pc->d->ref_count--; - pc->emptyTheNode(force); +void XMLNode::deleteNodeContent() +{ + if (!d) return; + if (d->pParent) { detachFromParent(d); d->pParent=NULL; d->ref_count--; } + emptyTheNode(1); +} +void XMLNode::emptyTheNode(char force) +{ + XMLNodeData *dd=d; // warning: must stay this way! + if ((dd->ref_count==0)||force) + { + if (d->pParent) detachFromParent(d); + int i; + XMLNode *pc; + for(i=0; inChild; i++) + { + pc=dd->pChild+i; + pc->d->pParent=NULL; + pc->d->ref_count--; + pc->emptyTheNode(force); + } + myFree(dd->pChild); + for(i=0; inText; i++) free((void*)dd->pText[i]); + myFree(dd->pText); + for(i=0; inClear; i++) free((void*)dd->pClear[i].lpszValue); + myFree(dd->pClear); + for(i=0; inAttribute; i++) + { + free((void*)dd->pAttribute[i].lpszName); + if (dd->pAttribute[i].lpszValue) free((void*)dd->pAttribute[i].lpszValue); + } + myFree(dd->pAttribute); + myFree(dd->pOrder); + myFree((void*)dd->lpszName); + dd->nChild=0; dd->nText=0; dd->nClear=0; dd->nAttribute=0; + dd->pChild=NULL; dd->pText=NULL; dd->pClear=NULL; dd->pAttribute=NULL; + dd->pOrder=NULL; dd->lpszName=NULL; dd->pParent=NULL; } - myFree(dd->pChild); - for (i = 0; i < dd->nText; i++) free((void *)dd->pText[i]); - myFree(dd->pText); - for (i = 0; i < dd->nClear; i++) free((void *)dd->pClear[i].lpszValue); - myFree(dd->pClear); - for (i = 0; i < dd->nAttribute; i++) { - free((void *)dd->pAttribute[i].lpszName); - if (dd->pAttribute[i].lpszValue) - free((void *)dd->pAttribute[i].lpszValue); + if (dd->ref_count==0) + { + free(dd); + d=NULL; } - myFree(dd->pAttribute); - myFree(dd->pOrder); - myFree((void *)dd->lpszName); - dd->nChild = 0; - dd->nText = 0; - dd->nClear = 0; - dd->nAttribute = 0; - dd->pChild = NULL; - dd->pText = NULL; - dd->pClear = NULL; - dd->pAttribute = NULL; - dd->pOrder = NULL; - dd->lpszName = NULL; - dd->pParent = NULL; - } - if (dd->ref_count == 0) { - free(dd); - d = NULL; - } -} - -XMLNode &XMLNode::operator=(const XMLNode &A) { - // shallow copy - if (this != &A) { - if (d) { - d->ref_count--; - emptyTheNode(0); +} + +XMLNode& XMLNode::operator=( const XMLNode& A ) +{ + // shallow copy + if (this != &A) + { + if (d) { d->ref_count--; emptyTheNode(0); } + d=A.d; + if (d) (d->ref_count) ++ ; } - d = A.d; - if (d) (d->ref_count)++; - } - return *this; -} - -XMLNode::XMLNode(const XMLNode &A) { - // shallow copy - d = A.d; - if (d) (d->ref_count)++; -} - -XMLNode XMLNode::deepCopy() const { - if (!d) return XMLNode::emptyXMLNode; - XMLNode x(NULL, stringDup(d->lpszName), d->isDeclaration); - XMLNodeData *p = x.d; - int n = d->nAttribute; - if (n) { - p->nAttribute = n; - p->pAttribute = (XMLAttribute *)malloc(n * sizeof(XMLAttribute)); - while (n--) { - p->pAttribute[n].lpszName = stringDup(d->pAttribute[n].lpszName); - p->pAttribute[n].lpszValue = stringDup(d->pAttribute[n].lpszValue); + return *this; +} + +XMLNode::XMLNode(const XMLNode &A) +{ + // shallow copy + d=A.d; + if (d) (d->ref_count)++ ; +} + +XMLNode XMLNode::deepCopy() const +{ + if (!d) return XMLNode::emptyXMLNode; + XMLNode x(NULL,stringDup(d->lpszName),d->isDeclaration); + XMLNodeData *p=x.d; + int n=d->nAttribute; + if (n) + { + p->nAttribute=n; p->pAttribute=(XMLAttribute*)malloc(n*sizeof(XMLAttribute)); + while (n--) + { + p->pAttribute[n].lpszName=stringDup(d->pAttribute[n].lpszName); + p->pAttribute[n].lpszValue=stringDup(d->pAttribute[n].lpszValue); + } } - } - if (d->pOrder) { - n = (d->nChild + d->nText + d->nClear) * sizeof(int); - p->pOrder = (int *)malloc(n); - memcpy(p->pOrder, d->pOrder, n); - } - n = d->nText; - if (n) { - p->nText = n; - p->pText = (XMLCSTR *)malloc(n * sizeof(XMLCSTR)); - while (n--) p->pText[n] = stringDup(d->pText[n]); - } - n = d->nClear; - if (n) { - p->nClear = n; - p->pClear = (XMLClear *)malloc(n * sizeof(XMLClear)); - while (n--) { - p->pClear[n].lpszCloseTag = d->pClear[n].lpszCloseTag; - p->pClear[n].lpszOpenTag = d->pClear[n].lpszOpenTag; - p->pClear[n].lpszValue = stringDup(d->pClear[n].lpszValue); + if (d->pOrder) + { + n=(d->nChild+d->nText+d->nClear)*sizeof(int); p->pOrder=(int*)malloc(n); memcpy(p->pOrder,d->pOrder,n); + } + n=d->nText; + if (n) + { + p->nText=n; p->pText=(XMLCSTR*)malloc(n*sizeof(XMLCSTR)); + while(n--) p->pText[n]=stringDup(d->pText[n]); + } + n=d->nClear; + if (n) + { + p->nClear=n; p->pClear=(XMLClear*)malloc(n*sizeof(XMLClear)); + while (n--) + { + p->pClear[n].lpszCloseTag=d->pClear[n].lpszCloseTag; + p->pClear[n].lpszOpenTag=d->pClear[n].lpszOpenTag; + p->pClear[n].lpszValue=stringDup(d->pClear[n].lpszValue); + } } - } - n = d->nChild; - if (n) { - p->nChild = n; - p->pChild = (XMLNode *)malloc(n * sizeof(XMLNode)); - while (n--) { - p->pChild[n].d = NULL; - p->pChild[n] = d->pChild[n].deepCopy(); - p->pChild[n].d->pParent = p; + n=d->nChild; + if (n) + { + p->nChild=n; p->pChild=(XMLNode*)malloc(n*sizeof(XMLNode)); + while (n--) + { + p->pChild[n].d=NULL; + p->pChild[n]=d->pChild[n].deepCopy(); + p->pChild[n].d->pParent=p; + } } - } - return x; -} - -XMLNode XMLNode::addChild(XMLNode childNode, int pos) { - XMLNodeData *dc = childNode.d; - if ((!dc) || (!d)) return childNode; - if (!dc->lpszName) { - // this is a root node: todo: correct fix - int j = pos; - while (dc->nChild) { - addChild(dc->pChild[0], j); - if (pos >= 0) j++; + return x; +} + +XMLNode XMLNode::addChild(XMLNode childNode, int pos) +{ + XMLNodeData *dc=childNode.d; + if ((!dc)||(!d)) return childNode; + if (!dc->lpszName) + { + // this is a root node: todo: correct fix + int j=pos; + while (dc->nChild) + { + addChild(dc->pChild[0],j); + if (pos>=0) j++; + } + return childNode; } + if (dc->pParent) { if ((detachFromParent(dc)<=pos)&&(dc->pParent==d)) pos--; } else dc->ref_count++; + dc->pParent=d; +// int nc=d->nChild; +// d->pChild=(XMLNode*)myRealloc(d->pChild,(nc+1),memoryIncrease,sizeof(XMLNode)); + d->pChild=(XMLNode*)addToOrder(0,&pos,d->nChild,d->pChild,sizeof(XMLNode),eNodeChild); + d->pChild[pos].d=dc; + d->nChild++; return childNode; - } - if (dc->pParent) { - if ((detachFromParent(dc) <= pos) && (dc->pParent == d)) pos--; - } else - dc->ref_count++; - dc->pParent = d; - // int nc=d->nChild; - // d->pChild=(XMLNode*)myRealloc(d->pChild,(nc+1),memoryIncrease,sizeof(XMLNode)); - d->pChild = (XMLNode *)addToOrder(0, &pos, d->nChild, d->pChild, - sizeof(XMLNode), eNodeChild); - d->pChild[pos].d = dc; - d->nChild++; - return childNode; -} - -void XMLNode::deleteAttribute(int i) { - if ((!d) || (i < 0) || (i >= d->nAttribute)) return; - d->nAttribute--; - XMLAttribute *p = d->pAttribute + i; - free((void *)p->lpszName); - if (p->lpszValue) free((void *)p->lpszValue); - if (d->nAttribute) - memmove(p, p + 1, (d->nAttribute - i) * sizeof(XMLAttribute)); - else { - free(p); - d->pAttribute = NULL; - } -} - -void XMLNode::deleteAttribute(XMLAttribute *a) { - if (a) deleteAttribute(a->lpszName); -} -void XMLNode::deleteAttribute(XMLCSTR lpszName) { - int j = 0; - getAttribute(lpszName, &j); - if (j) deleteAttribute(j - 1); -} - -XMLAttribute *XMLNode::updateAttribute_WOSD(XMLSTR lpszNewValue, - XMLSTR lpszNewName, int i) { - if (!d) { - if (lpszNewValue) free(lpszNewValue); - if (lpszNewName) free(lpszNewName); - return NULL; - } - if (i >= d->nAttribute) { - if (lpszNewName) return addAttribute_WOSD(lpszNewName, lpszNewValue); - return NULL; - } - XMLAttribute *p = d->pAttribute + i; - if (p->lpszValue && p->lpszValue != lpszNewValue) free((void *)p->lpszValue); - p->lpszValue = lpszNewValue; - if (lpszNewName && p->lpszName != lpszNewName) { - free((void *)p->lpszName); - p->lpszName = lpszNewName; - }; - return p; -} - -XMLAttribute *XMLNode::updateAttribute_WOSD(XMLAttribute *newAttribute, - XMLAttribute *oldAttribute) { - if (oldAttribute) - return updateAttribute_WOSD((XMLSTR)newAttribute->lpszValue, - (XMLSTR)newAttribute->lpszName, - oldAttribute->lpszName); - return addAttribute_WOSD((XMLSTR)newAttribute->lpszName, - (XMLSTR)newAttribute->lpszValue); -} - -XMLAttribute *XMLNode::updateAttribute_WOSD(XMLSTR lpszNewValue, - XMLSTR lpszNewName, - XMLCSTR lpszOldName) { - int j = 0; - getAttribute(lpszOldName, &j); - if (j) - return updateAttribute_WOSD(lpszNewValue, lpszNewName, j - 1); - else { - if (lpszNewName) - return addAttribute_WOSD(lpszNewName, lpszNewValue); +} + +void XMLNode::deleteAttribute(int i) +{ + if ((!d)||(i<0)||(i>=d->nAttribute)) return; + d->nAttribute--; + XMLAttribute *p=d->pAttribute+i; + free((void*)p->lpszName); + if (p->lpszValue) free((void*)p->lpszValue); + if (d->nAttribute) memmove(p,p+1,(d->nAttribute-i)*sizeof(XMLAttribute)); else { free(p); d->pAttribute=NULL; } +} + +void XMLNode::deleteAttribute(XMLAttribute *a){ if (a) deleteAttribute(a->lpszName); } +void XMLNode::deleteAttribute(XMLCSTR lpszName) +{ + int j=0; + getAttribute(lpszName,&j); + if (j) deleteAttribute(j-1); +} + +XMLAttribute *XMLNode::updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName,int i) +{ + if (!d) { if (lpszNewValue) free(lpszNewValue); if (lpszNewName) free(lpszNewName); return NULL; } + if (i>=d->nAttribute) + { + if (lpszNewName) return addAttribute_WOSD(lpszNewName,lpszNewValue); + return NULL; + } + XMLAttribute *p=d->pAttribute+i; + if (p->lpszValue&&p->lpszValue!=lpszNewValue) free((void*)p->lpszValue); + p->lpszValue=lpszNewValue; + if (lpszNewName&&p->lpszName!=lpszNewName) { free((void*)p->lpszName); p->lpszName=lpszNewName; }; + return p; +} + +XMLAttribute *XMLNode::updateAttribute_WOSD(XMLAttribute *newAttribute, XMLAttribute *oldAttribute) +{ + if (oldAttribute) return updateAttribute_WOSD((XMLSTR)newAttribute->lpszValue,(XMLSTR)newAttribute->lpszName,oldAttribute->lpszName); + return addAttribute_WOSD((XMLSTR)newAttribute->lpszName,(XMLSTR)newAttribute->lpszValue); +} + +XMLAttribute *XMLNode::updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName,XMLCSTR lpszOldName) +{ + int j=0; + getAttribute(lpszOldName,&j); + if (j) return updateAttribute_WOSD(lpszNewValue,lpszNewName,j-1); else - return addAttribute_WOSD(stringDup(lpszOldName), lpszNewValue); - } + { + if (lpszNewName) return addAttribute_WOSD(lpszNewName,lpszNewValue); + else return addAttribute_WOSD(stringDup(lpszOldName),lpszNewValue); + } } -int XMLNode::indexText(XMLCSTR lpszValue) const { - if (!d) return -1; - int i, l = d->nText; - if (!lpszValue) { - if (l) return 0; - return -1; - } - XMLCSTR *p = d->pText; - for (i = 0; i < l; i++) - if (lpszValue == p[i]) return i; - return -1; -} - -void XMLNode::deleteText(int i) { - if ((!d) || (i < 0) || (i >= d->nText)) return; - d->nText--; - XMLCSTR *p = d->pText + i; - free((void *)*p); - if (d->nText) - memmove(p, p + 1, (d->nText - i) * sizeof(XMLCSTR)); - else { - free(p); - d->pText = NULL; - } - removeOrderElement(d, eNodeText, i); -} - -void XMLNode::deleteText(XMLCSTR lpszValue) { - deleteText(indexText(lpszValue)); -} - -XMLCSTR XMLNode::updateText_WOSD(XMLSTR lpszNewValue, int i) { - if (!d) { - if (lpszNewValue) free(lpszNewValue); - return NULL; - } - if (i >= d->nText) return addText_WOSD(lpszNewValue); - XMLCSTR *p = d->pText + i; - if (*p != lpszNewValue) { - free((void *)*p); - *p = lpszNewValue; - } - return lpszNewValue; -} - -XMLCSTR XMLNode::updateText_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue) { - if (!d) { - if (lpszNewValue) free(lpszNewValue); - return NULL; - } - int i = indexText(lpszOldValue); - if (i >= 0) return updateText_WOSD(lpszNewValue, i); - return addText_WOSD(lpszNewValue); -} - -void XMLNode::deleteClear(int i) { - if ((!d) || (i < 0) || (i >= d->nClear)) return; - d->nClear--; - XMLClear *p = d->pClear + i; - free((void *)p->lpszValue); - if (d->nClear) - memmove(p, p + 1, (d->nClear - i) * sizeof(XMLClear)); - else { - free(p); - d->pClear = NULL; - } - removeOrderElement(d, eNodeClear, i); -} - -int XMLNode::indexClear(XMLCSTR lpszValue) const { - if (!d) return -1; - int i, l = d->nClear; - if (!lpszValue) { - if (l) return 0; +int XMLNode::indexText(XMLCSTR lpszValue) const +{ + if (!d) return -1; + int i,l=d->nText; + if (!lpszValue) { if (l) return 0; return -1; } + XMLCSTR *p=d->pText; + for (i=0; ipClear; - for (i = 0; i < l; i++) - if (lpszValue == p[i].lpszValue) return i; - return -1; } -void XMLNode::deleteClear(XMLCSTR lpszValue) { - deleteClear(indexClear(lpszValue)); +void XMLNode::deleteText(int i) +{ + if ((!d)||(i<0)||(i>=d->nText)) return; + d->nText--; + XMLCSTR *p=d->pText+i; + free((void*)*p); + if (d->nText) memmove(p,p+1,(d->nText-i)*sizeof(XMLCSTR)); else { free(p); d->pText=NULL; } + removeOrderElement(d,eNodeText,i); } -void XMLNode::deleteClear(XMLClear *a) { - if (a) deleteClear(a->lpszValue); + +void XMLNode::deleteText(XMLCSTR lpszValue) { deleteText(indexText(lpszValue)); } + +XMLCSTR XMLNode::updateText_WOSD(XMLSTR lpszNewValue, int i) +{ + if (!d) { if (lpszNewValue) free(lpszNewValue); return NULL; } + if (i>=d->nText) return addText_WOSD(lpszNewValue); + XMLCSTR *p=d->pText+i; + if (*p!=lpszNewValue) { free((void*)*p); *p=lpszNewValue; } + return lpszNewValue; } -XMLClear *XMLNode::updateClear_WOSD(XMLSTR lpszNewContent, int i) { - if (!d) { - if (lpszNewContent) free(lpszNewContent); - return NULL; - } - if (i >= d->nClear) return addClear_WOSD(lpszNewContent); - XMLClear *p = d->pClear + i; - if (lpszNewContent != p->lpszValue) { - free((void *)p->lpszValue); - p->lpszValue = lpszNewContent; - } - return p; -} - -XMLClear *XMLNode::updateClear_WOSD(XMLSTR lpszNewContent, - XMLCSTR lpszOldValue) { - if (!d) { - if (lpszNewContent) free(lpszNewContent); - return NULL; - } - int i = indexClear(lpszOldValue); - if (i >= 0) return updateClear_WOSD(lpszNewContent, i); - return addClear_WOSD(lpszNewContent); -} - -XMLClear *XMLNode::updateClear_WOSD(XMLClear *newP, XMLClear *oldP) { - if (oldP) - return updateClear_WOSD((XMLSTR)newP->lpszValue, (XMLSTR)oldP->lpszValue); - return NULL; -} - -int XMLNode::nChildNode(XMLCSTR name) const { - if (!d) return 0; - int i, j = 0, n = d->nChild; - XMLNode *pc = d->pChild; - for (i = 0; i < n; i++) { - if (xstricmp(pc->d->lpszName, name) == 0) j++; - pc++; - } - return j; -} - -XMLNode XMLNode::getChildNode(XMLCSTR name, int *j) const { - if (!d) return emptyXMLNode; - int i = 0, n = d->nChild; - if (j) i = *j; - XMLNode *pc = d->pChild + i; - for (; i < n; i++) { - if (!xstricmp(pc->d->lpszName, name)) { - if (j) *j = i + 1; - return *pc; - } - pc++; - } - return emptyXMLNode; -} - -XMLNode XMLNode::getChildNode(XMLCSTR name, int j) const { - if (!d) return emptyXMLNode; - if (j >= 0) { - int i = 0; - while (j-- > 0) getChildNode(name, &i); - return getChildNode(name, &i); - } - int i = d->nChild; - while (i--) - if (!xstricmp(name, d->pChild[i].d->lpszName)) break; - if (i < 0) return emptyXMLNode; - return getChildNode(i); -} - -XMLNode XMLNode::getChildNodeByPath(XMLCSTR _path, char createMissing, - XMLCHAR sep) { - XMLSTR path = stringDup(_path); - XMLNode x = getChildNodeByPathNonConst(path, createMissing, sep); - if (path) free(path); - return x; -} - -XMLNode XMLNode::getChildNodeByPathNonConst(XMLSTR path, char createIfMissing, - XMLCHAR sep) { - if ((!path) || (!(*path))) return *this; - XMLNode xn, xbase = *this; - XMLCHAR *tend1, sepString[2]; - sepString[0] = sep; - sepString[1] = 0; - tend1 = xstrstr(path, sepString); - while (tend1) { - *tend1 = 0; - xn = xbase.getChildNode(path); - if (xn.isEmpty()) { - if (createIfMissing) - xn = xbase.addChild(path); - else { - *tend1 = sep; - return XMLNode::emptyXMLNode; - } - } - *tend1 = sep; - xbase = xn; - path = tend1 + 1; - tend1 = xstrstr(path, sepString); - } - xn = xbase.getChildNode(path); - if (xn.isEmpty() && createIfMissing) xn = xbase.addChild(path); - return xn; -} - -XMLElementPosition XMLNode::positionOfText(int i) const { - if (i >= d->nText) i = d->nText - 1; - return findPosition(d, i, eNodeText); -} -XMLElementPosition XMLNode::positionOfClear(int i) const { - if (i >= d->nClear) i = d->nClear - 1; - return findPosition(d, i, eNodeClear); -} -XMLElementPosition XMLNode::positionOfChildNode(int i) const { - if (i >= d->nChild) i = d->nChild - 1; - return findPosition(d, i, eNodeChild); -} -XMLElementPosition XMLNode::positionOfText(XMLCSTR lpszValue) const { - return positionOfText(indexText(lpszValue)); -} -XMLElementPosition XMLNode::positionOfClear(XMLCSTR lpszValue) const { - return positionOfClear(indexClear(lpszValue)); -} -XMLElementPosition XMLNode::positionOfClear(XMLClear *a) const { - if (a) return positionOfClear(a->lpszValue); - return positionOfClear(); -} -XMLElementPosition XMLNode::positionOfChildNode(XMLNode x) const { - if ((!d) || (!x.d)) return -1; - XMLNodeData *dd = x.d; - XMLNode *pc = d->pChild; - int i = d->nChild; - while (i--) - if (pc[i].d == dd) return findPosition(d, i, eNodeChild); - return -1; -} -XMLElementPosition XMLNode::positionOfChildNode(XMLCSTR name, int count) const { - if (!name) return positionOfChildNode(count); - int j = 0; - do { - getChildNode(name, &j); - if (j < 0) return -1; - } while (count--); - return findPosition(d, j - 1, eNodeChild); -} - -XMLNode XMLNode::getChildNodeWithAttribute(XMLCSTR name, XMLCSTR attributeName, - XMLCSTR attributeValue, - int *k) const { - int i = 0, j; - if (k) i = *k; - XMLNode x; - XMLCSTR t; - do { - x = getChildNode(name, &i); - if (!x.isEmpty()) { - if (attributeValue) { - j = 0; - do { - t = x.getAttribute(attributeName, &j); - if (t && (xstricmp(attributeValue, t) == 0)) { - if (k) *k = i; - return x; - } - } while (t); - } else { - if (x.isAttributeSet(attributeName)) { - if (k) *k = i; - return x; - } - } - } - } while (!x.isEmpty()); - return emptyXMLNode; +XMLCSTR XMLNode::updateText_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue) +{ + if (!d) { if (lpszNewValue) free(lpszNewValue); return NULL; } + int i=indexText(lpszOldValue); + if (i>=0) return updateText_WOSD(lpszNewValue,i); + return addText_WOSD(lpszNewValue); } -// Find an attribute on an node. -XMLCSTR XMLNode::getAttribute(XMLCSTR lpszAttrib, int *j) const { - if (!d) return NULL; - int i = 0, n = d->nAttribute; - if (j) i = *j; - XMLAttribute *pAttr = d->pAttribute + i; - for (; i < n; i++) { - if (xstricmp(pAttr->lpszName, lpszAttrib) == 0) { - if (j) *j = i + 1; - return pAttr->lpszValue; - } - pAttr++; - } - return NULL; -} - -char XMLNode::isAttributeSet(XMLCSTR lpszAttrib) const { - if (!d) return FALSE; - int i, n = d->nAttribute; - XMLAttribute *pAttr = d->pAttribute; - for (i = 0; i < n; i++) { - if (xstricmp(pAttr->lpszName, lpszAttrib) == 0) { - return TRUE; - } - pAttr++; - } - return FALSE; +void XMLNode::deleteClear(int i) +{ + if ((!d)||(i<0)||(i>=d->nClear)) return; + d->nClear--; + XMLClear *p=d->pClear+i; + free((void*)p->lpszValue); + if (d->nClear) memmove(p,p+1,(d->nClear-i)*sizeof(XMLClear)); else { free(p); d->pClear=NULL; } + removeOrderElement(d,eNodeClear,i); } -XMLCSTR XMLNode::getAttribute(XMLCSTR name, int j) const { - if (!d) return NULL; - int i = 0; - while (j-- > 0) getAttribute(name, &i); - return getAttribute(name, &i); +int XMLNode::indexClear(XMLCSTR lpszValue) const +{ + if (!d) return -1; + int i,l=d->nClear; + if (!lpszValue) { if (l) return 0; return -1; } + XMLClear *p=d->pClear; + for (i=0; inAttribute) { - c.etype = eNodeAttribute; - c.attrib = d->pAttribute[i]; - return c; - } - i -= d->nAttribute; - c.etype = (XMLElementType)(d->pOrder[i] & 3); - i = (d->pOrder[i]) >> 2; - switch (c.etype) { - case eNodeChild: - c.child = d->pChild[i]; - break; - case eNodeText: - c.text = d->pText[i]; - break; - case eNodeClear: - c.clear = d->pClear[i]; - break; - default: - break; - } - return c; -} - -XMLCSTR XMLNode::getName() const { - if (!d) return NULL; - return d->lpszName; -} -int XMLNode::nText() const { - if (!d) return 0; - return d->nText; -} -int XMLNode::nChildNode() const { - if (!d) return 0; - return d->nChild; -} -int XMLNode::nAttribute() const { - if (!d) return 0; - return d->nAttribute; -} -int XMLNode::nClear() const { - if (!d) return 0; - return d->nClear; -} -int XMLNode::nElement() const { - if (!d) return 0; - return d->nAttribute + d->nChild + d->nText + d->nClear; -} -XMLClear XMLNode::getClear(int i) const { - if ((!d) || (i >= d->nClear)) return emptyXMLClear; - return d->pClear[i]; -} -XMLAttribute XMLNode::getAttribute(int i) const { - if ((!d) || (i >= d->nAttribute)) return emptyXMLAttribute; - return d->pAttribute[i]; -} -XMLCSTR XMLNode::getAttributeName(int i) const { - if ((!d) || (i >= d->nAttribute)) return NULL; - return d->pAttribute[i].lpszName; -} -XMLCSTR XMLNode::getAttributeValue(int i) const { - if ((!d) || (i >= d->nAttribute)) return NULL; - return d->pAttribute[i].lpszValue; -} -XMLCSTR XMLNode::getText(int i) const { - if ((!d) || (i >= d->nText)) return NULL; - return d->pText[i]; -} -XMLNode XMLNode::getChildNode(int i) const { - if ((!d) || (i >= d->nChild)) return emptyXMLNode; - return d->pChild[i]; -} -XMLNode XMLNode::getParentNode() const { - if ((!d) || (!d->pParent)) return emptyXMLNode; - return XMLNode(d->pParent); -} -char XMLNode::isDeclaration() const { - if (!d) return 0; - return d->isDeclaration; -} -char XMLNode::isEmpty() const { return (d == NULL); } -XMLNode XMLNode::emptyNode() { return XMLNode::emptyXMLNode; } - -XMLNode XMLNode::addChild(XMLCSTR lpszName, char isDeclaration, - XMLElementPosition pos) { - return addChild_priv(0, stringDup(lpszName), isDeclaration, pos); -} -XMLNode XMLNode::addChild_WOSD(XMLSTR lpszName, char isDeclaration, - XMLElementPosition pos) { - return addChild_priv(0, lpszName, isDeclaration, pos); -} -XMLAttribute *XMLNode::addAttribute(XMLCSTR lpszName, XMLCSTR lpszValue) { - return addAttribute_priv(0, stringDup(lpszName), stringDup(lpszValue)); -} -XMLAttribute *XMLNode::addAttribute_WOSD(XMLSTR lpszName, XMLSTR lpszValuev) { - return addAttribute_priv(0, lpszName, lpszValuev); -} -XMLCSTR XMLNode::addText(XMLCSTR lpszValue, XMLElementPosition pos) { - return addText_priv(0, stringDup(lpszValue), pos); -} -XMLCSTR XMLNode::addText_WOSD(XMLSTR lpszValue, XMLElementPosition pos) { - return addText_priv(0, lpszValue, pos); -} -XMLClear *XMLNode::addClear(XMLCSTR lpszValue, XMLCSTR lpszOpen, - XMLCSTR lpszClose, XMLElementPosition pos) { - return addClear_priv(0, stringDup(lpszValue), lpszOpen, lpszClose, pos); -} -XMLClear *XMLNode::addClear_WOSD(XMLSTR lpszValue, XMLCSTR lpszOpen, - XMLCSTR lpszClose, XMLElementPosition pos) { - return addClear_priv(0, lpszValue, lpszOpen, lpszClose, pos); +void XMLNode::deleteClear(XMLCSTR lpszValue) { deleteClear(indexClear(lpszValue)); } +void XMLNode::deleteClear(XMLClear *a) { if (a) deleteClear(a->lpszValue); } + +XMLClear *XMLNode::updateClear_WOSD(XMLSTR lpszNewContent, int i) +{ + if (!d) { if (lpszNewContent) free(lpszNewContent); return NULL; } + if (i>=d->nClear) return addClear_WOSD(lpszNewContent); + XMLClear *p=d->pClear+i; + if (lpszNewContent!=p->lpszValue) { free((void*)p->lpszValue); p->lpszValue=lpszNewContent; } + return p; } -XMLCSTR XMLNode::updateName(XMLCSTR lpszName) { - return updateName_WOSD(stringDup(lpszName)); + +XMLClear *XMLNode::updateClear_WOSD(XMLSTR lpszNewContent, XMLCSTR lpszOldValue) +{ + if (!d) { if (lpszNewContent) free(lpszNewContent); return NULL; } + int i=indexClear(lpszOldValue); + if (i>=0) return updateClear_WOSD(lpszNewContent,i); + return addClear_WOSD(lpszNewContent); } -XMLAttribute *XMLNode::updateAttribute(XMLAttribute *newAttribute, - XMLAttribute *oldAttribute) { - return updateAttribute_WOSD(stringDup(newAttribute->lpszValue), - stringDup(newAttribute->lpszName), - oldAttribute->lpszName); + +XMLClear *XMLNode::updateClear_WOSD(XMLClear *newP,XMLClear *oldP) +{ + if (oldP) return updateClear_WOSD((XMLSTR)newP->lpszValue,(XMLSTR)oldP->lpszValue); + return NULL; } -XMLAttribute *XMLNode::updateAttribute(XMLCSTR lpszNewValue, - XMLCSTR lpszNewName, int i) { - return updateAttribute_WOSD(stringDup(lpszNewValue), stringDup(lpszNewName), - i); + +int XMLNode::nChildNode(XMLCSTR name) const +{ + if (!d) return 0; + int i,j=0,n=d->nChild; + XMLNode *pc=d->pChild; + for (i=0; id->lpszName, name)==0) j++; + pc++; + } + return j; } -XMLAttribute *XMLNode::updateAttribute(XMLCSTR lpszNewValue, - XMLCSTR lpszNewName, - XMLCSTR lpszOldName) { - return updateAttribute_WOSD(stringDup(lpszNewValue), stringDup(lpszNewName), - lpszOldName); + +XMLNode XMLNode::getChildNode(XMLCSTR name, int *j) const +{ + if (!d) return emptyXMLNode; + int i=0,n=d->nChild; + if (j) i=*j; + XMLNode *pc=d->pChild+i; + for (; id->lpszName, name)) + { + if (j) *j=i+1; + return *pc; + } + pc++; + } + return emptyXMLNode; } -XMLCSTR XMLNode::updateText(XMLCSTR lpszNewValue, int i) { - return updateText_WOSD(stringDup(lpszNewValue), i); + +XMLNode XMLNode::getChildNode(XMLCSTR name, int j) const +{ + if (!d) return emptyXMLNode; + if (j>=0) + { + int i=0; + while (j-->0) getChildNode(name,&i); + return getChildNode(name,&i); + } + int i=d->nChild; + while (i--) if (!xstricmp(name,d->pChild[i].d->lpszName)) break; + if (i<0) return emptyXMLNode; + return getChildNode(i); +} + +XMLNode XMLNode::getChildNodeByPath(XMLCSTR _path, char createMissing, XMLCHAR sep) +{ + XMLSTR path=stringDup(_path); + XMLNode x=getChildNodeByPathNonConst(path,createMissing,sep); + if (path) free(path); + return x; +} + +XMLNode XMLNode::getChildNodeByPathNonConst(XMLSTR path, char createIfMissing, XMLCHAR sep) +{ + if ((!path)||(!(*path))) return *this; + XMLNode xn,xbase=*this; + XMLCHAR *tend1,sepString[2]; sepString[0]=sep; sepString[1]=0; + tend1=xstrstr(path,sepString); + while(tend1) + { + *tend1=0; + xn=xbase.getChildNode(path); + if (xn.isEmpty()) + { + if (createIfMissing) xn=xbase.addChild(path); + else { *tend1=sep; return XMLNode::emptyXMLNode; } + } + *tend1=sep; + xbase=xn; + path=tend1+1; + tend1=xstrstr(path,sepString); + } + xn=xbase.getChildNode(path); + if (xn.isEmpty()&&createIfMissing) xn=xbase.addChild(path); + return xn; +} + +XMLElementPosition XMLNode::positionOfText (int i) const { if (i>=d->nText ) i=d->nText-1; return findPosition(d,i,eNodeText ); } +XMLElementPosition XMLNode::positionOfClear (int i) const { if (i>=d->nClear) i=d->nClear-1; return findPosition(d,i,eNodeClear); } +XMLElementPosition XMLNode::positionOfChildNode(int i) const { if (i>=d->nChild) i=d->nChild-1; return findPosition(d,i,eNodeChild); } +XMLElementPosition XMLNode::positionOfText (XMLCSTR lpszValue) const { return positionOfText (indexText (lpszValue)); } +XMLElementPosition XMLNode::positionOfClear(XMLCSTR lpszValue) const { return positionOfClear(indexClear(lpszValue)); } +XMLElementPosition XMLNode::positionOfClear(XMLClear *a) const { if (a) return positionOfClear(a->lpszValue); return positionOfClear(); } +XMLElementPosition XMLNode::positionOfChildNode(XMLNode x) const +{ + if ((!d)||(!x.d)) return -1; + XMLNodeData *dd=x.d; + XMLNode *pc=d->pChild; + int i=d->nChild; + while (i--) if (pc[i].d==dd) return findPosition(d,i,eNodeChild); + return -1; } -XMLCSTR XMLNode::updateText(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue) { - return updateText_WOSD(stringDup(lpszNewValue), lpszOldValue); +XMLElementPosition XMLNode::positionOfChildNode(XMLCSTR name, int count) const +{ + if (!name) return positionOfChildNode(count); + int j=0; + do { getChildNode(name,&j); if (j<0) return -1; } while (count--); + return findPosition(d,j-1,eNodeChild); } -XMLClear *XMLNode::updateClear(XMLCSTR lpszNewContent, int i) { - return updateClear_WOSD(stringDup(lpszNewContent), i); + +XMLNode XMLNode::getChildNodeWithAttribute(XMLCSTR name,XMLCSTR attributeName,XMLCSTR attributeValue, int *k) const +{ + int i=0,j; + if (k) i=*k; + XMLNode x; + XMLCSTR t; + do + { + x=getChildNode(name,&i); + if (!x.isEmpty()) + { + if (attributeValue) + { + j=0; + do + { + t=x.getAttribute(attributeName,&j); + if (t&&(xstricmp(attributeValue,t)==0)) { if (k) *k=i; return x; } + } while (t); + } else + { + if (x.isAttributeSet(attributeName)) { if (k) *k=i; return x; } + } + } + } while (!x.isEmpty()); + return emptyXMLNode; } -XMLClear *XMLNode::updateClear(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue) { - return updateClear_WOSD(stringDup(lpszNewValue), lpszOldValue); + +// Find an attribute on an node. +XMLCSTR XMLNode::getAttribute(XMLCSTR lpszAttrib, int *j) const +{ + if (!d) return NULL; + int i=0,n=d->nAttribute; + if (j) i=*j; + XMLAttribute *pAttr=d->pAttribute+i; + for (; ilpszName, lpszAttrib)==0) + { + if (j) *j=i+1; + return pAttr->lpszValue; + } + pAttr++; + } + return NULL; +} + +char XMLNode::isAttributeSet(XMLCSTR lpszAttrib) const +{ + if (!d) return FALSE; + int i,n=d->nAttribute; + XMLAttribute *pAttr=d->pAttribute; + for (i=0; ilpszName, lpszAttrib)==0) + { + return TRUE; + } + pAttr++; + } + return FALSE; } -XMLClear *XMLNode::updateClear(XMLClear *newP, XMLClear *oldP) { - return updateClear_WOSD(stringDup(newP->lpszValue), oldP->lpszValue); + +XMLCSTR XMLNode::getAttribute(XMLCSTR name, int j) const +{ + if (!d) return NULL; + int i=0; + while (j-->0) getAttribute(name,&i); + return getAttribute(name,&i); +} + +XMLNodeContents XMLNode::enumContents(int i) const +{ + XMLNodeContents c; + if (!d) { c.etype=eNodeNULL; return c; } + if (inAttribute) + { + c.etype=eNodeAttribute; + c.attrib=d->pAttribute[i]; + return c; + } + i-=d->nAttribute; + c.etype=(XMLElementType)(d->pOrder[i]&3); + i=(d->pOrder[i])>>2; + switch (c.etype) + { + case eNodeChild: c.child = d->pChild[i]; break; + case eNodeText: c.text = d->pText[i]; break; + case eNodeClear: c.clear = d->pClear[i]; break; + default: break; + } + return c; } -char XMLNode::setGlobalOptions(XMLCharEncoding _characterEncoding, - char _guessWideCharChars, char _dropWhiteSpace, - char _removeCommentsInMiddleOfText) { - guessWideCharChars = _guessWideCharChars; - dropWhiteSpace = _dropWhiteSpace; - removeCommentsInMiddleOfText = _removeCommentsInMiddleOfText; +XMLCSTR XMLNode::getName() const { if (!d) return NULL; return d->lpszName; } +int XMLNode::nText() const { if (!d) return 0; return d->nText; } +int XMLNode::nChildNode() const { if (!d) return 0; return d->nChild; } +int XMLNode::nAttribute() const { if (!d) return 0; return d->nAttribute; } +int XMLNode::nClear() const { if (!d) return 0; return d->nClear; } +int XMLNode::nElement() const { if (!d) return 0; return d->nAttribute+d->nChild+d->nText+d->nClear; } +XMLClear XMLNode::getClear (int i) const { if ((!d)||(i>=d->nClear )) return emptyXMLClear; return d->pClear[i]; } +XMLAttribute XMLNode::getAttribute (int i) const { if ((!d)||(i>=d->nAttribute)) return emptyXMLAttribute; return d->pAttribute[i]; } +XMLCSTR XMLNode::getAttributeName (int i) const { if ((!d)||(i>=d->nAttribute)) return NULL; return d->pAttribute[i].lpszName; } +XMLCSTR XMLNode::getAttributeValue(int i) const { if ((!d)||(i>=d->nAttribute)) return NULL; return d->pAttribute[i].lpszValue; } +XMLCSTR XMLNode::getText (int i) const { if ((!d)||(i>=d->nText )) return NULL; return d->pText[i]; } +XMLNode XMLNode::getChildNode (int i) const { if ((!d)||(i>=d->nChild )) return emptyXMLNode; return d->pChild[i]; } +XMLNode XMLNode::getParentNode ( ) const { if ((!d)||(!d->pParent )) return emptyXMLNode; return XMLNode(d->pParent); } +char XMLNode::isDeclaration ( ) const { if (!d) return 0; return d->isDeclaration; } +char XMLNode::isEmpty ( ) const { return (d==NULL); } +XMLNode XMLNode::emptyNode ( ) { return XMLNode::emptyXMLNode; } + +XMLNode XMLNode::addChild(XMLCSTR lpszName, char isDeclaration, XMLElementPosition pos) + { return addChild_priv(0,stringDup(lpszName),isDeclaration,pos); } +XMLNode XMLNode::addChild_WOSD(XMLSTR lpszName, char isDeclaration, XMLElementPosition pos) + { return addChild_priv(0,lpszName,isDeclaration,pos); } +XMLAttribute *XMLNode::addAttribute(XMLCSTR lpszName, XMLCSTR lpszValue) + { return addAttribute_priv(0,stringDup(lpszName),stringDup(lpszValue)); } +XMLAttribute *XMLNode::addAttribute_WOSD(XMLSTR lpszName, XMLSTR lpszValuev) + { return addAttribute_priv(0,lpszName,lpszValuev); } +XMLCSTR XMLNode::addText(XMLCSTR lpszValue, XMLElementPosition pos) + { return addText_priv(0,stringDup(lpszValue),pos); } +XMLCSTR XMLNode::addText_WOSD(XMLSTR lpszValue, XMLElementPosition pos) + { return addText_priv(0,lpszValue,pos); } +XMLClear *XMLNode::addClear(XMLCSTR lpszValue, XMLCSTR lpszOpen, XMLCSTR lpszClose, XMLElementPosition pos) + { return addClear_priv(0,stringDup(lpszValue),lpszOpen,lpszClose,pos); } +XMLClear *XMLNode::addClear_WOSD(XMLSTR lpszValue, XMLCSTR lpszOpen, XMLCSTR lpszClose, XMLElementPosition pos) + { return addClear_priv(0,lpszValue,lpszOpen,lpszClose,pos); } +XMLCSTR XMLNode::updateName(XMLCSTR lpszName) + { return updateName_WOSD(stringDup(lpszName)); } +XMLAttribute *XMLNode::updateAttribute(XMLAttribute *newAttribute, XMLAttribute *oldAttribute) + { return updateAttribute_WOSD(stringDup(newAttribute->lpszValue),stringDup(newAttribute->lpszName),oldAttribute->lpszName); } +XMLAttribute *XMLNode::updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,int i) + { return updateAttribute_WOSD(stringDup(lpszNewValue),stringDup(lpszNewName),i); } +XMLAttribute *XMLNode::updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,XMLCSTR lpszOldName) + { return updateAttribute_WOSD(stringDup(lpszNewValue),stringDup(lpszNewName),lpszOldName); } +XMLCSTR XMLNode::updateText(XMLCSTR lpszNewValue, int i) + { return updateText_WOSD(stringDup(lpszNewValue),i); } +XMLCSTR XMLNode::updateText(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue) + { return updateText_WOSD(stringDup(lpszNewValue),lpszOldValue); } +XMLClear *XMLNode::updateClear(XMLCSTR lpszNewContent, int i) + { return updateClear_WOSD(stringDup(lpszNewContent),i); } +XMLClear *XMLNode::updateClear(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue) + { return updateClear_WOSD(stringDup(lpszNewValue),lpszOldValue); } +XMLClear *XMLNode::updateClear(XMLClear *newP,XMLClear *oldP) + { return updateClear_WOSD(stringDup(newP->lpszValue),oldP->lpszValue); } + +char XMLNode::setGlobalOptions(XMLCharEncoding _characterEncoding, char _guessWideCharChars, + char _dropWhiteSpace, char _removeCommentsInMiddleOfText) +{ + guessWideCharChars=_guessWideCharChars; dropWhiteSpace=_dropWhiteSpace; removeCommentsInMiddleOfText=_removeCommentsInMiddleOfText; #ifdef _XMLWIDECHAR - if (_characterEncoding) characterEncoding = _characterEncoding; + if (_characterEncoding) characterEncoding=_characterEncoding; #else - switch (_characterEncoding) { - case char_encoding_UTF8: - characterEncoding = _characterEncoding; - XML_ByteTable = XML_utf8ByteTable; - break; - case char_encoding_legacy: - characterEncoding = _characterEncoding; - XML_ByteTable = XML_legacyByteTable; - break; - case char_encoding_ShiftJIS: - characterEncoding = _characterEncoding; - XML_ByteTable = XML_sjisByteTable; - break; - case char_encoding_GB2312: - characterEncoding = _characterEncoding; - XML_ByteTable = XML_gb2312ByteTable; - break; + switch(_characterEncoding) + { + case char_encoding_UTF8: characterEncoding=_characterEncoding; XML_ByteTable=XML_utf8ByteTable; break; + case char_encoding_legacy: characterEncoding=_characterEncoding; XML_ByteTable=XML_legacyByteTable; break; + case char_encoding_ShiftJIS: characterEncoding=_characterEncoding; XML_ByteTable=XML_sjisByteTable; break; + case char_encoding_GB2312: characterEncoding=_characterEncoding; XML_ByteTable=XML_gb2312ByteTable; break; case char_encoding_Big5: - case char_encoding_GBK: - characterEncoding = _characterEncoding; - XML_ByteTable = XML_gbk_big5_ByteTable; - break; - default: - return 1; - } + case char_encoding_GBK: characterEncoding=_characterEncoding; XML_ByteTable=XML_gbk_big5_ByteTable; break; + default: return 1; + } #endif - return 0; + return 0; } -XMLNode::XMLCharEncoding XMLNode::guessCharEncoding( - void *buf, int l, char useXMLEncodingAttribute) { +XMLNode::XMLCharEncoding XMLNode::guessCharEncoding(void *buf,int l, char useXMLEncodingAttribute) +{ #ifdef _XMLWIDECHAR - return (XMLCharEncoding)0; -#else - if (l < 25) return (XMLCharEncoding)0; - if (guessWideCharChars && (myIsTextWideChar(buf, l))) return (XMLCharEncoding)0; - unsigned char *b = (unsigned char *)buf; - if ((b[0] == 0xef) && (b[1] == 0xbb) && (b[2] == 0xbf)) - return char_encoding_UTF8; - - // Match utf-8 model ? - XMLCharEncoding bestGuess = char_encoding_UTF8; - int i = 0; - while (i < l) switch (XML_utf8ByteTable[b[i]]) { - case 4: - i++; - if ((i < l) && (b[i] & 0xC0) != 0x80) { - bestGuess = char_encoding_legacy; - i = l; - } // 10bbbbbb ? - case 3: - i++; - if ((i < l) && (b[i] & 0xC0) != 0x80) { - bestGuess = char_encoding_legacy; - i = l; - } // 10bbbbbb ? - case 2: - i++; - if ((i < l) && (b[i] & 0xC0) != 0x80) { - bestGuess = char_encoding_legacy; - i = l; - } // 10bbbbbb ? - case 1: - i++; - break; - case 0: - i = l; +#else + if (l<25) return (XMLCharEncoding)0; + if (guessWideCharChars&&(myIsTextWideChar(buf,l))) return (XMLCharEncoding)0; + unsigned char *b=(unsigned char*)buf; + if ((b[0]==0xef)&&(b[1]==0xbb)&&(b[2]==0xbf)) return char_encoding_UTF8; + + // Match utf-8 model ? + XMLCharEncoding bestGuess=char_encoding_UTF8; + int i=0; + while (i>18 ]; + *(curr++)=base64EncodeTable[(j>>12)&0x3f]; + *(curr++)=base64EncodeTable[(j>> 6)&0x3f]; + *(curr++)=base64EncodeTable[(j )&0x3f]; + if (formatted) { if (!k) { *(curr++)=_CXML('\n'); k=18; } k--; } } - } - eLen = inlen - eLen * 3; // 0 - 2. - if (eLen == 1) { - *(curr++) = base64EncodeTable[inbuf[0] >> 2]; - *(curr++) = base64EncodeTable[(inbuf[0] << 4) & 0x3F]; - *(curr++) = base64Fillchar; - *(curr++) = base64Fillchar; - } else if (eLen == 2) { - j = (inbuf[0] << 8) | inbuf[1]; - *(curr++) = base64EncodeTable[j >> 10]; - *(curr++) = base64EncodeTable[(j >> 4) & 0x3f]; - *(curr++) = base64EncodeTable[(j << 2) & 0x3f]; - *(curr++) = base64Fillchar; - } - *(curr++) = 0; - return (XMLSTR)buf; -} - -unsigned int XMLParserBase64Tool::decodeSize(XMLCSTR data, XMLError *xe) { - if (xe) *xe = eXMLErrorNone; - int size = 0; - unsigned char c; - // skip any extra characters (e.g. newlines or spaces) - while (*data) { -#ifdef _XMLWIDECHAR - if (*data > 255) { - if (xe) *xe = eXMLErrorBase64DecodeIllegalCharacter; - return 0; + eLen=inlen-eLen*3; // 0 - 2. + if (eLen==1) + { + *(curr++)=base64EncodeTable[ inbuf[0]>>2 ]; + *(curr++)=base64EncodeTable[(inbuf[0]<<4)&0x3F]; + *(curr++)=base64Fillchar; + *(curr++)=base64Fillchar; + } else if (eLen==2) + { + j=(inbuf[0]<<8)|inbuf[1]; + *(curr++)=base64EncodeTable[ j>>10 ]; + *(curr++)=base64EncodeTable[(j>> 4)&0x3f]; + *(curr++)=base64EncodeTable[(j<< 2)&0x3f]; + *(curr++)=base64Fillchar; } + *(curr++)=0; + return (XMLSTR)buf; +} + +unsigned int XMLParserBase64Tool::decodeSize(XMLCSTR data,XMLError *xe) +{ + if (xe) *xe=eXMLErrorNone; + int size=0; + unsigned char c; + //skip any extra characters (e.g. newlines or spaces) + while (*data) + { +#ifdef _XMLWIDECHAR + if (*data>255) { if (xe) *xe=eXMLErrorBase64DecodeIllegalCharacter; return 0; } #endif - c = base64DecodeTable[(unsigned char)(*data)]; - if (c < 97) - size++; - else if (c == 98) { - if (xe) *xe = eXMLErrorBase64DecodeIllegalCharacter; - return 0; + c=base64DecodeTable[(unsigned char)(*data)]; + if (c<97) size++; + else if (c==98) { if (xe) *xe=eXMLErrorBase64DecodeIllegalCharacter; return 0; } + data++; } - data++; - } - if (xe && (size % 4 != 0)) *xe = eXMLErrorBase64DataSizeIsNotMultipleOf4; - if (size == 0) return 0; - do { - data--; - size--; - } while (*data == base64Fillchar); - size++; - return (unsigned int)((size * 3) / 4); -} - -unsigned char XMLParserBase64Tool::decode(XMLCSTR data, unsigned char *buf, - int len, XMLError *xe) { - if (xe) *xe = eXMLErrorNone; - int i = 0, p = 0; - unsigned char d, c; - for (;;) { + if (xe&&(size%4!=0)) *xe=eXMLErrorBase64DataSizeIsNotMultipleOf4; + if (size==0) return 0; + do { data--; size--; } while(*data==base64Fillchar); size++; + return (unsigned int)((size*3)/4); +} + +unsigned char XMLParserBase64Tool::decode(XMLCSTR data, unsigned char *buf, int len, XMLError *xe) +{ + if (xe) *xe=eXMLErrorNone; + int i=0,p=0; + unsigned char d,c; + for(;;) + { + #ifdef _XMLWIDECHAR -#define BASE64DECODE_READ_NEXT_CHAR(c) \ - do { \ - if (data[i] > 255) { \ - c = 98; \ - break; \ - } \ - c = base64DecodeTable[(unsigned char)data[i++]]; \ - } while (c == 97); \ - if (c == 98) { \ - if (xe) *xe = eXMLErrorBase64DecodeIllegalCharacter; \ - return 0; \ - } +#define BASE64DECODE_READ_NEXT_CHAR(c) \ + do { \ + if (data[i]>255){ c=98; break; } \ + c=base64DecodeTable[(unsigned char)data[i++]]; \ + }while (c==97); \ + if(c==98){ if(xe)*xe=eXMLErrorBase64DecodeIllegalCharacter; return 0; } #else -#define BASE64DECODE_READ_NEXT_CHAR(c) \ - do { \ - c = base64DecodeTable[(unsigned char)data[i++]]; \ - } while (c == 97); \ - if (c == 98) { \ - if (xe) *xe = eXMLErrorBase64DecodeIllegalCharacter; \ - return 0; \ - } +#define BASE64DECODE_READ_NEXT_CHAR(c) \ + do { c=base64DecodeTable[(unsigned char)data[i++]]; }while (c==97); \ + if(c==98){ if(xe)*xe=eXMLErrorBase64DecodeIllegalCharacter; return 0; } #endif - BASE64DECODE_READ_NEXT_CHAR(c) - if (c == 99) { - return 2; - } - if (c == 96) { - if (p == (int)len) return 2; - if (xe) *xe = eXMLErrorBase64DecodeTruncatedData; - return 1; - } - - BASE64DECODE_READ_NEXT_CHAR(d) - if ((d == 99) || (d == 96)) { - if (xe) *xe = eXMLErrorBase64DecodeTruncatedData; - return 1; - } - if (p == (int)len) { - if (xe) *xe = eXMLErrorBase64DecodeBufferTooSmall; - return 0; - } - buf[p++] = (unsigned char)((c << 2) | ((d >> 4) & 0x3)); - - BASE64DECODE_READ_NEXT_CHAR(c) - if (c == 99) { - if (xe) *xe = eXMLErrorBase64DecodeTruncatedData; - return 1; - } - if (p == (int)len) { - if (c == 96) return 2; - if (xe) *xe = eXMLErrorBase64DecodeBufferTooSmall; - return 0; - } - if (c == 96) { - if (xe) *xe = eXMLErrorBase64DecodeTruncatedData; - return 1; - } - buf[p++] = (unsigned char)(((d << 4) & 0xf0) | ((c >> 2) & 0xf)); + BASE64DECODE_READ_NEXT_CHAR(c) + if (c==99) { return 2; } + if (c==96) + { + if (p==(int)len) return 2; + if (xe) *xe=eXMLErrorBase64DecodeTruncatedData; + return 1; + } - BASE64DECODE_READ_NEXT_CHAR(d) - if (d == 99) { - if (xe) *xe = eXMLErrorBase64DecodeTruncatedData; - return 1; - } - if (p == (int)len) { - if (d == 96) return 2; - if (xe) *xe = eXMLErrorBase64DecodeBufferTooSmall; - return 0; - } - if (d == 96) { - if (xe) *xe = eXMLErrorBase64DecodeTruncatedData; - return 1; + BASE64DECODE_READ_NEXT_CHAR(d) + if ((d==99)||(d==96)) { if (xe) *xe=eXMLErrorBase64DecodeTruncatedData; return 1; } + if (p==(int)len) { if (xe) *xe=eXMLErrorBase64DecodeBufferTooSmall; return 0; } + buf[p++]=(unsigned char)((c<<2)|((d>>4)&0x3)); + + BASE64DECODE_READ_NEXT_CHAR(c) + if (c==99) { if (xe) *xe=eXMLErrorBase64DecodeTruncatedData; return 1; } + if (p==(int)len) + { + if (c==96) return 2; + if (xe) *xe=eXMLErrorBase64DecodeBufferTooSmall; + return 0; + } + if (c==96) { if (xe) *xe=eXMLErrorBase64DecodeTruncatedData; return 1; } + buf[p++]=(unsigned char)(((d<<4)&0xf0)|((c>>2)&0xf)); + + BASE64DECODE_READ_NEXT_CHAR(d) + if (d==99 ) { if (xe) *xe=eXMLErrorBase64DecodeTruncatedData; return 1; } + if (p==(int)len) + { + if (d==96) return 2; + if (xe) *xe=eXMLErrorBase64DecodeBufferTooSmall; + return 0; + } + if (d==96) { if (xe) *xe=eXMLErrorBase64DecodeTruncatedData; return 1; } + buf[p++]=(unsigned char)(((c<<6)&0xc0)|d); } - buf[p++] = (unsigned char)(((c << 6) & 0xc0) | d); - } } #undef BASE64DECODE_READ_NEXT_CHAR -void XMLParserBase64Tool::alloc(int newsize) { - if ((!buf) && (newsize)) { - buf = malloc(newsize); - buflen = newsize; - return; - } - if (newsize > buflen) { - buf = realloc(buf, newsize); - buflen = newsize; - } -} - -unsigned char *XMLParserBase64Tool::decode(XMLCSTR data, int *outlen, - XMLError *xe) { - if (xe) *xe = eXMLErrorNone; - unsigned int len = decodeSize(data, xe); - if (outlen) *outlen = len; - if (!len) return NULL; - alloc(len + 1); - if (!decode(data, (unsigned char *)buf, len, xe)) { - return NULL; - } - return (unsigned char *)buf; +void XMLParserBase64Tool::alloc(int newsize) +{ + if ((!buf)&&(newsize)) { buf=malloc(newsize); buflen=newsize; return; } + if (newsize>buflen) { buf=realloc(buf,newsize); buflen=newsize; } } + +unsigned char *XMLParserBase64Tool::decode(XMLCSTR data, int *outlen, XMLError *xe) +{ + if (xe) *xe=eXMLErrorNone; + unsigned int len=decodeSize(data,xe); + if (outlen) *outlen=len; + if (!len) return NULL; + alloc(len+1); + if(!decode(data,(unsigned char*)buf,len,xe)){ return NULL; } + return (unsigned char*)buf; +} + diff --git a/src/gpuwattch/xmlParser.h b/src/gpuwattch/xmlParser.h index 64f5515..068b36f 100644 --- a/src/gpuwattch/xmlParser.h +++ b/src/gpuwattch/xmlParser.h @@ -9,20 +9,17 @@ * @version V2.41 * @author Frank Vanden Berghen * - * The following license terms for the "XMLParser library from Business-Insight" - *apply to projects + * The following license terms for the "XMLParser library from Business-Insight" apply to projects * that are in some way related to * the "mcpat project", including applications * using "mcpat project" and tools developed * for enhancing "mcpat project". All other projects - * (not related to "mcpat project") have to use the "XMLParser library from - *Business-Insight" + * (not related to "mcpat project") have to use the "XMLParser library from Business-Insight" * code under the Aladdin Free Public License (AFPL) * See the file "AFPL-license.txt" for more informations about the AFPL license. * (see http://www.artifex.com/downloads/doc/Public.htm for detailed AFPL terms) * - * Redistribution and use of the "XMLParser library from Business-Insight" in - *source and binary forms, with or without + * Redistribution and use of the "XMLParser library from Business-Insight" in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. @@ -49,31 +46,21 @@ * All rights reserved. * * \section tutorial First Tutorial - * You can follow a simple Tutorial to know - *the basics... + * You can follow a simple Tutorial to know the basics... * - * \section usage General usage: How to include the XMLParser library inside - *your project. + * \section usage General usage: How to include the XMLParser library inside your project. * - * The library is composed of two files: xmlParser.cpp and - * xmlParser.h. These are the ONLY 2 files that - *you need when + * The library is composed of two files: xmlParser.cpp and + * xmlParser.h. These are the ONLY 2 files that you need when * using the library inside your own projects. * - * All the functions of the library are documented inside the comments of the - *file - * xmlParser.h. These comments can be - *transformed in - * full-fledged HTML documentation using the DOXYGEN software: simply type: - *"doxygen doxy.cfg" + * All the functions of the library are documented inside the comments of the file + * xmlParser.h. These comments can be transformed in + * full-fledged HTML documentation using the DOXYGEN software: simply type: "doxygen doxy.cfg" * - * By default, the XMLParser library uses (char*) for string representation.To - *use the (wchar_t*) - * version of the library, you need to define the "_UNICODE" preprocessor - *definition variable - * (this is usually done inside your project definition file) (This is done - *automatically for you + * By default, the XMLParser library uses (char*) for string representation.To use the (wchar_t*) + * version of the library, you need to define the "_UNICODE" preprocessor definition variable + * (this is usually done inside your project definition file) (This is done automatically for you * when using Visual Studio). * * \section example Advanced Tutorial and Many Examples of usage. @@ -81,66 +68,48 @@ * Some very small introductory examples are described inside the Tutorial file * xmlParser.html * - * Some additional small examples are also inside the file xmlTest.cpp + * Some additional small examples are also inside the file xmlTest.cpp * (for the "char*" version of the library) and inside the file * xmlTestUnicode.cpp (for the "wchar_t*" - * version of the library). If you have a question, please review these - *additionnal examples + * version of the library). If you have a question, please review these additionnal examples * before sending an e-mail to the author. * * To build the examples: * - linux/unix: type "make" * - solaris: type "make -f makefile.solaris" * - windows: Visual Studio: double-click on xmlParser.dsw - * (under Visual Studio .NET, the .dsp and .dsw files will be automatically - *converted to .vcproj and .sln files) + * (under Visual Studio .NET, the .dsp and .dsw files will be automatically converted to .vcproj and .sln files) * * In order to build the examples you need some additional files: * - linux/unix: makefile * - solaris: makefile.solaris - * - windows: Visual Studio: *.dsp, xmlParser.dsw and also xmlParser.lib and - *xmlParser.dll + * - windows: Visual Studio: *.dsp, xmlParser.dsw and also xmlParser.lib and xmlParser.dll * * \section debugging Debugging with the XMLParser library * * \subsection debugwin Debugging under WINDOWS * - * Inside Visual C++, the "debug versions" of the memory allocation - *functions are - * very slow: Do not forget to compile in "release mode" to get maximum - *speed. - * When I had to debug a software that was using the XMLParser Library, it - *was usually - * a nightmare because the library was sooOOOoooo slow in debug mode - *(because of the + * Inside Visual C++, the "debug versions" of the memory allocation functions are + * very slow: Do not forget to compile in "release mode" to get maximum speed. + * When I had to debug a software that was using the XMLParser Library, it was usually + * a nightmare because the library was sooOOOoooo slow in debug mode (because of the * slow memory allocations in Debug mode). To solve this - * problem, during all the debugging session, I am now using a very fast - *DLL version of the - * XMLParser Library (the DLL is compiled in release mode). Using the DLL - *version of - * the XMLParser Library allows me to have lightening XML parsing speed - *even in debug! - * Other than that, the DLL version is useless: In the release version of - *my tool, - * I always use the normal, ".cpp"-based, XMLParser Library (I simply - *include the + * problem, during all the debugging session, I am now using a very fast DLL version of the + * XMLParser Library (the DLL is compiled in release mode). Using the DLL version of + * the XMLParser Library allows me to have lightening XML parsing speed even in debug! + * Other than that, the DLL version is useless: In the release version of my tool, + * I always use the normal, ".cpp"-based, XMLParser Library (I simply include the * xmlParser.cpp and * xmlParser.h files into the project). * - * The file XMLNodeAutoexp.txt - *contains some - * "tweaks" that improve substancially the display of the content of the XMLNode - *objects - * inside the Visual Studio Debugger. Believe me, once you have seen inside the - *debugger - * the "smooth" display of the XMLNode objects, you cannot live without it - *anymore! + * The file XMLNodeAutoexp.txt contains some + * "tweaks" that improve substancially the display of the content of the XMLNode objects + * inside the Visual Studio Debugger. Believe me, once you have seen inside the debugger + * the "smooth" display of the XMLNode objects, you cannot live without it anymore! * * \subsection debuglinux Debugging under LINUX/UNIX * - * The speed of the debug version of the XMLParser library is tolerable so - *no extra + * The speed of the debug version of the XMLParser library is tolerable so no extra * work.has been done. * ****************************************************************************/ @@ -151,21 +120,16 @@ #include #ifdef _UNICODE -// If you comment the next "define" line then the library will never "switch to" -// _UNICODE (wchar_t*) mode (16/32 bits per characters). +// If you comment the next "define" line then the library will never "switch to" _UNICODE (wchar_t*) mode (16/32 bits per characters). // This is useful when you get error messages like: -// 'XMLNode::openFileHelper' : cannot convert parameter 2 from 'const char -// [5]' to 'const wchar_t *' -// The _XMLWIDECHAR preprocessor variable force the XMLParser library into -// either utf16/32-mode (the proprocessor variable +// 'XMLNode::openFileHelper' : cannot convert parameter 2 from 'const char [5]' to 'const wchar_t *' +// The _XMLWIDECHAR preprocessor variable force the XMLParser library into either utf16/32-mode (the proprocessor variable // must be defined) or utf8-mode(the pre-processor variable must be undefined). #define _XMLWIDECHAR #endif -#if defined(WIN32) || defined(UNDER_CE) || defined(_WIN32) || \ - defined(WIN64) || defined(__BORLANDC__) -// comment the next line if you are under windows and the compiler is not -// Microsoft Visual Studio (6.0 or .NET) or Borland +#if defined(WIN32) || defined(UNDER_CE) || defined(_WIN32) || defined(WIN64) || defined(__BORLANDC__) +// comment the next line if you are under windows and the compiler is not Microsoft Visual Studio (6.0 or .NET) or Borland #define _XMLWINDOWS #endif @@ -182,8 +146,7 @@ #define XMLDLLENTRY #endif -// uncomment the next line if you want no support for wchar_t* (no need for the -// or libraries anymore to compile) +// uncomment the next line if you want no support for wchar_t* (no need for the or libraries anymore to compile) //#define XML_NO_WIDE_CHAR #ifdef XML_NO_WIDE_CHAR @@ -196,880 +159,604 @@ #else #define XMLDLLENTRY #ifndef XML_NO_WIDE_CHAR -#include // to have 'wcsrtombs' for ANSI version -// to have 'mbsrtowcs' for WIDECHAR version +#include // to have 'wcsrtombs' for ANSI version + // to have 'mbsrtowcs' for WIDECHAR version #endif #endif // Some common types for char set portable code #ifdef _XMLWIDECHAR -#define _CXML(c) L##c -#define XMLCSTR const wchar_t * -#define XMLSTR wchar_t * -#define XMLCHAR wchar_t + #define _CXML(c) L ## c + #define XMLCSTR const wchar_t * + #define XMLSTR wchar_t * + #define XMLCHAR wchar_t #else -#define _CXML(c) c -#define XMLCSTR const char * -#define XMLSTR char * -#define XMLCHAR char + #define _CXML(c) c + #define XMLCSTR const char * + #define XMLSTR char * + #define XMLCHAR char #endif #ifndef FALSE -#define FALSE 0 + #define FALSE 0 #endif /* FALSE */ #ifndef TRUE -#define TRUE 1 + #define TRUE 1 #endif /* TRUE */ + /// Enumeration for XML parse errors. -typedef enum XMLError { - eXMLErrorNone = 0, - eXMLErrorMissingEndTag, - eXMLErrorNoXMLTagFound, - eXMLErrorEmpty, - eXMLErrorMissingTagName, - eXMLErrorMissingEndTagName, - eXMLErrorUnmatchedEndTag, - eXMLErrorUnmatchedEndClearTag, - eXMLErrorUnexpectedToken, - eXMLErrorNoElements, - eXMLErrorFileNotFound, - eXMLErrorFirstTagNotFound, - eXMLErrorUnknownCharacterEntity, - eXMLErrorCharacterCodeAbove255, - eXMLErrorCharConversionError, - eXMLErrorCannotOpenWriteFile, - eXMLErrorCannotWriteFile, - - eXMLErrorBase64DataSizeIsNotMultipleOf4, - eXMLErrorBase64DecodeIllegalCharacter, - eXMLErrorBase64DecodeTruncatedData, - eXMLErrorBase64DecodeBufferTooSmall +typedef enum XMLError +{ + eXMLErrorNone = 0, + eXMLErrorMissingEndTag, + eXMLErrorNoXMLTagFound, + eXMLErrorEmpty, + eXMLErrorMissingTagName, + eXMLErrorMissingEndTagName, + eXMLErrorUnmatchedEndTag, + eXMLErrorUnmatchedEndClearTag, + eXMLErrorUnexpectedToken, + eXMLErrorNoElements, + eXMLErrorFileNotFound, + eXMLErrorFirstTagNotFound, + eXMLErrorUnknownCharacterEntity, + eXMLErrorCharacterCodeAbove255, + eXMLErrorCharConversionError, + eXMLErrorCannotOpenWriteFile, + eXMLErrorCannotWriteFile, + + eXMLErrorBase64DataSizeIsNotMultipleOf4, + eXMLErrorBase64DecodeIllegalCharacter, + eXMLErrorBase64DecodeTruncatedData, + eXMLErrorBase64DecodeBufferTooSmall } XMLError; -/// Enumeration used to manage type of data. Use in conjunction with structure -/// XMLNodeContents -typedef enum XMLElementType { - eNodeChild = 0, - eNodeAttribute = 1, - eNodeText = 2, - eNodeClear = 3, - eNodeNULL = 4 + +/// Enumeration used to manage type of data. Use in conjunction with structure XMLNodeContents +typedef enum XMLElementType +{ + eNodeChild=0, + eNodeAttribute=1, + eNodeText=2, + eNodeClear=3, + eNodeNULL=4 } XMLElementType; /// Structure used to obtain error details if the parse fails. -typedef struct XMLResults { - enum XMLError error; - int nLine, nColumn; +typedef struct XMLResults +{ + enum XMLError error; + int nLine,nColumn; } XMLResults; /// Structure for XML clear (unformatted) node (usually comments) typedef struct XMLClear { - XMLCSTR lpszValue; - XMLCSTR lpszOpenTag; - XMLCSTR lpszCloseTag; + XMLCSTR lpszValue; XMLCSTR lpszOpenTag; XMLCSTR lpszCloseTag; } XMLClear; /// Structure for XML attribute. typedef struct XMLAttribute { - XMLCSTR lpszName; - XMLCSTR lpszValue; + XMLCSTR lpszName; XMLCSTR lpszValue; } XMLAttribute; /// XMLElementPosition are not interchangeable with simple indexes typedef int XMLElementPosition; struct XMLNodeContents; - + /** @defgroup XMLParserGeneral The XML parser */ /// Main Class representing a XML node /** * All operations are performed using this class. - * \note The constructors of the XMLNode class are protected, so use instead one - * of these four methods to get your first instance of XMLNode: + * \note The constructors of the XMLNode class are protected, so use instead one of these four methods to get your first instance of XMLNode: *
    *
  • XMLNode::parseString
  • *
  • XMLNode::parseFile
  • *
  • XMLNode::openFileHelper
  • *
  • XMLNode::createXMLTopNode (or XMLNode::createXMLTopNode_WOSD)
  • *
*/ -typedef struct XMLDLLENTRY XMLNode { - private: - struct XMLNodeDataTag; - - /// Constructors are protected, so use instead one of: XMLNode::parseString, - /// XMLNode::parseFile, XMLNode::openFileHelper, XMLNode::createXMLTopNode - XMLNode(struct XMLNodeDataTag *pParent, XMLSTR lpszName, char isDeclaration); - /// Constructors are protected, so use instead one of: XMLNode::parseString, - /// XMLNode::parseFile, XMLNode::openFileHelper, XMLNode::createXMLTopNode - XMLNode(struct XMLNodeDataTag *p); - - public: - static XMLCSTR getVersion(); ///< Return the XMLParser library version number - - /** @defgroup conversions Parsing XML files/strings to an XMLNode structure - * and Rendering XMLNode's to files/string. - * @ingroup XMLParserGeneral - * @{ */ - - /// Parse an XML string and return the root of a XMLNode tree representing the - /// string. - static XMLNode parseString(XMLCSTR lpXMLString, XMLCSTR tag = NULL, - XMLResults *pResults = NULL); - /**< The "parseString" function parse an XML string and return the root of a - * XMLNode tree. The "opposite" of this function is - * the function "createXMLString" that re-creates an XML string from an - * XMLNode tree. If the XML document is corrupted, the - * "parseString" method will initialize the "pResults" variable with some - * information that can be used to trace the error. - * If you still want to parse the file, you can use the APPROXIMATE_PARSING - * option as explained inside the note at the - * beginning of the "xmlParser.cpp" file. - * - * @param lpXMLString the XML string to parse - * @param tag the name of the first tag inside the XML file. If the tag - * parameter is omitted, this function returns a node that represents the head - * of the xml document including the declaration term (). - * @param pResults a pointer to a XMLResults variable that will contain some - * information that can be used to trace the XML parsing error. You can have a - * user-friendly explanation of the parsing error with the "getError" - * function. - */ - - /// Parse an XML file and return the root of a XMLNode tree representing the - /// file. - static XMLNode parseFile(XMLCSTR filename, XMLCSTR tag = NULL, - XMLResults *pResults = NULL); - /**< The "parseFile" function parse an XML file and return the root of a - * XMLNode tree. The "opposite" of this function is - * the function "writeToFile" that re-creates an XML file from an XMLNode - * tree. If the XML document is corrupted, the - * "parseFile" method will initialize the "pResults" variable with some - * information that can be used to trace the error. - * If you still want to parse the file, you can use the APPROXIMATE_PARSING - * option as explained inside the note at the - * beginning of the "xmlParser.cpp" file. - * - * @param filename the path to the XML file to parse - * @param tag the name of the first tag inside the XML file. If the tag - * parameter is omitted, this function returns a node that represents the head - * of the xml document including the declaration term (). - * @param pResults a pointer to a XMLResults variable that will contain some - * information that can be used to trace the XML parsing error. You can have a - * user-friendly explanation of the parsing error with the "getError" - * function. - */ - - /// Parse an XML file and return the root of a XMLNode tree representing the - /// file. A very crude error checking is made. An attempt to guess the Char - /// Encoding used in the file is made. - static XMLNode openFileHelper(XMLCSTR filename, XMLCSTR tag = NULL); - /**< The "openFileHelper" function reports to the screen all the warnings and - * errors that occurred during parsing of the XML file. - * This function also tries to guess char Encoding (UTF-8, ASCII or SHIT-JIS) - * based on the first 200 bytes of the file. Since each - * application has its own way to report and deal with errors, you should - * rather use the "parseFile" function to parse XML files - * and program yourself thereafter an "error reporting" tailored for your - * needs (instead of using the very crude "error reporting" - * mechanism included inside the "openFileHelper" function). - * - * If the XML document is corrupted, the "openFileHelper" method will: - * - display an error message on the console (or inside a messageBox - * for windows). - * - stop execution (exit). - * - * I strongly suggest that you write your own "openFileHelper" method tailored - * to your needs. If you still want to parse - * the file, you can use the APPROXIMATE_PARSING option as explained inside - * the note at the beginning of the "xmlParser.cpp" file. - * - * @param filename the path of the XML file to parse. - * @param tag the name of the first tag inside the XML file. If the tag - * parameter is omitted, this function returns a node that represents the head - * of the xml document including the declaration term (). - */ - - static XMLCSTR getError(XMLError error); ///< this gives you a user-friendly - ///explanation of the parsing error - - /// Create an XML string starting from the current XMLNode. - XMLSTR createXMLString(int nFormat = 1, int *pnSize = NULL) const; - /**< The returned string should be free'd using the "freeXMLString" function. - * - * If nFormat==0, no formatting is required otherwise this returns an user - * friendly XML string from a given element - * with appropriate white spaces and carriage returns. if pnSize is given it - * returns the size in character of the string. */ - - /// Save the content of an xmlNode inside a file - XMLError writeToFile(XMLCSTR filename, const char *encoding = NULL, - char nFormat = 1) const; - /**< If nFormat==0, no formatting is required otherwise this returns an user - * friendly XML string from a given element with appropriate white spaces and - * carriage returns. - * If the global parameter "characterEncoding==encoding_UTF8", then the - * "encoding" parameter is ignored and always set to "utf-8". - * If the global parameter "characterEncoding==encoding_ShiftJIS", then the - * "encoding" parameter is ignored and always set to "SHIFT-JIS". - * If "_XMLWIDECHAR=1", then the "encoding" parameter is ignored and always - * set to "utf-16". - * If no "encoding" parameter is given the "ISO-8859-1" encoding is used. */ - /** @} */ - - /** @defgroup navigate Navigate the XMLNode structure - * @ingroup XMLParserGeneral - * @{ */ - XMLCSTR getName() const; ///< name of the node - XMLCSTR getText(int i = 0) const; ///< return ith text field - int nText() const; ///< nbr of text field - XMLNode getParentNode() const; ///< return the parent node - XMLNode getChildNode(int i = 0) const; ///< return ith child node - XMLNode getChildNode(XMLCSTR name, int i) const; ///< return ith child node - ///with specific name - ///(return an empty node if - ///failing). If i==-1, this - ///returns the last XMLNode - ///with the given name. - XMLNode getChildNode(XMLCSTR name, int *i = NULL) const; ///< return next - ///child node with - ///specific name - ///(return an empty - ///node if failing) - XMLNode getChildNodeWithAttribute(XMLCSTR tagName, XMLCSTR attributeName, - XMLCSTR attributeValue = NULL, - int *i = NULL) const; ///< return child - ///node with specific - ///name/attribute - ///(return an empty - ///node if failing) - XMLNode getChildNodeByPath(XMLCSTR path, char createNodeIfMissing = 0, - XMLCHAR sep = '/'); - ///< return the first child node with specific path - XMLNode getChildNodeByPathNonConst(XMLSTR path, char createNodeIfMissing = 0, - XMLCHAR sep = '/'); - ///< return the first child node with specific path. - - int nChildNode(XMLCSTR name) - const; ///< return the number of child node with specific name - int nChildNode() const; ///< nbr of child node - XMLAttribute getAttribute(int i = 0) const; ///< return ith attribute - XMLCSTR getAttributeName(int i = 0) const; ///< return ith attribute name - XMLCSTR getAttributeValue(int i = 0) const; ///< return ith attribute value - char isAttributeSet(XMLCSTR name) - const; ///< test if an attribute with a specific name is given - XMLCSTR getAttribute(XMLCSTR name, int i) const; ///< return ith attribute - ///content with specific - ///name (return a NULL if - ///failing) - XMLCSTR getAttribute(XMLCSTR name, int *i = NULL) const; ///< return next - ///attribute content - ///with specific - ///name (return a - ///NULL if failing) - int nAttribute() const; ///< nbr of attribute - XMLClear getClear(int i = 0) const; ///< return ith clear field (comments) - int nClear() const; ///< nbr of clear field - XMLNodeContents enumContents(XMLElementPosition i) - const; ///< enumerate all the different contents (attribute,child,text, - ///clear) of the current XMLNode. The order is reflecting the - ///order of the original file/string. NOTE: 0 <= i < nElement(); - int nElement() const; ///< nbr of different contents for current node - char isEmpty() const; ///< is this node Empty? - char isDeclaration() const; ///< is this node a declaration - XMLNode deepCopy() const; ///< deep copy (duplicate/clone) a XMLNode - static XMLNode emptyNode(); ///< return XMLNode::emptyXMLNode; - /** @} */ - - ~XMLNode(); - XMLNode(const XMLNode &A); ///< to allow shallow/fast copy: - XMLNode &operator=(const XMLNode &A); ///< to allow shallow/fast copy: - - XMLNode() : d(NULL){}; - static XMLNode emptyXMLNode; - static XMLClear emptyXMLClear; - static XMLAttribute emptyXMLAttribute; - - /** @defgroup xmlModify Create or Update the XMLNode structure - * @ingroup XMLParserGeneral - * The functions in this group allows you to create from scratch (or update) - * a XMLNode structure. Start by creating your top - * node with the "createXMLTopNode" function and then add new nodes with the - * "addChild" function. The parameter 'pos' gives - * the position where the childNode, the text or the XMLClearTag will be - * inserted. The default value (pos=-1) inserts at the - * end. The value (pos=0) insert at the beginning (Insertion at the beginning - * is slower than at the end).
- * - * REMARK: 0 <= pos < nChild()+nText()+nClear()
- */ - - /** @defgroup creation Creating from scratch a XMLNode structure - * @ingroup xmlModify - * @{ */ - static XMLNode createXMLTopNode( - XMLCSTR lpszName, - char isDeclaration = - FALSE); ///< Create the top node of an XMLNode structure - XMLNode addChild(XMLCSTR lpszName, char isDeclaration = FALSE, - XMLElementPosition pos = -1); ///< Add a new child node - XMLNode addChild(XMLNode nodeToAdd, - XMLElementPosition pos = -1); ///< If the "nodeToAdd" has - ///some parents, it will be - ///detached from it's parents - ///before being attached to - ///the current XMLNode - XMLAttribute *addAttribute(XMLCSTR lpszName, - XMLCSTR lpszValuev); ///< Add a new attribute - XMLCSTR addText(XMLCSTR lpszValue, - XMLElementPosition pos = -1); ///< Add a new text content - XMLClear *addClear(XMLCSTR lpszValue, XMLCSTR lpszOpen = NULL, - XMLCSTR lpszClose = NULL, XMLElementPosition pos = -1); - /**< Add a new clear tag - * @param lpszOpen default value "" - */ - /** @} */ - - /** @defgroup xmlUpdate Updating Nodes - * @ingroup xmlModify - * Some update functions: - * @{ - */ - XMLCSTR updateName(XMLCSTR lpszName); ///< change node's name - XMLAttribute *updateAttribute(XMLAttribute *newAttribute, - XMLAttribute *oldAttribute); ///< if the - ///attribute to - ///update is - ///missing, a new - ///one will be - ///added - XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, - XMLCSTR lpszNewName = NULL, - int i = 0); ///< if the attribute to update is - ///missing, a new one will be added - XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName, - XMLCSTR lpszOldName); ///< set lpszNewName=NULL - ///if you don't want to - ///change the name of the - ///attribute if the - ///attribute to update is - ///missing, a new one - ///will be added - XMLCSTR updateText(XMLCSTR lpszNewValue, int i = 0); ///< if the text to - ///update is missing, a - ///new one will be added - XMLCSTR updateText(XMLCSTR lpszNewValue, - XMLCSTR lpszOldValue); ///< if the text to update is - ///missing, a new one will be added - XMLClear *updateClear(XMLCSTR lpszNewContent, - int i = 0); ///< if the clearTag to update is missing, - ///a new one will be added - XMLClear *updateClear(XMLClear *newP, XMLClear *oldP); ///< if the clearTag - ///to update is - ///missing, a new one - ///will be added - XMLClear *updateClear(XMLCSTR lpszNewValue, - XMLCSTR lpszOldValue); ///< if the clearTag to update - ///is missing, a new one will be - ///added - /** @} */ - - /** @defgroup xmlDelete Deleting Nodes or Attributes - * @ingroup xmlModify - * Some deletion functions: - * @{ - */ - /// The "deleteNodeContent" function forces the deletion of the content of - /// this XMLNode and the subtree. - void deleteNodeContent(); - /**< \note The XMLNode instances that are referring to the part of the subtree - * that has been deleted CANNOT be used anymore!!. Unexpected results will - * occur if you continue using them. */ - void deleteAttribute( - int i = 0); ///< Delete the ith attribute of the current XMLNode - void deleteAttribute(XMLCSTR lpszName); ///< Delete the attribute with the - ///given name (the "strcmp" function - ///is used to find the right - ///attribute) - void deleteAttribute(XMLAttribute *anAttribute); ///< Delete the attribute - ///with the name - ///"anAttribute->lpszName" - ///(the "strcmp" function is - ///used to find the right - ///attribute) - void deleteText( - int i = 0); ///< Delete the Ith text content of the current XMLNode - void deleteText(XMLCSTR lpszValue); ///< Delete the text content "lpszValue" - ///inside the current XMLNode (direct - ///"pointer-to-pointer" comparison is - ///used to find the right text) - void deleteClear( - int i = 0); ///< Delete the Ith clear tag inside the current XMLNode - void deleteClear(XMLCSTR lpszValue); ///< Delete the clear tag "lpszValue" - ///inside the current XMLNode (direct - ///"pointer-to-pointer" comparison is - ///used to find the clear tag) - void deleteClear(XMLClear *p); ///< Delete the clear tag "p" inside the - ///current XMLNode (direct - ///"pointer-to-pointer" comparison on the - ///lpszName of the clear tag is used to find - ///the clear tag) - /** @} */ - - /** @defgroup xmlWOSD ???_WOSD functions. - * @ingroup xmlModify - * The strings given as parameters for the "add" and "update" methods that - * have a name with - * the postfix "_WOSD" (that means "WithOut String Duplication")(for example - * "addText_WOSD") - * will be free'd by the XMLNode class. For example, it means that this is - * incorrect: - * \code - * xNode.addText_WOSD("foo"); - * xNode.updateAttribute_WOSD("#newcolor" ,NULL,"color"); - * \endcode - * In opposition, this is correct: - * \code - * xNode.addText("foo"); - * xNode.addText_WOSD(stringDup("foo")); - * xNode.updateAttribute("#newcolor" ,NULL,"color"); - * xNode.updateAttribute_WOSD(stringDup("#newcolor"),NULL,"color"); - * \endcode - * Typically, you will never do: - * \code - * char *b=(char*)malloc(...); - * xNode.addText(b); - * free(b); - * \endcode - * ... but rather: - * \code - * char *b=(char*)malloc(...); - * xNode.addText_WOSD(b); - * \endcode - * ('free(b)' is performed by the XMLNode class) - * @{ */ - static XMLNode createXMLTopNode_WOSD( - XMLSTR lpszName, - char isDeclaration = - FALSE); ///< Create the top node of an XMLNode structure - XMLNode addChild_WOSD(XMLSTR lpszName, char isDeclaration = FALSE, - XMLElementPosition pos = -1); ///< Add a new child node - XMLAttribute *addAttribute_WOSD(XMLSTR lpszName, - XMLSTR lpszValue); ///< Add a new attribute - XMLCSTR addText_WOSD(XMLSTR lpszValue, XMLElementPosition pos = - -1); ///< Add a new text content - XMLClear *addClear_WOSD( - XMLSTR lpszValue, XMLCSTR lpszOpen = NULL, XMLCSTR lpszClose = NULL, - XMLElementPosition pos = -1); ///< Add a new clear Tag - - XMLCSTR updateName_WOSD(XMLSTR lpszName); ///< change node's name - XMLAttribute *updateAttribute_WOSD(XMLAttribute *newAttribute, - XMLAttribute *oldAttribute); ///< if the - ///attribute - ///to update - ///is - ///missing, a - ///new one - ///will be - ///added - XMLAttribute *updateAttribute_WOSD(XMLSTR lpszNewValue, - XMLSTR lpszNewName = NULL, - int i = 0); ///< if the attribute to - ///update is missing, a new - ///one will be added - XMLAttribute *updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName, - XMLCSTR lpszOldName); ///< set - ///lpszNewName=NULL - ///if you don't want - ///to change the - ///name of the - ///attribute if the - ///attribute to - ///update is - ///missing, a new - ///one will be added - XMLCSTR updateText_WOSD(XMLSTR lpszNewValue, int i = 0); ///< if the text to - ///update is - ///missing, a new - ///one will be added - XMLCSTR updateText_WOSD(XMLSTR lpszNewValue, - XMLCSTR lpszOldValue); ///< if the text to update is - ///missing, a new one will be - ///added - XMLClear *updateClear_WOSD(XMLSTR lpszNewContent, - int i = 0); ///< if the clearTag to update is - ///missing, a new one will be added - XMLClear *updateClear_WOSD(XMLClear *newP, - XMLClear *oldP); ///< if the clearTag to update is - ///missing, a new one will be - ///added - XMLClear *updateClear_WOSD(XMLSTR lpszNewValue, - XMLCSTR lpszOldValue); ///< if the clearTag to - ///update is missing, a new - ///one will be added - /** @} */ - - /** @defgroup xmlPosition Position helper functions (use in conjunction with - * the update&add functions - * @ingroup xmlModify - * These are some useful functions when you want to insert a childNode, a text - * or a XMLClearTag in the - * middle (at a specified position) of a XMLNode tree already constructed. The - * value returned by these - * methods is to be used as last parameter (parameter 'pos') of addChild, - * addText or addClear. - * @{ */ - XMLElementPosition positionOfText(int i = 0) const; - XMLElementPosition positionOfText(XMLCSTR lpszValue) const; - XMLElementPosition positionOfClear(int i = 0) const; - XMLElementPosition positionOfClear(XMLCSTR lpszValue) const; - XMLElementPosition positionOfClear(XMLClear *a) const; - XMLElementPosition positionOfChildNode(int i = 0) const; - XMLElementPosition positionOfChildNode(XMLNode x) const; - XMLElementPosition positionOfChildNode(XMLCSTR name, int i = 0) - const; ///< return the position of the ith childNode with the specified - ///name if (name==NULL) return the position of the ith childNode - /** @} */ - - /// Enumeration for XML character encoding. - typedef enum XMLCharEncoding { - char_encoding_error = 0, - char_encoding_UTF8 = 1, - char_encoding_legacy = 2, - char_encoding_ShiftJIS = 3, - char_encoding_GB2312 = 4, - char_encoding_Big5 = 5, - char_encoding_GBK = 6 // this is actually the same as Big5 - } XMLCharEncoding; - - /** \addtogroup conversions - * @{ */ - - /// Sets the global options for the conversions - static char setGlobalOptions( - XMLCharEncoding characterEncoding = XMLNode::char_encoding_UTF8, - char guessWideCharChars = 1, char dropWhiteSpace = 1, - char removeCommentsInMiddleOfText = 1); - /**< The "setGlobalOptions" function allows you to change four global - * parameters that affect string & file - * parsing. First of all, you most-probably will never have to change these 3 - * global parameters. - * - * @param guessWideCharChars If "guessWideCharChars"=1 and if this library is - * compiled in WideChar mode, then the - * XMLNode::parseFile and XMLNode::openFileHelper functions will test if - * the file contains ASCII - * characters. If this is the case, then the file will be loaded and - * converted in memory to - * WideChar before being parsed. If 0, no conversion will be performed. - * - * @param guessWideCharChars If "guessWideCharChars"=1 and if this library is - * compiled in ASCII/UTF8/char* mode, then the - * XMLNode::parseFile and XMLNode::openFileHelper functions will test if - * the file contains WideChar - * characters. If this is the case, then the file will be loaded and - * converted in memory to - * ASCII/UTF8/char* before being parsed. If 0, no conversion will be - * performed. - * - * @param characterEncoding This parameter is only meaningful when compiling - * in char* mode (multibyte character mode). - * In wchar_t* (wide char mode), this parameter is ignored. This parameter - * should be one of the - * three currently recognized encodings: XMLNode::encoding_UTF8, - * XMLNode::encoding_ascii, - * XMLNode::encoding_ShiftJIS. - * - * @param dropWhiteSpace In most situations, text fields containing only white - * spaces (and carriage returns) - * are useless. Even more, these "empty" text fields are annoying because - * they increase the - * complexity of the user's code for parsing. So, 99% of the time, it's - * better to drop - * the "empty" text fields. However The XML specification indicates that - * no white spaces - * should be lost when parsing the file. So to be perfectly XML-compliant, - * you should set - * dropWhiteSpace=0. A note of caution: if you set "dropWhiteSpace=0", the - * parser will be - * slower and your code will be more complex. - * - * @param removeCommentsInMiddleOfText To explain this parameter, let's - * consider this code: - * \code - * XMLNode x=XMLNode::parseString("foobarchu","a"); - * \endcode - * If removeCommentsInMiddleOfText=0, then we will have: - * \code - * x.getText(0) -> "foo" - * x.getText(1) -> "bar" - * x.getText(2) -> "chu" - * x.getClear(0) --> "" - * x.getClear(1) --> "" - * \endcode - * If removeCommentsInMiddleOfText=1, then we will have: - * \code - * x.getText(0) -> "foobar" - * x.getText(1) -> "chu" - * x.getClear(0) --> "" - * \endcode - * - * \return "0" when there are no errors. If you try to set an unrecognized - * encoding then the return value will be "1" to signal an error. - * - * \note Sometime, it's useful to set "guessWideCharChars=0" to disable any - * conversion - * because the test to detect the file-type (ASCII/UTF8/char* or WideChar) may - * fail (rarely). */ - - /// Guess the character encoding of the string (ascii, utf8 or shift-JIS) - static XMLCharEncoding guessCharEncoding(void *buffer, int bufLen, - char useXMLEncodingAttribute = 1); - /**< The "guessCharEncoding" function try to guess the character encoding. You - * most-probably will never - * have to use this function. It then returns the appropriate value of the - * global parameter - * "characterEncoding" described in the XMLNode::setGlobalOptions. The guess - * is based on the content of a buffer of length - * "bufLen" bytes that contains the first bytes (minimum 25 bytes; 200 bytes - * is a good value) of the - * file to be parsed. The XMLNode::openFileHelper function is using this - * function to automatically compute - * the value of the "characterEncoding" global parameter. There are several - * heuristics used to do the - * guess. One of the heuristic is based on the "encoding" attribute. The - * original XML specifications - * forbids to use this attribute to do the guess but you can still use it if - * you set - * "useXMLEncodingAttribute" to 1 (this is the default behavior and the - * behavior of most parsers). - * If an inconsistency in the encoding is detected, then the return value is - * "0". */ - /** @} */ - - private: - // these are functions and structures used internally by the XMLNode class - // (don't bother about them): - - typedef struct XMLNodeDataTag // to allow shallow copy and - // "intelligent/smart" pointers (automatic - // delete): - { - XMLCSTR lpszName; // Element name (=NULL if root) - int nChild, // Number of child nodes - nText, // Number of text fields - nClear, // Number of Clear fields (comments) - nAttribute; // Number of attributes - char isDeclaration; // Whether node is an XML declaration - '' - struct XMLNodeDataTag - *pParent; // Pointer to parent element (=NULL if root) - XMLNode *pChild; // Array of child nodes - XMLCSTR *pText; // Array of text fields - XMLClear *pClear; // Array of clear fields - XMLAttribute *pAttribute; // Array of attributes - int *pOrder; // order of the child_nodes,text_fields,clear_fields - int ref_count; // for garbage collection (smart pointers) - } XMLNodeData; - XMLNodeData *d; - - char parseClearTag(void *px, void *pa); - char maybeAddTxT(void *pa, XMLCSTR tokenPStr); - int ParseXMLElement(void *pXML); - void *addToOrder(int memInc, int *_pos, int nc, void *p, int size, - XMLElementType xtype); - int indexText(XMLCSTR lpszValue) const; - int indexClear(XMLCSTR lpszValue) const; - XMLNode addChild_priv(int, XMLSTR, char, int); - XMLAttribute *addAttribute_priv(int, XMLSTR, XMLSTR); - XMLCSTR addText_priv(int, XMLSTR, int); - XMLClear *addClear_priv(int, XMLSTR, XMLCSTR, XMLCSTR, int); - void emptyTheNode(char force); - static inline XMLElementPosition findPosition(XMLNodeData *d, int index, - XMLElementType xtype); - static int CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, - int nFormat); - static int removeOrderElement(XMLNodeData *d, XMLElementType t, int index); - static void exactMemory(XMLNodeData *d); - static int detachFromParent(XMLNodeData *d); +typedef struct XMLDLLENTRY XMLNode +{ + private: + + struct XMLNodeDataTag; + + /// Constructors are protected, so use instead one of: XMLNode::parseString, XMLNode::parseFile, XMLNode::openFileHelper, XMLNode::createXMLTopNode + XMLNode(struct XMLNodeDataTag *pParent, XMLSTR lpszName, char isDeclaration); + /// Constructors are protected, so use instead one of: XMLNode::parseString, XMLNode::parseFile, XMLNode::openFileHelper, XMLNode::createXMLTopNode + XMLNode(struct XMLNodeDataTag *p); + + public: + static XMLCSTR getVersion();///< Return the XMLParser library version number + + /** @defgroup conversions Parsing XML files/strings to an XMLNode structure and Rendering XMLNode's to files/string. + * @ingroup XMLParserGeneral + * @{ */ + + /// Parse an XML string and return the root of a XMLNode tree representing the string. + static XMLNode parseString (XMLCSTR lpXMLString, XMLCSTR tag=NULL, XMLResults *pResults=NULL); + /**< The "parseString" function parse an XML string and return the root of a XMLNode tree. The "opposite" of this function is + * the function "createXMLString" that re-creates an XML string from an XMLNode tree. If the XML document is corrupted, the + * "parseString" method will initialize the "pResults" variable with some information that can be used to trace the error. + * If you still want to parse the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the + * beginning of the "xmlParser.cpp" file. + * + * @param lpXMLString the XML string to parse + * @param tag the name of the first tag inside the XML file. If the tag parameter is omitted, this function returns a node that represents the head of the xml document including the declaration term (). + * @param pResults a pointer to a XMLResults variable that will contain some information that can be used to trace the XML parsing error. You can have a user-friendly explanation of the parsing error with the "getError" function. + */ + + /// Parse an XML file and return the root of a XMLNode tree representing the file. + static XMLNode parseFile (XMLCSTR filename, XMLCSTR tag=NULL, XMLResults *pResults=NULL); + /**< The "parseFile" function parse an XML file and return the root of a XMLNode tree. The "opposite" of this function is + * the function "writeToFile" that re-creates an XML file from an XMLNode tree. If the XML document is corrupted, the + * "parseFile" method will initialize the "pResults" variable with some information that can be used to trace the error. + * If you still want to parse the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the + * beginning of the "xmlParser.cpp" file. + * + * @param filename the path to the XML file to parse + * @param tag the name of the first tag inside the XML file. If the tag parameter is omitted, this function returns a node that represents the head of the xml document including the declaration term (). + * @param pResults a pointer to a XMLResults variable that will contain some information that can be used to trace the XML parsing error. You can have a user-friendly explanation of the parsing error with the "getError" function. + */ + + /// Parse an XML file and return the root of a XMLNode tree representing the file. A very crude error checking is made. An attempt to guess the Char Encoding used in the file is made. + static XMLNode openFileHelper(XMLCSTR filename, XMLCSTR tag=NULL); + /**< The "openFileHelper" function reports to the screen all the warnings and errors that occurred during parsing of the XML file. + * This function also tries to guess char Encoding (UTF-8, ASCII or SHIT-JIS) based on the first 200 bytes of the file. Since each + * application has its own way to report and deal with errors, you should rather use the "parseFile" function to parse XML files + * and program yourself thereafter an "error reporting" tailored for your needs (instead of using the very crude "error reporting" + * mechanism included inside the "openFileHelper" function). + * + * If the XML document is corrupted, the "openFileHelper" method will: + * - display an error message on the console (or inside a messageBox for windows). + * - stop execution (exit). + * + * I strongly suggest that you write your own "openFileHelper" method tailored to your needs. If you still want to parse + * the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the beginning of the "xmlParser.cpp" file. + * + * @param filename the path of the XML file to parse. + * @param tag the name of the first tag inside the XML file. If the tag parameter is omitted, this function returns a node that represents the head of the xml document including the declaration term (). + */ + + static XMLCSTR getError(XMLError error); ///< this gives you a user-friendly explanation of the parsing error + + /// Create an XML string starting from the current XMLNode. + XMLSTR createXMLString(int nFormat=1, int *pnSize=NULL) const; + /**< The returned string should be free'd using the "freeXMLString" function. + * + * If nFormat==0, no formatting is required otherwise this returns an user friendly XML string from a given element + * with appropriate white spaces and carriage returns. if pnSize is given it returns the size in character of the string. */ + + /// Save the content of an xmlNode inside a file + XMLError writeToFile(XMLCSTR filename, + const char *encoding=NULL, + char nFormat=1) const; + /**< If nFormat==0, no formatting is required otherwise this returns an user friendly XML string from a given element with appropriate white spaces and carriage returns. + * If the global parameter "characterEncoding==encoding_UTF8", then the "encoding" parameter is ignored and always set to "utf-8". + * If the global parameter "characterEncoding==encoding_ShiftJIS", then the "encoding" parameter is ignored and always set to "SHIFT-JIS". + * If "_XMLWIDECHAR=1", then the "encoding" parameter is ignored and always set to "utf-16". + * If no "encoding" parameter is given the "ISO-8859-1" encoding is used. */ + /** @} */ + + /** @defgroup navigate Navigate the XMLNode structure + * @ingroup XMLParserGeneral + * @{ */ + XMLCSTR getName() const; ///< name of the node + XMLCSTR getText(int i=0) const; ///< return ith text field + int nText() const; ///< nbr of text field + XMLNode getParentNode() const; ///< return the parent node + XMLNode getChildNode(int i=0) const; ///< return ith child node + XMLNode getChildNode(XMLCSTR name, int i) const; ///< return ith child node with specific name (return an empty node if failing). If i==-1, this returns the last XMLNode with the given name. + XMLNode getChildNode(XMLCSTR name, int *i=NULL) const; ///< return next child node with specific name (return an empty node if failing) + XMLNode getChildNodeWithAttribute(XMLCSTR tagName, + XMLCSTR attributeName, + XMLCSTR attributeValue=NULL, + int *i=NULL) const; ///< return child node with specific name/attribute (return an empty node if failing) + XMLNode getChildNodeByPath(XMLCSTR path, char createNodeIfMissing=0, XMLCHAR sep='/'); + ///< return the first child node with specific path + XMLNode getChildNodeByPathNonConst(XMLSTR path, char createNodeIfMissing=0, XMLCHAR sep='/'); + ///< return the first child node with specific path. + + int nChildNode(XMLCSTR name) const; ///< return the number of child node with specific name + int nChildNode() const; ///< nbr of child node + XMLAttribute getAttribute(int i=0) const; ///< return ith attribute + XMLCSTR getAttributeName(int i=0) const; ///< return ith attribute name + XMLCSTR getAttributeValue(int i=0) const; ///< return ith attribute value + char isAttributeSet(XMLCSTR name) const; ///< test if an attribute with a specific name is given + XMLCSTR getAttribute(XMLCSTR name, int i) const; ///< return ith attribute content with specific name (return a NULL if failing) + XMLCSTR getAttribute(XMLCSTR name, int *i=NULL) const; ///< return next attribute content with specific name (return a NULL if failing) + int nAttribute() const; ///< nbr of attribute + XMLClear getClear(int i=0) const; ///< return ith clear field (comments) + int nClear() const; ///< nbr of clear field + XMLNodeContents enumContents(XMLElementPosition i) const; ///< enumerate all the different contents (attribute,child,text, clear) of the current XMLNode. The order is reflecting the order of the original file/string. NOTE: 0 <= i < nElement(); + int nElement() const; ///< nbr of different contents for current node + char isEmpty() const; ///< is this node Empty? + char isDeclaration() const; ///< is this node a declaration + XMLNode deepCopy() const; ///< deep copy (duplicate/clone) a XMLNode + static XMLNode emptyNode(); ///< return XMLNode::emptyXMLNode; + /** @} */ + + ~XMLNode(); + XMLNode(const XMLNode &A); ///< to allow shallow/fast copy: + XMLNode& operator=( const XMLNode& A ); ///< to allow shallow/fast copy: + + XMLNode(): d(NULL){}; + static XMLNode emptyXMLNode; + static XMLClear emptyXMLClear; + static XMLAttribute emptyXMLAttribute; + + /** @defgroup xmlModify Create or Update the XMLNode structure + * @ingroup XMLParserGeneral + * The functions in this group allows you to create from scratch (or update) a XMLNode structure. Start by creating your top + * node with the "createXMLTopNode" function and then add new nodes with the "addChild" function. The parameter 'pos' gives + * the position where the childNode, the text or the XMLClearTag will be inserted. The default value (pos=-1) inserts at the + * end. The value (pos=0) insert at the beginning (Insertion at the beginning is slower than at the end).
+ * + * REMARK: 0 <= pos < nChild()+nText()+nClear()
+ */ + + /** @defgroup creation Creating from scratch a XMLNode structure + * @ingroup xmlModify + * @{ */ + static XMLNode createXMLTopNode(XMLCSTR lpszName, char isDeclaration=FALSE); ///< Create the top node of an XMLNode structure + XMLNode addChild(XMLCSTR lpszName, char isDeclaration=FALSE, XMLElementPosition pos=-1); ///< Add a new child node + XMLNode addChild(XMLNode nodeToAdd, XMLElementPosition pos=-1); ///< If the "nodeToAdd" has some parents, it will be detached from it's parents before being attached to the current XMLNode + XMLAttribute *addAttribute(XMLCSTR lpszName, XMLCSTR lpszValuev); ///< Add a new attribute + XMLCSTR addText(XMLCSTR lpszValue, XMLElementPosition pos=-1); ///< Add a new text content + XMLClear *addClear(XMLCSTR lpszValue, XMLCSTR lpszOpen=NULL, XMLCSTR lpszClose=NULL, XMLElementPosition pos=-1); + /**< Add a new clear tag + * @param lpszOpen default value "" + */ + /** @} */ + + /** @defgroup xmlUpdate Updating Nodes + * @ingroup xmlModify + * Some update functions: + * @{ + */ + XMLCSTR updateName(XMLCSTR lpszName); ///< change node's name + XMLAttribute *updateAttribute(XMLAttribute *newAttribute, XMLAttribute *oldAttribute); ///< if the attribute to update is missing, a new one will be added + XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName=NULL,int i=0); ///< if the attribute to update is missing, a new one will be added + XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,XMLCSTR lpszOldName);///< set lpszNewName=NULL if you don't want to change the name of the attribute if the attribute to update is missing, a new one will be added + XMLCSTR updateText(XMLCSTR lpszNewValue, int i=0); ///< if the text to update is missing, a new one will be added + XMLCSTR updateText(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the text to update is missing, a new one will be added + XMLClear *updateClear(XMLCSTR lpszNewContent, int i=0); ///< if the clearTag to update is missing, a new one will be added + XMLClear *updateClear(XMLClear *newP,XMLClear *oldP); ///< if the clearTag to update is missing, a new one will be added + XMLClear *updateClear(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the clearTag to update is missing, a new one will be added + /** @} */ + + /** @defgroup xmlDelete Deleting Nodes or Attributes + * @ingroup xmlModify + * Some deletion functions: + * @{ + */ + /// The "deleteNodeContent" function forces the deletion of the content of this XMLNode and the subtree. + void deleteNodeContent(); + /**< \note The XMLNode instances that are referring to the part of the subtree that has been deleted CANNOT be used anymore!!. Unexpected results will occur if you continue using them. */ + void deleteAttribute(int i=0); ///< Delete the ith attribute of the current XMLNode + void deleteAttribute(XMLCSTR lpszName); ///< Delete the attribute with the given name (the "strcmp" function is used to find the right attribute) + void deleteAttribute(XMLAttribute *anAttribute); ///< Delete the attribute with the name "anAttribute->lpszName" (the "strcmp" function is used to find the right attribute) + void deleteText(int i=0); ///< Delete the Ith text content of the current XMLNode + void deleteText(XMLCSTR lpszValue); ///< Delete the text content "lpszValue" inside the current XMLNode (direct "pointer-to-pointer" comparison is used to find the right text) + void deleteClear(int i=0); ///< Delete the Ith clear tag inside the current XMLNode + void deleteClear(XMLCSTR lpszValue); ///< Delete the clear tag "lpszValue" inside the current XMLNode (direct "pointer-to-pointer" comparison is used to find the clear tag) + void deleteClear(XMLClear *p); ///< Delete the clear tag "p" inside the current XMLNode (direct "pointer-to-pointer" comparison on the lpszName of the clear tag is used to find the clear tag) + /** @} */ + + /** @defgroup xmlWOSD ???_WOSD functions. + * @ingroup xmlModify + * The strings given as parameters for the "add" and "update" methods that have a name with + * the postfix "_WOSD" (that means "WithOut String Duplication")(for example "addText_WOSD") + * will be free'd by the XMLNode class. For example, it means that this is incorrect: + * \code + * xNode.addText_WOSD("foo"); + * xNode.updateAttribute_WOSD("#newcolor" ,NULL,"color"); + * \endcode + * In opposition, this is correct: + * \code + * xNode.addText("foo"); + * xNode.addText_WOSD(stringDup("foo")); + * xNode.updateAttribute("#newcolor" ,NULL,"color"); + * xNode.updateAttribute_WOSD(stringDup("#newcolor"),NULL,"color"); + * \endcode + * Typically, you will never do: + * \code + * char *b=(char*)malloc(...); + * xNode.addText(b); + * free(b); + * \endcode + * ... but rather: + * \code + * char *b=(char*)malloc(...); + * xNode.addText_WOSD(b); + * \endcode + * ('free(b)' is performed by the XMLNode class) + * @{ */ + static XMLNode createXMLTopNode_WOSD(XMLSTR lpszName, char isDeclaration=FALSE); ///< Create the top node of an XMLNode structure + XMLNode addChild_WOSD(XMLSTR lpszName, char isDeclaration=FALSE, XMLElementPosition pos=-1); ///< Add a new child node + XMLAttribute *addAttribute_WOSD(XMLSTR lpszName, XMLSTR lpszValue); ///< Add a new attribute + XMLCSTR addText_WOSD(XMLSTR lpszValue, XMLElementPosition pos=-1); ///< Add a new text content + XMLClear *addClear_WOSD(XMLSTR lpszValue, XMLCSTR lpszOpen=NULL, XMLCSTR lpszClose=NULL, XMLElementPosition pos=-1); ///< Add a new clear Tag + + XMLCSTR updateName_WOSD(XMLSTR lpszName); ///< change node's name + XMLAttribute *updateAttribute_WOSD(XMLAttribute *newAttribute, XMLAttribute *oldAttribute); ///< if the attribute to update is missing, a new one will be added + XMLAttribute *updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName=NULL,int i=0); ///< if the attribute to update is missing, a new one will be added + XMLAttribute *updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName,XMLCSTR lpszOldName); ///< set lpszNewName=NULL if you don't want to change the name of the attribute if the attribute to update is missing, a new one will be added + XMLCSTR updateText_WOSD(XMLSTR lpszNewValue, int i=0); ///< if the text to update is missing, a new one will be added + XMLCSTR updateText_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the text to update is missing, a new one will be added + XMLClear *updateClear_WOSD(XMLSTR lpszNewContent, int i=0); ///< if the clearTag to update is missing, a new one will be added + XMLClear *updateClear_WOSD(XMLClear *newP,XMLClear *oldP); ///< if the clearTag to update is missing, a new one will be added + XMLClear *updateClear_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the clearTag to update is missing, a new one will be added + /** @} */ + + /** @defgroup xmlPosition Position helper functions (use in conjunction with the update&add functions + * @ingroup xmlModify + * These are some useful functions when you want to insert a childNode, a text or a XMLClearTag in the + * middle (at a specified position) of a XMLNode tree already constructed. The value returned by these + * methods is to be used as last parameter (parameter 'pos') of addChild, addText or addClear. + * @{ */ + XMLElementPosition positionOfText(int i=0) const; + XMLElementPosition positionOfText(XMLCSTR lpszValue) const; + XMLElementPosition positionOfClear(int i=0) const; + XMLElementPosition positionOfClear(XMLCSTR lpszValue) const; + XMLElementPosition positionOfClear(XMLClear *a) const; + XMLElementPosition positionOfChildNode(int i=0) const; + XMLElementPosition positionOfChildNode(XMLNode x) const; + XMLElementPosition positionOfChildNode(XMLCSTR name, int i=0) const; ///< return the position of the ith childNode with the specified name if (name==NULL) return the position of the ith childNode + /** @} */ + + /// Enumeration for XML character encoding. + typedef enum XMLCharEncoding + { + char_encoding_error=0, + char_encoding_UTF8=1, + char_encoding_legacy=2, + char_encoding_ShiftJIS=3, + char_encoding_GB2312=4, + char_encoding_Big5=5, + char_encoding_GBK=6 // this is actually the same as Big5 + } XMLCharEncoding; + + /** \addtogroup conversions + * @{ */ + + /// Sets the global options for the conversions + static char setGlobalOptions(XMLCharEncoding characterEncoding=XMLNode::char_encoding_UTF8, char guessWideCharChars=1, + char dropWhiteSpace=1, char removeCommentsInMiddleOfText=1); + /**< The "setGlobalOptions" function allows you to change four global parameters that affect string & file + * parsing. First of all, you most-probably will never have to change these 3 global parameters. + * + * @param guessWideCharChars If "guessWideCharChars"=1 and if this library is compiled in WideChar mode, then the + * XMLNode::parseFile and XMLNode::openFileHelper functions will test if the file contains ASCII + * characters. If this is the case, then the file will be loaded and converted in memory to + * WideChar before being parsed. If 0, no conversion will be performed. + * + * @param guessWideCharChars If "guessWideCharChars"=1 and if this library is compiled in ASCII/UTF8/char* mode, then the + * XMLNode::parseFile and XMLNode::openFileHelper functions will test if the file contains WideChar + * characters. If this is the case, then the file will be loaded and converted in memory to + * ASCII/UTF8/char* before being parsed. If 0, no conversion will be performed. + * + * @param characterEncoding This parameter is only meaningful when compiling in char* mode (multibyte character mode). + * In wchar_t* (wide char mode), this parameter is ignored. This parameter should be one of the + * three currently recognized encodings: XMLNode::encoding_UTF8, XMLNode::encoding_ascii, + * XMLNode::encoding_ShiftJIS. + * + * @param dropWhiteSpace In most situations, text fields containing only white spaces (and carriage returns) + * are useless. Even more, these "empty" text fields are annoying because they increase the + * complexity of the user's code for parsing. So, 99% of the time, it's better to drop + * the "empty" text fields. However The XML specification indicates that no white spaces + * should be lost when parsing the file. So to be perfectly XML-compliant, you should set + * dropWhiteSpace=0. A note of caution: if you set "dropWhiteSpace=0", the parser will be + * slower and your code will be more complex. + * + * @param removeCommentsInMiddleOfText To explain this parameter, let's consider this code: + * \code + * XMLNode x=XMLNode::parseString("foobarchu","a"); + * \endcode + * If removeCommentsInMiddleOfText=0, then we will have: + * \code + * x.getText(0) -> "foo" + * x.getText(1) -> "bar" + * x.getText(2) -> "chu" + * x.getClear(0) --> "" + * x.getClear(1) --> "" + * \endcode + * If removeCommentsInMiddleOfText=1, then we will have: + * \code + * x.getText(0) -> "foobar" + * x.getText(1) -> "chu" + * x.getClear(0) --> "" + * \endcode + * + * \return "0" when there are no errors. If you try to set an unrecognized encoding then the return value will be "1" to signal an error. + * + * \note Sometime, it's useful to set "guessWideCharChars=0" to disable any conversion + * because the test to detect the file-type (ASCII/UTF8/char* or WideChar) may fail (rarely). */ + + /// Guess the character encoding of the string (ascii, utf8 or shift-JIS) + static XMLCharEncoding guessCharEncoding(void *buffer, int bufLen, char useXMLEncodingAttribute=1); + /**< The "guessCharEncoding" function try to guess the character encoding. You most-probably will never + * have to use this function. It then returns the appropriate value of the global parameter + * "characterEncoding" described in the XMLNode::setGlobalOptions. The guess is based on the content of a buffer of length + * "bufLen" bytes that contains the first bytes (minimum 25 bytes; 200 bytes is a good value) of the + * file to be parsed. The XMLNode::openFileHelper function is using this function to automatically compute + * the value of the "characterEncoding" global parameter. There are several heuristics used to do the + * guess. One of the heuristic is based on the "encoding" attribute. The original XML specifications + * forbids to use this attribute to do the guess but you can still use it if you set + * "useXMLEncodingAttribute" to 1 (this is the default behavior and the behavior of most parsers). + * If an inconsistency in the encoding is detected, then the return value is "0". */ + /** @} */ + + private: + // these are functions and structures used internally by the XMLNode class (don't bother about them): + + typedef struct XMLNodeDataTag // to allow shallow copy and "intelligent/smart" pointers (automatic delete): + { + XMLCSTR lpszName; // Element name (=NULL if root) + int nChild, // Number of child nodes + nText, // Number of text fields + nClear, // Number of Clear fields (comments) + nAttribute; // Number of attributes + char isDeclaration; // Whether node is an XML declaration - '' + struct XMLNodeDataTag *pParent; // Pointer to parent element (=NULL if root) + XMLNode *pChild; // Array of child nodes + XMLCSTR *pText; // Array of text fields + XMLClear *pClear; // Array of clear fields + XMLAttribute *pAttribute; // Array of attributes + int *pOrder; // order of the child_nodes,text_fields,clear_fields + int ref_count; // for garbage collection (smart pointers) + } XMLNodeData; + XMLNodeData *d; + + char parseClearTag(void *px, void *pa); + char maybeAddTxT(void *pa, XMLCSTR tokenPStr); + int ParseXMLElement(void *pXML); + void *addToOrder(int memInc, int *_pos, int nc, void *p, int size, XMLElementType xtype); + int indexText(XMLCSTR lpszValue) const; + int indexClear(XMLCSTR lpszValue) const; + XMLNode addChild_priv(int,XMLSTR,char,int); + XMLAttribute *addAttribute_priv(int,XMLSTR,XMLSTR); + XMLCSTR addText_priv(int,XMLSTR,int); + XMLClear *addClear_priv(int,XMLSTR,XMLCSTR,XMLCSTR,int); + void emptyTheNode(char force); + static inline XMLElementPosition findPosition(XMLNodeData *d, int index, XMLElementType xtype); + static int CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, int nFormat); + static int removeOrderElement(XMLNodeData *d, XMLElementType t, int index); + static void exactMemory(XMLNodeData *d); + static int detachFromParent(XMLNodeData *d); } XMLNode; /// This structure is given by the function XMLNode::enumContents. -typedef struct XMLNodeContents { - /// This dictates what's the content of the XMLNodeContent - enum XMLElementType etype; - /**< should be an union to access the appropriate data. Compiler does not - * allow union of object with constructor... too bad. */ - XMLNode child; - XMLAttribute attrib; - XMLCSTR text; - XMLClear clear; +typedef struct XMLNodeContents +{ + /// This dictates what's the content of the XMLNodeContent + enum XMLElementType etype; + /**< should be an union to access the appropriate data. Compiler does not allow union of object with constructor... too bad. */ + XMLNode child; + XMLAttribute attrib; + XMLCSTR text; + XMLClear clear; } XMLNodeContents; -/** @defgroup StringAlloc String Allocation/Free functions - * @ingroup xmlModify - * @{ */ +/** @defgroup StringAlloc String Allocation/Free functions + * @ingroup xmlModify + * @{ */ /// Duplicate (copy in a new allocated buffer) the source string. -XMLDLLENTRY XMLSTR stringDup(XMLCSTR source, int cbData = -1); -/**< This is - * a very handy function when used with all the "XMLNode::*_WOSD" functions - * (\link xmlWOSD \endlink). - * @param cbData If !=0 then cbData is the number of chars to duplicate. New - * strings allocated with - * this function should be free'd using the "freeXMLString" function. */ - -/// to free the string allocated inside the "stringDup" function or the -/// "createXMLString" function. -XMLDLLENTRY void freeXMLString(XMLSTR t); // {free(t);} - /** @} */ +XMLDLLENTRY XMLSTR stringDup(XMLCSTR source, int cbData=-1); +/**< This is + * a very handy function when used with all the "XMLNode::*_WOSD" functions (\link xmlWOSD \endlink). + * @param cbData If !=0 then cbData is the number of chars to duplicate. New strings allocated with + * this function should be free'd using the "freeXMLString" function. */ + +/// to free the string allocated inside the "stringDup" function or the "createXMLString" function. +XMLDLLENTRY void freeXMLString(XMLSTR t); // {free(t);} +/** @} */ /** @defgroup atoX ato? like functions - * @ingroup XMLParserGeneral + * @ingroup XMLParserGeneral * The "xmlto?" functions are equivalents to the atoi, atol, atof functions. - * The only difference is: If the variable "xmlString" is NULL, than the return - * value - * is "defautValue". These 6 functions are only here as "convenience" functions - * for the - * user (they are not used inside the XMLparser). If you don't need them, you - * can + * The only difference is: If the variable "xmlString" is NULL, than the return value + * is "defautValue". These 6 functions are only here as "convenience" functions for the + * user (they are not used inside the XMLparser). If you don't need them, you can * delete them without any trouble. * * @{ */ -XMLDLLENTRY char xmltob(XMLCSTR xmlString, char defautValue = 0); -XMLDLLENTRY int xmltoi(XMLCSTR xmlString, int defautValue = 0); -XMLDLLENTRY long xmltol(XMLCSTR xmlString, long defautValue = 0); -XMLDLLENTRY double xmltof(XMLCSTR xmlString, double defautValue = .0); -XMLDLLENTRY XMLCSTR xmltoa(XMLCSTR xmlString, XMLCSTR defautValue = _CXML("")); -XMLDLLENTRY XMLCHAR xmltoc(XMLCSTR xmlString, - XMLCHAR defautValue = _CXML('\0')); +XMLDLLENTRY char xmltob(XMLCSTR xmlString,char defautValue=0); +XMLDLLENTRY int xmltoi(XMLCSTR xmlString,int defautValue=0); +XMLDLLENTRY long xmltol(XMLCSTR xmlString,long defautValue=0); +XMLDLLENTRY double xmltof(XMLCSTR xmlString,double defautValue=.0); +XMLDLLENTRY XMLCSTR xmltoa(XMLCSTR xmlString,XMLCSTR defautValue=_CXML("")); +XMLDLLENTRY XMLCHAR xmltoc(XMLCSTR xmlString,XMLCHAR defautValue=_CXML('\0')); /** @} */ -/** @defgroup ToXMLStringTool Helper class to create XML files using "printf", - * "fprintf", "cout",... functions. - * @ingroup XMLParserGeneral +/** @defgroup ToXMLStringTool Helper class to create XML files using "printf", "fprintf", "cout",... functions. + * @ingroup XMLParserGeneral * @{ */ -/// Helper class to create XML files using "printf", "fprintf", "cout",... -/// functions. -/** The ToXMLStringTool class helps you creating XML files using "printf", - * "fprintf", "cout",... functions. +/// Helper class to create XML files using "printf", "fprintf", "cout",... functions. +/** The ToXMLStringTool class helps you creating XML files using "printf", "fprintf", "cout",... functions. * The "ToXMLStringTool" class is processing strings so that all the characters * &,",',<,> are replaced by their XML equivalent: * \verbatim &, ", ', <, > \endverbatim - * Using the "ToXMLStringTool class" and the "fprintf function" is THE most - * efficient + * Using the "ToXMLStringTool class" and the "fprintf function" is THE most efficient * way to produce VERY large XML documents VERY fast. - * \note If you are creating from scratch an XML file using the provided XMLNode - * class - * you must not use the "ToXMLStringTool" class (because the "XMLNode" class - * does the + * \note If you are creating from scratch an XML file using the provided XMLNode class + * you must not use the "ToXMLStringTool" class (because the "XMLNode" class does the * processing job for you during rendering).*/ -typedef struct XMLDLLENTRY ToXMLStringTool { - public: - ToXMLStringTool() : buf(NULL), buflen(0) {} - ~ToXMLStringTool(); - void freeBuffer(); /// Date: Fri, 13 Sep 2019 08:02:14 -0400 Subject: Seems like multiple passes for reformatting comments --- src/cuda-sim/half.h | 198 +- src/cuda-sim/instructions.cc | 2 +- src/gpgpu-sim/gpu-cache.cc | 4 +- src/gpgpu-sim/gpu-cache.h | 19 +- src/gpgpu-sim/gpu-sim.cc | 6 +- src/gpgpu-sim/gpu-sim.h | 16 +- src/gpgpu-sim/shader.cc | 4 +- src/gpuwattch/XML_Parse.cc | 6562 ++++++++++++------ src/gpuwattch/XML_Parse.h | 1201 ++-- src/gpuwattch/arch_const.h | 358 +- src/gpuwattch/array.cc | 464 +- src/gpuwattch/array.h | 87 +- src/gpuwattch/basic_components.cc | 142 +- src/gpuwattch/basic_components.h | 486 +- src/gpuwattch/core.cc | 11742 ++++++++++++++++++-------------- src/gpuwattch/core.h | 933 +-- src/gpuwattch/globalvar.h | 7 +- src/gpuwattch/gpgpu_sim_wrapper.cc | 1458 ++-- src/gpuwattch/gpgpu_sim_wrapper.h | 261 +- src/gpuwattch/interconnect.cc | 201 +- src/gpuwattch/interconnect.h | 109 +- src/gpuwattch/iocontrollers.cc | 796 ++- src/gpuwattch/iocontrollers.h | 68 +- src/gpuwattch/logic.cc | 2211 +++--- src/gpuwattch/logic.h | 358 +- src/gpuwattch/main.cc | 104 +- src/gpuwattch/memoryctrl.cc | 1965 +++--- src/gpuwattch/memoryctrl.h | 165 +- src/gpuwattch/noc.cc | 723 +- src/gpuwattch/noc.h | 81 +- src/gpuwattch/processor.cc | 2039 +++--- src/gpuwattch/processor.h | 520 +- src/gpuwattch/sharedcache.cc | 1796 ++--- src/gpuwattch/sharedcache.h | 83 +- src/gpuwattch/technology_xeon_core.cc | 3331 ++++----- src/gpuwattch/version.h | 6 +- src/gpuwattch/xmlParser.cc | 5398 ++++++++------- src/gpuwattch/xmlParser.h | 1396 ++-- 38 files changed, 25656 insertions(+), 19644 deletions(-) (limited to 'src/gpuwattch/processor.cc') diff --git a/src/cuda-sim/half.h b/src/cuda-sim/half.h index 54bedc2..fab1a22 100644 --- a/src/cuda-sim/half.h +++ b/src/cuda-sim/half.h @@ -551,8 +551,8 @@ bool builtin_signbit(T arg) { template uint16 float2half_impl(float value, true_type) { typedef bits::type uint32; - uint32 bits; // = *reinterpret_cast(&value); //violating - // strict aliasing! + uint32 bits; // = *reinterpret_cast(&value); + // //violating strict aliasing! std::memcpy(&bits, &value, sizeof(float)); /* uint16 hbits = (bits>>16) & 0x8000; bits &= 0x7FFFFFFF; @@ -728,8 +728,8 @@ template uint16 float2half_impl(double value, true_type) { typedef bits::type uint32; typedef bits::type uint64; - uint64 bits; // = *reinterpret_cast(&value); //violating - // strict aliasing! + uint64 bits; // = *reinterpret_cast(&value); + // //violating strict aliasing! std::memcpy(&bits, &value, sizeof(double)); uint32 hi = bits >> 32, lo = bits & 0xFFFFFFFF; uint16 hbits = (hi >> 16) & 0x8000; @@ -1257,8 +1257,8 @@ inline float half2float_impl(uint16 value, float, true_type) { 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024}; uint32 bits = mantissa_table[offset_table[value >> 10] + (value & 0x3FF)] + exponent_table[value >> 10]; - // return *reinterpret_cast(&bits); //violating - //strict aliasing! + // return *reinterpret_cast(&bits); + ////violating strict aliasing! float out; std::memcpy(&out, &bits, sizeof(float)); return out; @@ -1279,8 +1279,8 @@ inline double half2float_impl(uint16 value, double, true_type) { hi += static_cast(abs) << 10; } uint64 bits = static_cast(hi) << 32; - // return *reinterpret_cast(&bits); //violating - //strict aliasing! + // return *reinterpret_cast(&bits); + ////violating strict aliasing! double out; std::memcpy(&out, &bits, sizeof(double)); return out; @@ -2719,7 +2719,7 @@ std::basic_istream &operator>>( /// \param arg operand /// \return absolute value of \a arg // template typename enable::type abs(T arg) { -//return unary_specialized::fabs(arg); } +// return unary_specialized::fabs(arg); } inline half abs(half arg) { return unary_specialized::fabs(arg); } inline expr abs(expr arg) { return unary_specialized::fabs(arg); } @@ -2727,7 +2727,7 @@ inline expr abs(expr arg) { return unary_specialized::fabs(arg); } /// \param arg operand /// \return absolute value of \a arg // template typename enable::type fabs(T arg) { -//return unary_specialized::fabs(arg); } +// return unary_specialized::fabs(arg); } inline half fabs(half arg) { return unary_specialized::fabs(arg); } inline expr fabs(expr arg) { return unary_specialized::fabs(arg); } @@ -2736,7 +2736,7 @@ inline expr fabs(expr arg) { return unary_specialized::fabs(arg); } /// \param y second operand /// \return remainder of floating point division. // template typename enable::type -//fmod(T x, U y) { return functions::fmod(x, y); } +// fmod(T x, U y) { return functions::fmod(x, y); } inline expr fmod(half x, half y) { return functions::fmod(x, y); } inline expr fmod(half x, expr y) { return functions::fmod(x, y); } inline expr fmod(expr x, half y) { return functions::fmod(x, y); } @@ -2747,7 +2747,7 @@ inline expr fmod(expr x, expr y) { return functions::fmod(x, y); } /// \param y second operand /// \return remainder of floating point division. // template typename enable::type -//remainder(T x, U y) { return functions::remainder(x, y); } +// remainder(T x, U y) { return functions::remainder(x, y); } inline expr remainder(half x, half y) { return functions::remainder(x, y); } inline expr remainder(half x, expr y) { return functions::remainder(x, y); } inline expr remainder(expr x, half y) { return functions::remainder(x, y); } @@ -2759,7 +2759,7 @@ inline expr remainder(expr x, expr y) { return functions::remainder(x, y); } /// \param quo address to store some bits of quotient at /// \return remainder of floating point division. // template typename enable::type -//remquo(T x, U y, int *quo) { return functions::remquo(x, y, quo); } +// remquo(T x, U y, int *quo) { return functions::remquo(x, y, quo); } inline expr remquo(half x, half y, int *quo) { return functions::remquo(x, y, quo); } @@ -2779,7 +2779,7 @@ inline expr remquo(expr x, expr y, int *quo) { /// \param z third operand /// \return ( \a x * \a y ) + \a z rounded as one operation. // template typename -//enable::type fma(T x, U y, V z) { return functions::fma(x, y, z); +// enable::type fma(T x, U y, V z) { return functions::fma(x, y, z); //} inline expr fma(half x, half y, half z) { return functions::fma(x, y, z); } inline expr fma(half x, half y, expr z) { return functions::fma(x, y, z); } @@ -2794,8 +2794,8 @@ inline expr fma(expr x, expr y, expr z) { return functions::fma(x, y, z); } /// \param x first operand /// \param y second operand /// \return maximum of operands -// template typename result::type fmax(T -//x, U y) { return binary_specialized::fmax(x, y); } +// template typename result::type +// fmax(T x, U y) { return binary_specialized::fmax(x, y); } inline half fmax(half x, half y) { return binary_specialized::fmax(x, y); } @@ -2813,8 +2813,8 @@ inline expr fmax(expr x, expr y) { /// \param x first operand /// \param y second operand /// \return minimum of operands -// template typename result::type fmin(T -//x, U y) { return binary_specialized::fmin(x, y); } +// template typename result::type +// fmin(T x, U y) { return binary_specialized::fmin(x, y); } inline half fmin(half x, half y) { return binary_specialized::fmin(x, y); } @@ -2833,7 +2833,7 @@ inline expr fmin(expr x, expr y) { /// \param y second operand /// \return \a x - \a y or 0 if difference negative // template typename enable::type -//fdim(T x, U y) { return functions::fdim(x, y); } +// fdim(T x, U y) { return functions::fdim(x, y); } inline expr fdim(half x, half y) { return functions::fdim(x, y); } inline expr fdim(half x, expr y) { return functions::fdim(x, y); } inline expr fdim(expr x, half y) { return functions::fdim(x, y); } @@ -2851,15 +2851,15 @@ inline half nanh(const char *) { return functions::nanh(); } /// \param arg function argument /// \return e raised to \a arg // template typename enable::type exp(T arg) { -//return functions::exp(arg); } +// return functions::exp(arg); } inline expr exp(half arg) { return functions::exp(arg); } inline expr exp(expr arg) { return functions::exp(arg); } /// Exponential minus one. /// \param arg function argument /// \return e raised to \a arg subtracted by 1 -// template typename enable::type expm1(T arg) { -//return functions::expm1(arg); } +// template typename enable::type expm1(T arg) +//{ return functions::expm1(arg); } inline expr expm1(half arg) { return functions::expm1(arg); } inline expr expm1(expr arg) { return functions::expm1(arg); } @@ -2867,7 +2867,7 @@ inline expr expm1(expr arg) { return functions::expm1(arg); } /// \param arg function argument /// \return 2 raised to \a arg // template typename enable::type exp2(T arg) { -//return functions::exp2(arg); } +// return functions::exp2(arg); } inline expr exp2(half arg) { return functions::exp2(arg); } inline expr exp2(expr arg) { return functions::exp2(arg); } @@ -2875,23 +2875,23 @@ inline expr exp2(expr arg) { return functions::exp2(arg); } /// \param arg function argument /// \return logarithm of \a arg to base e // template typename enable::type log(T arg) { -//return functions::log(arg); } +// return functions::log(arg); } inline expr log(half arg) { return functions::log(arg); } inline expr log(expr arg) { return functions::log(arg); } /// Common logorithm. /// \param arg function argument /// \return logarithm of \a arg to base 10 -// template typename enable::type log10(T arg) { -//return functions::log10(arg); } +// template typename enable::type log10(T arg) +//{ return functions::log10(arg); } inline expr log10(half arg) { return functions::log10(arg); } inline expr log10(expr arg) { return functions::log10(arg); } /// Natural logorithm. /// \param arg function argument /// \return logarithm of \a arg plus 1 to base e -// template typename enable::type log1p(T arg) { -//return functions::log1p(arg); } +// template typename enable::type log1p(T arg) +//{ return functions::log1p(arg); } inline expr log1p(half arg) { return functions::log1p(arg); } inline expr log1p(expr arg) { return functions::log1p(arg); } @@ -2899,7 +2899,7 @@ inline expr log1p(expr arg) { return functions::log1p(arg); } /// \param arg function argument /// \return logarithm of \a arg to base 2 // template typename enable::type log2(T arg) { -//return functions::log2(arg); } +// return functions::log2(arg); } inline expr log2(half arg) { return functions::log2(arg); } inline expr log2(expr arg) { return functions::log2(arg); } @@ -2911,7 +2911,7 @@ inline expr log2(expr arg) { return functions::log2(arg); } /// \param arg function argument /// \return square root of \a arg // template typename enable::type sqrt(T arg) { -//return functions::sqrt(arg); } +// return functions::sqrt(arg); } inline expr sqrt(half arg) { return functions::sqrt(arg); } inline expr sqrt(expr arg) { return functions::sqrt(arg); } @@ -2919,7 +2919,7 @@ inline expr sqrt(expr arg) { return functions::sqrt(arg); } /// \param arg function argument /// \return cubic root of \a arg // template typename enable::type cbrt(T arg) { -//return functions::cbrt(arg); } +// return functions::cbrt(arg); } inline expr cbrt(half arg) { return functions::cbrt(arg); } inline expr cbrt(expr arg) { return functions::cbrt(arg); } @@ -2928,7 +2928,7 @@ inline expr cbrt(expr arg) { return functions::cbrt(arg); } /// \param y second argument /// \return square root of sum of squares without internal over- or underflows // template typename enable::type -//hypot(T x, U y) { return functions::hypot(x, y); } +// hypot(T x, U y) { return functions::hypot(x, y); } inline expr hypot(half x, half y) { return functions::hypot(x, y); } inline expr hypot(half x, expr y) { return functions::hypot(x, y); } inline expr hypot(expr x, half y) { return functions::hypot(x, y); } @@ -2939,7 +2939,7 @@ inline expr hypot(expr x, expr y) { return functions::hypot(x, y); } /// \param exp second argument /// \return \a base raised to \a exp // template typename enable::type -//pow(T base, U exp) { return functions::pow(base, exp); } +// pow(T base, U exp) { return functions::pow(base, exp); } inline expr pow(half base, half exp) { return functions::pow(base, exp); } inline expr pow(half base, expr exp) { return functions::pow(base, exp); } inline expr pow(expr base, half exp) { return functions::pow(base, exp); } @@ -2953,7 +2953,7 @@ inline expr pow(expr base, expr exp) { return functions::pow(base, exp); } /// \param arg function argument /// \return sine value of \a arg // template typename enable::type sin(T arg) { -//return functions::sin(arg); } +// return functions::sin(arg); } inline expr sin(half arg) { return functions::sin(arg); } inline expr sin(expr arg) { return functions::sin(arg); } @@ -2961,7 +2961,7 @@ inline expr sin(expr arg) { return functions::sin(arg); } /// \param arg function argument /// \return cosine value of \a arg // template typename enable::type cos(T arg) { -//return functions::cos(arg); } +// return functions::cos(arg); } inline expr cos(half arg) { return functions::cos(arg); } inline expr cos(expr arg) { return functions::cos(arg); } @@ -2969,7 +2969,7 @@ inline expr cos(expr arg) { return functions::cos(arg); } /// \param arg function argument /// \return tangent value of \a arg // template typename enable::type tan(T arg) { -//return functions::tan(arg); } +// return functions::tan(arg); } inline expr tan(half arg) { return functions::tan(arg); } inline expr tan(expr arg) { return functions::tan(arg); } @@ -2977,7 +2977,7 @@ inline expr tan(expr arg) { return functions::tan(arg); } /// \param arg function argument /// \return arc sine value of \a arg // template typename enable::type asin(T arg) { -//return functions::asin(arg); } +// return functions::asin(arg); } inline expr asin(half arg) { return functions::asin(arg); } inline expr asin(expr arg) { return functions::asin(arg); } @@ -2985,7 +2985,7 @@ inline expr asin(expr arg) { return functions::asin(arg); } /// \param arg function argument /// \return arc cosine value of \a arg // template typename enable::type acos(T arg) { -//return functions::acos(arg); } +// return functions::acos(arg); } inline expr acos(half arg) { return functions::acos(arg); } inline expr acos(expr arg) { return functions::acos(arg); } @@ -2993,7 +2993,7 @@ inline expr acos(expr arg) { return functions::acos(arg); } /// \param arg function argument /// \return arc tangent value of \a arg // template typename enable::type atan(T arg) { -//return functions::atan(arg); } +// return functions::atan(arg); } inline expr atan(half arg) { return functions::atan(arg); } inline expr atan(expr arg) { return functions::atan(arg); } @@ -3002,7 +3002,7 @@ inline expr atan(expr arg) { return functions::atan(arg); } /// \param y second argument /// \return arc tangent value // template typename enable::type -//atan2(T x, U y) { return functions::atan2(x, y); } +// atan2(T x, U y) { return functions::atan2(x, y); } inline expr atan2(half x, half y) { return functions::atan2(x, y); } inline expr atan2(half x, expr y) { return functions::atan2(x, y); } inline expr atan2(expr x, half y) { return functions::atan2(x, y); } @@ -3016,7 +3016,7 @@ inline expr atan2(expr x, expr y) { return functions::atan2(x, y); } /// \param arg function argument /// \return hyperbolic sine value of \a arg // template typename enable::type sinh(T arg) { -//return functions::sinh(arg); } +// return functions::sinh(arg); } inline expr sinh(half arg) { return functions::sinh(arg); } inline expr sinh(expr arg) { return functions::sinh(arg); } @@ -3024,7 +3024,7 @@ inline expr sinh(expr arg) { return functions::sinh(arg); } /// \param arg function argument /// \return hyperbolic cosine value of \a arg // template typename enable::type cosh(T arg) { -//return functions::cosh(arg); } +// return functions::cosh(arg); } inline expr cosh(half arg) { return functions::cosh(arg); } inline expr cosh(expr arg) { return functions::cosh(arg); } @@ -3032,31 +3032,31 @@ inline expr cosh(expr arg) { return functions::cosh(arg); } /// \param arg function argument /// \return hyperbolic tangent value of \a arg // template typename enable::type tanh(T arg) { -//return functions::tanh(arg); } +// return functions::tanh(arg); } inline expr tanh(half arg) { return functions::tanh(arg); } inline expr tanh(expr arg) { return functions::tanh(arg); } /// Hyperbolic area sine. /// \param arg function argument /// \return area sine value of \a arg -// template typename enable::type asinh(T arg) { -//return functions::asinh(arg); } +// template typename enable::type asinh(T arg) +//{ return functions::asinh(arg); } inline expr asinh(half arg) { return functions::asinh(arg); } inline expr asinh(expr arg) { return functions::asinh(arg); } /// Hyperbolic area cosine. /// \param arg function argument /// \return area cosine value of \a arg -// template typename enable::type acosh(T arg) { -//return functions::acosh(arg); } +// template typename enable::type acosh(T arg) +//{ return functions::acosh(arg); } inline expr acosh(half arg) { return functions::acosh(arg); } inline expr acosh(expr arg) { return functions::acosh(arg); } /// Hyperbolic area tangent. /// \param arg function argument /// \return area tangent value of \a arg -// template typename enable::type atanh(T arg) { -//return functions::atanh(arg); } +// template typename enable::type atanh(T arg) +//{ return functions::atanh(arg); } inline expr atanh(half arg) { return functions::atanh(arg); } inline expr atanh(expr arg) { return functions::atanh(arg); } @@ -3068,7 +3068,7 @@ inline expr atanh(expr arg) { return functions::atanh(arg); } /// \param arg function argument /// \return error function value of \a arg // template typename enable::type erf(T arg) { -//return functions::erf(arg); } +// return functions::erf(arg); } inline expr erf(half arg) { return functions::erf(arg); } inline expr erf(expr arg) { return functions::erf(arg); } @@ -3076,23 +3076,23 @@ inline expr erf(expr arg) { return functions::erf(arg); } /// \param arg function argument /// \return 1 minus error function value of \a arg // template typename enable::type erfc(T arg) { -//return functions::erfc(arg); } +// return functions::erfc(arg); } inline expr erfc(half arg) { return functions::erfc(arg); } inline expr erfc(expr arg) { return functions::erfc(arg); } /// Natural logarithm of gamma function. /// \param arg function argument /// \return natural logarith of gamma function for \a arg -// template typename enable::type lgamma(T arg) { -//return functions::lgamma(arg); } +// template typename enable::type lgamma(T arg) +//{ return functions::lgamma(arg); } inline expr lgamma(half arg) { return functions::lgamma(arg); } inline expr lgamma(expr arg) { return functions::lgamma(arg); } /// Gamma function. /// \param arg function argument /// \return gamma function value of \a arg -// template typename enable::type tgamma(T arg) { -//return functions::tgamma(arg); } +// template typename enable::type tgamma(T arg) +//{ return functions::tgamma(arg); } inline expr tgamma(half arg) { return functions::tgamma(arg); } inline expr tgamma(expr arg) { return functions::tgamma(arg); } @@ -3104,39 +3104,39 @@ inline expr tgamma(expr arg) { return functions::tgamma(arg); } /// \param arg half to round /// \return nearest integer not less than \a arg // template typename enable::type ceil(T arg) { -//return functions::ceil(arg); } +// return functions::ceil(arg); } inline half ceil(half arg) { return functions::ceil(arg); } inline half ceil(expr arg) { return functions::ceil(arg); } /// Nearest integer not greater than half value. /// \param arg half to round /// \return nearest integer not greater than \a arg -// template typename enable::type floor(T arg) { -//return functions::floor(arg); } +// template typename enable::type floor(T arg) +//{ return functions::floor(arg); } inline half floor(half arg) { return functions::floor(arg); } inline half floor(expr arg) { return functions::floor(arg); } /// Nearest integer not greater in magnitude than half value. /// \param arg half to round /// \return nearest integer not greater in magnitude than \a arg -// template typename enable::type trunc(T arg) { -//return functions::trunc(arg); } +// template typename enable::type trunc(T arg) +//{ return functions::trunc(arg); } inline half trunc(half arg) { return functions::trunc(arg); } inline half trunc(expr arg) { return functions::trunc(arg); } /// Nearest integer. /// \param arg half to round /// \return nearest integer, rounded away from zero in half-way cases -// template typename enable::type round(T arg) { -//return functions::round(arg); } +// template typename enable::type round(T arg) +//{ return functions::round(arg); } inline half round(half arg) { return functions::round(arg); } inline half round(expr arg) { return functions::round(arg); } /// Nearest integer. /// \param arg half to round /// \return nearest integer, rounded away from zero in half-way cases -// template typename enable::type lround(T arg) { -//return functions::lround(arg); } +// template typename enable::type lround(T arg) +//{ return functions::lround(arg); } inline long lround(half arg) { return functions::lround(arg); } inline long lround(expr arg) { return functions::lround(arg); } @@ -3144,7 +3144,7 @@ inline long lround(expr arg) { return functions::lround(arg); } /// \param arg half expression to round /// \return nearest integer using default rounding mode // template typename enable::type nearbyint(T -//arg) { return functions::nearbyint(arg); } +// arg) { return functions::nearbyint(arg); } inline half nearbyint(half arg) { return functions::rint(arg); } inline half nearbyint(expr arg) { return functions::rint(arg); } @@ -3152,23 +3152,23 @@ inline half nearbyint(expr arg) { return functions::rint(arg); } /// \param arg half expression to round /// \return nearest integer using default rounding mode // template typename enable::type rint(T arg) { -//return functions::rint(arg); } +// return functions::rint(arg); } inline half rint(half arg) { return functions::rint(arg); } inline half rint(expr arg) { return functions::rint(arg); } /// Nearest integer using half's internal rounding mode. /// \param arg half expression to round /// \return nearest integer using default rounding mode -// template typename enable::type lrint(T arg) { -//return functions::lrint(arg); } +// template typename enable::type lrint(T arg) +//{ return functions::lrint(arg); } inline long lrint(half arg) { return functions::lrint(arg); } inline long lrint(expr arg) { return functions::lrint(arg); } #if HALF_ENABLE_CPP11_LONG_LONG /// Nearest integer. /// \param arg half to round /// \return nearest integer, rounded away from zero in half-way cases -// template typename enable::type llround(T -//arg) { return functions::llround(arg); } +// template typename enable::type +// llround(T arg) { return functions::llround(arg); } inline long long llround(half arg) { return functions::llround(arg); } inline long long llround(expr arg) { return functions::llround(arg); } @@ -3176,7 +3176,7 @@ inline long long llround(expr arg) { return functions::llround(arg); } /// \param arg half expression to round /// \return nearest integer using default rounding mode // template typename enable::type llrint(T -//arg) { return functions::llrint(arg); } +// arg) { return functions::llrint(arg); } inline long long llrint(half arg) { return functions::llrint(arg); } inline long long llrint(expr arg) { return functions::llrint(arg); } #endif @@ -3190,7 +3190,7 @@ inline long long llrint(expr arg) { return functions::llrint(arg); } /// \param exp address to store exponent at /// \return significant in range [0.5, 1) // template typename enable::type frexp(T arg, -//int *exp) { return functions::frexp(arg, exp); } +// int *exp) { return functions::frexp(arg, exp); } inline half frexp(half arg, int *exp) { return functions::frexp(arg, exp); } inline half frexp(expr arg, int *exp) { return functions::frexp(arg, exp); } @@ -3199,7 +3199,7 @@ inline half frexp(expr arg, int *exp) { return functions::frexp(arg, exp); } /// \param exp power of two to multiply with /// \return \a arg multplied by 2 raised to \a exp // template typename enable::type ldexp(T arg, -//int exp) { return functions::scalbln(arg, exp); } +// int exp) { return functions::scalbln(arg, exp); } inline half ldexp(half arg, int exp) { return functions::scalbln(arg, exp); } inline half ldexp(expr arg, int exp) { return functions::scalbln(arg, exp); } @@ -3208,7 +3208,7 @@ inline half ldexp(expr arg, int exp) { return functions::scalbln(arg, exp); } /// \param iptr address to store integer part at /// \return fractional part // template typename enable::type modf(T arg, -//half *iptr) { return functions::modf(arg, iptr); } +// half *iptr) { return functions::modf(arg, iptr); } inline half modf(half arg, half *iptr) { return functions::modf(arg, iptr); } inline half modf(expr arg, half *iptr) { return functions::modf(arg, iptr); } @@ -3217,7 +3217,7 @@ inline half modf(expr arg, half *iptr) { return functions::modf(arg, iptr); } /// \param exp power of two to multiply with /// \return \a arg multplied by 2 raised to \a exp // template typename enable::type scalbn(T arg, -//int exp) { return functions::scalbln(arg, exp); } +// int exp) { return functions::scalbln(arg, exp); } inline half scalbn(half arg, int exp) { return functions::scalbln(arg, exp); } inline half scalbn(expr arg, int exp) { return functions::scalbln(arg, exp); } @@ -3225,8 +3225,8 @@ inline half scalbn(expr arg, int exp) { return functions::scalbln(arg, exp); } /// \param arg number to modify /// \param exp power of two to multiply with /// \return \a arg multplied by 2 raised to \a exp -// template typename enable::type scalbln(T arg, -//long exp) { return functions::scalbln(arg, exp); } +// template typename enable::type scalbln(T +// arg, long exp) { return functions::scalbln(arg, exp); } inline half scalbln(half arg, long exp) { return functions::scalbln(arg, exp); } inline half scalbln(expr arg, long exp) { return functions::scalbln(arg, exp); } @@ -3237,7 +3237,7 @@ inline half scalbln(expr arg, long exp) { return functions::scalbln(arg, exp); } /// \retval FP_ILOGBNAN for NaN /// \retval MAX_INT for infinity // template typename enable::type ilogb(T arg) { -//return functions::ilogb(arg); } +// return functions::ilogb(arg); } inline int ilogb(half arg) { return functions::ilogb(arg); } inline int ilogb(expr arg) { return functions::ilogb(arg); } @@ -3245,7 +3245,7 @@ inline int ilogb(expr arg) { return functions::ilogb(arg); } /// \param arg number to query /// \return floating point exponent // template typename enable::type logb(T arg) { -//return functions::logb(arg); } +// return functions::logb(arg); } inline half logb(half arg) { return functions::logb(arg); } inline half logb(expr arg) { return functions::logb(arg); } @@ -3254,7 +3254,7 @@ inline half logb(expr arg) { return functions::logb(arg); } /// \param to direction towards which to compute next value /// \return next representable value after \a from in direction towards \a to // template typename enable::type -//nextafter(T from, U to) { return functions::nextafter(from, to); } +// nextafter(T from, U to) { return functions::nextafter(from, to); } inline half nextafter(half from, half to) { return functions::nextafter(from, to); } @@ -3273,7 +3273,7 @@ inline half nextafter(expr from, expr to) { /// \param to direction towards which to compute next value /// \return next representable value after \a from in direction towards \a to // template typename enable::type nexttoward(T -//from, long double to) { return functions::nexttoward(from, to); } +// from, long double to) { return functions::nexttoward(from, to); } inline half nexttoward(half from, long double to) { return functions::nexttoward(from, to); } @@ -3286,7 +3286,7 @@ inline half nexttoward(expr from, long double to) { /// \param y value to take sign from /// \return value equal to \a x in magnitude and to \a y in sign // template typename enable::type -//copysign(T x, U y) { return functions::copysign(x, y); } +// copysign(T x, U y) { return functions::copysign(x, y); } inline half copysign(half x, half y) { return functions::copysign(x, y); } inline half copysign(half x, expr y) { return functions::copysign(x, y); } inline half copysign(expr x, half y) { return functions::copysign(x, y); } @@ -3304,7 +3304,7 @@ inline half copysign(expr x, expr y) { return functions::copysign(x, y); } /// \retval FP_NAN for NaNs /// \retval FP_NORMAL for all other (normal) values // template typename enable::type fpclassify(T -//arg) { return functions::fpclassify(arg); } +// arg) { return functions::fpclassify(arg); } inline int fpclassify(half arg) { return functions::fpclassify(arg); } inline int fpclassify(expr arg) { return functions::fpclassify(arg); } @@ -3312,8 +3312,8 @@ inline int fpclassify(expr arg) { return functions::fpclassify(arg); } /// \param arg number to check /// \retval true if neither infinity nor NaN /// \retval false else -// template typename enable::type isfinite(T arg) -//{ return functions::isfinite(arg); } +// template typename enable::type isfinite(T +// arg) { return functions::isfinite(arg); } inline bool isfinite(half arg) { return functions::isfinite(arg); } inline bool isfinite(expr arg) { return functions::isfinite(arg); } @@ -3321,8 +3321,8 @@ inline bool isfinite(expr arg) { return functions::isfinite(arg); } /// \param arg number to check /// \retval true for positive or negative infinity /// \retval false else -// template typename enable::type isinf(T arg) { -//return functions::isinf(arg); } +// template typename enable::type isinf(T arg) +//{ return functions::isinf(arg); } inline bool isinf(half arg) { return functions::isinf(arg); } inline bool isinf(expr arg) { return functions::isinf(arg); } @@ -3330,8 +3330,8 @@ inline bool isinf(expr arg) { return functions::isinf(arg); } /// \param arg number to check /// \retval true for NaNs /// \retval false else -// template typename enable::type isnan(T arg) { -//return functions::isnan(arg); } +// template typename enable::type isnan(T arg) +//{ return functions::isnan(arg); } inline bool isnan(half arg) { return functions::isnan(arg); } inline bool isnan(expr arg) { return functions::isnan(arg); } @@ -3339,8 +3339,8 @@ inline bool isnan(expr arg) { return functions::isnan(arg); } /// \param arg number to check /// \retval true if normal number /// \retval false if either subnormal, zero, infinity or NaN -// template typename enable::type isnormal(T arg) -//{ return functions::isnormal(arg); } +// template typename enable::type isnormal(T +// arg) { return functions::isnormal(arg); } inline bool isnormal(half arg) { return functions::isnormal(arg); } inline bool isnormal(expr arg) { return functions::isnormal(arg); } @@ -3348,8 +3348,8 @@ inline bool isnormal(expr arg) { return functions::isnormal(arg); } /// \param arg number to check /// \retval true for negative number /// \retval false for positive number -// template typename enable::type signbit(T arg) -//{ return functions::signbit(arg); } +// template typename enable::type signbit(T +// arg) { return functions::signbit(arg); } inline bool signbit(half arg) { return functions::signbit(arg); } inline bool signbit(expr arg) { return functions::signbit(arg); } @@ -3363,7 +3363,7 @@ inline bool signbit(expr arg) { return functions::signbit(arg); } /// \retval true if \a x greater than \a y /// \retval false else // template typename enable::type -//isgreater(T x, U y) { return functions::isgreater(x, y); } +// isgreater(T x, U y) { return functions::isgreater(x, y); } inline bool isgreater(half x, half y) { return functions::isgreater(x, y); } inline bool isgreater(half x, expr y) { return functions::isgreater(x, y); } inline bool isgreater(expr x, half y) { return functions::isgreater(x, y); } @@ -3375,7 +3375,7 @@ inline bool isgreater(expr x, expr y) { return functions::isgreater(x, y); } /// \retval true if \a x greater equal \a y /// \retval false else // template typename enable::type -//isgreaterequal(T x, U y) { return functions::isgreaterequal(x, y); } +// isgreaterequal(T x, U y) { return functions::isgreaterequal(x, y); } inline bool isgreaterequal(half x, half y) { return functions::isgreaterequal(x, y); } @@ -3395,7 +3395,7 @@ inline bool isgreaterequal(expr x, expr y) { /// \retval true if \a x less than \a y /// \retval false else // template typename enable::type -//isless(T x, U y) { return functions::isless(x, y); } +// isless(T x, U y) { return functions::isless(x, y); } inline bool isless(half x, half y) { return functions::isless(x, y); } inline bool isless(half x, expr y) { return functions::isless(x, y); } inline bool isless(expr x, half y) { return functions::isless(x, y); } @@ -3407,7 +3407,7 @@ inline bool isless(expr x, expr y) { return functions::isless(x, y); } /// \retval true if \a x less equal \a y /// \retval false else // template typename enable::type -//islessequal(T x, U y) { return functions::islessequal(x, y); } +// islessequal(T x, U y) { return functions::islessequal(x, y); } inline bool islessequal(half x, half y) { return functions::islessequal(x, y); } inline bool islessequal(half x, expr y) { return functions::islessequal(x, y); } inline bool islessequal(expr x, half y) { return functions::islessequal(x, y); } @@ -3419,7 +3419,7 @@ inline bool islessequal(expr x, expr y) { return functions::islessequal(x, y); } /// \retval true if either less or greater /// \retval false else // template typename enable::type -//islessgreater(T x, U y) { return functions::islessgreater(x, y); } +// islessgreater(T x, U y) { return functions::islessgreater(x, y); } inline bool islessgreater(half x, half y) { return functions::islessgreater(x, y); } @@ -3439,7 +3439,7 @@ inline bool islessgreater(expr x, expr y) { /// \retval true if unordered (one or two NaN operands) /// \retval false else // template typename enable::type -//isunordered(T x, U y) { return functions::isunordered(x, y); } +// isunordered(T x, U y) { return functions::isunordered(x, y); } inline bool isunordered(half x, half y) { return functions::isunordered(x, y); } inline bool isunordered(half x, expr y) { return functions::isunordered(x, y); } inline bool isunordered(expr x, half y) { return functions::isunordered(x, y); } diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc index 0d56558..bf9a040 100644 --- a/src/cuda-sim/instructions.cc +++ b/src/cuda-sim/instructions.cc @@ -3619,7 +3619,7 @@ void mma_ld_impl(const ptx_instruction *pI, core_t *core, warp_inst_t &inst) { if ((wmma_type == LOAD_C) && (type == F16_TYPE) && (wmma_layout == COL)) // memory address is scattered, check the // profiling xls for more detail. - inst.data_size = 2; // 2 byte transaction + inst.data_size = 2; // 2 byte transaction else inst.data_size = 4; // 4 byte transaction assert(inst.memory_op == insn_memory_op); diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index 156c174..76f9aef 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -1329,8 +1329,8 @@ enum cache_request_status data_cache::wr_miss_wa_fetch_on_write( if (mf->get_access_byte_mask().count() == m_config.get_atom_sz()) { // if the request writes to the whole cache line/sector, then, write and set - // cache line Modified. and no need to send read request to memory or reserve - // mshr + // cache line Modified. and no need to send read request to memory or + // reserve mshr if (miss_queue_full(0)) { m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL); diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 647ed7a..d4bc9b4 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -547,13 +547,14 @@ class cache_config { } if (m_alloc_policy == STREAMING) { // For streaming cache, we set the alloc policy to be on-fill to remove - // all line_alloc_fail stalls we set the MSHRs to be equal to max allocated - // cache lines. This is possible by moving TAG to be shared between cache - // line and MSHR enrty (i.e. for each cache line, there is an MSHR rntey - // associated with it) This is the easiest think we can think about to - // model (mimic) L1 streaming cache in Pascal and Volta Based on our - // microbenchmakrs, MSHRs entries have been increasing substantially in - // Pascal and Volta For more information about streaming cache, see: + // all line_alloc_fail stalls we set the MSHRs to be equal to max + // allocated cache lines. This is possible by moving TAG to be shared + // between cache line and MSHR enrty (i.e. for each cache line, there is + // an MSHR rntey associated with it) This is the easiest think we can + // think about to model (mimic) L1 streaming cache in Pascal and Volta + // Based on our microbenchmakrs, MSHRs entries have been increasing + // substantially in Pascal and Volta For more information about streaming + // cache, see: // http://on-demand.gputechconf.com/gtc/2017/presentation/s7798-luke-durant-inside-volta.pdf // https://ieeexplore.ieee.org/document/8344474/ m_is_streaming = true; @@ -1303,9 +1304,9 @@ class baseline_cache : public cache_t { const cache_config &m_config; int m_data_port_occupied_cycles; //< Number of cycle that the data port - //remains used + // remains used int m_fill_port_occupied_cycles; //< Number of cycle that the fill port - //remains used + // remains used }; bandwidth_management m_bandwidth_management; diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index e44ab95..485d42e 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -1224,7 +1224,7 @@ void gpgpu_sim::gpu_print_stat() { partiton_reqs_in_parallel_util_total) / (gpu_sim_cycle_parition_util + gpu_tot_sim_cycle_parition_util)); // printf("partiton_replys_in_parallel = %lld\n", - // partiton_replys_in_parallel); printf("partiton_replys_in_parallel_total = + // partiton_replys_in_parallel); printf("partiton_replys_in_parallel_total = // %lld\n", partiton_replys_in_parallel_total ); printf("L2_BW = %12.4f GB/Sec\n", ((float)(partiton_replys_in_parallel * 32) / @@ -1735,8 +1735,8 @@ void gpgpu_sim::cycle() { m_power_stats->pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX].clear(); for (unsigned i = 0; i < m_memory_config->m_n_mem_sub_partition; i++) { // move memory request from interconnect into memory partition (if not - // backed up) Note:This needs to be called in DRAM clock domain if there is - // no L2 cache in the system In the worst case, we may need to push + // backed up) Note:This needs to be called in DRAM clock domain if there + // is no L2 cache in the system In the worst case, we may need to push // SECTOR_CHUNCK_SIZE requests, so ensure you have enough buffer for them if (m_memory_sub_partition[i]->full(SECTOR_CHUNCK_SIZE)) { gpu_stall_dramfull++; diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h index 9765b38..c75897c 100644 --- a/src/gpgpu-sim/gpu-sim.h +++ b/src/gpgpu-sim/gpu-sim.h @@ -263,11 +263,11 @@ class memory_config { // GDDR5 this is identical to RTPS, if for other DRAM this is // different, you will need to split them in two - unsigned tCCD; // column to column delay - unsigned tRRD; // minimal time required between activation of rows in - // different banks - unsigned tRCD; // row to column delay - time required to activate a row - // before a read + unsigned tCCD; // column to column delay + unsigned tRRD; // minimal time required between activation of rows in + // different banks + unsigned tRCD; // row to column delay - time required to activate a row + // before a read unsigned tRCDWR; // row to column delay for a write command unsigned tRAS; // time needed to activate row unsigned tRP; // row precharge ie. deactivate row @@ -275,7 +275,7 @@ class memory_config { tRC; // row cycle time ie. precharge current, then activate different row unsigned tCDLR; // Last data-in to Read command (switching from write to // read) - unsigned tWR; // Last data-in to Row precharge + unsigned tWR; // Last data-in to Row precharge unsigned CL; // CAS latency unsigned WL; // WRITE latency @@ -626,9 +626,9 @@ class gpgpu_sim : public gpgpu_t { std::map g_watchpoint_hits; std::string executed_kernel_info_string(); //< format the kernel information - //into a string for stat printout + // into a string for stat printout void clear_executed_kernel_info(); //< clear the kernel information after - //stat printout + // stat printout public: unsigned long long gpu_sim_insn; diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 45e6790..c7738c0 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -3426,8 +3426,8 @@ void shader_core_ctx::warp_exit(unsigned warp_id) { for (unsigned i = warp_id * get_config()->warp_size; i < (warp_id + 1) * get_config()->warp_size; i++) { // if(this->m_thread[i]->m_functional_model_thread_state && - //this->m_thread[i].m_functional_model_thread_state->donecycle()==0) { done - //= false; + // this->m_thread[i].m_functional_model_thread_state->donecycle()==0) { + // done = false; // } if (m_thread[i] && !m_thread[i]->is_done()) done = false; diff --git a/src/gpuwattch/XML_Parse.cc b/src/gpuwattch/XML_Parse.cc index 39bf2a1..1b9a38a 100644 --- a/src/gpuwattch/XML_Parse.cc +++ b/src/gpuwattch/XML_Parse.cc @@ -29,2102 +29,4556 @@ * ***************************************************************************/ /******************************************************************** -* 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 "XML_Parse.h" #include -#include "xmlParser.h" #include -#include "XML_Parse.h" +#include "xmlParser.h" using namespace std; -const char * perf_count_label[] = {"TOT_INST,", "FP_INT,", "IC_H,", "IC_M,", "DC_RH,", "DC_RM,", "DC_WH,", "DC_WM,", - "TC_H,", "TC_M,", "CC_H,", "CC_M,", "SHRD_ACC,", "REG_RD,", "REG_WR,", "NON_REG_OPs,", - "SP_ACC,", "SFU_ACC,", "FPU_ACC,", "MEM_RD,","MEM_WR,", "MEM_PRE,", "L2_RH,", "L2_RM,", "L2_WH,", - "L2_WM,", "NOC_A,", "PIPE_A,", "IDLE_CORE_N,", "CONST_DYNAMICN"}; - -void ParseXML::parse(char* filepath) -{ - unsigned int i,j,k,m,n; - unsigned int NumofCom_4; - unsigned int itmp; - //Initialize all structures - ParseXML::initialize(); - string strtmp; - char chtmp[60]; - char chtmp1[60]; - chtmp1[0]='\0'; - // this open and parse the XML file: - XMLNode xMainNode=XMLNode::openFileHelper(filepath,"component"); //the 'component' in the first layer - - XMLNode xNode2=xMainNode.getChildNode("component"); // the 'component' in the second layer - //get all params in the second layer - itmp=xNode2.nChildNode("param"); - for(i=0; iOrderofComponents_3layer) - { - //___________________________get all system.core0-n________________________________________________ - if (sys.homogeneous_cores==1) OrderofComponents_3layer=0; - else OrderofComponents_3layer=sys.number_of_cores-1; - for (i=0; i<=OrderofComponents_3layer; i++) - { - xNode3=xNode2.getChildNode("component",i); - if (xNode3.isEmpty()==1) { - printf("The value of homogeneous_cores or number_of_cores is not correct!"); - exit(0); - } - else{ - if (strstr(xNode3.getAttribute("name"),"core")!=NULL) - { - { //For cpu0-cpui - //Get all params with system.core? - itmp=xNode3.nChildNode("param"); - for(k=0; k OrderofComponents_3layer) { + //___________________________get all + // system.core0-n________________________________________________ + if (sys.homogeneous_cores == 1) + OrderofComponents_3layer = 0; + else + OrderofComponents_3layer = sys.number_of_cores - 1; + for (i = 0; i <= OrderofComponents_3layer; i++) { + xNode3 = xNode2.getChildNode("component", i); + if (xNode3.isEmpty() == 1) { + printf( + "The value of homogeneous_cores or number_of_cores is not " + "correct!"); + exit(0); + } else { + if (strstr(xNode3.getAttribute("name"), "core") != NULL) { + { // For cpu0-cpui + // Get all params with system.core? + itmp = xNode3.nChildNode("param"); + for (k = 0; k < itmp; k++) { + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "clock_rate") == 0) { + sys.core[i].clock_rate = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "opt_local") == 0) { + sys.core[i].opt_local = (bool)atoi( + xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "x86") == 0) { + sys.core[i].x86 = (bool)atoi( + xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "machine_bits") == 0) { + sys.core[i].machine_bits = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "virtual_address_width") == 0) { + sys.core[i].virtual_address_width = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "physical_address_width") == 0) { + sys.core[i].physical_address_width = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "instruction_length") == 0) { + sys.core[i].instruction_length = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "opcode_width") == 0) { + sys.core[i].opcode_width = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "micro_opcode_width") == 0) { + sys.core[i].micro_opcode_width = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "machine_type") == 0) { + sys.core[i].machine_type = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "internal_datapath_width") == 0) { + sys.core[i].internal_datapath_width = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "number_hardware_threads") == 0) { + sys.core[i].number_hardware_threads = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "fetch_width") == 0) { + sys.core[i].fetch_width = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "number_instruction_fetch_ports") == 0) { + sys.core[i].number_instruction_fetch_ports = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "decode_width") == 0) { + sys.core[i].decode_width = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "issue_width") == 0) { + sys.core[i].issue_width = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "peak_issue_width") == 0) { + sys.core[i].peak_issue_width = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "commit_width") == 0) { + sys.core[i].commit_width = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "fp_issue_width") == 0) { + sys.core[i].fp_issue_width = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "prediction_width") == 0) { + sys.core[i].prediction_width = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } - } - } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "pipelines_per_core") == 0) { + strtmp.assign( + xNode3.getChildNode("param", k).getAttribute("value")); + m = 0; + for (n = 0; n < strtmp.length(); n++) { + if (strtmp[n] != ',') { + sprintf(chtmp, "%c", strtmp[n]); + strcat(chtmp1, chtmp); + } else { + sys.core[i].pipelines_per_core[m] = atoi(chtmp1); + m++; + chtmp1[0] = '\0'; + } + } + sys.core[i].pipelines_per_core[m] = atoi(chtmp1); + m++; + chtmp1[0] = '\0'; + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "pipeline_depth") == 0) { + strtmp.assign( + xNode3.getChildNode("param", k).getAttribute("value")); + m = 0; + for (n = 0; n < strtmp.length(); n++) { + if (strtmp[n] != ',') { + sprintf(chtmp, "%c", strtmp[n]); + strcat(chtmp1, chtmp); + } else { + sys.core[i].pipeline_depth[m] = atoi(chtmp1); + m++; + chtmp1[0] = '\0'; + } + } + sys.core[i].pipeline_depth[m] = atoi(chtmp1); + m++; + chtmp1[0] = '\0'; + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "FPU") == 0) { + strcpy(sys.core[i].FPU, + xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "divider_multiplier") == 0) { + strcpy(sys.core[i].divider_multiplier, + xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "ALU_per_core") == 0) { + sys.core[i].ALU_per_core = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "FPU_per_core") == 0) { + sys.core[i].FPU_per_core = + atof(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "MUL_per_core") == 0) { + sys.core[i].MUL_per_core = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "instruction_buffer_size") == 0) { + sys.core[i].instruction_buffer_size = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "decoded_stream_buffer_size") == 0) { + sys.core[i].decoded_stream_buffer_size = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "instruction_window_scheme") == 0) { + sys.core[i].instruction_window_scheme = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "instruction_window_size") == 0) { + sys.core[i].instruction_window_size = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "fp_instruction_window_size") == 0) { + sys.core[i].fp_instruction_window_size = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "ROB_size") == 0) { + sys.core[i].ROB_size = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "rf_banks") == 0) { + sys.core[i].rf_banks = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "simd_width") == 0) { + sys.core[i].simd_width = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "collector_units") == 0) { + sys.core[i].collector_units = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "core_clock_ratio") == 0) { + sys.core[i].core_clock_ratio = + atof(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "warp_size") == 0) { + sys.core[i].warp_size = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } - if (strcmp(xNode4.getAttribute("name"),"BTB")==0) - {//find system.core0.BTB - itmp=xNode4.nChildNode("param"); - for(k=0; k0) OrderofComponents_3layer=OrderofComponents_3layer+1; - xNode3=xNode2.getChildNode("component",OrderofComponents_3layer); - if (xNode3.isEmpty()==1) { - printf("some value(s) of number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are not correct!"); - exit(0); - } - if (strstr(xNode3.getAttribute("id"),"system.mem")!=NULL) - { + //__________________________________________Get + // system.L2[0..n]____________________________________________ + w = OrderofComponents_3layer + 1; + tmpOrderofComponents_3layer = OrderofComponents_3layer; + if (sys.homogeneous_L2s == 1) + OrderofComponents_3layer = OrderofComponents_3layer + 1; + else + OrderofComponents_3layer = OrderofComponents_3layer + sys.number_of_L2s; - itmp=xNode3.nChildNode("param"); - for(k=0; k0) OrderofComponents_3layer=OrderofComponents_3layer+1; - xNode3=xNode2.getChildNode("component",OrderofComponents_3layer); - if (xNode3.isEmpty()==1) { - printf("some value(s) of number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are not correct!"); - exit(0); - } - if (strstr(xNode3.getAttribute("id"),"system.mc")!=NULL) - { - itmp=xNode3.nChildNode("param"); - for(k=0; k0) OrderofComponents_3layer=OrderofComponents_3layer+1; - xNode3=xNode2.getChildNode("component",OrderofComponents_3layer); - if (xNode3.isEmpty()==1) { - printf("some value(s) of number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are not correct!"); - exit(0); - } - if (strstr(xNode3.getAttribute("id"),"system.niu")!=NULL) - { - itmp=xNode3.nChildNode("param"); - for(k=0; k0) OrderofComponents_3layer=OrderofComponents_3layer+1; - xNode3=xNode2.getChildNode("component",OrderofComponents_3layer); - if (xNode3.isEmpty()==1) { - printf("some value(s) of number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are not correct!"); - exit(0); - } - if (strstr(xNode3.getAttribute("id"),"system.pcie")!=NULL) - { - itmp=xNode3.nChildNode("param"); - for(k=0; k0) OrderofComponents_3layer=OrderofComponents_3layer+1; - xNode3=xNode2.getChildNode("component",OrderofComponents_3layer); - if (xNode3.isEmpty()==1) { - printf("some value(s) of number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are not correct!"); - exit(0); - } - if (strstr(xNode3.getAttribute("id"),"system.flashc")!=NULL) - { - itmp=xNode3.nChildNode("param"); - for(k=0; k 0) + OrderofComponents_3layer = OrderofComponents_3layer + 1; + xNode3 = xNode2.getChildNode("component", OrderofComponents_3layer); + if (xNode3.isEmpty() == 1) { + printf( + "some value(s) of " + "number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are " + "not correct!"); + exit(0); + } + if (strstr(xNode3.getAttribute("id"), "system.mem") != NULL) { + itmp = xNode3.nChildNode("param"); + for (k = 0; k < itmp; k++) { // get all items of param in system.mem + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "mem_tech_node") == 0) { + sys.mem.mem_tech_node = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "device_clock") == 0) { + sys.mem.device_clock = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "peak_transfer_rate") == 0) { + sys.mem.peak_transfer_rate = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "capacity_per_channel") == 0) { + sys.mem.capacity_per_channel = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "number_ranks") == 0) { + sys.mem.number_ranks = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "num_banks_of_DRAM_chip") == 0) { + sys.mem.num_banks_of_DRAM_chip = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "Block_width_of_DRAM_chip") == 0) { + sys.mem.Block_width_of_DRAM_chip = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "output_width_of_DRAM_chip") == 0) { + sys.mem.output_width_of_DRAM_chip = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "page_size_of_DRAM_chip") == 0) { + sys.mem.page_size_of_DRAM_chip = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "burstlength_of_DRAM_chip") == 0) { + sys.mem.burstlength_of_DRAM_chip = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "internal_prefetch_of_DRAM_chip") == 0) { + sys.mem.internal_prefetch_of_DRAM_chip = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + } + itmp = xNode3.nChildNode("stat"); + for (k = 0; k < itmp; k++) { // get all items of stat in system.mem + if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), + "memory_accesses") == 0) { + sys.mem.memory_accesses = + atof(xNode3.getChildNode("stat", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), + "memory_reads") == 0) { + sys.mem.memory_reads = + atof(xNode3.getChildNode("stat", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), + "memory_writes") == 0) { + sys.mem.memory_writes = + atof(xNode3.getChildNode("stat", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), + "dram_pre") == 0) { + sys.mem.dram_pre = + atof(xNode3.getChildNode("stat", k).getAttribute("value")); + continue; + } + } + } else { + printf( + "some value(s) of " + "number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are " + "not correct!"); + exit(0); + } + //__________________________________________Get + // system.mc____________________________________________ + if (OrderofComponents_3layer > 0) + OrderofComponents_3layer = OrderofComponents_3layer + 1; + xNode3 = xNode2.getChildNode("component", OrderofComponents_3layer); + if (xNode3.isEmpty() == 1) { + printf( + "some value(s) of " + "number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are " + "not correct!"); + exit(0); + } + if (strstr(xNode3.getAttribute("id"), "system.mc") != NULL) { + itmp = xNode3.nChildNode("param"); + for (k = 0; k < itmp; k++) { // get all items of param in system.mem + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "mc_clock") == 0) { + sys.mc.mc_clock = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "block_size") == 0) { + sys.mc.llc_line_length = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "number_mcs") == 0) { + sys.mc.number_mcs = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "memory_channels_per_mc") == 0) { + sys.mc.memory_channels_per_mc = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "req_window_size_per_channel") == 0) { + sys.mc.req_window_size_per_channel = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "IO_buffer_size_per_channel") == 0) { + sys.mc.IO_buffer_size_per_channel = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "databus_width") == 0) { + sys.mc.databus_width = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "addressbus_width") == 0) { + sys.mc.addressbus_width = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "PRT_entries") == 0) { + sys.mc.PRT_entries = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "peak_transfer_rate") == 0) { + sys.mc.peak_transfer_rate = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "number_ranks") == 0) { + sys.mc.number_ranks = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "LVDS") == 0) { + sys.mc.LVDS = + (bool)atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "type") == 0) { + sys.mc.type = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "withPHY") == 0) { + sys.mc.withPHY = + (bool)atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } - } - } - else{ - printf("some value(s) of number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are not correct!"); - exit(0); - } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "dram_cmd_coeff") == 0) { + sys.mc.dram_cmd_coeff = + atof(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "dram_act_coeff") == 0) { + sys.mc.dram_act_coeff = + atof(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "dram_nop_coeff") == 0) { + sys.mc.dram_nop_coeff = + atof(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "dram_activity_coeff") == 0) { + sys.mc.dram_activity_coeff = + atof(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "dram_pre_coeff") == 0) { + sys.mc.dram_pre_coeff = + atof(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "dram_rd_coeff") == 0) { + sys.mc.dram_rd_coeff = + atof(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "dram_wr_coeff") == 0) { + sys.mc.dram_wr_coeff = + atof(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "dram_req_coeff") == 0) { + sys.mc.dram_req_coeff = + atof(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "dram_const_coeff") == 0) { + sys.mc.dram_const_coeff = + atof(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + } + itmp = xNode3.nChildNode("stat"); + for (k = 0; k < itmp; + k++) { // get all items of stat in system.mendirectory + if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), + "memory_accesses") == 0) { + sys.mc.memory_accesses = + atof(xNode3.getChildNode("stat", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), + "memory_reads") == 0) { + sys.mc.memory_reads = + atof(xNode3.getChildNode("stat", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), + "memory_writes") == 0) { + sys.mc.memory_writes = + atof(xNode3.getChildNode("stat", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), + "dram_pre") == 0) { + sys.mc.dram_pre = + atof(xNode3.getChildNode("stat", k).getAttribute("value")); + continue; + } + } + } else { + printf( + "some value(s) of " + "number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are " + "not correct!"); + exit(0); + } + //__________________________________________Get + // system.niu____________________________________________ + if (OrderofComponents_3layer > 0) + OrderofComponents_3layer = OrderofComponents_3layer + 1; + xNode3 = xNode2.getChildNode("component", OrderofComponents_3layer); + if (xNode3.isEmpty() == 1) { + printf( + "some value(s) of " + "number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are " + "not correct!"); + exit(0); + } + if (strstr(xNode3.getAttribute("id"), "system.niu") != NULL) { + itmp = xNode3.nChildNode("param"); + for (k = 0; k < itmp; k++) { // get all items of param in system.mem + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "clockrate") == 0) { + sys.niu.clockrate = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "number_units") == 0) { + sys.niu.number_units = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "type") == 0) { + sys.niu.type = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + } + itmp = xNode3.nChildNode("stat"); + for (k = 0; k < itmp; + k++) { // get all items of stat in system.mendirectory + if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), + "duty_cycle") == 0) { + sys.niu.duty_cycle = + atof(xNode3.getChildNode("stat", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), + "total_load_perc") == 0) { + sys.niu.total_load_perc = + atof(xNode3.getChildNode("stat", k).getAttribute("value")); + continue; + } + } + } else { + printf( + "some value(s) of " + "number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are " + "not correct!"); + exit(0); + } - } + //__________________________________________Get + // system.pcie____________________________________________ + if (OrderofComponents_3layer > 0) + OrderofComponents_3layer = OrderofComponents_3layer + 1; + xNode3 = xNode2.getChildNode("component", OrderofComponents_3layer); + if (xNode3.isEmpty() == 1) { + printf( + "some value(s) of " + "number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are " + "not correct!"); + exit(0); + } + if (strstr(xNode3.getAttribute("id"), "system.pcie") != NULL) { + itmp = xNode3.nChildNode("param"); + for (k = 0; k < itmp; k++) { // get all items of param in system.mem + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "clockrate") == 0) { + sys.pcie.clockrate = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "number_units") == 0) { + sys.pcie.number_units = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "num_channels") == 0) { + sys.pcie.num_channels = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "type") == 0) { + sys.pcie.type = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "withPHY") == 0) { + sys.pcie.withPHY = + (bool)atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + } + itmp = xNode3.nChildNode("stat"); + for (k = 0; k < itmp; + k++) { // get all items of stat in system.mendirectory + if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), + "duty_cycle") == 0) { + sys.pcie.duty_cycle = + atof(xNode3.getChildNode("stat", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), + "total_load_perc") == 0) { + sys.pcie.total_load_perc = + atof(xNode3.getChildNode("stat", k).getAttribute("value")); + continue; + } + } + } else { + printf( + "some value(s) of " + "number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are " + "not correct!"); + exit(0); + } + //__________________________________________Get + // system.flashcontroller____________________________________________ + if (OrderofComponents_3layer > 0) + OrderofComponents_3layer = OrderofComponents_3layer + 1; + xNode3 = xNode2.getChildNode("component", OrderofComponents_3layer); + if (xNode3.isEmpty() == 1) { + printf( + "some value(s) of " + "number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are " + "not correct!"); + exit(0); + } + if (strstr(xNode3.getAttribute("id"), "system.flashc") != NULL) { + itmp = xNode3.nChildNode("param"); + for (k = 0; k < itmp; k++) { // get all items of param in system.mem + // if + //(strcmp(xNode3.getChildNode("param",k).getAttribute("name"),"flashc_clock")==0) + //{sys.flashc.mc_clock=atoi(xNode3.getChildNode("param",k).getAttribute("value"));continue;} + // if + //(strcmp(xNode3.getChildNode("param",k).getAttribute("name"),"block_size")==0) + //{sys.flashc.llc_line_length=atoi(xNode3.getChildNode("param",k).getAttribute("value"));continue;} + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "number_flashcs") == 0) { + sys.flashc.number_mcs = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + // if + //(strcmp(xNode3.getChildNode("param",k).getAttribute("name"),"memory_channels_per_flashc")==0) + //{sys.flashc.memory_channels_per_mc=atoi(xNode3.getChildNode("param",k).getAttribute("value"));continue;} + // if + //(strcmp(xNode3.getChildNode("param",k).getAttribute("name"),"req_window_size_per_channel")==0) + //{sys.flashc.req_window_size_per_channel=atoi(xNode3.getChildNode("param",k).getAttribute("value"));continue;} + // if + //(strcmp(xNode3.getChildNode("param",k).getAttribute("name"),"IO_buffer_size_per_channel")==0) + //{sys.flashc.IO_buffer_size_per_channel=atoi(xNode3.getChildNode("param",k).getAttribute("value"));continue;} + // if + //(strcmp(xNode3.getChildNode("param",k).getAttribute("name"),"databus_width")==0) + //{sys.flashc.databus_width=atoi(xNode3.getChildNode("param",k).getAttribute("value"));continue;} + // if + //(strcmp(xNode3.getChildNode("param",k).getAttribute("name"),"addressbus_width")==0) + //{sys.flashc.addressbus_width=atoi(xNode3.getChildNode("param",k).getAttribute("value"));continue;} + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "peak_transfer_rate") == 0) { + sys.flashc.peak_transfer_rate = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + // if + //(strcmp(xNode3.getChildNode("param",k).getAttribute("name"),"number_ranks")==0) + //{sys.flashc.number_ranks=atoi(xNode3.getChildNode("param",k).getAttribute("value"));continue;} + // if + //(strcmp(xNode3.getChildNode("param",k).getAttribute("name"),"LVDS")==0) + //{sys.flashc.LVDS=(bool)atoi(xNode3.getChildNode("param",k).getAttribute("value"));continue;} + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "type") == 0) { + sys.flashc.type = + atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("param", k).getAttribute("name"), + "withPHY") == 0) { + sys.flashc.withPHY = + (bool)atoi(xNode3.getChildNode("param", k).getAttribute("value")); + continue; + } + } + itmp = xNode3.nChildNode("stat"); + for (k = 0; k < itmp; + k++) { // get all items of stat in system.mendirectory + // if + //(strcmp(xNode3.getChildNode("stat",k).getAttribute("name"),"memory_accesses")==0) + //{sys.flashc.memory_accesses=atof(xNode3.getChildNode("stat",k).getAttribute("value"));continue;} + // if + //(strcmp(xNode3.getChildNode("stat",k).getAttribute("name"),"memory_reads")==0) + //{sys.flashc.memory_reads=atof(xNode3.getChildNode("stat",k).getAttribute("value"));continue;} + // if + //(strcmp(xNode3.getChildNode("stat",k).getAttribute("name"),"memory_writes")==0) + //{sys.flashc.memory_writes=atof(xNode3.getChildNode("stat",k).getAttribute("value"));continue;} + if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), + "duty_cycle") == 0) { + sys.flashc.duty_cycle = + atof(xNode3.getChildNode("stat", k).getAttribute("value")); + continue; + } + if (strcmp(xNode3.getChildNode("stat", k).getAttribute("name"), + "total_load_perc") == 0) { + sys.flashc.total_load_perc = + atof(xNode3.getChildNode("stat", k).getAttribute("value")); + continue; + } + } + } else { + printf( + "some value(s) of " + "number_of_cores/number_of_L2s/number_of_L3s/number_of_NoCs is/are " + "not correct!"); + exit(0); + } + } } -void ParseXML::initialize() //Initialize all +void ParseXML::initialize() // Initialize all { - //All number_of_* at the level of 'system' 03/21/2009 - sys.number_of_cores=1; - sys.architecture=1; //1 - fermi - sys.number_of_L1Directories=1; - sys.number_of_L2Directories=1; - sys.number_of_L2s=1; - sys.Private_L2 = false; - sys.number_of_L3s=1; - sys.number_of_NoCs=1; - // All params at the level of 'system' - //strcpy(sys.homogeneous_cores,"default"); - sys.core_tech_node=1; - sys.target_core_clockrate=1; - sys.target_chip_area=1; - sys.temperature=1; - sys.number_cache_levels=1; - sys.homogeneous_cores=1; - sys.homogeneous_L1Directories=1; - sys.homogeneous_L2Directories=1; - sys.homogeneous_L2s=1; - sys.homogeneous_L3s=1; - sys.homogeneous_NoCs=1; - sys.homogeneous_ccs=1; + // All number_of_* at the level of 'system' 03/21/2009 + sys.number_of_cores = 1; + sys.architecture = 1; // 1 - fermi + sys.number_of_L1Directories = 1; + sys.number_of_L2Directories = 1; + sys.number_of_L2s = 1; + sys.Private_L2 = false; + sys.number_of_L3s = 1; + sys.number_of_NoCs = 1; + // All params at the level of 'system' + // strcpy(sys.homogeneous_cores,"default"); + sys.core_tech_node = 1; + sys.target_core_clockrate = 1; + sys.target_chip_area = 1; + sys.temperature = 1; + sys.number_cache_levels = 1; + sys.homogeneous_cores = 1; + sys.homogeneous_L1Directories = 1; + sys.homogeneous_L2Directories = 1; + sys.homogeneous_L2s = 1; + sys.homogeneous_L3s = 1; + sys.homogeneous_NoCs = 1; + sys.homogeneous_ccs = 1; - sys.Max_area_deviation=1; - sys.Max_power_deviation=1; - sys.device_type=1; - sys.longer_channel_device =true; - sys.Embedded =false; - sys.opt_dynamic_power=false; - sys.opt_lakage_power=false; - sys.opt_clockrate=true; - sys.opt_area=false; - sys.interconnect_projection_type=1; - sys.idle_core_power=0; - int i,j; - for (i=0; i<=63; i++) - { - sys.scaling_coefficients[i]=1; - sys.core[i].clock_rate=1; - sys.core[i].opt_local = true; - sys.core[i].x86 = false; - sys.core[i].machine_bits=1; - sys.core[i].virtual_address_width=1; - sys.core[i].physical_address_width=1; - sys.core[i].opcode_width=1; - sys.core[i].micro_opcode_width=1; - //strcpy(sys.core[i].machine_type,"default"); - sys.core[i].internal_datapath_width=1; - sys.core[i].number_hardware_threads=1; - sys.core[i].fetch_width=1; - sys.core[i].number_instruction_fetch_ports=1; - sys.core[i].decode_width=1; - sys.core[i].issue_width=1; - sys.core[i].peak_issue_width=1; - sys.core[i].commit_width=1; - for (j=0; j<20; j++) sys.core[i].pipelines_per_core[j]=1; - for (j=0; j<20; j++) sys.core[i].pipeline_depth[j]=1; - strcpy(sys.core[i].FPU,"default"); - strcpy(sys.core[i]. divider_multiplier,"default"); - sys.core[i].ALU_per_core=1; - sys.core[i].FPU_per_core=1.0; - sys.core[i].MUL_per_core=1; - sys.core[i].instruction_buffer_size=1; - sys.core[i].decoded_stream_buffer_size=1; - //strcpy(sys.core[i].instruction_window_scheme,"default"); - sys.core[i].instruction_window_size=1; - sys.core[i].ROB_size=1; - sys.core[i].archi_Regs_IRF_size=1; - sys.core[i].archi_Regs_FRF_size=1; - sys.core[i].phy_Regs_IRF_size=1; - sys.core[i].phy_Regs_FRF_size=1; - //strcpy(sys.core[i].rename_scheme,"default"); - sys.core[i].register_windows_size=1; - strcpy(sys.core[i].LSU_order,"default"); - sys.core[i].store_buffer_size=1; - sys.core[i].load_buffer_size=1; - sys.core[i].memory_ports=1; - strcpy(sys.core[i].Dcache_dual_pump,"default"); - sys.core[i].RAS_size=1; - //all stats at the level of system.core(0-n) - sys.core[i].total_instructions=1; - sys.core[i].int_instructions=1; - sys.core[i].fp_instructions=1; - sys.core[i].branch_instructions=1; - sys.core[i].branch_mispredictions=1; - sys.core[i].committed_instructions=1; - sys.core[i].load_instructions=1; - sys.core[i].store_instructions=1; - sys.core[i].total_cycles=1; - sys.core[i].idle_cycles=1; - sys.core[i].busy_cycles=1; - sys.core[i].instruction_buffer_reads=1; - sys.core[i].instruction_buffer_write=1; - sys.core[i].ROB_reads=1; - sys.core[i].ROB_writes=1; - sys.core[i].rename_accesses=1; - sys.core[i].inst_window_reads=1; - sys.core[i].inst_window_writes=1; - sys.core[i].inst_window_wakeup_accesses=1; - sys.core[i].inst_window_selections=1; - sys.core[i].archi_int_regfile_reads=1; - sys.core[i].archi_float_regfile_reads=1; - sys.core[i].phy_int_regfile_reads=1; - sys.core[i].phy_float_regfile_reads=1; - sys.core[i].windowed_reg_accesses=1; - sys.core[i].windowed_reg_transports=1; - sys.core[i].function_calls=1; - sys.core[i].ialu_accesses=1; - sys.core[i].fpu_accesses=1; - sys.core[i].mul_accesses=1; - sys.core[i].cdb_alu_accesses=1; - sys.core[i].cdb_mul_accesses=1; - sys.core[i].cdb_fpu_accesses=1; - sys.core[i].load_buffer_reads=1; - sys.core[i].load_buffer_writes=1; - sys.core[i].load_buffer_cams=1; - sys.core[i].store_buffer_reads=1; - sys.core[i].store_buffer_writes=1; - sys.core[i].store_buffer_cams=1; - sys.core[i].store_buffer_forwards=1; - sys.core[i].main_memory_access=1; - sys.core[i].main_memory_read=1; - sys.core[i].main_memory_write=1; - sys.core[i].IFU_duty_cycle = 1; - sys.core[i].BR_duty_cycle = 1; - sys.core[i].LSU_duty_cycle = 1; - sys.core[i].MemManU_I_duty_cycle =1; - sys.core[i].MemManU_D_duty_cycle =1; - sys.core[i].ALU_duty_cycle =1; - sys.core[i].MUL_duty_cycle =1; - sys.core[i].FPU_duty_cycle =1; - sys.core[i].ALU_cdb_duty_cycle =1; - sys.core[i].MUL_cdb_duty_cycle =1; - sys.core[i].FPU_cdb_duty_cycle =1; - //system.core?.predictor - sys.core[i].predictor.prediction_width=1; - strcpy(sys.core[i].predictor.prediction_scheme,"default"); - sys.core[i].predictor.predictor_size=1; - sys.core[i].predictor.predictor_entries=1; - sys.core[i].predictor.local_predictor_entries=1; - for (j=0; j<20; j++) sys.core[i].predictor.local_predictor_size[j]=1; - sys.core[i].predictor.global_predictor_entries=1; - sys.core[i].predictor.global_predictor_bits=1; - sys.core[i].predictor.chooser_predictor_entries=1; - sys.core[i].predictor.chooser_predictor_bits=1; - sys.core[i].predictor.predictor_accesses=1; - //system.core?.itlb - sys.core[i].itlb.number_entries=1; - sys.core[i].itlb.total_hits=1; - sys.core[i].itlb.total_accesses=1; - sys.core[i].itlb.total_misses=1; - //system.core?.icache - for (j=0; j<20; j++) sys.core[i].icache.icache_config[j]=1; - //strcpy(sys.core[i].icache.buffer_sizes,"default"); - sys.core[i].icache.total_accesses=1; - sys.core[i].icache.read_accesses=1; - sys.core[i].icache.read_misses=1; - sys.core[i].icache.replacements=1; - sys.core[i].icache.read_hits=1; - sys.core[i].icache.total_hits=1; - sys.core[i].icache.total_misses=1; - sys.core[i].icache.miss_buffer_access=1; - sys.core[i].icache.fill_buffer_accesses=1; - sys.core[i].icache.prefetch_buffer_accesses=1; - sys.core[i].icache.prefetch_buffer_writes=1; - sys.core[i].icache.prefetch_buffer_reads=1; - sys.core[i].icache.prefetch_buffer_hits=1; - //system.core?.dtlb - sys.core[i].dtlb.number_entries=1; - sys.core[i].dtlb.total_accesses=1; - sys.core[i].dtlb.read_accesses=1; - sys.core[i].dtlb.write_accesses=1; - sys.core[i].dtlb.write_hits=1; - sys.core[i].dtlb.read_hits=1; - sys.core[i].dtlb.read_misses=1; - sys.core[i].dtlb.write_misses=1; - sys.core[i].dtlb.total_hits=1; - sys.core[i].dtlb.total_misses=1; - //system.core?.dcache - for (j=0; j<20; j++) sys.core[i].dcache.dcache_config[j]=1; - //strcpy(sys.core[i].dcache.buffer_sizes,"default"); - sys.core[i].dcache.total_accesses=1; - sys.core[i].dcache.read_accesses=1; - sys.core[i].dcache.write_accesses=1; - sys.core[i].dcache.total_hits=1; - sys.core[i].dcache.total_misses=1; - sys.core[i].dcache.read_hits=1; - sys.core[i].dcache.write_hits=1; - sys.core[i].dcache.read_misses=1; - sys.core[i].dcache.write_misses=1; - sys.core[i].dcache.replacements=1; - sys.core[i].dcache.write_backs=1; - sys.core[i].dcache.miss_buffer_access=1; - sys.core[i].dcache.fill_buffer_accesses=1; - sys.core[i].dcache.prefetch_buffer_accesses=1; - sys.core[i].dcache.prefetch_buffer_writes=1; - sys.core[i].dcache.prefetch_buffer_reads=1; - sys.core[i].dcache.prefetch_buffer_hits=1; - sys.core[i].dcache.wbb_writes=1; - sys.core[i].dcache.wbb_reads=1; - //system.core?.BTB - for (j=0; j<20; j++) sys.core[i].BTB.BTB_config[j]=1; - sys.core[i].BTB.total_accesses=1; - sys.core[i].BTB.read_accesses=1; - sys.core[i].BTB.write_accesses=1; - sys.core[i].BTB.total_hits=1; - sys.core[i].BTB.total_misses=1; - sys.core[i].BTB.read_hits=1; - sys.core[i].BTB.write_hits=1; - sys.core[i].BTB.read_misses=1; - sys.core[i].BTB.write_misses=1; - sys.core[i].BTB.replacements=1; - } + sys.Max_area_deviation = 1; + sys.Max_power_deviation = 1; + sys.device_type = 1; + sys.longer_channel_device = true; + sys.Embedded = false; + sys.opt_dynamic_power = false; + sys.opt_lakage_power = false; + sys.opt_clockrate = true; + sys.opt_area = false; + sys.interconnect_projection_type = 1; + sys.idle_core_power = 0; + int i, j; + for (i = 0; i <= 63; i++) { + sys.scaling_coefficients[i] = 1; + sys.core[i].clock_rate = 1; + sys.core[i].opt_local = true; + sys.core[i].x86 = false; + sys.core[i].machine_bits = 1; + sys.core[i].virtual_address_width = 1; + sys.core[i].physical_address_width = 1; + sys.core[i].opcode_width = 1; + sys.core[i].micro_opcode_width = 1; + // strcpy(sys.core[i].machine_type,"default"); + sys.core[i].internal_datapath_width = 1; + sys.core[i].number_hardware_threads = 1; + sys.core[i].fetch_width = 1; + sys.core[i].number_instruction_fetch_ports = 1; + sys.core[i].decode_width = 1; + sys.core[i].issue_width = 1; + sys.core[i].peak_issue_width = 1; + sys.core[i].commit_width = 1; + for (j = 0; j < 20; j++) sys.core[i].pipelines_per_core[j] = 1; + for (j = 0; j < 20; j++) sys.core[i].pipeline_depth[j] = 1; + strcpy(sys.core[i].FPU, "default"); + strcpy(sys.core[i].divider_multiplier, "default"); + sys.core[i].ALU_per_core = 1; + sys.core[i].FPU_per_core = 1.0; + sys.core[i].MUL_per_core = 1; + sys.core[i].instruction_buffer_size = 1; + sys.core[i].decoded_stream_buffer_size = 1; + // strcpy(sys.core[i].instruction_window_scheme,"default"); + sys.core[i].instruction_window_size = 1; + sys.core[i].ROB_size = 1; + sys.core[i].archi_Regs_IRF_size = 1; + sys.core[i].archi_Regs_FRF_size = 1; + sys.core[i].phy_Regs_IRF_size = 1; + sys.core[i].phy_Regs_FRF_size = 1; + // strcpy(sys.core[i].rename_scheme,"default"); + sys.core[i].register_windows_size = 1; + strcpy(sys.core[i].LSU_order, "default"); + sys.core[i].store_buffer_size = 1; + sys.core[i].load_buffer_size = 1; + sys.core[i].memory_ports = 1; + strcpy(sys.core[i].Dcache_dual_pump, "default"); + sys.core[i].RAS_size = 1; + // all stats at the level of system.core(0-n) + sys.core[i].total_instructions = 1; + sys.core[i].int_instructions = 1; + sys.core[i].fp_instructions = 1; + sys.core[i].branch_instructions = 1; + sys.core[i].branch_mispredictions = 1; + sys.core[i].committed_instructions = 1; + sys.core[i].load_instructions = 1; + sys.core[i].store_instructions = 1; + sys.core[i].total_cycles = 1; + sys.core[i].idle_cycles = 1; + sys.core[i].busy_cycles = 1; + sys.core[i].instruction_buffer_reads = 1; + sys.core[i].instruction_buffer_write = 1; + sys.core[i].ROB_reads = 1; + sys.core[i].ROB_writes = 1; + sys.core[i].rename_accesses = 1; + sys.core[i].inst_window_reads = 1; + sys.core[i].inst_window_writes = 1; + sys.core[i].inst_window_wakeup_accesses = 1; + sys.core[i].inst_window_selections = 1; + sys.core[i].archi_int_regfile_reads = 1; + sys.core[i].archi_float_regfile_reads = 1; + sys.core[i].phy_int_regfile_reads = 1; + sys.core[i].phy_float_regfile_reads = 1; + sys.core[i].windowed_reg_accesses = 1; + sys.core[i].windowed_reg_transports = 1; + sys.core[i].function_calls = 1; + sys.core[i].ialu_accesses = 1; + sys.core[i].fpu_accesses = 1; + sys.core[i].mul_accesses = 1; + sys.core[i].cdb_alu_accesses = 1; + sys.core[i].cdb_mul_accesses = 1; + sys.core[i].cdb_fpu_accesses = 1; + sys.core[i].load_buffer_reads = 1; + sys.core[i].load_buffer_writes = 1; + sys.core[i].load_buffer_cams = 1; + sys.core[i].store_buffer_reads = 1; + sys.core[i].store_buffer_writes = 1; + sys.core[i].store_buffer_cams = 1; + sys.core[i].store_buffer_forwards = 1; + sys.core[i].main_memory_access = 1; + sys.core[i].main_memory_read = 1; + sys.core[i].main_memory_write = 1; + sys.core[i].IFU_duty_cycle = 1; + sys.core[i].BR_duty_cycle = 1; + sys.core[i].LSU_duty_cycle = 1; + sys.core[i].MemManU_I_duty_cycle = 1; + sys.core[i].MemManU_D_duty_cycle = 1; + sys.core[i].ALU_duty_cycle = 1; + sys.core[i].MUL_duty_cycle = 1; + sys.core[i].FPU_duty_cycle = 1; + sys.core[i].ALU_cdb_duty_cycle = 1; + sys.core[i].MUL_cdb_duty_cycle = 1; + sys.core[i].FPU_cdb_duty_cycle = 1; + // system.core?.predictor + sys.core[i].predictor.prediction_width = 1; + strcpy(sys.core[i].predictor.prediction_scheme, "default"); + sys.core[i].predictor.predictor_size = 1; + sys.core[i].predictor.predictor_entries = 1; + sys.core[i].predictor.local_predictor_entries = 1; + for (j = 0; j < 20; j++) sys.core[i].predictor.local_predictor_size[j] = 1; + sys.core[i].predictor.global_predictor_entries = 1; + sys.core[i].predictor.global_predictor_bits = 1; + sys.core[i].predictor.chooser_predictor_entries = 1; + sys.core[i].predictor.chooser_predictor_bits = 1; + sys.core[i].predictor.predictor_accesses = 1; + // system.core?.itlb + sys.core[i].itlb.number_entries = 1; + sys.core[i].itlb.total_hits = 1; + sys.core[i].itlb.total_accesses = 1; + sys.core[i].itlb.total_misses = 1; + // system.core?.icache + for (j = 0; j < 20; j++) sys.core[i].icache.icache_config[j] = 1; + // strcpy(sys.core[i].icache.buffer_sizes,"default"); + sys.core[i].icache.total_accesses = 1; + sys.core[i].icache.read_accesses = 1; + sys.core[i].icache.read_misses = 1; + sys.core[i].icache.replacements = 1; + sys.core[i].icache.read_hits = 1; + sys.core[i].icache.total_hits = 1; + sys.core[i].icache.total_misses = 1; + sys.core[i].icache.miss_buffer_access = 1; + sys.core[i].icache.fill_buffer_accesses = 1; + sys.core[i].icache.prefetch_buffer_accesses = 1; + sys.core[i].icache.prefetch_buffer_writes = 1; + sys.core[i].icache.prefetch_buffer_reads = 1; + sys.core[i].icache.prefetch_buffer_hits = 1; + // system.core?.dtlb + sys.core[i].dtlb.number_entries = 1; + sys.core[i].dtlb.total_accesses = 1; + sys.core[i].dtlb.read_accesses = 1; + sys.core[i].dtlb.write_accesses = 1; + sys.core[i].dtlb.write_hits = 1; + sys.core[i].dtlb.read_hits = 1; + sys.core[i].dtlb.read_misses = 1; + sys.core[i].dtlb.write_misses = 1; + sys.core[i].dtlb.total_hits = 1; + sys.core[i].dtlb.total_misses = 1; + // system.core?.dcache + for (j = 0; j < 20; j++) sys.core[i].dcache.dcache_config[j] = 1; + // strcpy(sys.core[i].dcache.buffer_sizes,"default"); + sys.core[i].dcache.total_accesses = 1; + sys.core[i].dcache.read_accesses = 1; + sys.core[i].dcache.write_accesses = 1; + sys.core[i].dcache.total_hits = 1; + sys.core[i].dcache.total_misses = 1; + sys.core[i].dcache.read_hits = 1; + sys.core[i].dcache.write_hits = 1; + sys.core[i].dcache.read_misses = 1; + sys.core[i].dcache.write_misses = 1; + sys.core[i].dcache.replacements = 1; + sys.core[i].dcache.write_backs = 1; + sys.core[i].dcache.miss_buffer_access = 1; + sys.core[i].dcache.fill_buffer_accesses = 1; + sys.core[i].dcache.prefetch_buffer_accesses = 1; + sys.core[i].dcache.prefetch_buffer_writes = 1; + sys.core[i].dcache.prefetch_buffer_reads = 1; + sys.core[i].dcache.prefetch_buffer_hits = 1; + sys.core[i].dcache.wbb_writes = 1; + sys.core[i].dcache.wbb_reads = 1; + // system.core?.BTB + for (j = 0; j < 20; j++) sys.core[i].BTB.BTB_config[j] = 1; + sys.core[i].BTB.total_accesses = 1; + sys.core[i].BTB.read_accesses = 1; + sys.core[i].BTB.write_accesses = 1; + sys.core[i].BTB.total_hits = 1; + sys.core[i].BTB.total_misses = 1; + sys.core[i].BTB.read_hits = 1; + sys.core[i].BTB.write_hits = 1; + sys.core[i].BTB.read_misses = 1; + sys.core[i].BTB.write_misses = 1; + sys.core[i].BTB.replacements = 1; + } - //system_L1directory - for (i=0; i<=63; i++) - { - for (j=0; j<20; j++) sys.L1Directory[i].Dir_config[j]=1; - for (j=0; j<20; j++) sys.L1Directory[i].buffer_sizes[j]=1; - sys.L1Directory[i].clockrate=1; - sys.L1Directory[i].ports[20]=1; - sys.L1Directory[i].device_type=1; - strcpy(sys.L1Directory[i].threeD_stack,"default"); - sys.L1Directory[i].total_accesses=1; - sys.L1Directory[i].read_accesses=1; - sys.L1Directory[i].write_accesses=1; - sys.L1Directory[i].duty_cycle =1; - } - //system_L2directory - for (i=0; i<=63; i++) - { - for (j=0; j<20; j++) sys.L2Directory[i].Dir_config[j]=1; - for (j=0; j<20; j++) sys.L2Directory[i].buffer_sizes[j]=1; - sys.L2Directory[i].clockrate=1; - sys.L2Directory[i].ports[20]=1; - sys.L2Directory[i].device_type=1; - strcpy(sys.L2Directory[i].threeD_stack,"default"); - sys.L2Directory[i].total_accesses=1; - sys.L2Directory[i].read_accesses=1; - sys.L2Directory[i].write_accesses=1; - sys.L2Directory[i].duty_cycle =1; - } - for (i=0; i<=63; i++) - { - //system_L2 - for (j=0; j<20; j++) sys.L2[i].L2_config[j]=1; - sys.L2[i].clockrate=1; - for (j=0; j<20; j++) sys.L2[i].ports[j]=1; - sys.L2[i].device_type=1; - strcpy(sys.L2[i].threeD_stack,"default"); - for (j=0; j<20; j++) sys.L2[i].buffer_sizes[j]=1; - sys.L2[i].total_accesses=1; - sys.L2[i].read_accesses=1; - sys.L2[i].write_accesses=1; - sys.L2[i].total_hits=1; - sys.L2[i].total_misses=1; - sys.L2[i].read_hits=1; - sys.L2[i].write_hits=1; - sys.L2[i].read_misses=1; - sys.L2[i].write_misses=1; - sys.L2[i].replacements=1; - sys.L2[i].write_backs=1; - sys.L2[i].miss_buffer_accesses=1; - sys.L2[i].fill_buffer_accesses=1; - sys.L2[i].prefetch_buffer_accesses=1; - sys.L2[i].prefetch_buffer_writes=1; - sys.L2[i].prefetch_buffer_reads=1; - sys.L2[i].prefetch_buffer_hits=1; - sys.L2[i].wbb_writes=1; - sys.L2[i].wbb_reads=1; - sys.L2[i].duty_cycle =1; - sys.L2[i].merged_dir=false; - sys.L2[i].homenode_read_accesses =1; - sys.L2[i].homenode_write_accesses=1; - sys.L2[i].homenode_read_hits=1; - sys.L2[i].homenode_write_hits=1; - sys.L2[i].homenode_read_misses=1; - sys.L2[i].homenode_write_misses=1; - sys.L2[i].dir_duty_cycle=1; - } - for (i=0; i<=63; i++) - { - //system_L3 - for (j=0; j<20; j++) sys.L3[i].L3_config[j]=1; - sys.L3[i].clockrate=1; - for (j=0; j<20; j++) sys.L3[i].ports[j]=1; - sys.L3[i].device_type=1; - strcpy(sys.L3[i].threeD_stack,"default"); - for (j=0; j<20; j++) sys.L3[i].buffer_sizes[j]=1; - sys.L3[i].total_accesses=1; - sys.L3[i].read_accesses=1; - sys.L3[i].write_accesses=1; - sys.L3[i].total_hits=1; - sys.L3[i].total_misses=1; - sys.L3[i].read_hits=1; - sys.L3[i].write_hits=1; - sys.L3[i].read_misses=1; - sys.L3[i].write_misses=1; - sys.L3[i].replacements=1; - sys.L3[i].write_backs=1; - sys.L3[i].miss_buffer_accesses=1; - sys.L3[i].fill_buffer_accesses=1; - sys.L3[i].prefetch_buffer_accesses=1; - sys.L3[i].prefetch_buffer_writes=1; - sys.L3[i].prefetch_buffer_reads=1; - sys.L3[i].prefetch_buffer_hits=1; - sys.L3[i].wbb_writes=1; - sys.L3[i].wbb_reads=1; - sys.L3[i].duty_cycle =1; - sys.L3[i].merged_dir=false; - sys.L3[i].homenode_read_accesses =1; - sys.L3[i].homenode_write_accesses=1; - sys.L3[i].homenode_read_hits=1; - sys.L3[i].homenode_write_hits=1; - sys.L3[i].homenode_read_misses=1; - sys.L3[i].homenode_write_misses=1; - sys.L3[i].dir_duty_cycle=1; - } - //system_NoC - for (i=0; i<=63; i++) - { - sys.NoC[i].clockrate=1; - sys.NoC[i].type=true; - sys.NoC[i].chip_coverage=1; - sys.NoC[i].has_global_link = true; - strcpy(sys.NoC[i].topology,"default"); - sys.NoC[i].horizontal_nodes=1; - sys.NoC[i].vertical_nodes=1; - sys.NoC[i].input_ports=1; - sys.NoC[i].output_ports=1; - sys.NoC[i].virtual_channel_per_port=1; - sys.NoC[i].flit_bits=1; - sys.NoC[i].input_buffer_entries_per_vc=1; - sys.NoC[i].total_accesses=1; - sys.NoC[i].duty_cycle=1; - sys.NoC[i].route_over_perc = 0.5; - for (j=0; j<20; j++) sys.NoC[i].ports_of_input_buffer[j]=1; - sys.NoC[i].number_of_crossbars=1; - strcpy(sys.NoC[i].crossbar_type,"default"); - strcpy(sys.NoC[i].crosspoint_type,"default"); - //system.NoC?.xbar0; - sys.NoC[i].xbar0.number_of_inputs_of_crossbars=1; - sys.NoC[i].xbar0.number_of_outputs_of_crossbars=1; - sys.NoC[i].xbar0.flit_bits=1; - sys.NoC[i].xbar0.input_buffer_entries_per_port=1; - sys.NoC[i].xbar0.ports_of_input_buffer[20]=1; - sys.NoC[i].xbar0.crossbar_accesses=1; - } - //system_mem - sys.mem.mem_tech_node=1; - sys.mem.device_clock=1; - sys.mem.capacity_per_channel=1; - sys.mem.number_ranks=1; - sys.mem.peak_transfer_rate =1; - sys.mem.num_banks_of_DRAM_chip=1; - sys.mem.Block_width_of_DRAM_chip=1; - sys.mem.output_width_of_DRAM_chip=1; - sys.mem.page_size_of_DRAM_chip=1; - sys.mem.burstlength_of_DRAM_chip=1; - sys.mem.internal_prefetch_of_DRAM_chip=1; - sys.mem.memory_accesses=1; - sys.mem.memory_reads=1; - sys.mem.memory_writes=1; + // system_L1directory + for (i = 0; i <= 63; i++) { + for (j = 0; j < 20; j++) sys.L1Directory[i].Dir_config[j] = 1; + for (j = 0; j < 20; j++) sys.L1Directory[i].buffer_sizes[j] = 1; + sys.L1Directory[i].clockrate = 1; + sys.L1Directory[i].ports[20] = 1; + sys.L1Directory[i].device_type = 1; + strcpy(sys.L1Directory[i].threeD_stack, "default"); + sys.L1Directory[i].total_accesses = 1; + sys.L1Directory[i].read_accesses = 1; + sys.L1Directory[i].write_accesses = 1; + sys.L1Directory[i].duty_cycle = 1; + } + // system_L2directory + for (i = 0; i <= 63; i++) { + for (j = 0; j < 20; j++) sys.L2Directory[i].Dir_config[j] = 1; + for (j = 0; j < 20; j++) sys.L2Directory[i].buffer_sizes[j] = 1; + sys.L2Directory[i].clockrate = 1; + sys.L2Directory[i].ports[20] = 1; + sys.L2Directory[i].device_type = 1; + strcpy(sys.L2Directory[i].threeD_stack, "default"); + sys.L2Directory[i].total_accesses = 1; + sys.L2Directory[i].read_accesses = 1; + sys.L2Directory[i].write_accesses = 1; + sys.L2Directory[i].duty_cycle = 1; + } + for (i = 0; i <= 63; i++) { + // system_L2 + for (j = 0; j < 20; j++) sys.L2[i].L2_config[j] = 1; + sys.L2[i].clockrate = 1; + for (j = 0; j < 20; j++) sys.L2[i].ports[j] = 1; + sys.L2[i].device_type = 1; + strcpy(sys.L2[i].threeD_stack, "default"); + for (j = 0; j < 20; j++) sys.L2[i].buffer_sizes[j] = 1; + sys.L2[i].total_accesses = 1; + sys.L2[i].read_accesses = 1; + sys.L2[i].write_accesses = 1; + sys.L2[i].total_hits = 1; + sys.L2[i].total_misses = 1; + sys.L2[i].read_hits = 1; + sys.L2[i].write_hits = 1; + sys.L2[i].read_misses = 1; + sys.L2[i].write_misses = 1; + sys.L2[i].replacements = 1; + sys.L2[i].write_backs = 1; + sys.L2[i].miss_buffer_accesses = 1; + sys.L2[i].fill_buffer_accesses = 1; + sys.L2[i].prefetch_buffer_accesses = 1; + sys.L2[i].prefetch_buffer_writes = 1; + sys.L2[i].prefetch_buffer_reads = 1; + sys.L2[i].prefetch_buffer_hits = 1; + sys.L2[i].wbb_writes = 1; + sys.L2[i].wbb_reads = 1; + sys.L2[i].duty_cycle = 1; + sys.L2[i].merged_dir = false; + sys.L2[i].homenode_read_accesses = 1; + sys.L2[i].homenode_write_accesses = 1; + sys.L2[i].homenode_read_hits = 1; + sys.L2[i].homenode_write_hits = 1; + sys.L2[i].homenode_read_misses = 1; + sys.L2[i].homenode_write_misses = 1; + sys.L2[i].dir_duty_cycle = 1; + } + for (i = 0; i <= 63; i++) { + // system_L3 + for (j = 0; j < 20; j++) sys.L3[i].L3_config[j] = 1; + sys.L3[i].clockrate = 1; + for (j = 0; j < 20; j++) sys.L3[i].ports[j] = 1; + sys.L3[i].device_type = 1; + strcpy(sys.L3[i].threeD_stack, "default"); + for (j = 0; j < 20; j++) sys.L3[i].buffer_sizes[j] = 1; + sys.L3[i].total_accesses = 1; + sys.L3[i].read_accesses = 1; + sys.L3[i].write_accesses = 1; + sys.L3[i].total_hits = 1; + sys.L3[i].total_misses = 1; + sys.L3[i].read_hits = 1; + sys.L3[i].write_hits = 1; + sys.L3[i].read_misses = 1; + sys.L3[i].write_misses = 1; + sys.L3[i].replacements = 1; + sys.L3[i].write_backs = 1; + sys.L3[i].miss_buffer_accesses = 1; + sys.L3[i].fill_buffer_accesses = 1; + sys.L3[i].prefetch_buffer_accesses = 1; + sys.L3[i].prefetch_buffer_writes = 1; + sys.L3[i].prefetch_buffer_reads = 1; + sys.L3[i].prefetch_buffer_hits = 1; + sys.L3[i].wbb_writes = 1; + sys.L3[i].wbb_reads = 1; + sys.L3[i].duty_cycle = 1; + sys.L3[i].merged_dir = false; + sys.L3[i].homenode_read_accesses = 1; + sys.L3[i].homenode_write_accesses = 1; + sys.L3[i].homenode_read_hits = 1; + sys.L3[i].homenode_write_hits = 1; + sys.L3[i].homenode_read_misses = 1; + sys.L3[i].homenode_write_misses = 1; + sys.L3[i].dir_duty_cycle = 1; + } + // system_NoC + for (i = 0; i <= 63; i++) { + sys.NoC[i].clockrate = 1; + sys.NoC[i].type = true; + sys.NoC[i].chip_coverage = 1; + sys.NoC[i].has_global_link = true; + strcpy(sys.NoC[i].topology, "default"); + sys.NoC[i].horizontal_nodes = 1; + sys.NoC[i].vertical_nodes = 1; + sys.NoC[i].input_ports = 1; + sys.NoC[i].output_ports = 1; + sys.NoC[i].virtual_channel_per_port = 1; + sys.NoC[i].flit_bits = 1; + sys.NoC[i].input_buffer_entries_per_vc = 1; + sys.NoC[i].total_accesses = 1; + sys.NoC[i].duty_cycle = 1; + sys.NoC[i].route_over_perc = 0.5; + for (j = 0; j < 20; j++) sys.NoC[i].ports_of_input_buffer[j] = 1; + sys.NoC[i].number_of_crossbars = 1; + strcpy(sys.NoC[i].crossbar_type, "default"); + strcpy(sys.NoC[i].crosspoint_type, "default"); + // system.NoC?.xbar0; + sys.NoC[i].xbar0.number_of_inputs_of_crossbars = 1; + sys.NoC[i].xbar0.number_of_outputs_of_crossbars = 1; + sys.NoC[i].xbar0.flit_bits = 1; + sys.NoC[i].xbar0.input_buffer_entries_per_port = 1; + sys.NoC[i].xbar0.ports_of_input_buffer[20] = 1; + sys.NoC[i].xbar0.crossbar_accesses = 1; + } + // system_mem + sys.mem.mem_tech_node = 1; + sys.mem.device_clock = 1; + sys.mem.capacity_per_channel = 1; + sys.mem.number_ranks = 1; + sys.mem.peak_transfer_rate = 1; + sys.mem.num_banks_of_DRAM_chip = 1; + sys.mem.Block_width_of_DRAM_chip = 1; + sys.mem.output_width_of_DRAM_chip = 1; + sys.mem.page_size_of_DRAM_chip = 1; + sys.mem.burstlength_of_DRAM_chip = 1; + sys.mem.internal_prefetch_of_DRAM_chip = 1; + sys.mem.memory_accesses = 1; + sys.mem.memory_reads = 1; + sys.mem.memory_writes = 1; - //system_mc - sys.mc.mc_clock =1; - sys.mc.number_mcs=1; - sys.mc.peak_transfer_rate =1; - sys.mc.memory_channels_per_mc=1; - sys.mc.number_ranks=1; - sys.mc.req_window_size_per_channel=1; - sys.mc.IO_buffer_size_per_channel=1; - sys.mc.databus_width=1; - sys.mc.addressbus_width=1; - sys.mc.memory_accesses=1; - sys.mc.memory_reads=1; - sys.mc.memory_writes=1; - sys.mc.LVDS=true; - sys.mc.type=1; + // system_mc + sys.mc.mc_clock = 1; + sys.mc.number_mcs = 1; + sys.mc.peak_transfer_rate = 1; + sys.mc.memory_channels_per_mc = 1; + sys.mc.number_ranks = 1; + sys.mc.req_window_size_per_channel = 1; + sys.mc.IO_buffer_size_per_channel = 1; + sys.mc.databus_width = 1; + sys.mc.addressbus_width = 1; + sys.mc.memory_accesses = 1; + sys.mc.memory_reads = 1; + sys.mc.memory_writes = 1; + sys.mc.LVDS = true; + sys.mc.type = 1; - //system_niu - sys.niu.clockrate =1; - sys.niu.number_units=1; - sys.niu.type = 1; - sys.niu.duty_cycle =1; - sys.niu.total_load_perc=1; - //system_pcie - sys.pcie.clockrate =1; - sys.pcie.number_units=1; - sys.pcie.num_channels=1; - sys.pcie.type = 1; - sys.pcie.withPHY = false; - sys.pcie.duty_cycle =1; - sys.pcie.total_load_perc=1; - //system_flash_controller - sys.flashc.mc_clock =1; - sys.flashc.number_mcs=1; - sys.flashc.peak_transfer_rate =1; - sys.flashc.memory_channels_per_mc=1; - sys.flashc.number_ranks=1; - sys.flashc.req_window_size_per_channel=1; - sys.flashc.IO_buffer_size_per_channel=1; - sys.flashc.databus_width=1; - sys.flashc.addressbus_width=1; - sys.flashc.memory_accesses=1; - sys.flashc.memory_reads=1; - sys.flashc.memory_writes=1; - sys.flashc.LVDS=true; - sys.flashc.withPHY = false; - sys.flashc.type =1; - sys.flashc.duty_cycle =1; - sys.flashc.total_load_perc=1; + // system_niu + sys.niu.clockrate = 1; + sys.niu.number_units = 1; + sys.niu.type = 1; + sys.niu.duty_cycle = 1; + sys.niu.total_load_perc = 1; + // system_pcie + sys.pcie.clockrate = 1; + sys.pcie.number_units = 1; + sys.pcie.num_channels = 1; + sys.pcie.type = 1; + sys.pcie.withPHY = false; + sys.pcie.duty_cycle = 1; + sys.pcie.total_load_perc = 1; + // system_flash_controller + sys.flashc.mc_clock = 1; + sys.flashc.number_mcs = 1; + sys.flashc.peak_transfer_rate = 1; + sys.flashc.memory_channels_per_mc = 1; + sys.flashc.number_ranks = 1; + sys.flashc.req_window_size_per_channel = 1; + sys.flashc.IO_buffer_size_per_channel = 1; + sys.flashc.databus_width = 1; + sys.flashc.addressbus_width = 1; + sys.flashc.memory_accesses = 1; + sys.flashc.memory_reads = 1; + sys.flashc.memory_writes = 1; + sys.flashc.LVDS = true; + sys.flashc.withPHY = false; + sys.flashc.type = 1; + sys.flashc.duty_cycle = 1; + sys.flashc.total_load_perc = 1; } diff --git a/src/gpuwattch/XML_Parse.h b/src/gpuwattch/XML_Parse.h index d2f82be..30c4e4b 100644 --- a/src/gpuwattch/XML_Parse.h +++ b/src/gpuwattch/XML_Parse.h @@ -27,662 +27,665 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.” * - ***************************************************************************/ + ***************************************************************************/ /******************************************************************** -* 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 * + ********************************************************************/ #ifndef XML_PARSE_H_ #define XML_PARSE_H_ - //#ifdef WIN32 //#define _CRT_SECURE_NO_DEPRECATE //#endif #include -#include "xmlParser.h" #include #include +#include "xmlParser.h" using namespace std; /* void myfree(char *t); // {free(t);} ToXMLStringTool tx,tx2; */ -//all subnodes at the level of system.core(0-n) -//cache_policy is added into cache property arrays;//0 no write or write-though with non-write allocate;1 write-back with write-allocate -// -//tgrogers - This was a static array declared in the header... -// Not too sure why the authors did this, maybe they didn't understand the context -// of the "static" keyword outside a class declaration. As it was written, each object file -// had it's own copy of the string list - which is okay, since the string is constant but -// wastes space and causes the compiler to complain about unused vars in files where this header -// is included but they don't use the variable. Now this is extern'd here and the storage/definition -// is in the XML_Parse.cc file -extern const char * perf_count_label[]; - +// all subnodes at the level of system.core(0-n) +// cache_policy is added into cache property arrays;//0 no write or write-though +// with non-write allocate;1 write-back with write-allocate +// +// tgrogers - This was a static array declared in the header... +// Not too sure why the authors did this, maybe they didn't understand +// the context of the "static" keyword outside a class declaration. As +// it was written, each object file had it's own copy of the string +// list - which is okay, since the string is constant but wastes space +// and causes the compiler to complain about unused vars in files +// where this header is included but they don't use the variable. Now +// this is extern'd here and the storage/definition is in the +// XML_Parse.cc file +extern const char* perf_count_label[]; + enum perf_count_t { - TOT_INST=0, - FP_INT, - IC_H, - IC_M, - DC_RH, - DC_RM, - DC_WH, - DC_WM, - TC_H, - TC_M, - CC_H, - CC_M, - SHRD_ACC, - REG_RD, - REG_WR, - NON_REG_OPs, - SP_ACC, - SFU_ACC, - FPU_ACC, - MEM_RD, - MEM_WR, - MEM_PRE, - L2_RH, - L2_RM, - L2_WH, - L2_WM, - NOC_A, - PIPE_A, - IDLE_CORE_N, - CONST_DYNAMICN, - NUM_PERFORMANCE_COUNTERS + TOT_INST = 0, + FP_INT, + IC_H, + IC_M, + DC_RH, + DC_RM, + DC_WH, + DC_WM, + TC_H, + TC_M, + CC_H, + CC_M, + SHRD_ACC, + REG_RD, + REG_WR, + NON_REG_OPs, + SP_ACC, + SFU_ACC, + FPU_ACC, + MEM_RD, + MEM_WR, + MEM_PRE, + L2_RH, + L2_RM, + L2_WH, + L2_WM, + NOC_A, + PIPE_A, + IDLE_CORE_N, + CONST_DYNAMICN, + NUM_PERFORMANCE_COUNTERS }; -typedef struct{ - int prediction_width; - char prediction_scheme[20]; - int predictor_size; - int predictor_entries; - int local_predictor_size[20]; - int local_predictor_entries; - int global_predictor_entries; - int global_predictor_bits; - int chooser_predictor_entries; - int chooser_predictor_bits; - double predictor_accesses; +typedef struct { + int prediction_width; + char prediction_scheme[20]; + int predictor_size; + int predictor_entries; + int local_predictor_size[20]; + int local_predictor_entries; + int global_predictor_entries; + int global_predictor_bits; + int chooser_predictor_entries; + int chooser_predictor_bits; + double predictor_accesses; } predictor_systemcore; -typedef struct{ - int number_entries; - int cache_policy;//0 no write or write-though with non-write allocate;1 write-back with write-allocate - double total_hits; - double total_accesses; - double total_misses; - double conflicts; +typedef struct { + int number_entries; + int cache_policy; // 0 no write or write-though with non-write allocate;1 + // write-back with write-allocate + double total_hits; + double total_accesses; + double total_misses; + double conflicts; } itlb_systemcore; -typedef struct{ - //params - double icache_config[20]; - int buffer_sizes[20]; - int cache_policy;//0 no write or write-though with non-write allocate;1 write-back with write-allocate - //stats - double total_accesses; - double read_accesses; - double read_misses; - double replacements; - double read_hits; - double total_hits; - double total_misses; - double miss_buffer_access; - double fill_buffer_accesses; - double prefetch_buffer_accesses; - double prefetch_buffer_writes; - double prefetch_buffer_reads; - double prefetch_buffer_hits; - double conflicts; +typedef struct { + // params + double icache_config[20]; + int buffer_sizes[20]; + int cache_policy; // 0 no write or write-though with non-write allocate;1 + // write-back with write-allocate + // stats + double total_accesses; + double read_accesses; + double read_misses; + double replacements; + double read_hits; + double total_hits; + double total_misses; + double miss_buffer_access; + double fill_buffer_accesses; + double prefetch_buffer_accesses; + double prefetch_buffer_writes; + double prefetch_buffer_reads; + double prefetch_buffer_hits; + double conflicts; } icache_systemcore; -typedef struct{ - //params - int number_entries; - int cache_policy;//0 no write or write-though with non-write allocate;1 write-back with write-allocate - //stats - double total_accesses; - double read_accesses; - double write_accesses; - double write_hits; - double read_hits; - double read_misses; - double write_misses; - double total_hits; - double total_misses; - double conflicts; +typedef struct { + // params + int number_entries; + int cache_policy; // 0 no write or write-though with non-write allocate;1 + // write-back with write-allocate + // stats + double total_accesses; + double read_accesses; + double write_accesses; + double write_hits; + double read_hits; + double read_misses; + double write_misses; + double total_hits; + double total_misses; + double conflicts; } dtlb_systemcore; -typedef struct{ - //params - double dcache_config[20]; - int buffer_sizes[20]; - int cache_policy;//0 no write or write-though with non-write allocate;1 write-back with write-allocate - //stats - double total_accesses; - double read_accesses; - double write_accesses; - double total_hits; - double total_misses; - double read_hits; - double write_hits; - double read_misses; - double write_misses; - double replacements; - double write_backs; - double miss_buffer_access; - double fill_buffer_accesses; - double prefetch_buffer_accesses; - double prefetch_buffer_writes; - double prefetch_buffer_reads; - double prefetch_buffer_hits; - double wbb_writes; - double wbb_reads; - double conflicts; +typedef struct { + // params + double dcache_config[20]; + int buffer_sizes[20]; + int cache_policy; // 0 no write or write-though with non-write allocate;1 + // write-back with write-allocate + // stats + double total_accesses; + double read_accesses; + double write_accesses; + double total_hits; + double total_misses; + double read_hits; + double write_hits; + double read_misses; + double write_misses; + double replacements; + double write_backs; + double miss_buffer_access; + double fill_buffer_accesses; + double prefetch_buffer_accesses; + double prefetch_buffer_writes; + double prefetch_buffer_reads; + double prefetch_buffer_hits; + double wbb_writes; + double wbb_reads; + double conflicts; } dcache_systemcore; -typedef struct{ - //params - int BTB_config[20]; - //stats - double total_accesses; - double read_accesses; - double write_accesses; - double total_hits; - double total_misses; - double read_hits; - double write_hits; - double read_misses; - double write_misses; - double replacements; +typedef struct { + // params + int BTB_config[20]; + // stats + double total_accesses; + double read_accesses; + double write_accesses; + double total_hits; + double total_misses; + double read_hits; + double write_hits; + double read_misses; + double write_misses; + double replacements; } BTB_systemcore; -typedef struct{ - //all params at the level of system.core(0-n) - int clock_rate; - bool opt_local; - bool x86; - int machine_bits; - int virtual_address_width; - int physical_address_width; - int opcode_width; - int micro_opcode_width; - int instruction_length; - int machine_type; - int internal_datapath_width; - int number_hardware_threads; - int fetch_width; - int number_instruction_fetch_ports; - int decode_width; - int issue_width; - int peak_issue_width; - int commit_width; - int pipelines_per_core[20]; - int pipeline_depth[20]; - char FPU[20]; - char divider_multiplier[20]; - int ALU_per_core; - double FPU_per_core; - int MUL_per_core; - int instruction_buffer_size; - int decoded_stream_buffer_size; - int instruction_window_scheme; - int instruction_window_size; - int fp_instruction_window_size; - int ROB_size; - int archi_Regs_IRF_size; - int archi_Regs_FRF_size; - int phy_Regs_IRF_size; - int phy_Regs_FRF_size; - int rename_scheme; - int register_windows_size; - char LSU_order[20]; - int store_buffer_size; - int load_buffer_size; - int memory_ports; - char Dcache_dual_pump[20]; - int RAS_size; - int fp_issue_width; - int prediction_width; - int number_of_BTB; - int number_of_BPT; - bool gpgpu_clock_gated_lanes; +typedef struct { + // all params at the level of system.core(0-n) + int clock_rate; + bool opt_local; + bool x86; + int machine_bits; + int virtual_address_width; + int physical_address_width; + int opcode_width; + int micro_opcode_width; + int instruction_length; + int machine_type; + int internal_datapath_width; + int number_hardware_threads; + int fetch_width; + int number_instruction_fetch_ports; + int decode_width; + int issue_width; + int peak_issue_width; + int commit_width; + int pipelines_per_core[20]; + int pipeline_depth[20]; + char FPU[20]; + char divider_multiplier[20]; + int ALU_per_core; + double FPU_per_core; + int MUL_per_core; + int instruction_buffer_size; + int decoded_stream_buffer_size; + int instruction_window_scheme; + int instruction_window_size; + int fp_instruction_window_size; + int ROB_size; + int archi_Regs_IRF_size; + int archi_Regs_FRF_size; + int phy_Regs_IRF_size; + int phy_Regs_FRF_size; + int rename_scheme; + int register_windows_size; + char LSU_order[20]; + int store_buffer_size; + int load_buffer_size; + int memory_ports; + char Dcache_dual_pump[20]; + int RAS_size; + int fp_issue_width; + int prediction_width; + int number_of_BTB; + int number_of_BPT; + bool gpgpu_clock_gated_lanes; - //all stats at the level of system.core(0-n) - double total_instructions; - double int_instructions; - double fp_instructions; - double branch_instructions; - double branch_mispredictions; - double committed_instructions; - double committed_int_instructions; - double committed_fp_instructions; - double load_instructions; - double store_instructions; - double total_cycles; - double idle_cycles; - double busy_cycles; - double instruction_buffer_reads; - double instruction_buffer_write; - double ROB_reads; - double ROB_writes; - double rename_accesses; - double fp_rename_accesses; - double rename_reads; - double rename_writes; - double fp_rename_reads; - double fp_rename_writes; - double inst_window_reads; - double inst_window_writes; - double inst_window_wakeup_accesses; - double inst_window_selections; - double fp_inst_window_reads; - double fp_inst_window_writes; - double fp_inst_window_wakeup_accesses; - double fp_inst_window_selections; - double archi_int_regfile_reads; - double archi_float_regfile_reads; - double phy_int_regfile_reads; - double phy_float_regfile_reads; - double phy_int_regfile_writes; - double phy_float_regfile_writes; - double archi_int_regfile_writes; - double archi_float_regfile_writes; - double int_regfile_reads; - double float_regfile_reads; - double int_regfile_writes; - double float_regfile_writes; - double non_rf_operands; - double windowed_reg_accesses; - double windowed_reg_transports; - double function_calls; - double context_switches; - double ialu_accesses; - double fpu_accesses; - double mul_accesses; - double sp_average_active_lanes; - double sfu_average_active_lanes; - double cdb_alu_accesses; - double cdb_mul_accesses; - double cdb_fpu_accesses; - double load_buffer_reads; - double load_buffer_writes; - double load_buffer_cams; - double store_buffer_reads; - double store_buffer_writes; - double store_buffer_cams; - double store_buffer_forwards; - double main_memory_access; - double main_memory_read; - double main_memory_write; - double pipeline_duty_cycle; + // all stats at the level of system.core(0-n) + double total_instructions; + double int_instructions; + double fp_instructions; + double branch_instructions; + double branch_mispredictions; + double committed_instructions; + double committed_int_instructions; + double committed_fp_instructions; + double load_instructions; + double store_instructions; + double total_cycles; + double idle_cycles; + double busy_cycles; + double instruction_buffer_reads; + double instruction_buffer_write; + double ROB_reads; + double ROB_writes; + double rename_accesses; + double fp_rename_accesses; + double rename_reads; + double rename_writes; + double fp_rename_reads; + double fp_rename_writes; + double inst_window_reads; + double inst_window_writes; + double inst_window_wakeup_accesses; + double inst_window_selections; + double fp_inst_window_reads; + double fp_inst_window_writes; + double fp_inst_window_wakeup_accesses; + double fp_inst_window_selections; + double archi_int_regfile_reads; + double archi_float_regfile_reads; + double phy_int_regfile_reads; + double phy_float_regfile_reads; + double phy_int_regfile_writes; + double phy_float_regfile_writes; + double archi_int_regfile_writes; + double archi_float_regfile_writes; + double int_regfile_reads; + double float_regfile_reads; + double int_regfile_writes; + double float_regfile_writes; + double non_rf_operands; + double windowed_reg_accesses; + double windowed_reg_transports; + double function_calls; + double context_switches; + double ialu_accesses; + double fpu_accesses; + double mul_accesses; + double sp_average_active_lanes; + double sfu_average_active_lanes; + double cdb_alu_accesses; + double cdb_mul_accesses; + double cdb_fpu_accesses; + double load_buffer_reads; + double load_buffer_writes; + double load_buffer_cams; + double store_buffer_reads; + double store_buffer_writes; + double store_buffer_cams; + double store_buffer_forwards; + double main_memory_access; + double main_memory_read; + double main_memory_write; + double pipeline_duty_cycle; - double IFU_duty_cycle ; - double BR_duty_cycle ; - double LSU_duty_cycle ; - double MemManU_I_duty_cycle; - double MemManU_D_duty_cycle ; - double ALU_duty_cycle ; - double MUL_duty_cycle ; - double FPU_duty_cycle ; - double ALU_cdb_duty_cycle ; - double MUL_cdb_duty_cycle ; - double FPU_cdb_duty_cycle ; + double IFU_duty_cycle; + double BR_duty_cycle; + double LSU_duty_cycle; + double MemManU_I_duty_cycle; + double MemManU_D_duty_cycle; + double ALU_duty_cycle; + double MUL_duty_cycle; + double FPU_duty_cycle; + double ALU_cdb_duty_cycle; + double MUL_cdb_duty_cycle; + double FPU_cdb_duty_cycle; - double num_idle_cores; + double num_idle_cores; + int rf_banks; // (4) + int simd_width; // (8) + int collector_units; // (4) + double core_clock_ratio; // (2.0) + int warp_size; // (32) - int rf_banks;// (4) - int simd_width;// (8) - int collector_units;// (4) - double core_clock_ratio;// (2.0) - int warp_size;// (32) - - //all subnodes at the level of system.core(0-n) - predictor_systemcore predictor; - itlb_systemcore itlb; - icache_systemcore icache; - dtlb_systemcore dtlb; - dcache_systemcore dcache; - dcache_systemcore ccache; - dcache_systemcore tcache; - dcache_systemcore sharedmemory; // added by Jingwen - BTB_systemcore BTB; + // all subnodes at the level of system.core(0-n) + predictor_systemcore predictor; + itlb_systemcore itlb; + icache_systemcore icache; + dtlb_systemcore dtlb; + dcache_systemcore dcache; + dcache_systemcore ccache; + dcache_systemcore tcache; + dcache_systemcore sharedmemory; // added by Jingwen + BTB_systemcore BTB; } system_core; -typedef struct{ - //params - int Directory_type; - double Dir_config[20]; - int buffer_sizes[20]; - int clockrate; - int ports[20]; - int device_type; - int cache_policy;//0 no write or write-though with non-write allocate;1 write-back with write-allocate - char threeD_stack[20]; - //stats - double total_accesses; - double read_accesses; - double write_accesses; - double read_misses; - double write_misses; - double conflicts; - double duty_cycle; +typedef struct { + // params + int Directory_type; + double Dir_config[20]; + int buffer_sizes[20]; + int clockrate; + int ports[20]; + int device_type; + int cache_policy; // 0 no write or write-though with non-write allocate;1 + // write-back with write-allocate + char threeD_stack[20]; + // stats + double total_accesses; + double read_accesses; + double write_accesses; + double read_misses; + double write_misses; + double conflicts; + double duty_cycle; } system_L1Directory; -typedef struct{ - //params - int Directory_type; - double Dir_config[20]; - int buffer_sizes[20]; - int clockrate; - int ports[20]; - int device_type; - int cache_policy;//0 no write or write-though with non-write allocate;1 write-back with write-allocate - char threeD_stack[20]; - //stats - double total_accesses; - double read_accesses; - double write_accesses; - double read_misses; - double write_misses; - double conflicts; - double duty_cycle; +typedef struct { + // params + int Directory_type; + double Dir_config[20]; + int buffer_sizes[20]; + int clockrate; + int ports[20]; + int device_type; + int cache_policy; // 0 no write or write-though with non-write allocate;1 + // write-back with write-allocate + char threeD_stack[20]; + // stats + double total_accesses; + double read_accesses; + double write_accesses; + double read_misses; + double write_misses; + double conflicts; + double duty_cycle; } system_L2Directory; -typedef struct{ - //params - double L2_config[20]; - int clockrate; - int ports[20]; - int device_type; - int cache_policy;//0 no write or write-though with non-write allocate;1 write-back with write-allocate - char threeD_stack[20]; - int buffer_sizes[20]; - //stats - double total_accesses; - double read_accesses; - double write_accesses; - double total_hits; - double total_misses; - double read_hits; - double write_hits; - double read_misses; - double write_misses; - double replacements; - double write_backs; - double miss_buffer_accesses; - double fill_buffer_accesses; - double prefetch_buffer_accesses; - double prefetch_buffer_writes; - double prefetch_buffer_reads; - double prefetch_buffer_hits; - double wbb_writes; - double wbb_reads; - double conflicts; - double duty_cycle; +typedef struct { + // params + double L2_config[20]; + int clockrate; + int ports[20]; + int device_type; + int cache_policy; // 0 no write or write-though with non-write allocate;1 + // write-back with write-allocate + char threeD_stack[20]; + int buffer_sizes[20]; + // stats + double total_accesses; + double read_accesses; + double write_accesses; + double total_hits; + double total_misses; + double read_hits; + double write_hits; + double read_misses; + double write_misses; + double replacements; + double write_backs; + double miss_buffer_accesses; + double fill_buffer_accesses; + double prefetch_buffer_accesses; + double prefetch_buffer_writes; + double prefetch_buffer_reads; + double prefetch_buffer_hits; + double wbb_writes; + double wbb_reads; + double conflicts; + double duty_cycle; - bool merged_dir; - double homenode_read_accesses; - double homenode_write_accesses; - double homenode_read_hits; - double homenode_write_hits; - double homenode_read_misses; - double homenode_write_misses; - double dir_duty_cycle; + bool merged_dir; + double homenode_read_accesses; + double homenode_write_accesses; + double homenode_read_hits; + double homenode_write_hits; + double homenode_read_misses; + double homenode_write_misses; + double dir_duty_cycle; } system_L2; -typedef struct{ - //params - double L3_config[20]; - int clockrate; - int ports[20]; - int device_type; - int cache_policy;//0 no write or write-though with non-write allocate;1 write-back with write-allocate - char threeD_stack[20]; - int buffer_sizes[20]; - //stats - double total_accesses; - double read_accesses; - double write_accesses; - double total_hits; - double total_misses; - double read_hits; - double write_hits; - double read_misses; - double write_misses; - double replacements; - double write_backs; - double miss_buffer_accesses; - double fill_buffer_accesses; - double prefetch_buffer_accesses; - double prefetch_buffer_writes; - double prefetch_buffer_reads; - double prefetch_buffer_hits; - double wbb_writes; - double wbb_reads; - double conflicts; - double duty_cycle; +typedef struct { + // params + double L3_config[20]; + int clockrate; + int ports[20]; + int device_type; + int cache_policy; // 0 no write or write-though with non-write allocate;1 + // write-back with write-allocate + char threeD_stack[20]; + int buffer_sizes[20]; + // stats + double total_accesses; + double read_accesses; + double write_accesses; + double total_hits; + double total_misses; + double read_hits; + double write_hits; + double read_misses; + double write_misses; + double replacements; + double write_backs; + double miss_buffer_accesses; + double fill_buffer_accesses; + double prefetch_buffer_accesses; + double prefetch_buffer_writes; + double prefetch_buffer_reads; + double prefetch_buffer_hits; + double wbb_writes; + double wbb_reads; + double conflicts; + double duty_cycle; - bool merged_dir; - double homenode_read_accesses; - double homenode_write_accesses; - double homenode_read_hits; - double homenode_write_hits; - double homenode_read_misses; - double homenode_write_misses; - double dir_duty_cycle; + bool merged_dir; + double homenode_read_accesses; + double homenode_write_accesses; + double homenode_read_hits; + double homenode_write_hits; + double homenode_read_misses; + double homenode_write_misses; + double dir_duty_cycle; } system_L3; -typedef struct{ - //params - int number_of_inputs_of_crossbars; - int number_of_outputs_of_crossbars; - int flit_bits; - int input_buffer_entries_per_port; - int ports_of_input_buffer[20]; - //stats - double crossbar_accesses; +typedef struct { + // params + int number_of_inputs_of_crossbars; + int number_of_outputs_of_crossbars; + int flit_bits; + int input_buffer_entries_per_port; + int ports_of_input_buffer[20]; + // stats + double crossbar_accesses; } xbar0_systemNoC; -typedef struct{ - //params - int clockrate; - bool type; - bool has_global_link; - char topology[20]; - int horizontal_nodes; - int vertical_nodes; - int link_throughput; - int link_latency; - int input_ports; - int output_ports; - int virtual_channel_per_port; - int flit_bits; - int input_buffer_entries_per_vc; - int ports_of_input_buffer[20]; - int dual_pump; - int number_of_crossbars; - char crossbar_type[20]; - char crosspoint_type[20]; - xbar0_systemNoC xbar0; - int arbiter_type; - double chip_coverage; - //stats - double total_accesses; - double duty_cycle; - double route_over_perc; +typedef struct { + // params + int clockrate; + bool type; + bool has_global_link; + char topology[20]; + int horizontal_nodes; + int vertical_nodes; + int link_throughput; + int link_latency; + int input_ports; + int output_ports; + int virtual_channel_per_port; + int flit_bits; + int input_buffer_entries_per_vc; + int ports_of_input_buffer[20]; + int dual_pump; + int number_of_crossbars; + char crossbar_type[20]; + char crosspoint_type[20]; + xbar0_systemNoC xbar0; + int arbiter_type; + double chip_coverage; + // stats + double total_accesses; + double duty_cycle; + double route_over_perc; } system_NoC; -typedef struct{ - //params - int mem_tech_node; - int device_clock; - int peak_transfer_rate; - int internal_prefetch_of_DRAM_chip; - int capacity_per_channel; - int number_ranks; - int num_banks_of_DRAM_chip; - int Block_width_of_DRAM_chip; - int output_width_of_DRAM_chip; - int page_size_of_DRAM_chip; - int burstlength_of_DRAM_chip; - - //stats - double memory_accesses; - double memory_reads; - double memory_writes; - double dram_pre; +typedef struct { + // params + int mem_tech_node; + int device_clock; + int peak_transfer_rate; + int internal_prefetch_of_DRAM_chip; + int capacity_per_channel; + int number_ranks; + int num_banks_of_DRAM_chip; + int Block_width_of_DRAM_chip; + int output_width_of_DRAM_chip; + int page_size_of_DRAM_chip; + int burstlength_of_DRAM_chip; + + // stats + double memory_accesses; + double memory_reads; + double memory_writes; + double dram_pre; } system_mem; -typedef struct{ - //params - //Common Param for mc and fc - double peak_transfer_rate; - int number_mcs; - bool withPHY; - int type; +typedef struct { + // params + // Common Param for mc and fc + double peak_transfer_rate; + int number_mcs; + bool withPHY; + int type; - //FCParam - //stats - double duty_cycle; - double total_load_perc; + // FCParam + // stats + double duty_cycle; + double total_load_perc; - //McParam - int mc_clock; - int llc_line_length; - int memory_channels_per_mc; - int number_ranks; - int req_window_size_per_channel; - int IO_buffer_size_per_channel; - int databus_width; - int addressbus_width; - int PRT_entries; - bool LVDS; - - // emprical DRAM coeff - double dram_cmd_coeff; - double dram_act_coeff; - double dram_nop_coeff; - double dram_activity_coeff; - double dram_pre_coeff; - double dram_rd_coeff; - double dram_wr_coeff; - double dram_req_coeff; - double dram_const_coeff; + // McParam + int mc_clock; + int llc_line_length; + int memory_channels_per_mc; + int number_ranks; + int req_window_size_per_channel; + int IO_buffer_size_per_channel; + int databus_width; + int addressbus_width; + int PRT_entries; + bool LVDS; - //stats - double memory_accesses; - double memory_reads; - double memory_writes; + // emprical DRAM coeff + double dram_cmd_coeff; + double dram_act_coeff; + double dram_nop_coeff; + double dram_activity_coeff; + double dram_pre_coeff; + double dram_rd_coeff; + double dram_wr_coeff; + double dram_req_coeff; + double dram_const_coeff; - //dram stats - double dram_cmd; - double dram_activity; - double dram_nop; - double dram_act; - double dram_pre; - double dram_rd; - double dram_wr; - double dram_req; + // stats + double memory_accesses; + double memory_reads; + double memory_writes; + // dram stats + double dram_cmd; + double dram_activity; + double dram_nop; + double dram_act; + double dram_pre; + double dram_rd; + double dram_wr; + double dram_req; } system_mc; -typedef struct{ - //params - int clockrate; - int number_units; - int type; - //stats - double duty_cycle; - double total_load_perc; +typedef struct { + // params + int clockrate; + int number_units; + int type; + // stats + double duty_cycle; + double total_load_perc; } system_niu; -typedef struct{ - //params - int clockrate; - int number_units; - int num_channels; - int type; - bool withPHY; - //stats - double duty_cycle; - double total_load_perc; +typedef struct { + // params + int clockrate; + int number_units; + int num_channels; + int type; + bool withPHY; + // stats + double duty_cycle; + double total_load_perc; } system_pcie; -typedef struct{ - //All number_of_* at the level of 'system' Ying 03/21/2009 - int GPU_Architecture; - int number_of_cores; - int architecture; - int number_of_L1Directories; - int number_of_L2Directories; - int number_of_L2s; - bool Private_L2; - int number_of_L3s; - int number_of_NoCs; - int number_of_dir_levels; - int domain_size; - int first_level_dir; - // All params at the level of 'system' - int homogeneous_cores; - int homogeneous_L1Directories; - int homogeneous_L2Directories; - double core_tech_node; - int target_core_clockrate; - int target_chip_area; - int temperature; - int number_cache_levels; - int L1_property; - int L2_property; - int homogeneous_L2s; - int L3_property; - int homogeneous_L3s; - int homogeneous_NoCs; - int homogeneous_ccs; - int Max_area_deviation; - int Max_power_deviation; - int device_type; - bool longer_channel_device; - bool Embedded; - bool opt_dynamic_power; - bool opt_lakage_power; - bool opt_clockrate; - bool opt_area; - int interconnect_projection_type; - int machine_bits; - int virtual_address_width; - int physical_address_width; - int virtual_memory_page_size; - double idle_core_power; - double num_idle_cores; - int arch; - double total_cycles; - //system.core(0-n):3rd level - double scaling_coefficients[64]; - system_core core[64]; - system_L1Directory L1Directory[64]; - system_L2Directory L2Directory[64]; - system_L2 L2[64]; - system_L2 l2; - system_L3 L3[64]; - system_NoC NoC[64]; - system_mem mem; - system_mc mc; - system_mc flashc; - system_niu niu; - system_pcie pcie; +typedef struct { + // All number_of_* at the level of 'system' Ying 03/21/2009 + int GPU_Architecture; + int number_of_cores; + int architecture; + int number_of_L1Directories; + int number_of_L2Directories; + int number_of_L2s; + bool Private_L2; + int number_of_L3s; + int number_of_NoCs; + int number_of_dir_levels; + int domain_size; + int first_level_dir; + // All params at the level of 'system' + int homogeneous_cores; + int homogeneous_L1Directories; + int homogeneous_L2Directories; + double core_tech_node; + int target_core_clockrate; + int target_chip_area; + int temperature; + int number_cache_levels; + int L1_property; + int L2_property; + int homogeneous_L2s; + int L3_property; + int homogeneous_L3s; + int homogeneous_NoCs; + int homogeneous_ccs; + int Max_area_deviation; + int Max_power_deviation; + int device_type; + bool longer_channel_device; + bool Embedded; + bool opt_dynamic_power; + bool opt_lakage_power; + bool opt_clockrate; + bool opt_area; + int interconnect_projection_type; + int machine_bits; + int virtual_address_width; + int physical_address_width; + int virtual_memory_page_size; + double idle_core_power; + double num_idle_cores; + int arch; + double total_cycles; + // system.core(0-n):3rd level + double scaling_coefficients[64]; + system_core core[64]; + system_L1Directory L1Directory[64]; + system_L2Directory L2Directory[64]; + system_L2 L2[64]; + system_L2 l2; + system_L3 L3[64]; + system_NoC NoC[64]; + system_mem mem; + system_mc mc; + system_mc flashc; + system_niu niu; + system_pcie pcie; } root_system; -class ParseXML -{ -public: - void parse(char* filepath); - void initialize(); -public: - root_system sys; -}; +class ParseXML { + public: + void parse(char* filepath); + void initialize(); + public: + root_system sys; +}; #endif /* XML_PARSE_H_ */ - - - - diff --git a/src/gpuwattch/arch_const.h b/src/gpuwattch/arch_const.h index feffa6c..555cc17 100644 --- a/src/gpuwattch/arch_const.h +++ b/src/gpuwattch/arch_const.h @@ -32,202 +32,189 @@ #ifndef ARCH_CONST_H_ #define ARCH_CONST_H_ -typedef struct{ - unsigned int capacity; - unsigned int assoc;//fully - unsigned int blocksize; +typedef struct { + unsigned int capacity; + unsigned int assoc; // fully + unsigned int blocksize; } array_inputs; -//Do Not change, unless you want to bypass the XML interface and do not care about the default values. -//Global parameters -const int number_of_cores = 8; -const int number_of_L2s = 1; -const int number_of_L3s = 1; -const int number_of_NoCs = 1; - -const double archi_F_sz_nm = 90.0; -const unsigned int dev_type = 0; -const double CLOCKRATE = 1.2*1e9; -const double AF = 0.5; -//const bool inorder = true; -const bool embedded = false; //NEW - -const bool homogeneous_cores = true; -const bool temperature = 360; -const int number_cache_levels = 3; -const int L1_property = 0; //private 0; coherent 1, shared 2. -const int L2_property = 2; -const bool homogeneous_L2s = true; -const bool L3_property = 2; -const bool homogeneous_L3s = true; -const double Max_area_deviation = 50; -const double Max_dynamic_deviation =50; //New -const int opt_dynamic_power = 1; -const int opt_lakage_power = 0; -const int opt_area = 0; -const int interconnect_projection_type = 0; +// Do Not change, unless you want to bypass the XML interface and do not care +// about the default values. Global parameters +const int number_of_cores = 8; +const int number_of_L2s = 1; +const int number_of_L3s = 1; +const int number_of_NoCs = 1; + +const double archi_F_sz_nm = 90.0; +const unsigned int dev_type = 0; +const double CLOCKRATE = 1.2 * 1e9; +const double AF = 0.5; +// const bool inorder = true; +const bool embedded = false; // NEW + +const bool homogeneous_cores = true; +const bool temperature = 360; +const int number_cache_levels = 3; +const int L1_property = 0; // private 0; coherent 1, shared 2. +const int L2_property = 2; +const bool homogeneous_L2s = true; +const bool L3_property = 2; +const bool homogeneous_L3s = true; +const double Max_area_deviation = 50; +const double Max_dynamic_deviation = 50; // New +const int opt_dynamic_power = 1; +const int opt_lakage_power = 0; +const int opt_area = 0; +const int interconnect_projection_type = 0; //******************************Core Parameters #if (inorder) -const int opcode_length = 8;//Niagara -const int reg_length = 5;//Niagara -const int instruction_length = 32;//Niagara -const int data_width = 64; +const int opcode_length = 8; // Niagara +const int reg_length = 5; // Niagara +const int instruction_length = 32; // Niagara +const int data_width = 64; #else -const int opcode_length = 8;//16;//Niagara -const int reg_length = 7;//Niagara -const int instruction_length = 32;//Niagara -const int data_width = 64; +const int opcode_length = 8; // 16;//Niagara +const int reg_length = 7; // Niagara +const int instruction_length = 32; // Niagara +const int data_width = 64; #endif - -//Caches -//itlb -const int itlbsize=512; -const int itlbassoc=0;//fully -const int itlbblocksize=8; -//icache -const int icachesize=32768; -const int icacheassoc=4; -const int icacheblocksize=32; -//dtlb -const int dtlbsize=512; -const int dtlbassoc=0;//fully -const int dtlbblocksize=8; -//dcache -const int dcachesize=32768; -const int dcacheassoc=4; -const int dcacheblocksize=32; -const int dcache_write_buffers=8; - -//cache controllers -//IB, -const int numIBEntries = 64; -const int IBsize = 64;//2*4*instruction_length/8*2; -const int IBassoc = 0;//In Niagara it is still fully associ -const int IBblocksize = 4; - -//IFB and MIL should have the same parameters CAM -const int IFBsize=128;// -const int IFBassoc=0;//In Niagara it is still fully associ -const int IFBblocksize=4; - - - - -const int icache_write_buffers=8; - -//register file RAM -const int regfilesize=5760; -const int regfileassoc=1; -const int regfileblocksize=18; -//regwin RAM -const int regwinsize=256; -const int regwinassoc=1; -const int regwinblocksize=8; - - - -//store buffer, lsq -const int lsqsize=512; -const int lsqassoc=0; -const int lsqblocksize=8; - -//data fill queue RAM -const int dfqsize=1024; -const int dfqassoc=1; -const int dfqblocksize=16; - -//outside the cores -//L2 cache bank -const int l2cachesize=262144; -const int l2cacheassoc=16; -const int l2cacheblocksize=64; - -//L2 directory -const int l2dirsize=1024; -const int l2dirassoc=0; -const int l2dirblocksize=2; - -//crossbar -//PCX +// Caches +// itlb +const int itlbsize = 512; +const int itlbassoc = 0; // fully +const int itlbblocksize = 8; +// icache +const int icachesize = 32768; +const int icacheassoc = 4; +const int icacheblocksize = 32; +// dtlb +const int dtlbsize = 512; +const int dtlbassoc = 0; // fully +const int dtlbblocksize = 8; +// dcache +const int dcachesize = 32768; +const int dcacheassoc = 4; +const int dcacheblocksize = 32; +const int dcache_write_buffers = 8; + +// cache controllers +// IB, +const int numIBEntries = 64; +const int IBsize = 64; // 2*4*instruction_length/8*2; +const int IBassoc = 0; // In Niagara it is still fully associ +const int IBblocksize = 4; + +// IFB and MIL should have the same parameters CAM +const int IFBsize = 128; // +const int IFBassoc = 0; // In Niagara it is still fully associ +const int IFBblocksize = 4; + +const int icache_write_buffers = 8; + +// register file RAM +const int regfilesize = 5760; +const int regfileassoc = 1; +const int regfileblocksize = 18; +// regwin RAM +const int regwinsize = 256; +const int regwinassoc = 1; +const int regwinblocksize = 8; + +// store buffer, lsq +const int lsqsize = 512; +const int lsqassoc = 0; +const int lsqblocksize = 8; + +// data fill queue RAM +const int dfqsize = 1024; +const int dfqassoc = 1; +const int dfqblocksize = 16; + +// outside the cores +// L2 cache bank +const int l2cachesize = 262144; +const int l2cacheassoc = 16; +const int l2cacheblocksize = 64; + +// L2 directory +const int l2dirsize = 1024; +const int l2dirassoc = 0; +const int l2dirblocksize = 2; + +// crossbar +// PCX const int PCX_NUMBER_INPUT_PORTS_CROSSBAR = 8; const int PCX_NUMBER_OUTPUT_PORTS_CROSSBAR = 9; -const int PCX_NUMBER_SIGNALS_PER_PORT_CROSSBAR =144; -//PCX buffer RAM -const int pcx_buffersize=1024; -const int pcx_bufferassoc=1; -const int pcx_bufferblocksize=32; -const int pcx_numbuffer=5; -//pcx arbiter -const int pcx_arbsize=128; -const int pcx_arbassoc=1; -const int pcx_arbblocksize=2; -const int pcx_numarb=5; - -//CPX +const int PCX_NUMBER_SIGNALS_PER_PORT_CROSSBAR = 144; +// PCX buffer RAM +const int pcx_buffersize = 1024; +const int pcx_bufferassoc = 1; +const int pcx_bufferblocksize = 32; +const int pcx_numbuffer = 5; +// pcx arbiter +const int pcx_arbsize = 128; +const int pcx_arbassoc = 1; +const int pcx_arbblocksize = 2; +const int pcx_numarb = 5; + +// CPX const int CPX_NUMBER_INPUT_PORTS_CROSSBAR = 5; const int CPX_NUMBER_OUTPUT_PORTS_CROSSBAR = 8; -const int CPX_NUMBER_SIGNALS_PER_PORT_CROSSBAR =150; -//CPX buffer RAM -const int cpx_buffersize=1024; -const int cpx_bufferassoc=1; -const int cpx_bufferblocksize=32; -const int cpx_numbuffer=8; -//cpx arbiter -const int cpx_arbsize=128; -const int cpx_arbassoc=1; -const int cpx_arbblocksize=2; -const int cpx_numarb=8; - - - - - -const int numPhysFloatRegs=256; -const int numPhysIntRegs=32; -const int numROBEntries=192; -const int umRobs=1; - -const int BTBEntries=4096; -const int BTBTagSize=16; -const int LFSTSize=1024; -const int LQEntries=32; -const int RASSize=16; -const int SQEntries=32; -const int SSITSize=1024; -const int activity=0; -const int backComSize=5; -const int cachePorts=200; -const int choiceCtrBits=2; -const int choicePredictorSize=8192; - - -const int commitWidth=8; -const int decodeWidth=8; -const int dispatchWidth=8; -const int fetchWidth=8; -const int issueWidth=1; -const int renameWidth=8; -//what is this forwardComSize=5?? - -const int globalCtrBits=2; -const int globalHistoryBits=13; -const int globalPredictorSize=8192; - - - -const int localCtrBits=2; -const int localHistoryBits=11; -const int localHistoryTableSize=2048; -const int localPredictorSize=2048; - -const double Woutdrvnandn =30 *0.09;//(24.0 * LSCALE) -const double Woutdrvnandp =12.5 *0.09;//(10.0 * LSCALE) -const double Woutdrvnorn =7.5*0.09;//(6.0 * LSCALE) -const double Woutdrvnorp =50 * 0.09;// (40.0 * LSCALE) -const double Woutdrivern =60*0.09;//(48.0 * LSCALE) -const double Woutdriverp =100 * 0.09;//(80.0 * LSCALE) +const int CPX_NUMBER_SIGNALS_PER_PORT_CROSSBAR = 150; +// CPX buffer RAM +const int cpx_buffersize = 1024; +const int cpx_bufferassoc = 1; +const int cpx_bufferblocksize = 32; +const int cpx_numbuffer = 8; +// cpx arbiter +const int cpx_arbsize = 128; +const int cpx_arbassoc = 1; +const int cpx_arbblocksize = 2; +const int cpx_numarb = 8; + +const int numPhysFloatRegs = 256; +const int numPhysIntRegs = 32; +const int numROBEntries = 192; +const int umRobs = 1; + +const int BTBEntries = 4096; +const int BTBTagSize = 16; +const int LFSTSize = 1024; +const int LQEntries = 32; +const int RASSize = 16; +const int SQEntries = 32; +const int SSITSize = 1024; +const int activity = 0; +const int backComSize = 5; +const int cachePorts = 200; +const int choiceCtrBits = 2; +const int choicePredictorSize = 8192; + +const int commitWidth = 8; +const int decodeWidth = 8; +const int dispatchWidth = 8; +const int fetchWidth = 8; +const int issueWidth = 1; +const int renameWidth = 8; +// what is this forwardComSize=5?? + +const int globalCtrBits = 2; +const int globalHistoryBits = 13; +const int globalPredictorSize = 8192; + +const int localCtrBits = 2; +const int localHistoryBits = 11; +const int localHistoryTableSize = 2048; +const int localPredictorSize = 2048; + +const double Woutdrvnandn = 30 * 0.09; //(24.0 * LSCALE) +const double Woutdrvnandp = 12.5 * 0.09; //(10.0 * LSCALE) +const double Woutdrvnorn = 7.5 * 0.09; //(6.0 * LSCALE) +const double Woutdrvnorp = 50 * 0.09; // (40.0 * LSCALE) +const double Woutdrivern = 60 * 0.09; //(48.0 * LSCALE) +const double Woutdriverp = 100 * 0.09; //(80.0 * LSCALE) /* smtCommitPolicy=RoundRobin @@ -270,7 +257,6 @@ mem_side=system.tol2bus.port[2] */ //[system.cpu0.dtb] -//type=AlphaDT - +// type=AlphaDT #endif /* ARCH_CONST_H_ */ diff --git a/src/gpuwattch/array.cc b/src/gpuwattch/array.cc index a67e857..6cb2f3b 100644 --- a/src/gpuwattch/array.cc +++ b/src/gpuwattch/array.cc @@ -29,273 +29,281 @@ * ***************************************************************************/ -#define GLOBALVAR -#include "cacti/area.h" -#include "decoder.h" -#include "parameter.h" +#define GLOBALVAR #include "array.h" -#include -#include #include +#include +#include +#include "cacti/area.h" +#include "decoder.h" #include "globalvar.h" +#include "parameter.h" using namespace std; -ArrayST::ArrayST(const InputParameter *configure_interface, - string _name, - enum Device_ty device_ty_, - bool opt_local_, - enum Core_type core_ty_, - bool _is_default) -:l_ip(*configure_interface), - name(_name), - device_ty(device_ty_), - opt_local(opt_local_), - core_ty(core_ty_), - is_default(_is_default) - { - - if (l_ip.cache_sz<64) l_ip.cache_sz=64; - l_ip.error_checking();//not only do the error checking but also fill some missing parameters - optimize_array(); +ArrayST::ArrayST(const InputParameter *configure_interface, string _name, + enum Device_ty device_ty_, bool opt_local_, + enum Core_type core_ty_, bool _is_default) + : l_ip(*configure_interface), + name(_name), + device_ty(device_ty_), + opt_local(opt_local_), + core_ty(core_ty_), + is_default(_is_default) { + if (l_ip.cache_sz < 64) l_ip.cache_sz = 64; + l_ip.error_checking(); // not only do the error checking but also fill some + // missing parameters + optimize_array(); +} +void ArrayST::compute_base_power() { + // l_ip.out_w =l_ip.line_sz*8; + local_result = cacti_interface(&l_ip); } +void ArrayST::optimize_array() { + list candidate_solutions(0); + list::iterator candidate_iter, min_dynamic_energy_iter; + + uca_org_t *temp_res = 0; + local_result.valid = false; + + double throughput = l_ip.throughput, latency = l_ip.latency; + double area_efficiency_threshold = 20.0; + bool throughput_overflow = true, latency_overflow = true; + compute_base_power(); + + if ((local_result.cycle_time - throughput) <= 1e-10) + throughput_overflow = false; + if ((local_result.access_time - latency) <= 1e-10) latency_overflow = false; + + if (opt_for_clk && opt_local) { + if (throughput_overflow || latency_overflow) { + l_ip.ed = 0; + + l_ip.delay_wt = 100; // Fixed number, make sure timing can be satisfied. + l_ip.cycle_time_wt = 1000; + + l_ip.area_wt = 10; // Fixed number, This is used to exhaustive search for + // individual components. + l_ip.dynamic_power_wt = 10; // Fixed number, This is used to exhaustive + // search for individual components. + l_ip.leakage_power_wt = 10; + + l_ip.delay_dev = + 1000000; // Fixed number, make sure timing can be satisfied. + l_ip.cycle_time_dev = 100; + + l_ip.area_dev = 1000000; // Fixed number, This is used to exhaustive + // search for individual components. + l_ip.dynamic_power_dev = + 1000000; // Fixed number, This is used to exhaustive search for + // individual components. + l_ip.leakage_power_dev = 1000000; + + throughput_overflow = + true; // Reset overflow flag before start optimization iterations + latency_overflow = true; + + temp_res = &local_result; // Clean up the result for optimized for ED^2P + temp_res->cleanup(); + } -void ArrayST::compute_base_power() + while ((throughput_overflow || latency_overflow) && + l_ip.cycle_time_dev > 10) // && l_ip.delay_dev > 10 { - //l_ip.out_w =l_ip.line_sz*8; - local_result=cacti_interface(&l_ip); + compute_base_power(); + + l_ip.cycle_time_dev -= + 10; // This is the time_dev to be used for next iteration + + // from best area to worst area -->worst timing to best + // timing + if ((((local_result.cycle_time - throughput) <= 1e-10) && + (local_result.access_time - latency) <= 1e-10) || + (local_result.data_array2->area_efficiency < + area_efficiency_threshold && + l_ip.assoc == 0)) { // if no satisfiable solution is found,the most + // aggressive one is left + candidate_solutions.push_back(local_result); + // output_data_csv(candidate_solutions.back()); + if (((local_result.cycle_time - throughput) <= 1e-10) && + ((local_result.access_time - latency) <= 1e-10)) + // ensure stop opt not because of cam + { + throughput_overflow = false; + latency_overflow = false; + } + + } else { + // TODO: whether checking the partial satisfied results too, or just + // change the mark??? + if ((local_result.cycle_time - throughput) <= 1e-10) + throughput_overflow = false; + if ((local_result.access_time - latency) <= 1e-10) + latency_overflow = false; + + if (l_ip.cycle_time_dev > 10) { // if not >10 local_result is the last + // result, it cannot be cleaned up + temp_res = &local_result; // Only solutions not saved in the list + // need to be cleaned up + temp_res->cleanup(); + } + } + // l_ip.cycle_time_dev-=10; + // l_ip.delay_dev-=10; + } + + if (l_ip.assoc > 0) { + // For array structures except CAM and FA, Give warning but still provide + // a result with best timing found + if (throughput_overflow == true) + cout << "Warning: " << name + << " array structure cannot satisfy throughput constraint." + << endl; + if (latency_overflow == true) + cout << "Warning: " << name + << " array structure cannot satisfy latency constraint." << endl; + } + // else + // { + // /*According to "Content-Addressable Memory (CAM) Circuits and + // Architectures": A Tutorial and Survey + // by Kostas Pagiamtzis et al. + // CAM structures can be heavily pipelined and use + // look-ahead techniques, therefore timing can be + // relaxed. But McPAT does not model the + // advanced techniques. If continue optimizing, the area efficiency + // will be too low + // */ + // //For CAM and FA, stop opt if area efficiency is too low + // if (throughput_overflow==true) + // cout<< "Warning: " <<" McPAT stopped optimization on + //throughput for + //"<< name + // <<" array structure because its area efficiency + //is below + //"< (candidate_iter)->power.readOp.dynamic) { + min_dynamic_energy = (candidate_iter)->power.readOp.dynamic; + min_dynamic_energy_iter = candidate_iter; + local_result = *(min_dynamic_energy_iter); + // TODO: since results are reordered results and l_ip may miss match. + // Therefore, the final output spread sheets may show the miss match. + + } else { + candidate_iter->cleanup(); + } + } } + candidate_solutions.clear(); + } + + double long_channel_device_reduction = + longer_channel_device_reduction(device_ty, core_ty); -void ArrayST::optimize_array() -{ - list candidate_solutions(0); - list::iterator candidate_iter, min_dynamic_energy_iter; - - uca_org_t * temp_res = 0; - local_result.valid=false; - - double throughput=l_ip.throughput, latency=l_ip.latency; - double area_efficiency_threshold = 20.0; - bool throughput_overflow=true, latency_overflow=true; - compute_base_power(); - - if ((local_result.cycle_time - throughput) <= 1e-10 ) - throughput_overflow=false; - if ((local_result.access_time - latency)<= 1e-10) - latency_overflow=false; - - if (opt_for_clk && opt_local) - { - if (throughput_overflow || latency_overflow) - { - l_ip.ed=0; - - l_ip.delay_wt = 100;//Fixed number, make sure timing can be satisfied. - l_ip.cycle_time_wt = 1000; - - l_ip.area_wt = 10;//Fixed number, This is used to exhaustive search for individual components. - l_ip.dynamic_power_wt = 10;//Fixed number, This is used to exhaustive search for individual components. - l_ip.leakage_power_wt = 10; - - l_ip.delay_dev = 1000000;//Fixed number, make sure timing can be satisfied. - l_ip.cycle_time_dev = 100; - - l_ip.area_dev = 1000000;//Fixed number, This is used to exhaustive search for individual components. - l_ip.dynamic_power_dev = 1000000;//Fixed number, This is used to exhaustive search for individual components. - l_ip.leakage_power_dev = 1000000; - - throughput_overflow=true; //Reset overflow flag before start optimization iterations - latency_overflow=true; - - temp_res = &local_result; //Clean up the result for optimized for ED^2P - temp_res->cleanup(); - } - - - while ((throughput_overflow || latency_overflow)&&l_ip.cycle_time_dev > 10)// && l_ip.delay_dev > 10 - { - compute_base_power(); - - l_ip.cycle_time_dev-=10;//This is the time_dev to be used for next iteration - - // from best area to worst area -->worst timing to best timing - if ((((local_result.cycle_time - throughput) <= 1e-10 ) && (local_result.access_time - latency)<= 1e-10)|| - (local_result.data_array2->area_efficiency < area_efficiency_threshold && l_ip.assoc == 0)) - { //if no satisfiable solution is found,the most aggressive one is left - candidate_solutions.push_back(local_result); - //output_data_csv(candidate_solutions.back()); - if (((local_result.cycle_time - throughput) <= 1e-10) && ((local_result.access_time - latency)<= 1e-10)) - //ensure stop opt not because of cam - { - throughput_overflow=false; - latency_overflow=false; - } - - } - else - { - //TODO: whether checking the partial satisfied results too, or just change the mark??? - if ((local_result.cycle_time - throughput) <= 1e-10) - throughput_overflow=false; - if ((local_result.access_time - latency)<= 1e-10) - latency_overflow=false; - - if (l_ip.cycle_time_dev > 10) - { //if not >10 local_result is the last result, it cannot be cleaned up - temp_res = &local_result; //Only solutions not saved in the list need to be cleaned up - temp_res->cleanup(); - } - } -// l_ip.cycle_time_dev-=10; -// l_ip.delay_dev-=10; - - } - - - if (l_ip.assoc > 0) - { - //For array structures except CAM and FA, Give warning but still provide a result with best timing found - if (throughput_overflow==true) - cout<< "Warning: " << name<<" array structure cannot satisfy throughput constraint." << endl; - if (latency_overflow==true) - cout<< "Warning: " << name<<" array structure cannot satisfy latency constraint." << endl; - } - -// else -// { -// /*According to "Content-Addressable Memory (CAM) Circuits and -// Architectures": A Tutorial and Survey -// by Kostas Pagiamtzis et al. -// CAM structures can be heavily pipelined and use look-ahead techniques, -// therefore timing can be relaxed. But McPAT does not model the advanced -// techniques. If continue optimizing, the area efficiency will be too low -// */ -// //For CAM and FA, stop opt if area efficiency is too low -// if (throughput_overflow==true) -// cout<< "Warning: " <<" McPAT stopped optimization on throughput for "<< name -// <<" array structure because its area efficiency is below "< (candidate_iter)->power.readOp.dynamic) - { - min_dynamic_energy = (candidate_iter)->power.readOp.dynamic; - min_dynamic_energy_iter = candidate_iter; - local_result = *(min_dynamic_energy_iter); - //TODO: since results are reordered results and l_ip may miss match. Therefore, the final output spread sheets may show the miss match. - - } - else - { - candidate_iter->cleanup() ; - } - - } - - - } - candidate_solutions.clear(); - } - - double long_channel_device_reduction = longer_channel_device_reduction(device_ty,core_ty); - - double macro_layout_overhead = g_tp.macro_layout_overhead; - double chip_PR_overhead = g_tp.chip_layout_overhead; - double total_overhead = macro_layout_overhead*chip_PR_overhead; - local_result.area *= total_overhead; - - //maintain constant power density - double pppm_t[4] = {total_overhead,1,1,total_overhead}; - - double sckRation = g_tp.sckt_co_eff; - local_result.power.readOp.dynamic *= sckRation; - local_result.power.writeOp.dynamic *= sckRation; - local_result.power.searchOp.dynamic *= sckRation; - local_result.power.readOp.leakage *= l_ip.nbanks; - local_result.power.readOp.longer_channel_leakage = - local_result.power.readOp.leakage*long_channel_device_reduction; - local_result.power = local_result.power* pppm_t; - - local_result.data_array2->power.readOp.dynamic *= sckRation; - local_result.data_array2->power.writeOp.dynamic *= sckRation; - local_result.data_array2->power.searchOp.dynamic *= sckRation; - local_result.data_array2->power.readOp.leakage *= l_ip.nbanks; - local_result.data_array2->power.readOp.longer_channel_leakage = - local_result.data_array2->power.readOp.leakage*long_channel_device_reduction; - local_result.data_array2->power = local_result.data_array2->power* pppm_t; - - - if (!(l_ip.pure_cam || l_ip.pure_ram || l_ip.fully_assoc) && l_ip.is_cache) - { - local_result.tag_array2->power.readOp.dynamic *= sckRation; - local_result.tag_array2->power.writeOp.dynamic *= sckRation; - local_result.tag_array2->power.searchOp.dynamic *= sckRation; - local_result.tag_array2->power.readOp.leakage *= l_ip.nbanks; - local_result.tag_array2->power.readOp.longer_channel_leakage = - local_result.tag_array2->power.readOp.leakage*long_channel_device_reduction; - local_result.tag_array2->power = local_result.tag_array2->power* pppm_t; - } + double macro_layout_overhead = g_tp.macro_layout_overhead; + double chip_PR_overhead = g_tp.chip_layout_overhead; + double total_overhead = macro_layout_overhead * chip_PR_overhead; + local_result.area *= total_overhead; + // maintain constant power density + double pppm_t[4] = {total_overhead, 1, 1, total_overhead}; + + double sckRation = g_tp.sckt_co_eff; + local_result.power.readOp.dynamic *= sckRation; + local_result.power.writeOp.dynamic *= sckRation; + local_result.power.searchOp.dynamic *= sckRation; + local_result.power.readOp.leakage *= l_ip.nbanks; + local_result.power.readOp.longer_channel_leakage = + local_result.power.readOp.leakage * long_channel_device_reduction; + local_result.power = local_result.power * pppm_t; + local_result.data_array2->power.readOp.dynamic *= sckRation; + local_result.data_array2->power.writeOp.dynamic *= sckRation; + local_result.data_array2->power.searchOp.dynamic *= sckRation; + local_result.data_array2->power.readOp.leakage *= l_ip.nbanks; + local_result.data_array2->power.readOp.longer_channel_leakage = + local_result.data_array2->power.readOp.leakage * + long_channel_device_reduction; + local_result.data_array2->power = local_result.data_array2->power * pppm_t; + + if (!(l_ip.pure_cam || l_ip.pure_ram || l_ip.fully_assoc) && l_ip.is_cache) { + local_result.tag_array2->power.readOp.dynamic *= sckRation; + local_result.tag_array2->power.writeOp.dynamic *= sckRation; + local_result.tag_array2->power.searchOp.dynamic *= sckRation; + local_result.tag_array2->power.readOp.leakage *= l_ip.nbanks; + local_result.tag_array2->power.readOp.longer_channel_leakage = + local_result.tag_array2->power.readOp.leakage * + long_channel_device_reduction; + local_result.tag_array2->power = local_result.tag_array2->power * pppm_t; + } } -void ArrayST::leakage_feedback(double temperature) -{ - // Update the temperature. l_ip is already set and error-checked in the creator function. - l_ip.temp = (unsigned int)round(temperature/10.0)*10; +void ArrayST::leakage_feedback(double temperature) { + // Update the temperature. l_ip is already set and error-checked in the + // creator function. + l_ip.temp = (unsigned int)round(temperature / 10.0) * 10; - // This corresponds to cacti_interface() in the initialization process. Leakage power is updated here. - reconfigure(&l_ip,&local_result); + // This corresponds to cacti_interface() in the initialization process. + // Leakage power is updated here. + reconfigure(&l_ip, &local_result); // Scale the power values. This is part of ArrayST::optimize_array(). - double long_channel_device_reduction = longer_channel_device_reduction(device_ty,core_ty); + double long_channel_device_reduction = + longer_channel_device_reduction(device_ty, core_ty); - double macro_layout_overhead = g_tp.macro_layout_overhead; - double chip_PR_overhead = g_tp.chip_layout_overhead; - double total_overhead = macro_layout_overhead*chip_PR_overhead; + double macro_layout_overhead = g_tp.macro_layout_overhead; + double chip_PR_overhead = g_tp.chip_layout_overhead; + double total_overhead = macro_layout_overhead * chip_PR_overhead; - double pppm_t[4] = {total_overhead,1,1,total_overhead}; + double pppm_t[4] = {total_overhead, 1, 1, total_overhead}; double sckRation = g_tp.sckt_co_eff; local_result.power.readOp.dynamic *= sckRation; local_result.power.writeOp.dynamic *= sckRation; local_result.power.searchOp.dynamic *= sckRation; local_result.power.readOp.leakage *= l_ip.nbanks; - local_result.power.readOp.longer_channel_leakage = local_result.power.readOp.leakage*long_channel_device_reduction; - local_result.power = local_result.power* pppm_t; + local_result.power.readOp.longer_channel_leakage = + local_result.power.readOp.leakage * long_channel_device_reduction; + local_result.power = local_result.power * pppm_t; local_result.data_array2->power.readOp.dynamic *= sckRation; local_result.data_array2->power.writeOp.dynamic *= sckRation; local_result.data_array2->power.searchOp.dynamic *= sckRation; local_result.data_array2->power.readOp.leakage *= l_ip.nbanks; - local_result.data_array2->power.readOp.longer_channel_leakage = local_result.data_array2->power.readOp.leakage*long_channel_device_reduction; - local_result.data_array2->power = local_result.data_array2->power* pppm_t; + local_result.data_array2->power.readOp.longer_channel_leakage = + local_result.data_array2->power.readOp.leakage * + long_channel_device_reduction; + local_result.data_array2->power = local_result.data_array2->power * pppm_t; - if (!(l_ip.pure_cam || l_ip.pure_ram || l_ip.fully_assoc) && l_ip.is_cache) - { + if (!(l_ip.pure_cam || l_ip.pure_ram || l_ip.fully_assoc) && l_ip.is_cache) { local_result.tag_array2->power.readOp.dynamic *= sckRation; local_result.tag_array2->power.writeOp.dynamic *= sckRation; local_result.tag_array2->power.searchOp.dynamic *= sckRation; local_result.tag_array2->power.readOp.leakage *= l_ip.nbanks; - local_result.tag_array2->power.readOp.longer_channel_leakage = local_result.tag_array2->power.readOp.leakage*long_channel_device_reduction; - local_result.tag_array2->power = local_result.tag_array2->power* pppm_t; + local_result.tag_array2->power.readOp.longer_channel_leakage = + local_result.tag_array2->power.readOp.leakage * + long_channel_device_reduction; + local_result.tag_array2->power = local_result.tag_array2->power * pppm_t; } } -ArrayST:: ~ArrayST() -{ - local_result.cleanup(); -} +ArrayST::~ArrayST() { local_result.cleanup(); } diff --git a/src/gpuwattch/array.h b/src/gpuwattch/array.h index b7f77dc..e2dc3d1 100644 --- a/src/gpuwattch/array.h +++ b/src/gpuwattch/array.h @@ -32,69 +32,86 @@ #ifndef ARRAY_H_ #define ARRAY_H_ +#include +#include #include "basic_components.h" -#include "cacti/const.h" #include "cacti/cacti_interface.h" -#include "cacti/parameter.h" #include "cacti/component.h" -#include -#include +#include "cacti/const.h" +#include "cacti/parameter.h" using namespace std; -class ArrayST :public Component{ +class ArrayST : public Component { public: ArrayST(){}; - ArrayST(const InputParameter *configure_interface, string _name, enum Device_ty device_ty_, bool opt_local_=true, enum Core_type core_ty_=Inorder, bool _is_default=true); + ArrayST(const InputParameter* configure_interface, string _name, + enum Device_ty device_ty_, bool opt_local_ = true, + enum Core_type core_ty_ = Inorder, bool _is_default = true); InputParameter l_ip; - string name; + string name; enum Device_ty device_ty; bool opt_local; enum Core_type core_ty; - bool is_default; - uca_org_t local_result; + bool is_default; + uca_org_t local_result; - statsDef tdp_stats; - statsDef rtp_stats; - statsDef stats_t; - powerDef power_t; + statsDef tdp_stats; + statsDef rtp_stats; + statsDef stats_t; + powerDef power_t; virtual void optimize_array(); virtual void compute_base_power(); virtual ~ArrayST(); - + void leakage_feedback(double temperature); }; -class InstCache :public Component{ -public: +class InstCache : public Component { + public: ArrayST* caches; ArrayST* missb; ArrayST* ifb; ArrayST* prefetchb; - powerDef power_t;//temp value holder for both (max) power and runtime power - InstCache(){caches=0;missb=0;ifb=0;prefetchb=0;}; - ~InstCache(){ - if (caches) {//caches->local_result.cleanup(); - delete caches; caches=0;} - if (missb) {//missb->local_result.cleanup(); - delete missb; missb=0;} - if (ifb) {//ifb->local_result.cleanup(); - delete ifb; ifb=0;} - if (prefetchb) {//prefetchb->local_result.cleanup(); - delete prefetchb; prefetchb=0;} - }; + powerDef power_t; // temp value holder for both (max) power and runtime power + InstCache() { + caches = 0; + missb = 0; + ifb = 0; + prefetchb = 0; + }; + ~InstCache() { + if (caches) { // caches->local_result.cleanup(); + delete caches; + caches = 0; + } + if (missb) { // missb->local_result.cleanup(); + delete missb; + missb = 0; + } + if (ifb) { // ifb->local_result.cleanup(); + delete ifb; + ifb = 0; + } + if (prefetchb) { // prefetchb->local_result.cleanup(); + delete prefetchb; + prefetchb = 0; + } + }; }; -class DataCache :public InstCache{ -public: +class DataCache : public InstCache { + public: ArrayST* wbb; - DataCache(){wbb=0;}; - ~DataCache(){ - if (wbb) {//wbb->local_result.cleanup(); - delete wbb; wbb=0;} - }; + DataCache() { wbb = 0; }; + ~DataCache() { + if (wbb) { // wbb->local_result.cleanup(); + delete wbb; + wbb = 0; + } + }; }; #endif /* TLB_H_ */ diff --git a/src/gpuwattch/basic_components.cc b/src/gpuwattch/basic_components.cc index d66c280..d58023a 100644 --- a/src/gpuwattch/basic_components.cc +++ b/src/gpuwattch/basic_components.cc @@ -30,97 +30,87 @@ ***************************************************************************/ #include "basic_components.h" -#include #include #include +#include -double longer_channel_device_reduction( - enum Device_ty device_ty, - enum Core_type core_ty) -{ - - double longer_channel_device_percentage_core; - double longer_channel_device_percentage_uncore; - double longer_channel_device_percentage_llc; - - double long_channel_device_reduction; - - longer_channel_device_percentage_llc = 1.0; - longer_channel_device_percentage_uncore = 0.82; - if (core_ty==OOO) - { - longer_channel_device_percentage_core = 0.56;//0.54 Xeon Tulsa //0.58 Nehelam - //longer_channel_device_percentage_uncore = 0.76;//0.85 Nehelam - - } - else - { - longer_channel_device_percentage_core = 0.8;//0.8;//Niagara - //longer_channel_device_percentage_uncore = 0.9;//Niagara - } - - if (device_ty==Core_device) - { - long_channel_device_reduction = (1- longer_channel_device_percentage_core) - + longer_channel_device_percentage_core * g_tp.peri_global.long_channel_leakage_reduction; - } - else if (device_ty==Uncore_device) - { - long_channel_device_reduction = (1- longer_channel_device_percentage_uncore) - + longer_channel_device_percentage_uncore * g_tp.peri_global.long_channel_leakage_reduction; - } - else if (device_ty==LLC_device) - { - long_channel_device_reduction = (1- longer_channel_device_percentage_llc) - + longer_channel_device_percentage_llc * g_tp.peri_global.long_channel_leakage_reduction; - } - else - { - cout<<"unknown device category"< #include "XML_Parse.h" #include "cacti/parameter.h" -#include const double cdb_overhead = 1.1; -enum FU_type { - FPU, - ALU, - MUL -}; +enum FU_type { FPU, ALU, MUL }; -enum Core_type { - OOO, - Inorder -}; +enum Core_type { OOO, Inorder }; -enum Renaming_type { - RAMbased, - CAMbased -}; +enum Renaming_type { RAMbased, CAMbased }; -enum Scheduler_type { - PhysicalRegFile, - ReservationStation -}; +enum Scheduler_type { PhysicalRegFile, ReservationStation }; -enum cache_level { - L2, - L3, - L1Directory, - L2Directory -}; +enum cache_level { L2, L3, L1Directory, L2Directory }; enum MemoryCtrl_type { - MC, //memory controller - FLASHC //flash controller -}; - -enum Dram_type { - GDDR5, - GDDR3 + MC, // memory controller + FLASHC // flash controller }; +enum Dram_type { GDDR5, GDDR3 }; enum Dir_type { - ST,//shadowed tag - DC,//directory cache - SBT,//static bank tag - NonDir - -}; + ST, // shadowed tag + DC, // directory cache + SBT, // static bank tag + NonDir -enum Cache_policy { - Write_through, - Write_back }; -enum Device_ty { - Core_device, - Uncore_device, - LLC_device +enum Cache_policy { Write_through, Write_back }; + +enum Device_ty { Core_device, Uncore_device, LLC_device }; + +class statsComponents { + public: + double access; + double hit; + double miss; + + statsComponents() : access(0), hit(0), miss(0) {} + statsComponents(const statsComponents &obj) { *this = obj; } + statsComponents &operator=(const statsComponents &rhs) { + access = rhs.access; + hit = rhs.hit; + miss = rhs.miss; + return *this; + } + void reset() { + access = 0; + hit = 0; + miss = 0; + } + + friend statsComponents operator+(const statsComponents &x, + const statsComponents &y); + friend statsComponents operator*(const statsComponents &x, + double const *const y); }; -class statsComponents -{ - public: - double access; - double hit; - double miss; - - statsComponents() : access(0), hit(0), miss(0) {} - statsComponents(const statsComponents & obj) { *this = obj; } - statsComponents & operator=(const statsComponents & rhs) - { - access = rhs.access; - hit = rhs.hit; - miss = rhs.miss; - return *this; - } - void reset() { access = 0; hit = 0; miss = 0;} - - friend statsComponents operator+(const statsComponents & x, const statsComponents & y); - friend statsComponents operator*(const statsComponents & x, double const * const y); -}; - -class statsDef -{ - public: - statsComponents readAc; - statsComponents writeAc; - statsComponents searchAc; - - statsDef() : readAc(), writeAc(),searchAc() { } - void reset() { readAc.reset(); writeAc.reset();searchAc.reset();} - - friend statsDef operator+(const statsDef & x, const statsDef & y); - friend statsDef operator*(const statsDef & x, double const * const y); +class statsDef { + public: + statsComponents readAc; + statsComponents writeAc; + statsComponents searchAc; + + statsDef() : readAc(), writeAc(), searchAc() {} + void reset() { + readAc.reset(); + writeAc.reset(); + searchAc.reset(); + } + + friend statsDef operator+(const statsDef &x, const statsDef &y); + friend statsDef operator*(const statsDef &x, double const *const y); }; -double longer_channel_device_reduction( - enum Device_ty device_ty=Core_device, - enum Core_type core_ty=Inorder); +double longer_channel_device_reduction(enum Device_ty device_ty = Core_device, + enum Core_type core_ty = Inorder); class CoreDynParam { -public: - CoreDynParam(){}; - CoreDynParam(ParseXML *XML_interface, int ithCore_); - // :XML(XML_interface), - // ithCore(ithCore_) - // core_ty(inorder), - // rm_ty(CAMbased), - // scheu_ty(PhysicalRegFile), - // clockRate(1e9),//1GHz - // arch_ireg_width(32), - // arch_freg_width(32), - // phy_ireg_width(128), - // phy_freg_width(128), - // perThreadState(8), - // globalCheckpoint(32), - // instructionLength(32){}; - //ParseXML * XML; - bool opt_local; - bool x86; - bool Embedded; - enum Core_type core_ty; - enum Renaming_type rm_ty; - enum Scheduler_type scheu_ty; - double clockRate,executionTime; - int arch_ireg_width, arch_freg_width, phy_ireg_width, phy_freg_width; - int num_IRF_entry, num_FRF_entry, num_ifreelist_entries, num_ffreelist_entries; - int fetchW, decodeW,issueW,peak_issueW, commitW,peak_commitW, predictionW, fp_issueW, fp_decodeW; - int perThreadState, globalCheckpoint, instruction_length, pc_width, opcode_length, micro_opcode_length; - int num_hthreads, pipeline_stages, fp_pipeline_stages, num_pipelines, num_fp_pipelines; - int num_alus, num_muls; - double num_fpus; - int int_data_width, fp_data_width,v_address_width, p_address_width; - double pipeline_duty_cycle, total_cycles, busy_cycles, idle_cycles; - bool regWindowing,multithreaded; - double pppm_lkg_multhread[4]; - double IFU_duty_cycle,BR_duty_cycle,LSU_duty_cycle,MemManU_I_duty_cycle, - MemManU_D_duty_cycle, ALU_duty_cycle,MUL_duty_cycle, - FPU_duty_cycle, ALU_cdb_duty_cycle,MUL_cdb_duty_cycle, - FPU_cdb_duty_cycle; - ~CoreDynParam(){}; + public: + CoreDynParam(){}; + CoreDynParam(ParseXML *XML_interface, int ithCore_); + // :XML(XML_interface), + // ithCore(ithCore_) + // core_ty(inorder), + // rm_ty(CAMbased), + // scheu_ty(PhysicalRegFile), + // clockRate(1e9),//1GHz + // arch_ireg_width(32), + // arch_freg_width(32), + // phy_ireg_width(128), + // phy_freg_width(128), + // perThreadState(8), + // globalCheckpoint(32), + // instructionLength(32){}; + // ParseXML * XML; + bool opt_local; + bool x86; + bool Embedded; + enum Core_type core_ty; + enum Renaming_type rm_ty; + enum Scheduler_type scheu_ty; + double clockRate, executionTime; + int arch_ireg_width, arch_freg_width, phy_ireg_width, phy_freg_width; + int num_IRF_entry, num_FRF_entry, num_ifreelist_entries, + num_ffreelist_entries; + int fetchW, decodeW, issueW, peak_issueW, commitW, peak_commitW, predictionW, + fp_issueW, fp_decodeW; + int perThreadState, globalCheckpoint, instruction_length, pc_width, + opcode_length, micro_opcode_length; + int num_hthreads, pipeline_stages, fp_pipeline_stages, num_pipelines, + num_fp_pipelines; + int num_alus, num_muls; + double num_fpus; + int int_data_width, fp_data_width, v_address_width, p_address_width; + double pipeline_duty_cycle, total_cycles, busy_cycles, idle_cycles; + bool regWindowing, multithreaded; + double pppm_lkg_multhread[4]; + double IFU_duty_cycle, BR_duty_cycle, LSU_duty_cycle, MemManU_I_duty_cycle, + MemManU_D_duty_cycle, ALU_duty_cycle, MUL_duty_cycle, FPU_duty_cycle, + ALU_cdb_duty_cycle, MUL_cdb_duty_cycle, FPU_cdb_duty_cycle; + ~CoreDynParam(){}; }; class CacheDynParam { -public: - CacheDynParam(){}; - CacheDynParam(ParseXML *XML_interface, int ithCache_); - string name; - enum Dir_type dir_ty; - double clockRate,executionTime; - double capacity, blockW, assoc, nbanks; - double throughput, latency; - double duty_cycle, dir_duty_cycle; - //double duty_cycle; - int missb_size, fu_size, prefetchb_size, wbb_size; - ~CacheDynParam(){}; + public: + CacheDynParam(){}; + CacheDynParam(ParseXML *XML_interface, int ithCache_); + string name; + enum Dir_type dir_ty; + double clockRate, executionTime; + double capacity, blockW, assoc, nbanks; + double throughput, latency; + double duty_cycle, dir_duty_cycle; + // double duty_cycle; + int missb_size, fu_size, prefetchb_size, wbb_size; + ~CacheDynParam(){}; }; class DRAMParam { -public: - DRAMParam(){}; - DRAMParam(ParseXML *XML_interface, int ithCache_); - string name; - double clockRate; - double executionTime; - double cmd_coeff; - double activity_coeff; - double nop_coeff; - double act_coeff; - double pre_coeff; - double rd_coeff; - double wr_coeff; - double req_coeff; - double const_coeff; - - int detailed_dram_model; // 1 - to use newly added DRAM model (GDDR5 only), 0 - use empirical model - // the following are the current specified by DATA SHEET - // unit: mA - int idd0; - int idd1; - int idd2p; - int idd2n; - int idd3p; - int idd3n; - int idd4r; - int idd4w; - int idd5; - int idd6; - int idd7; - - // the following are the vdd specified by DATA SHEET; NOT the actual VDD - double datasheet_vdd; - double actual_vdd; - - // the following are the timing parameters specified by DATA SHEET - // unit: ns - int t_ccd; - int t_rrd; - int t_rcd; - int t_ras; - int t_rp; - int t_rc; - int t_cl; - int t_cdlr; - int t_wr; - - // the following are the DRAM clocks - // unit: MHz - int datasheet_operating_clock; // this is specified by DATA SHEET. This is NOT the actual DRAM clock - int actual_operating_clock; - - // the following are each DRAM bank's IO info - int bank_width; // in bits - int dqs_signal_width; // in bits - int extra_dq_write_signal_width; //in bits - int per_dq_read_power; // in mW - int per_dq_write_power; // in mW - - ~DRAMParam(){}; + public: + DRAMParam(){}; + DRAMParam(ParseXML *XML_interface, int ithCache_); + string name; + double clockRate; + double executionTime; + double cmd_coeff; + double activity_coeff; + double nop_coeff; + double act_coeff; + double pre_coeff; + double rd_coeff; + double wr_coeff; + double req_coeff; + double const_coeff; + + int detailed_dram_model; // 1 - to use newly added DRAM model (GDDR5 only), 0 + // - use empirical model + // the following are the current specified by DATA SHEET + // unit: mA + int idd0; + int idd1; + int idd2p; + int idd2n; + int idd3p; + int idd3n; + int idd4r; + int idd4w; + int idd5; + int idd6; + int idd7; + + // the following are the vdd specified by DATA SHEET; NOT the actual VDD + double datasheet_vdd; + double actual_vdd; + + // the following are the timing parameters specified by DATA SHEET + // unit: ns + int t_ccd; + int t_rrd; + int t_rcd; + int t_ras; + int t_rp; + int t_rc; + int t_cl; + int t_cdlr; + int t_wr; + + // the following are the DRAM clocks + // unit: MHz + int datasheet_operating_clock; // this is specified by DATA SHEET. This is + // NOT the actual DRAM clock + int actual_operating_clock; + + // the following are each DRAM bank's IO info + int bank_width; // in bits + int dqs_signal_width; // in bits + int extra_dq_write_signal_width; // in bits + int per_dq_read_power; // in mW + int per_dq_write_power; // in mW + + ~DRAMParam(){}; }; class MCParam { -public: - MCParam(){}; - MCParam(ParseXML *XML_interface, int ithCache_); - string name; - double clockRate,num_mcs, peakDataTransferRate, num_channels; - // double mcTEPowerperGhz; - // double mcPHYperGbit; - // double area; - int llcBlockSize, dataBusWidth, addressBusWidth; - int opcodeW; - int memAccesses; - int memRank; - int type; - double frontend_duty_cycle, duty_cycle, perc_load; - double executionTime, reads, writes; - bool LVDS, withPHY; - - ~MCParam(){}; + public: + MCParam(){}; + MCParam(ParseXML *XML_interface, int ithCache_); + string name; + double clockRate, num_mcs, peakDataTransferRate, num_channels; + // double mcTEPowerperGhz; + // double mcPHYperGbit; + // double area; + int llcBlockSize, dataBusWidth, addressBusWidth; + int opcodeW; + int memAccesses; + int memRank; + int type; + double frontend_duty_cycle, duty_cycle, perc_load; + double executionTime, reads, writes; + bool LVDS, withPHY; + + ~MCParam(){}; }; class NoCParam { -public: - NoCParam(){}; - NoCParam(ParseXML *XML_interface, int ithCache_); - string name; - double clockRate; - int flit_size; - int input_ports, output_ports, min_ports, global_linked_ports; - int virtual_channel_per_port,input_buffer_entries_per_vc; - int horizontal_nodes,vertical_nodes, total_nodes; - double executionTime, total_access, link_throughput,link_latency, - duty_cycle, chip_coverage, route_over_perc; - bool has_global_link, type; - - ~NoCParam(){}; + public: + NoCParam(){}; + NoCParam(ParseXML *XML_interface, int ithCache_); + string name; + double clockRate; + int flit_size; + int input_ports, output_ports, min_ports, global_linked_ports; + int virtual_channel_per_port, input_buffer_entries_per_vc; + int horizontal_nodes, vertical_nodes, total_nodes; + double executionTime, total_access, link_throughput, link_latency, duty_cycle, + chip_coverage, route_over_perc; + bool has_global_link, type; + + ~NoCParam(){}; }; class ProcParam { -public: - ProcParam(){}; - ProcParam(ParseXML *XML_interface, int ithCache_); - string name; - int numCore, numL2, numL3, numNOC, numL1Dir, numL2Dir,numMC, numMCChannel; - bool homoCore, homoL2, homoL3, homoNOC, homoL1Dir, homoL2Dir; - - ~ProcParam(){}; + public: + ProcParam(){}; + ProcParam(ParseXML *XML_interface, int ithCache_); + string name; + int numCore, numL2, numL3, numNOC, numL1Dir, numL2Dir, numMC, numMCChannel; + bool homoCore, homoL2, homoL3, homoNOC, homoL1Dir, homoL2Dir; + + ~ProcParam(){}; }; class NIUParam { -public: - NIUParam(){}; - NIUParam(ParseXML *XML_interface, int ithCache_); - string name; - double clockRate; - int num_units; - int type; - double duty_cycle, perc_load; - ~NIUParam(){}; + public: + NIUParam(){}; + NIUParam(ParseXML *XML_interface, int ithCache_); + string name; + double clockRate; + int num_units; + int type; + double duty_cycle, perc_load; + ~NIUParam(){}; }; class PCIeParam { -public: - PCIeParam(){}; - PCIeParam(ParseXML *XML_interface, int ithCache_); - string name; - double clockRate; - int num_channels, num_units; - bool withPHY; - int type; - double duty_cycle, perc_load; - ~PCIeParam(){}; + public: + PCIeParam(){}; + PCIeParam(ParseXML *XML_interface, int ithCache_); + string name; + double clockRate; + int num_channels, num_units; + bool withPHY; + int type; + double duty_cycle, perc_load; + ~PCIeParam(){}; }; #endif /* BASIC_COMPONENTS_H_ */ diff --git a/src/gpuwattch/core.cc b/src/gpuwattch/core.cc index a5c3bf3..f2376fe 100644 --- a/src/gpuwattch/core.cc +++ b/src/gpuwattch/core.cc @@ -29,5309 +29,6791 @@ * ***************************************************************************/ /******************************************************************** -* 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 "io.h" -#include "parameter.h" -#include "const.h" -#include "cacti/basic_circuit.h" -#include +#include "core.h" +#include #include -#include "XML_Parse.h" -#include #include -#include -#include "core.h" +#include +#include +#include "XML_Parse.h" +#include "cacti/basic_circuit.h" +#include "const.h" +#include "io.h" +#include "parameter.h" //#include "globalvar.h" -//double exClockRate; +// double exClockRate; //********************* -//Operand collector (OC) modelling (Syed Gilani) +// Operand collector (OC) modelling (Syed Gilani) //********************* -//The OCs are modelled similar to the GPGPU-Sim v3.x documentation and -//nVIDIA patents. -//the OC need the following GPGPU-Sim config options: -//-gpgpu_num_reg_banks 8 # Number of register banks (default = 8) -//-gpgpu_reg_bank_use_warp_id 0 # Use warp ID in mapping registers to banks (default = off) -//-gpgpu_operand_collector_num_units_sp 6 # number of collector units (default = 4) -//-gpgpu_operand_collector_num_units_sfu 8 # number of collector units (default = 4) -//-gpgpu_operand_collector_num_units_mem 2 # number of collector units (default = 2) -//-gpgpu_operand_collector_num_units_gen 0 # number of collector units (default = 0) -//-gpgpu_operand_collector_num_in_ports_sp 1 # number of collector unit in ports (default = 1) -//-gpgpu_operand_collector_num_in_ports_sfu 1 # number of collector unit in ports (default = 1) -//-gpgpu_operand_collector_num_in_ports_mem 1 # number of collector unit in ports (default = 1) -//-gpgpu_operand_collector_num_in_ports_gen 0 # number of collector unit in ports (default = 0) -//-gpgpu_operand_collector_num_out_ports_sp 1 # number of collector unit in ports (default = 1) -//-gpgpu_operand_collector_num_out_ports_sfu 1 # number of collector unit in ports (default = 1) -//-gpgpu_operand_collector_num_out_ports_mem 1 # number of collector unit in ports (default = 1) -//-gpgpu_operand_collector_num_out_ports_gen 0 # number of collector unit in ports (default = 0) - -//The total number of collector units and their input ports, and the number of register file banks -//determine the crossbar size. - -InstFetchU::InstFetchU(ParseXML* XML_interface, int ithCore_, InputParameter* interface_ip_, const CoreDynParam & dyn_p_, bool exist_) -:XML(XML_interface), - ithCore(ithCore_), - interface_ip(*interface_ip_), - coredynp(dyn_p_), - IB (0), - BTB (0), - ID_inst (0), - ID_operand (0), - ID_misc (0), - exist(exist_) -{ - if (!exist) return; - int idx, tag, data, size, line, assoc, banks; - bool debug= false, is_default = true; - - clockRate = coredynp.clockRate; - executionTime = coredynp.executionTime; - - cache_p = (Cache_policy)XML->sys.core[ithCore].icache.icache_config[7]; - //Assuming all L1 caches are virtually idxed physically tagged. - //cache - - size = (int)XML->sys.core[ithCore].icache.icache_config[0]; - line = (int)XML->sys.core[ithCore].icache.icache_config[1]; - assoc = (int)XML->sys.core[ithCore].icache.icache_config[2]; - banks = (int)XML->sys.core[ithCore].icache.icache_config[3]; - idx = debug?9:int(ceil(log2(size/line/assoc))); - tag = debug?51:(int)XML->sys.physical_address_width-idx-int(ceil(log2(line))) + EXTRA_TAG_BITS; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.cache_sz = debug?32768:(int)XML->sys.core[ithCore].icache.icache_config[0]; - interface_ip.line_sz = debug?64:(int)XML->sys.core[ithCore].icache.icache_config[1]; - interface_ip.assoc = debug?8:(int)XML->sys.core[ithCore].icache.icache_config[2]; - interface_ip.nbanks = debug?1:(int)XML->sys.core[ithCore].icache.icache_config[3]; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 0;//debug?0:XML->sys.core[ithCore].icache.icache_config[5]; - interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].icache.icache_config[4]/clockRate; - interface_ip.latency = debug?3.0/clockRate:XML->sys.core[ithCore].icache.icache_config[5]/clockRate; - interface_ip.is_cache = true; - interface_ip.pure_cam = false; - interface_ip.pure_ram = false; - // interface_ip.obj_func_dyn_energy = 0; - // interface_ip.obj_func_dyn_power = 0; - // interface_ip.obj_func_leak_power = 0; - // interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].number_instruction_fetch_ports; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - icache.caches = new ArrayST(&interface_ip, "icache", Core_device, coredynp.opt_local, coredynp.core_ty); - scktRatio = g_tp.sckt_co_eff; - chip_PR_overhead = g_tp.chip_layout_overhead; - macro_PR_overhead = g_tp.macro_layout_overhead; - icache.area.set_area(icache.area.get_area()+ icache.caches->local_result.area); - area.set_area(area.get_area()+ icache.caches->local_result.area); - //output_data_csv(icache.caches.local_result); - - - /* - *iCache controllers - *miss buffer Each MSHR contains enough state - *to handle one or more accesses of any type to a single memory line. - *Due to the generality of the MSHR mechanism, - *the amount of state involved is non-trivial: - *including the address, pointers to the cache entry and destination register, - *written data, and various other pieces of state. - */ - interface_ip.num_search_ports = debug?1:XML->sys.core[ithCore].number_instruction_fetch_ports; - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = (XML->sys.physical_address_width) + int(ceil(log2(size/line))) + icache.caches->l_ip.line_sz*8; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = int(ceil(data/8.0));//int(ceil(pow(2.0,ceil(log2(data)))/8.0)); - interface_ip.cache_sz = XML->sys.core[ithCore].icache.buffer_sizes[0]*interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 0; - interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].icache.icache_config[4]/clockRate;//means cycle time - interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].icache.icache_config[5]/clockRate;//means access time - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].number_instruction_fetch_ports; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = XML->sys.core[ithCore].number_instruction_fetch_ports; - icache.missb = new ArrayST(&interface_ip, "icacheMissBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); - icache.area.set_area(icache.area.get_area()+ icache.missb->local_result.area); - area.set_area(area.get_area()+ icache.missb->local_result.area); - //output_data_csv(icache.missb.local_result); - - //fill buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = icache.caches->l_ip.line_sz; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); - interface_ip.cache_sz = data*XML->sys.core[ithCore].icache.buffer_sizes[1]; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 0; - interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].icache.icache_config[4]/clockRate; - interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].icache.icache_config[5]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].number_instruction_fetch_ports; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = XML->sys.core[ithCore].number_instruction_fetch_ports; - icache.ifb = new ArrayST(&interface_ip, "icacheFillBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); - icache.area.set_area(icache.area.get_area()+ icache.ifb->local_result.area); - area.set_area(area.get_area()+ icache.ifb->local_result.area); - //output_data_csv(icache.ifb.local_result); - - //prefetch buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS;//check with previous entries to decide wthether to merge. - data = icache.caches->l_ip.line_sz;//separate queue to prevent from cache polution. - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); - interface_ip.cache_sz = XML->sys.core[ithCore].icache.buffer_sizes[2]*interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 0; - interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].icache.icache_config[4]/clockRate; - interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].icache.icache_config[5]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].number_instruction_fetch_ports; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = XML->sys.core[ithCore].number_instruction_fetch_ports; - icache.prefetchb = new ArrayST(&interface_ip, "icacheprefetchBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); - icache.area.set_area(icache.area.get_area()+ icache.prefetchb->local_result.area); - area.set_area(area.get_area()+ icache.prefetchb->local_result.area); - //output_data_csv(icache.prefetchb.local_result); - - //Instruction buffer - data = XML->sys.core[ithCore].instruction_length*XML->sys.core[ithCore].peak_issue_width;//icache.caches.l_ip.line_sz; //multiple threads timing sharing the instruction buffer. - interface_ip.is_cache = false; - interface_ip.pure_ram = true; - interface_ip.pure_cam = false; - interface_ip.line_sz = int(ceil(data/8.0)); - interface_ip.cache_sz = XML->sys.core[ithCore].number_hardware_threads*XML->sys.core[ithCore].instruction_buffer_size*interface_ip.line_sz>64? - XML->sys.core[ithCore].number_hardware_threads*XML->sys.core[ithCore].instruction_buffer_size*interface_ip.line_sz:64; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 0; - interface_ip.throughput = 1.0/clockRate; - interface_ip.latency = 1.0/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - //NOTE: Assuming IB is time slice shared among threads, every fetch op will at least fetch "fetch width" instructions. - interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].number_instruction_fetch_ports;//XML->sys.core[ithCore].fetch_width; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - IB = new ArrayST(&interface_ip, "InstBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); - IB->area.set_area(IB->area.get_area()+ IB->local_result.area); - area.set_area(area.get_area()+ IB->local_result.area); - //output_data_csv(IB.IB.local_result); - - // inst_decoder.opcode_length = XML->sys.core[ithCore].opcode_width; - // inst_decoder.init_decoder(is_default, &interface_ip); - // inst_decoder.full_decoder_power(); - - if (coredynp.predictionW>0) - { - /* - * BTB branch target buffer, accessed during IF stage. Virtually indexed and virtually tagged - * It is only a cache without all the buffers in the cache controller since it is more like a - * look up table than a cache with cache controller. When access miss, no load from other places - * such as main memory (not actively fill the misses), it is passively updated under two circumstances: - * 1) when BPT@ID stage finds out current is a taken branch while BTB missed - * 2) When BPT@ID stage predicts differently than BTB - * 3) When ID stage finds out current instruction is not a branch while BTB had a hit.(mark as invalid) - * 4) when EXEU find out wrong target has been provided from BTB. - * - */ - size = XML->sys.core[ithCore].BTB.BTB_config[0]; - line = XML->sys.core[ithCore].BTB.BTB_config[1]; - assoc = XML->sys.core[ithCore].BTB.BTB_config[2]; - banks = XML->sys.core[ithCore].BTB.BTB_config[3]; - idx = debug?9:int(ceil(log2(size/line/assoc))); -// tag = debug?51:XML->sys.virtual_address_width-idx-int(ceil(log2(line))) + int(ceil(log2(XML->sys.core[ithCore].number_hardware_threads))) +EXTRA_TAG_BITS; - tag = debug?51:XML->sys.virtual_address_width + int(ceil(log2(XML->sys.core[ithCore].number_hardware_threads))) +EXTRA_TAG_BITS; - interface_ip.is_cache = true; - interface_ip.pure_ram = false; - interface_ip.pure_cam = false; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.cache_sz = debug?32768:size; - interface_ip.line_sz = debug?64:line; - interface_ip.assoc = debug?8:assoc; - interface_ip.nbanks = debug?1:banks; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 0;//debug?0:XML->sys.core[ithCore].dcache.dcache_config[5]; - interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].BTB.BTB_config[4]/clockRate; - interface_ip.latency = debug?3.0/clockRate:XML->sys.core[ithCore].BTB.BTB_config[5]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; - interface_ip.num_rd_ports = coredynp.predictionW; - interface_ip.num_wr_ports = coredynp.predictionW; - interface_ip.num_se_rd_ports = 0; - BTB = new ArrayST(&interface_ip, "Branch Target Buffer", Core_device, coredynp.opt_local, coredynp.core_ty); - BTB->area.set_area(BTB->area.get_area()+ BTB->local_result.area); - area.set_area(area.get_area()+ BTB->local_result.area); - ///cout<<"area="<area.get_area()); - } +// The OCs are modelled similar to the GPGPU-Sim v3.x documentation and +// nVIDIA patents. +// the OC need the following GPGPU-Sim config options: +//-gpgpu_num_reg_banks 8 # Number of register banks (default +//= 8) -gpgpu_reg_bank_use_warp_id 0 # Use warp ID in mapping +// registers to banks (default = off) -gpgpu_operand_collector_num_units_sp 6 # +// number of collector units (default = 4) +// -gpgpu_operand_collector_num_units_sfu 8 # number of collector units (default +// = 4) -gpgpu_operand_collector_num_units_mem 2 # number of +// collector units (default = 2) -gpgpu_operand_collector_num_units_gen 0 # +// number of collector units (default = 0) +//-gpgpu_operand_collector_num_in_ports_sp 1 # number of +// collector unit in ports (default = 1) +//-gpgpu_operand_collector_num_in_ports_sfu 1 # number of +// collector unit in ports (default = 1) +//-gpgpu_operand_collector_num_in_ports_mem 1 # number of +// collector unit in ports (default = 1) +//-gpgpu_operand_collector_num_in_ports_gen 0 # number of +// collector unit in ports (default = 0) +//-gpgpu_operand_collector_num_out_ports_sp 1 # number of +// collector unit in ports (default = 1) +//-gpgpu_operand_collector_num_out_ports_sfu 1 # number of +// collector unit in ports (default = 1) +//-gpgpu_operand_collector_num_out_ports_mem 1 # number of +// collector unit in ports (default = 1) +//-gpgpu_operand_collector_num_out_ports_gen 0 # number of +// collector unit in ports (default = 0) + +// The total number of collector units and their input ports, and the number of +// register file banks determine the crossbar size. + +InstFetchU::InstFetchU(ParseXML* XML_interface, int ithCore_, + InputParameter* interface_ip_, + const CoreDynParam& dyn_p_, bool exist_) + : XML(XML_interface), + ithCore(ithCore_), + interface_ip(*interface_ip_), + coredynp(dyn_p_), + IB(0), + BTB(0), + ID_inst(0), + ID_operand(0), + ID_misc(0), + exist(exist_) { + if (!exist) return; + int idx, tag, data, size, line, assoc, banks; + bool debug = false, is_default = true; - ID_inst = new inst_decoder(is_default, &interface_ip, - coredynp.opcode_length, 1/*Decoder should not know how many by itself*/, - coredynp.x86, - Core_device, coredynp.core_ty); - - ID_operand = new inst_decoder(is_default, &interface_ip, - coredynp.arch_ireg_width, 1, - coredynp.x86, - Core_device, coredynp.core_ty); - - ID_misc = new inst_decoder(is_default, &interface_ip, - 8/* Prefix field etc upto 14B*/, 1, - coredynp.x86, - Core_device, coredynp.core_ty); - //TODO: X86 decoder should decode the inst in cyclic mode under the control of squencer. - //So the dynamic power should be multiplied by a few times. - area.set_area(area.get_area()+ (ID_inst->area.get_area() - +ID_operand->area.get_area() - +ID_misc->area.get_area())*coredynp.decodeW); + clockRate = coredynp.clockRate; + executionTime = coredynp.executionTime; -} + cache_p = (Cache_policy)XML->sys.core[ithCore].icache.icache_config[7]; + // Assuming all L1 caches are virtually idxed physically tagged. + // cache + + size = (int)XML->sys.core[ithCore].icache.icache_config[0]; + line = (int)XML->sys.core[ithCore].icache.icache_config[1]; + assoc = (int)XML->sys.core[ithCore].icache.icache_config[2]; + banks = (int)XML->sys.core[ithCore].icache.icache_config[3]; + idx = debug ? 9 : int(ceil(log2(size / line / assoc))); + tag = debug ? 51 + : (int)XML->sys.physical_address_width - idx - + int(ceil(log2(line))) + EXTRA_TAG_BITS; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.cache_sz = + debug ? 32768 : (int)XML->sys.core[ithCore].icache.icache_config[0]; + interface_ip.line_sz = + debug ? 64 : (int)XML->sys.core[ithCore].icache.icache_config[1]; + interface_ip.assoc = + debug ? 8 : (int)XML->sys.core[ithCore].icache.icache_config[2]; + interface_ip.nbanks = + debug ? 1 : (int)XML->sys.core[ithCore].icache.icache_config[3]; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = + 0; // debug?0:XML->sys.core[ithCore].icache.icache_config[5]; + interface_ip.throughput = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].icache.icache_config[4] / clockRate; + interface_ip.latency = + debug ? 3.0 / clockRate + : XML->sys.core[ithCore].icache.icache_config[5] / clockRate; + interface_ip.is_cache = true; + interface_ip.pure_cam = false; + interface_ip.pure_ram = false; + // interface_ip.obj_func_dyn_energy = 0; + // interface_ip.obj_func_dyn_power = 0; + // interface_ip.obj_func_leak_power = 0; + // interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = + debug ? 1 : XML->sys.core[ithCore].number_instruction_fetch_ports; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + icache.caches = new ArrayST(&interface_ip, "icache", Core_device, + coredynp.opt_local, coredynp.core_ty); + scktRatio = g_tp.sckt_co_eff; + chip_PR_overhead = g_tp.chip_layout_overhead; + macro_PR_overhead = g_tp.macro_layout_overhead; + icache.area.set_area(icache.area.get_area() + + icache.caches->local_result.area); + area.set_area(area.get_area() + icache.caches->local_result.area); + // output_data_csv(icache.caches.local_result); + + /* + *iCache controllers + *miss buffer Each MSHR contains enough state + *to handle one or more accesses of any type to a single memory line. + *Due to the generality of the MSHR mechanism, + *the amount of state involved is non-trivial: + *including the address, pointers to the cache entry and destination register, + *written data, and various other pieces of state. + */ + interface_ip.num_search_ports = + debug ? 1 : XML->sys.core[ithCore].number_instruction_fetch_ports; + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = (XML->sys.physical_address_width) + int(ceil(log2(size / line))) + + icache.caches->l_ip.line_sz * 8; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = + int(ceil(data / 8.0)); // int(ceil(pow(2.0,ceil(log2(data)))/8.0)); + interface_ip.cache_sz = + XML->sys.core[ithCore].icache.buffer_sizes[0] * interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 0; + interface_ip.throughput = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].icache.icache_config[4] / + clockRate; // means cycle time + interface_ip.latency = debug + ? 1.0 / clockRate + : XML->sys.core[ithCore].icache.icache_config[5] / + clockRate; // means access time + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = + debug ? 1 : XML->sys.core[ithCore].number_instruction_fetch_ports; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = + XML->sys.core[ithCore].number_instruction_fetch_ports; + icache.missb = new ArrayST(&interface_ip, "icacheMissBuffer", Core_device, + coredynp.opt_local, coredynp.core_ty); + icache.area.set_area(icache.area.get_area() + + icache.missb->local_result.area); + area.set_area(area.get_area() + icache.missb->local_result.area); + // output_data_csv(icache.missb.local_result); + + // fill buffer + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = icache.caches->l_ip.line_sz; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data; // int(pow(2.0,ceil(log2(data)))); + interface_ip.cache_sz = data * XML->sys.core[ithCore].icache.buffer_sizes[1]; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 0; + interface_ip.throughput = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].icache.icache_config[4] / clockRate; + interface_ip.latency = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].icache.icache_config[5] / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = + debug ? 1 : XML->sys.core[ithCore].number_instruction_fetch_ports; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = + XML->sys.core[ithCore].number_instruction_fetch_ports; + icache.ifb = new ArrayST(&interface_ip, "icacheFillBuffer", Core_device, + coredynp.opt_local, coredynp.core_ty); + icache.area.set_area(icache.area.get_area() + icache.ifb->local_result.area); + area.set_area(area.get_area() + icache.ifb->local_result.area); + // output_data_csv(icache.ifb.local_result); + + // prefetch buffer + tag = XML->sys.physical_address_width + + EXTRA_TAG_BITS; // check with previous entries to decide wthether to + // merge. + data = icache.caches->l_ip + .line_sz; // separate queue to prevent from cache polution. + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data; // int(pow(2.0,ceil(log2(data)))); + interface_ip.cache_sz = + XML->sys.core[ithCore].icache.buffer_sizes[2] * interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 0; + interface_ip.throughput = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].icache.icache_config[4] / clockRate; + interface_ip.latency = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].icache.icache_config[5] / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = + debug ? 1 : XML->sys.core[ithCore].number_instruction_fetch_ports; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = + XML->sys.core[ithCore].number_instruction_fetch_ports; + icache.prefetchb = + new ArrayST(&interface_ip, "icacheprefetchBuffer", Core_device, + coredynp.opt_local, coredynp.core_ty); + icache.area.set_area(icache.area.get_area() + + icache.prefetchb->local_result.area); + area.set_area(area.get_area() + icache.prefetchb->local_result.area); + // output_data_csv(icache.prefetchb.local_result); + + // Instruction buffer + data = + XML->sys.core[ithCore].instruction_length * + XML->sys.core[ithCore] + .peak_issue_width; // icache.caches.l_ip.line_sz; //multiple threads + // timing sharing the instruction buffer. + interface_ip.is_cache = false; + interface_ip.pure_ram = true; + interface_ip.pure_cam = false; + interface_ip.line_sz = int(ceil(data / 8.0)); + interface_ip.cache_sz = + XML->sys.core[ithCore].number_hardware_threads * + XML->sys.core[ithCore].instruction_buffer_size * + interface_ip.line_sz > + 64 + ? XML->sys.core[ithCore].number_hardware_threads * + XML->sys.core[ithCore].instruction_buffer_size * + interface_ip.line_sz + : 64; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 0; + interface_ip.throughput = 1.0 / clockRate; + interface_ip.latency = 1.0 / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + // NOTE: Assuming IB is time slice shared among threads, every fetch op will + // at least fetch "fetch width" instructions. + interface_ip.num_rw_ports = + debug + ? 1 + : XML->sys.core[ithCore] + .number_instruction_fetch_ports; // XML->sys.core[ithCore].fetch_width; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + IB = new ArrayST(&interface_ip, "InstBuffer", Core_device, coredynp.opt_local, + coredynp.core_ty); + IB->area.set_area(IB->area.get_area() + IB->local_result.area); + area.set_area(area.get_area() + IB->local_result.area); + // output_data_csv(IB.IB.local_result); + + // inst_decoder.opcode_length = XML->sys.core[ithCore].opcode_width; + // inst_decoder.init_decoder(is_default, &interface_ip); + // inst_decoder.full_decoder_power(); + + if (coredynp.predictionW > 0) { + /* + * BTB branch target buffer, accessed during IF stage. Virtually indexed and + * virtually tagged It is only a cache without all the buffers in the cache + * controller since it is more like a look up table than a cache with cache + * controller. When access miss, no load from other places such as main + * memory (not actively fill the misses), it is passively updated under two + * circumstances: 1) when BPT@ID stage finds out current is a taken branch + * while BTB missed 2) When BPT@ID stage predicts differently than BTB 3) + * When ID stage finds out current instruction is not a branch while BTB had + * a hit.(mark as invalid) 4) when EXEU find out wrong target has been + * provided from BTB. + * + */ + size = XML->sys.core[ithCore].BTB.BTB_config[0]; + line = XML->sys.core[ithCore].BTB.BTB_config[1]; + assoc = XML->sys.core[ithCore].BTB.BTB_config[2]; + banks = XML->sys.core[ithCore].BTB.BTB_config[3]; + idx = debug ? 9 : int(ceil(log2(size / line / assoc))); + // tag = + // debug?51:XML->sys.virtual_address_width-idx-int(ceil(log2(line))) + + // int(ceil(log2(XML->sys.core[ithCore].number_hardware_threads))) + // +EXTRA_TAG_BITS; + tag = debug ? 51 + : XML->sys.virtual_address_width + + int(ceil(log2( + XML->sys.core[ithCore].number_hardware_threads))) + + EXTRA_TAG_BITS; + interface_ip.is_cache = true; + interface_ip.pure_ram = false; + interface_ip.pure_cam = false; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.cache_sz = debug ? 32768 : size; + interface_ip.line_sz = debug ? 64 : line; + interface_ip.assoc = debug ? 8 : assoc; + interface_ip.nbanks = debug ? 1 : banks; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = + 0; // debug?0:XML->sys.core[ithCore].dcache.dcache_config[5]; + interface_ip.throughput = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].BTB.BTB_config[4] / clockRate; + interface_ip.latency = + debug ? 3.0 / clockRate + : XML->sys.core[ithCore].BTB.BTB_config[5] / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1; + interface_ip.num_rd_ports = coredynp.predictionW; + interface_ip.num_wr_ports = coredynp.predictionW; + interface_ip.num_se_rd_ports = 0; + BTB = new ArrayST(&interface_ip, "Branch Target Buffer", Core_device, + coredynp.opt_local, coredynp.core_ty); + BTB->area.set_area(BTB->area.get_area() + BTB->local_result.area); + area.set_area(area.get_area() + BTB->local_result.area); + /// cout<<"area="<area.get_area()); + } + ID_inst = new inst_decoder(is_default, &interface_ip, coredynp.opcode_length, + 1 /*Decoder should not know how many by itself*/, + coredynp.x86, Core_device, coredynp.core_ty); + + ID_operand = + new inst_decoder(is_default, &interface_ip, coredynp.arch_ireg_width, 1, + coredynp.x86, Core_device, coredynp.core_ty); + + ID_misc = new inst_decoder(is_default, &interface_ip, + 8 /* Prefix field etc upto 14B*/, 1, coredynp.x86, + Core_device, coredynp.core_ty); + // TODO: X86 decoder should decode the inst in cyclic mode under the control + // of squencer. So the dynamic power should be multiplied by a few times. + area.set_area(area.get_area() + + (ID_inst->area.get_area() + ID_operand->area.get_area() + + ID_misc->area.get_area()) * + coredynp.decodeW); +} -BranchPredictor::BranchPredictor(ParseXML* XML_interface, int ithCore_, InputParameter* interface_ip_, const CoreDynParam & dyn_p_, bool exist_) -:XML(XML_interface), - ithCore(ithCore_), - interface_ip(*interface_ip_), - coredynp(dyn_p_), - globalBPT(0), - localBPT(0), - L1_localBPT(0), - L2_localBPT(0), - chooser(0), - RAS(0), - exist(exist_) -{ - /* - * Branch Predictor, accessed during ID stage. - * McPAT's branch predictor model is the tournament branch predictor used in Alpha 21264, - * including global predictor, local two level predictor, and Chooser. - * The Branch predictor also includes a RAS (return address stack) for function calls - * Branch predictors are tagged by thread ID and modeled as 1-way associative $ - * However RAS return address stacks are duplicated for each thread. - * TODO:Data Width need to be computed more precisely * - */ - if (!exist) return; - int tag, data; - - clockRate = coredynp.clockRate; - executionTime = coredynp.executionTime; - interface_ip.assoc = 1; - interface_ip.pure_cam = false; - if (coredynp.multithreaded) - { - - tag = int(log2(coredynp.num_hthreads)+ EXTRA_TAG_BITS); - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - - interface_ip.is_cache = true; - interface_ip.pure_ram = false; - } - else - { - interface_ip.is_cache = false; - interface_ip.pure_ram = true; - - } - //Global predictor - data = int(ceil(XML->sys.core[ithCore].predictor.global_predictor_bits/8.0)); - interface_ip.line_sz = data; - interface_ip.cache_sz = data*XML->sys.core[ithCore].predictor.global_predictor_entries; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 2; - interface_ip.throughput = 1.0/clockRate; - interface_ip.latency = 1.0/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = coredynp.predictionW; - interface_ip.num_wr_ports = coredynp.predictionW; - interface_ip.num_se_rd_ports = 0; - globalBPT = new ArrayST(&interface_ip, "Global Predictor", Core_device, coredynp.opt_local, coredynp.core_ty); - globalBPT->area.set_area(globalBPT->area.get_area()+ globalBPT->local_result.area); - area.set_area(area.get_area()+ globalBPT->local_result.area); - - //Local BPT (Level 1) - data = int(ceil(XML->sys.core[ithCore].predictor.local_predictor_size[0]/8.0)); - interface_ip.line_sz = data; - interface_ip.cache_sz = data*XML->sys.core[ithCore].predictor.local_predictor_entries; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 2; - interface_ip.throughput = 1.0/clockRate; - interface_ip.latency = 1.0/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = coredynp.predictionW; - interface_ip.num_wr_ports = coredynp.predictionW; - interface_ip.num_se_rd_ports = 0; - L1_localBPT = new ArrayST(&interface_ip, "L1 local Predictor", Core_device, coredynp.opt_local, coredynp.core_ty); - L1_localBPT->area.set_area(L1_localBPT->area.get_area()+ L1_localBPT->local_result.area); - area.set_area(area.get_area()+ L1_localBPT->local_result.area); - - //Local BPT (Level 2) - data = int(ceil(XML->sys.core[ithCore].predictor.local_predictor_size[1]/8.0)); - interface_ip.line_sz = data; - interface_ip.cache_sz = data*XML->sys.core[ithCore].predictor.local_predictor_entries; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 2; - interface_ip.throughput = 1.0/clockRate; - interface_ip.latency = 1.0/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = coredynp.predictionW; - interface_ip.num_wr_ports = coredynp.predictionW; - interface_ip.num_se_rd_ports = 0; - L2_localBPT = new ArrayST(&interface_ip, "L2 local Predictor", Core_device, coredynp.opt_local, coredynp.core_ty); - L2_localBPT->area.set_area(L2_localBPT->area.get_area()+ L2_localBPT->local_result.area); - area.set_area(area.get_area()+ L2_localBPT->local_result.area); - - //Chooser - data = int(ceil(XML->sys.core[ithCore].predictor.chooser_predictor_bits/8.0)); - interface_ip.line_sz = data; - interface_ip.cache_sz = data*XML->sys.core[ithCore].predictor.chooser_predictor_entries; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 2; - interface_ip.throughput = 1.0/clockRate; - interface_ip.latency = 1.0/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = coredynp.predictionW; - interface_ip.num_wr_ports = coredynp.predictionW; - interface_ip.num_se_rd_ports = 0; - chooser = new ArrayST(&interface_ip, "Predictor Chooser", Core_device, coredynp.opt_local, coredynp.core_ty); - chooser->area.set_area(chooser->area.get_area()+ chooser->local_result.area); - area.set_area(area.get_area()+ chooser->local_result.area); - - //RAS return address stacks are Duplicated for each thread. - interface_ip.is_cache = false; - interface_ip.pure_ram = true; - data = int(ceil(coredynp.pc_width/8.0)); - interface_ip.line_sz = data; - interface_ip.cache_sz = data*XML->sys.core[ithCore].RAS_size; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 2; - interface_ip.throughput = 1.0/clockRate; - interface_ip.latency = 1.0/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = coredynp.predictionW; - interface_ip.num_wr_ports = coredynp.predictionW; - interface_ip.num_se_rd_ports = 0; - RAS = new ArrayST(&interface_ip, "RAS", Core_device, coredynp.opt_local, coredynp.core_ty); - RAS->area.set_area(RAS->area.get_area()+ RAS->local_result.area*coredynp.num_hthreads); - area.set_area(area.get_area()+ RAS->local_result.area*coredynp.num_hthreads); +BranchPredictor::BranchPredictor(ParseXML* XML_interface, int ithCore_, + InputParameter* interface_ip_, + const CoreDynParam& dyn_p_, bool exist_) + : XML(XML_interface), + ithCore(ithCore_), + interface_ip(*interface_ip_), + coredynp(dyn_p_), + globalBPT(0), + localBPT(0), + L1_localBPT(0), + L2_localBPT(0), + chooser(0), + RAS(0), + exist(exist_) { + /* + * Branch Predictor, accessed during ID stage. + * McPAT's branch predictor model is the tournament branch predictor used in + * Alpha 21264, including global predictor, local two level predictor, and + * Chooser. The Branch predictor also includes a RAS (return address stack) + * for function calls Branch predictors are tagged by thread ID and modeled as + * 1-way associative $ However RAS return address stacks are duplicated for + * each thread. + * TODO:Data Width need to be computed more precisely * + */ + if (!exist) return; + int tag, data; + clockRate = coredynp.clockRate; + executionTime = coredynp.executionTime; + interface_ip.assoc = 1; + interface_ip.pure_cam = false; + if (coredynp.multithreaded) { + tag = int(log2(coredynp.num_hthreads) + EXTRA_TAG_BITS); + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + + interface_ip.is_cache = true; + interface_ip.pure_ram = false; + } else { + interface_ip.is_cache = false; + interface_ip.pure_ram = true; + } + // Global predictor + data = + int(ceil(XML->sys.core[ithCore].predictor.global_predictor_bits / 8.0)); + interface_ip.line_sz = data; + interface_ip.cache_sz = + data * XML->sys.core[ithCore].predictor.global_predictor_entries; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 2; + interface_ip.throughput = 1.0 / clockRate; + interface_ip.latency = 1.0 / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = coredynp.predictionW; + interface_ip.num_wr_ports = coredynp.predictionW; + interface_ip.num_se_rd_ports = 0; + globalBPT = new ArrayST(&interface_ip, "Global Predictor", Core_device, + coredynp.opt_local, coredynp.core_ty); + globalBPT->area.set_area(globalBPT->area.get_area() + + globalBPT->local_result.area); + area.set_area(area.get_area() + globalBPT->local_result.area); + + // Local BPT (Level 1) + data = + int(ceil(XML->sys.core[ithCore].predictor.local_predictor_size[0] / 8.0)); + interface_ip.line_sz = data; + interface_ip.cache_sz = + data * XML->sys.core[ithCore].predictor.local_predictor_entries; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 2; + interface_ip.throughput = 1.0 / clockRate; + interface_ip.latency = 1.0 / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = coredynp.predictionW; + interface_ip.num_wr_ports = coredynp.predictionW; + interface_ip.num_se_rd_ports = 0; + L1_localBPT = new ArrayST(&interface_ip, "L1 local Predictor", Core_device, + coredynp.opt_local, coredynp.core_ty); + L1_localBPT->area.set_area(L1_localBPT->area.get_area() + + L1_localBPT->local_result.area); + area.set_area(area.get_area() + L1_localBPT->local_result.area); + + // Local BPT (Level 2) + data = + int(ceil(XML->sys.core[ithCore].predictor.local_predictor_size[1] / 8.0)); + interface_ip.line_sz = data; + interface_ip.cache_sz = + data * XML->sys.core[ithCore].predictor.local_predictor_entries; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 2; + interface_ip.throughput = 1.0 / clockRate; + interface_ip.latency = 1.0 / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = coredynp.predictionW; + interface_ip.num_wr_ports = coredynp.predictionW; + interface_ip.num_se_rd_ports = 0; + L2_localBPT = new ArrayST(&interface_ip, "L2 local Predictor", Core_device, + coredynp.opt_local, coredynp.core_ty); + L2_localBPT->area.set_area(L2_localBPT->area.get_area() + + L2_localBPT->local_result.area); + area.set_area(area.get_area() + L2_localBPT->local_result.area); + + // Chooser + data = + int(ceil(XML->sys.core[ithCore].predictor.chooser_predictor_bits / 8.0)); + interface_ip.line_sz = data; + interface_ip.cache_sz = + data * XML->sys.core[ithCore].predictor.chooser_predictor_entries; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 2; + interface_ip.throughput = 1.0 / clockRate; + interface_ip.latency = 1.0 / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = coredynp.predictionW; + interface_ip.num_wr_ports = coredynp.predictionW; + interface_ip.num_se_rd_ports = 0; + chooser = new ArrayST(&interface_ip, "Predictor Chooser", Core_device, + coredynp.opt_local, coredynp.core_ty); + chooser->area.set_area(chooser->area.get_area() + chooser->local_result.area); + area.set_area(area.get_area() + chooser->local_result.area); + + // RAS return address stacks are Duplicated for each thread. + interface_ip.is_cache = false; + interface_ip.pure_ram = true; + data = int(ceil(coredynp.pc_width / 8.0)); + interface_ip.line_sz = data; + interface_ip.cache_sz = data * XML->sys.core[ithCore].RAS_size; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 2; + interface_ip.throughput = 1.0 / clockRate; + interface_ip.latency = 1.0 / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = coredynp.predictionW; + interface_ip.num_wr_ports = coredynp.predictionW; + interface_ip.num_se_rd_ports = 0; + RAS = new ArrayST(&interface_ip, "RAS", Core_device, coredynp.opt_local, + coredynp.core_ty); + RAS->area.set_area(RAS->area.get_area() + + RAS->local_result.area * coredynp.num_hthreads); + area.set_area(area.get_area() + + RAS->local_result.area * coredynp.num_hthreads); } -SchedulerU::SchedulerU(ParseXML* XML_interface, int ithCore_, InputParameter* interface_ip_, const CoreDynParam & dyn_p_, bool exist_) -:XML(XML_interface), - ithCore(ithCore_), - interface_ip(*interface_ip_), - coredynp(dyn_p_), - int_inst_window(0), - fp_inst_window(0), - ROB(0), - instruction_selection(0), - exist(exist_) - { - if (!exist) return; - int tag, data; - bool is_default=true; - string tmp_name; - - clockRate = coredynp.clockRate; - executionTime = coredynp.executionTime; - if ((coredynp.core_ty==Inorder && coredynp.multithreaded)) - { - //Instruction issue queue, in-order multi-issue or multithreaded processor also has this structure. Unified window for Inorder processors - tag = int(log2(XML->sys.core[ithCore].number_hardware_threads)*coredynp.perThreadState);//This is the normal thread state bits based on Niagara Design - data = XML->sys.core[ithCore].instruction_length; - //NOTE: x86 inst can be very lengthy, up to 15B. Source: Intel® 64 and IA-32 Architectures - //Software Developer’s Manual - interface_ip.is_cache = true; - interface_ip.pure_cam = false; - interface_ip.pure_ram = false; - interface_ip.line_sz = int(ceil(data/8.0)); - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.cache_sz = XML->sys.core[ithCore].instruction_window_size*interface_ip.line_sz>64?XML->sys.core[ithCore].instruction_window_size*interface_ip.line_sz:64; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 1; - interface_ip.throughput = 1.0/clockRate; - interface_ip.latency = 1.0/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = coredynp.peak_issueW; - interface_ip.num_wr_ports = coredynp.peak_issueW; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = coredynp.peak_issueW; - int_inst_window = new ArrayST(&interface_ip, "InstFetchQueue", Core_device, coredynp.opt_local, coredynp.core_ty); - int_inst_window->area.set_area(int_inst_window->area.get_area()+ int_inst_window->local_result.area*coredynp.num_pipelines); - area.set_area(area.get_area()+ int_inst_window->local_result.area*coredynp.num_pipelines); - //output_data_csv(iRS.RS.local_result); - Iw_height =int_inst_window->local_result.cache_ht; - - /* - * selection logic - * In a single-issue Inorder multithreaded processor like Niagara, issue width=1*number_of_threads since the processor does need to pick up - * instructions from multiple ready ones(although these ready ones are from different threads).While SMT processors do not distinguish which thread belongs to who - * at the issue stage. - */ - - instruction_selection = new selection_logic(is_default, XML->sys.core[ithCore].instruction_window_size, - coredynp.peak_issueW*XML->sys.core[ithCore].number_hardware_threads, - &interface_ip, Core_device, coredynp.core_ty); - } - - if (coredynp.core_ty==OOO) - { - /* - * CAM based instruction window - * For physicalRegFilebased OOO it is the instruction issue queue, where only tags of phy regs are stored - * For RS based OOO it is the Reservation station, where both tags and values of phy regs are stored - * It is written once and read twice(two operands) before an instruction can be issued. - * X86 instruction can be very long up to 15B. add instruction length in XML - */ - if(coredynp.scheu_ty==PhysicalRegFile) - { - tag = coredynp.phy_ireg_width; - // Each time only half of the tag is compared, but two tag should be stored. - // This underestimate the search power - data = int((ceil((coredynp.instruction_length+2*(coredynp.phy_ireg_width - coredynp.arch_ireg_width))/2.0)/8.0)); - //Data width being divided by 2 means only after both operands available the whole data will be read out. - //This is modeled using two equivalent readouts with half of the data width - tmp_name = "InstIssueQueue"; - } - else - { - tag = coredynp.phy_ireg_width; - // Each time only half of the tag is compared, but two tag should be stored. - // This underestimate the search power - data = int(ceil(((coredynp.instruction_length+2*(coredynp.phy_ireg_width - coredynp.arch_ireg_width)+ - 2*coredynp.int_data_width)/2.0)/8.0)); - //Data width being divided by 2 means only after both operands available the whole data will be read out. - //This is modeled using two equivalent readouts with half of the data width - - tmp_name = "IntReservationStation"; - } - interface_ip.is_cache = true; - interface_ip.pure_cam = false; - interface_ip.pure_ram = false; - interface_ip.line_sz = data; - interface_ip.cache_sz = data*XML->sys.core[ithCore].instruction_window_size; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.access_mode = 0; - interface_ip.throughput = 2*1.0/clockRate; - interface_ip.latency = 2*1.0/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = coredynp.peak_issueW; - interface_ip.num_wr_ports = coredynp.peak_issueW; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = coredynp.peak_issueW; - int_inst_window = new ArrayST(&interface_ip, tmp_name, Core_device, coredynp.opt_local, coredynp.core_ty); - int_inst_window->area.set_area(int_inst_window->area.get_area()+ int_inst_window->local_result.area*coredynp.num_pipelines); - area.set_area(area.get_area()+ int_inst_window->local_result.area*coredynp.num_pipelines); - Iw_height =int_inst_window->local_result.cache_ht; - //FU inst window - if(coredynp.scheu_ty==PhysicalRegFile) - { - tag = 2*coredynp.phy_freg_width;// TODO: each time only half of the tag is compared - data = int(ceil((coredynp.instruction_length+2*(coredynp.phy_freg_width - coredynp.arch_freg_width))/8.0)); - tmp_name = "FPIssueQueue"; - } - else - { - tag = 2*coredynp.phy_ireg_width; - data = int(ceil((coredynp.instruction_length+2*(coredynp.phy_freg_width - coredynp.arch_freg_width)+ - 2*coredynp.fp_data_width)/8.0)); - tmp_name = "FPReservationStation"; - } - interface_ip.is_cache = true; - interface_ip.pure_cam = false; - interface_ip.pure_ram = false; - interface_ip.line_sz = data; - interface_ip.cache_sz = data*XML->sys.core[ithCore].fp_instruction_window_size; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.access_mode = 0; - interface_ip.throughput = 1.0/clockRate; - interface_ip.latency = 1.0/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = coredynp.fp_issueW; - interface_ip.num_wr_ports = coredynp.fp_issueW; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = coredynp.fp_issueW; - fp_inst_window = new ArrayST(&interface_ip, tmp_name, Core_device, coredynp.opt_local, coredynp.core_ty); - fp_inst_window->area.set_area(fp_inst_window->area.get_area()+ fp_inst_window->local_result.area*coredynp.num_fp_pipelines); - area.set_area(area.get_area()+ fp_inst_window->local_result.area*coredynp.num_fp_pipelines); - fp_Iw_height =fp_inst_window->local_result.cache_ht; - - if (XML->sys.core[ithCore].ROB_size >0) - { - /* - * if ROB_size = 0, then the target processor does not support hardware-based - * speculation, i.e. , the processor allow OOO issue as well as OOO completion, which - * means branch must be resolved before instruction issued into instruction window, since - * there is no change to flush miss-predict branch path after instructions are issued in this situation. - * - * ROB.ROB size = inflight inst. ROB is unified for int and fp inst. - * One old approach is to combine the RAT and ROB as a huge CAM structure as in AMD K7. - * However, this approach is abandoned due to its high power and poor scalablility. - * McPAT uses current implementation of ROB as circular buffer. - * ROB is written once when instruction is issued and read once when the instruction is committed. * - */ - int robExtra = int(ceil(5 + log2(coredynp.num_hthreads))); - //5 bits are: busy, Issued, Finished, speculative, valid - if(coredynp.scheu_ty==PhysicalRegFile) - { - //PC is to id the instruction for recover exception. - //inst is used to map the renamed dest. registers.so that commit stage can know which reg/RRAT to update -// data = int(ceil((robExtra+coredynp.pc_width + -// coredynp.instruction_length + 2*coredynp.phy_ireg_width)/8.0)); - data = int(ceil((robExtra+coredynp.pc_width + - coredynp.phy_ireg_width)/8.0)); - } - else - { - //in RS based OOO, ROB also contains value of destination reg -// data = int(ceil((robExtra+coredynp.pc_width + -// coredynp.instruction_length + 2*coredynp.phy_ireg_width + coredynp.fp_data_width)/8.0)); - data = int(ceil((robExtra + coredynp.pc_width + - coredynp.phy_ireg_width + coredynp.fp_data_width)/8.0)); - } - interface_ip.is_cache = false; - interface_ip.pure_cam = false; - interface_ip.pure_ram = true; - interface_ip.line_sz = data; - interface_ip.cache_sz = data*XML->sys.core[ithCore].ROB_size;//The XML ROB size is for all threads - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 1; - interface_ip.throughput = 1.0/clockRate; - interface_ip.latency = 1.0/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = coredynp.peak_commitW; - interface_ip.num_wr_ports = coredynp.peak_issueW; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = 0; - ROB = new ArrayST(&interface_ip, "ReorderBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); - ROB->area.set_area(ROB->area.get_area()+ ROB->local_result.area*coredynp.num_pipelines); - area.set_area(area.get_area()+ ROB->local_result.area*coredynp.num_pipelines); - ROB_height =ROB->local_result.cache_ht; - } - - instruction_selection = new selection_logic(is_default, XML->sys.core[ithCore].instruction_window_size, - coredynp.peak_issueW, &interface_ip, Core_device, coredynp.core_ty); +SchedulerU::SchedulerU(ParseXML* XML_interface, int ithCore_, + InputParameter* interface_ip_, + const CoreDynParam& dyn_p_, bool exist_) + : XML(XML_interface), + ithCore(ithCore_), + interface_ip(*interface_ip_), + coredynp(dyn_p_), + int_inst_window(0), + fp_inst_window(0), + ROB(0), + instruction_selection(0), + exist(exist_) { + if (!exist) return; + int tag, data; + bool is_default = true; + string tmp_name; + + clockRate = coredynp.clockRate; + executionTime = coredynp.executionTime; + if ((coredynp.core_ty == Inorder && coredynp.multithreaded)) { + // Instruction issue queue, in-order multi-issue or multithreaded processor + // also has this structure. Unified window for Inorder processors + tag = int(log2(XML->sys.core[ithCore].number_hardware_threads) * + coredynp.perThreadState); // This is the normal thread state bits + // based on Niagara Design + data = XML->sys.core[ithCore].instruction_length; + // NOTE: x86 inst can be very lengthy, up to 15B. Source: Intel® 64 and + // IA-32 Architectures Software Developer’s Manual + interface_ip.is_cache = true; + interface_ip.pure_cam = false; + interface_ip.pure_ram = false; + interface_ip.line_sz = int(ceil(data / 8.0)); + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.cache_sz = + XML->sys.core[ithCore].instruction_window_size * interface_ip.line_sz > + 64 + ? XML->sys.core[ithCore].instruction_window_size * + interface_ip.line_sz + : 64; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 1; + interface_ip.throughput = 1.0 / clockRate; + interface_ip.latency = 1.0 / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = coredynp.peak_issueW; + interface_ip.num_wr_ports = coredynp.peak_issueW; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = coredynp.peak_issueW; + int_inst_window = new ArrayST(&interface_ip, "InstFetchQueue", Core_device, + coredynp.opt_local, coredynp.core_ty); + int_inst_window->area.set_area(int_inst_window->area.get_area() + + int_inst_window->local_result.area * + coredynp.num_pipelines); + area.set_area(area.get_area() + + int_inst_window->local_result.area * coredynp.num_pipelines); + // output_data_csv(iRS.RS.local_result); + Iw_height = int_inst_window->local_result.cache_ht; + + /* + * selection logic + * In a single-issue Inorder multithreaded processor like Niagara, issue + * width=1*number_of_threads since the processor does need to pick up + * instructions from multiple ready ones(although these ready ones are from + * different threads).While SMT processors do not distinguish which thread + * belongs to who at the issue stage. + */ + + instruction_selection = new selection_logic( + is_default, XML->sys.core[ithCore].instruction_window_size, + coredynp.peak_issueW * XML->sys.core[ithCore].number_hardware_threads, + &interface_ip, Core_device, coredynp.core_ty); + } + + if (coredynp.core_ty == OOO) { + /* + * CAM based instruction window + * For physicalRegFilebased OOO it is the instruction issue queue, where + * only tags of phy regs are stored For RS based OOO it is the Reservation + * station, where both tags and values of phy regs are stored It is written + * once and read twice(two operands) before an instruction can be issued. + * X86 instruction can be very long up to 15B. add instruction length in XML + */ + if (coredynp.scheu_ty == PhysicalRegFile) { + tag = coredynp.phy_ireg_width; + // Each time only half of the tag is compared, but two tag should be + // stored. This underestimate the search power + data = + int((ceil((coredynp.instruction_length + + 2 * (coredynp.phy_ireg_width - coredynp.arch_ireg_width)) / + 2.0) / + 8.0)); + // Data width being divided by 2 means only after both operands available + // the whole data will be read out. This is modeled using two equivalent + // readouts with half of the data width + tmp_name = "InstIssueQueue"; + } else { + tag = coredynp.phy_ireg_width; + // Each time only half of the tag is compared, but two tag should be + // stored. This underestimate the search power + data = + int(ceil(((coredynp.instruction_length + + 2 * (coredynp.phy_ireg_width - coredynp.arch_ireg_width) + + 2 * coredynp.int_data_width) / + 2.0) / + 8.0)); + // Data width being divided by 2 means only after both operands available + // the whole data will be read out. This is modeled using two equivalent + // readouts with half of the data width + + tmp_name = "IntReservationStation"; + } + interface_ip.is_cache = true; + interface_ip.pure_cam = false; + interface_ip.pure_ram = false; + interface_ip.line_sz = data; + interface_ip.cache_sz = + data * XML->sys.core[ithCore].instruction_window_size; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.access_mode = 0; + interface_ip.throughput = 2 * 1.0 / clockRate; + interface_ip.latency = 2 * 1.0 / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = coredynp.peak_issueW; + interface_ip.num_wr_ports = coredynp.peak_issueW; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = coredynp.peak_issueW; + int_inst_window = new ArrayST(&interface_ip, tmp_name, Core_device, + coredynp.opt_local, coredynp.core_ty); + int_inst_window->area.set_area(int_inst_window->area.get_area() + + int_inst_window->local_result.area * + coredynp.num_pipelines); + area.set_area(area.get_area() + + int_inst_window->local_result.area * coredynp.num_pipelines); + Iw_height = int_inst_window->local_result.cache_ht; + // FU inst window + if (coredynp.scheu_ty == PhysicalRegFile) { + tag = 2 * coredynp.phy_freg_width; // TODO: each time only half of the + // tag is compared + data = + int(ceil((coredynp.instruction_length + + 2 * (coredynp.phy_freg_width - coredynp.arch_freg_width)) / + 8.0)); + tmp_name = "FPIssueQueue"; + } else { + tag = 2 * coredynp.phy_ireg_width; + data = + int(ceil((coredynp.instruction_length + + 2 * (coredynp.phy_freg_width - coredynp.arch_freg_width) + + 2 * coredynp.fp_data_width) / + 8.0)); + tmp_name = "FPReservationStation"; + } + interface_ip.is_cache = true; + interface_ip.pure_cam = false; + interface_ip.pure_ram = false; + interface_ip.line_sz = data; + interface_ip.cache_sz = + data * XML->sys.core[ithCore].fp_instruction_window_size; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.access_mode = 0; + interface_ip.throughput = 1.0 / clockRate; + interface_ip.latency = 1.0 / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = coredynp.fp_issueW; + interface_ip.num_wr_ports = coredynp.fp_issueW; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = coredynp.fp_issueW; + fp_inst_window = new ArrayST(&interface_ip, tmp_name, Core_device, + coredynp.opt_local, coredynp.core_ty); + fp_inst_window->area.set_area(fp_inst_window->area.get_area() + + fp_inst_window->local_result.area * + coredynp.num_fp_pipelines); + area.set_area(area.get_area() + fp_inst_window->local_result.area * + coredynp.num_fp_pipelines); + fp_Iw_height = fp_inst_window->local_result.cache_ht; + + if (XML->sys.core[ithCore].ROB_size > 0) { + /* + * if ROB_size = 0, then the target processor does not support + *hardware-based speculation, i.e. , the processor allow OOO issue as well + *as OOO completion, which means branch must be resolved before + *instruction issued into instruction window, since there is no change to + *flush miss-predict branch path after instructions are issued in this + *situation. + * + * ROB.ROB size = inflight inst. ROB is unified for int and fp inst. + * One old approach is to combine the RAT and ROB as a huge CAM structure + *as in AMD K7. However, this approach is abandoned due to its high power + *and poor scalablility. McPAT uses current implementation of ROB as + *circular buffer. ROB is written once when instruction is issued and read + *once when the instruction is committed. * + */ + int robExtra = int(ceil(5 + log2(coredynp.num_hthreads))); + // 5 bits are: busy, Issued, Finished, speculative, valid + if (coredynp.scheu_ty == PhysicalRegFile) { + // PC is to id the instruction for recover exception. + // inst is used to map the renamed dest. registers.so that commit stage + // can know which reg/RRAT to update + // data = + // int(ceil((robExtra+coredynp.pc_width + //+ coredynp.instruction_length + //+ 2*coredynp.phy_ireg_width)/8.0)); + data = int(ceil( + (robExtra + coredynp.pc_width + coredynp.phy_ireg_width) / 8.0)); + } else { + // in RS based OOO, ROB also contains value of destination reg + // data = + // int(ceil((robExtra+coredynp.pc_width + //+ coredynp.instruction_length + //+ 2*coredynp.phy_ireg_width + coredynp.fp_data_width)/8.0)); + data = int(ceil((robExtra + coredynp.pc_width + + coredynp.phy_ireg_width + coredynp.fp_data_width) / + 8.0)); + } + interface_ip.is_cache = false; + interface_ip.pure_cam = false; + interface_ip.pure_ram = true; + interface_ip.line_sz = data; + interface_ip.cache_sz = + data * XML->sys.core[ithCore] + .ROB_size; // The XML ROB size is for all threads + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 1; + interface_ip.throughput = 1.0 / clockRate; + interface_ip.latency = 1.0 / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = coredynp.peak_commitW; + interface_ip.num_wr_ports = coredynp.peak_issueW; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = 0; + ROB = new ArrayST(&interface_ip, "ReorderBuffer", Core_device, + coredynp.opt_local, coredynp.core_ty); + ROB->area.set_area(ROB->area.get_area() + + ROB->local_result.area * coredynp.num_pipelines); + area.set_area(area.get_area() + + ROB->local_result.area * coredynp.num_pipelines); + ROB_height = ROB->local_result.cache_ht; } + + instruction_selection = new selection_logic( + is_default, XML->sys.core[ithCore].instruction_window_size, + coredynp.peak_issueW, &interface_ip, Core_device, coredynp.core_ty); + } } -LoadStoreU::LoadStoreU(ParseXML* XML_interface, int ithCore_, InputParameter* interface_ip_, const CoreDynParam & dyn_p_,bool exist_) -:XML(XML_interface), - ithCore(ithCore_), - interface_ip(*interface_ip_), - coredynp(dyn_p_), - LSQ(0), - exist(exist_) -{ - if (!exist) return; - int idx, tag, data, size, line, assoc; - bool debug= false; - int ldst_opcode = XML->sys.core[ithCore].opcode_width;//16; - - clockRate = coredynp.clockRate; - executionTime = coredynp.executionTime; - cache_p = (Cache_policy)XML->sys.core[ithCore].dcache.dcache_config[7]; - - interface_ip.num_search_ports = XML->sys.core[ithCore].memory_ports; - interface_ip.is_cache = true; - interface_ip.pure_cam = false; - interface_ip.pure_ram = false; - - - //Crossbar based interconnect for shared memory accesses, added by Syed - //Crossbar - - if(XML->sys.architecture==1){ - xbar_shared = new Crossbar(coredynp.num_fpus,coredynp.num_fpus,32,&(g_tp.peri_global));//Syed: coredynp.num_fpus is used as simd_width - } - else{ - xbar_shared = new Crossbar(coredynp.num_fpus,coredynp.num_fpus,32,&(g_tp.peri_global));//Syed: coredynp.num_fpus is used as simd_width - } - - - //TODO: Check if this line should be changed to - //new Crossbar(simd_width,shared_memory_banks,word_length*simd_width,&(g_tp.peri_global)); - - //shared memory added by Jingwen - size = (int)XML->sys.core[ithCore].sharedmemory.dcache_config[0]; - line = (int)XML->sys.core[ithCore].sharedmemory.dcache_config[1]; - assoc = (int)XML->sys.core[ithCore].sharedmemory.dcache_config[2]; - idx = debug?9:int(ceil(log2(size/line/assoc))); - tag = debug?51:XML->sys.physical_address_width-idx-int(ceil(log2(line))) + EXTRA_TAG_BITS; - interface_ip.specific_tag = 1; - interface_ip.tag_w = 1; - interface_ip.cache_sz = debug?32768:(int)XML->sys.core[ithCore].sharedmemory.dcache_config[0]; - interface_ip.line_sz = debug?64:(int)XML->sys.core[ithCore].sharedmemory.dcache_config[1]; - interface_ip.assoc = debug?8:(int)XML->sys.core[ithCore].sharedmemory.dcache_config[2]; - interface_ip.nbanks = debug?1:(int)XML->sys.core[ithCore].sharedmemory.dcache_config[3]; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 0;//debug?0:XML->sys.core[ithCore].sharedmemory.dcache_config[5]; - interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].sharedmemory.dcache_config[4]/clockRate; - interface_ip.latency = debug?3.0/clockRate:XML->sys.core[ithCore].sharedmemory.dcache_config[5]/clockRate; - interface_ip.is_cache = true; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;//usually In-order has 1 and OOO has 2 at least. - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - sharedmemory.caches = new ArrayST(&interface_ip, "sharedmemory", Core_device, coredynp.opt_local, coredynp.core_ty); - sharedmemory.area.set_area(sharedmemory.area.get_area()+ sharedmemory.caches->local_result.area); - area.set_area(area.get_area()+ sharedmemory.caches->local_result.area + xbar_shared->area.get_area()); - - - //shared memory buffer - //miss buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = (XML->sys.physical_address_width) + int(ceil(log2(size/line))) + sharedmemory.caches->l_ip.line_sz*8; - interface_ip.specific_tag = 1; - interface_ip.tag_w = 1; - interface_ip.line_sz = int(ceil(data/8.0));//int(ceil(pow(2.0,ceil(log2(data)))/8.0)); - interface_ip.cache_sz = XML->sys.core[ithCore].sharedmemory.buffer_sizes[0]*interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 2; - interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].sharedmemory.dcache_config[4]/clockRate; - interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].sharedmemory.dcache_config[5]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - sharedmemory.missb = new ArrayST(&interface_ip, "SharedmemoryMissBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); - sharedmemory.area.set_area(sharedmemory.area.get_area()+ sharedmemory.missb->local_result.area); - area.set_area(area.get_area()+ sharedmemory.missb->local_result.area); - - - //sharedmemory fill buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = sharedmemory.caches->l_ip.line_sz; - interface_ip.specific_tag = 1; - interface_ip.tag_w = 1; - interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); - interface_ip.cache_sz = data*XML->sys.core[ithCore].sharedmemory.buffer_sizes[1]; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 2; - interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].sharedmemory.dcache_config[4]/clockRate; - interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].sharedmemory.dcache_config[5]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - sharedmemory.ifb = new ArrayST(&interface_ip, "SharedMemoryFillBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); - sharedmemory.area.set_area(sharedmemory.area.get_area()+ sharedmemory.ifb->local_result.area); - area.set_area(area.get_area()+ sharedmemory.ifb->local_result.area); - - //sharedmemory prefetch buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS;//check with previous entries to decide wthether to merge. - data = sharedmemory.caches->l_ip.line_sz;//separate queue to prevent from cache polution. - interface_ip.specific_tag = 1; - interface_ip.tag_w = 1; - interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); - interface_ip.cache_sz = XML->sys.core[ithCore].sharedmemory.buffer_sizes[2]*interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 2; - interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].sharedmemory.dcache_config[4]/clockRate; - interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].sharedmemory.dcache_config[5]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - sharedmemory.prefetchb = new ArrayST(&interface_ip, "dcacheprefetchBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); - sharedmemory.area.set_area(sharedmemory.area.get_area()+ sharedmemory.prefetchb->local_result.area); - area.set_area(area.get_area()+ sharedmemory.prefetchb->local_result.area); - - //shared memory WBB - if (cache_p==Write_back) - { - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = sharedmemory.caches->l_ip.line_sz; - interface_ip.specific_tag = 1; - interface_ip.tag_w = 1; - interface_ip.line_sz = data; - interface_ip.cache_sz = XML->sys.core[ithCore].sharedmemory.buffer_sizes[3]*interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 2; - interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].sharedmemory.dcache_config[4]/clockRate; - interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].sharedmemory.dcache_config[5]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = XML->sys.core[ithCore].memory_ports; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - sharedmemory.wbb = new ArrayST(&interface_ip, "dcacheWBB", Core_device, coredynp.opt_local, coredynp.core_ty); - sharedmemory.area.set_area(sharedmemory.area.get_area()+ sharedmemory.wbb->local_result.area); - area.set_area(area.get_area()+ sharedmemory.wbb->local_result.area); - //output_data_csv(sharedmemory.wbb.local_result); - } - - - /* - * ccache starts here - */ - //Constant cache - size = (int)XML->sys.core[ithCore].ccache.dcache_config[0]; - line = (int)XML->sys.core[ithCore].ccache.dcache_config[1]; - assoc = (int)XML->sys.core[ithCore].ccache.dcache_config[2]; - idx = debug?9:int(ceil(log2(size/line/assoc))); - tag = debug?51:XML->sys.physical_address_width-idx-int(ceil(log2(line))) + EXTRA_TAG_BITS; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.cache_sz = debug?32768:(int)XML->sys.core[ithCore].ccache.dcache_config[0]; - interface_ip.line_sz = debug?64:(int)XML->sys.core[ithCore].ccache.dcache_config[1]; - interface_ip.assoc = debug?8:(int)XML->sys.core[ithCore].ccache.dcache_config[2]; - interface_ip.nbanks = debug?1:(int)XML->sys.core[ithCore].ccache.dcache_config[3]; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 0;//debug?0:XML->sys.core[ithCore].ccache.dcache_config[5]; - interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].ccache.dcache_config[4]/clockRate; - interface_ip.latency = debug?3.0/clockRate:XML->sys.core[ithCore].ccache.dcache_config[5]/clockRate; - interface_ip.is_cache = true; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;//usually In-order has 1 and OOO has 2 at least. - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - ccache.caches = new ArrayST(&interface_ip, "ccache", Core_device, coredynp.opt_local, coredynp.core_ty); - ccache.area.set_area(ccache.area.get_area()+ ccache.caches->local_result.area); - area.set_area(area.get_area()+ ccache.caches->local_result.area); - //output_data_csv(ccache.caches.local_result); - - - - //cCache controllers - //miss buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = (XML->sys.physical_address_width) + int(ceil(log2(size/line))) + ccache.caches->l_ip.line_sz*8; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = int(ceil(data/8.0));//int(ceil(pow(2.0,ceil(log2(data)))/8.0)); - interface_ip.cache_sz = XML->sys.core[ithCore].ccache.buffer_sizes[0]*interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 2; - interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].ccache.dcache_config[4]/clockRate; - interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].ccache.dcache_config[5]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - ccache.missb = new ArrayST(&interface_ip, "ccacheMissBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); - ccache.area.set_area(ccache.area.get_area()+ ccache.missb->local_result.area); - area.set_area(area.get_area()+ ccache.missb->local_result.area); - //output_data_csv(ccache.missb.local_result); - - //fill buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = ccache.caches->l_ip.line_sz; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); - interface_ip.cache_sz = data*XML->sys.core[ithCore].ccache.buffer_sizes[1]; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 2; - interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].ccache.dcache_config[4]/clockRate; - interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].ccache.dcache_config[5]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - ccache.ifb = new ArrayST(&interface_ip, "ccacheFillBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); - ccache.area.set_area(ccache.area.get_area()+ ccache.ifb->local_result.area); - area.set_area(area.get_area()+ ccache.ifb->local_result.area); - //output_data_csv(ccache.ifb.local_result); - - //prefetch buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS;//check with previous entries to decide wthether to merge. - data = ccache.caches->l_ip.line_sz;//separate queue to prevent from cache polution. - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); - interface_ip.cache_sz = XML->sys.core[ithCore].ccache.buffer_sizes[2]*interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 2; - interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].ccache.dcache_config[4]/clockRate; - interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].ccache.dcache_config[5]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - ccache.prefetchb = new ArrayST(&interface_ip, "ccacheprefetchBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); - ccache.area.set_area(ccache.area.get_area()+ ccache.prefetchb->local_result.area); - area.set_area(area.get_area()+ ccache.prefetchb->local_result.area); - //output_data_csv(ccache.prefetchb.local_result); - - //WBB - if (cache_p==Write_back) - { - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = ccache.caches->l_ip.line_sz; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data; - interface_ip.cache_sz = XML->sys.core[ithCore].ccache.buffer_sizes[3]*interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 2; - interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].ccache.dcache_config[4]/clockRate; - interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].ccache.dcache_config[5]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = XML->sys.core[ithCore].memory_ports; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - ccache.wbb = new ArrayST(&interface_ip, "ccacheWBB", Core_device, coredynp.opt_local, coredynp.core_ty); - ccache.area.set_area(ccache.area.get_area()+ ccache.wbb->local_result.area); - area.set_area(area.get_area()+ ccache.wbb->local_result.area); - //output_data_csv(ccache.wbb.local_result); - } - - /* - * tcache starts here - */ - //Texture cache - size = (int)XML->sys.core[ithCore].tcache.dcache_config[0]; - line = (int)XML->sys.core[ithCore].tcache.dcache_config[1]; - assoc = (int)XML->sys.core[ithCore].tcache.dcache_config[2]; - idx = debug?9:int(ceil(log2(size/line/assoc))); - tag = debug?51:XML->sys.physical_address_width-idx-int(ceil(log2(line))) + EXTRA_TAG_BITS; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.cache_sz = debug?32768:(int)XML->sys.core[ithCore].tcache.dcache_config[0]; - interface_ip.line_sz = debug?64:(int)XML->sys.core[ithCore].tcache.dcache_config[1]; - interface_ip.assoc = debug?8:(int)XML->sys.core[ithCore].tcache.dcache_config[2]; - interface_ip.nbanks = debug?1:(int)XML->sys.core[ithCore].tcache.dcache_config[3]; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 0;//debug?0:XML->sys.core[ithCore].tcache.dcache_config[5]; - interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].tcache.dcache_config[4]/clockRate; - interface_ip.latency = debug?3.0/clockRate:XML->sys.core[ithCore].tcache.dcache_config[5]/clockRate; - interface_ip.is_cache = true; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;//usually In-order has 1 and OOO has 2 at least. - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - tcache.caches = new ArrayST(&interface_ip, "tcache", Core_device, coredynp.opt_local, coredynp.core_ty); - tcache.area.set_area(tcache.area.get_area()+ tcache.caches->local_result.area); - area.set_area(area.get_area()+ tcache.caches->local_result.area); - //output_data_csv(tcache.caches.local_result); - - - //tCache controllers - //miss buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = (XML->sys.physical_address_width) + int(ceil(log2(size/line))) + tcache.caches->l_ip.line_sz*8; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = int(ceil(data/8.0));//int(ceil(pow(2.0,ceil(log2(data)))/8.0)); - interface_ip.cache_sz = XML->sys.core[ithCore].tcache.buffer_sizes[0]*interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 2; - interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].tcache.dcache_config[4]/clockRate; - interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].tcache.dcache_config[5]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - tcache.missb = new ArrayST(&interface_ip, "tcacheMissBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); - tcache.area.set_area(tcache.area.get_area()+ tcache.missb->local_result.area); - area.set_area(area.get_area()+ tcache.missb->local_result.area); - //output_data_csv(tcache.missb.local_result); - - //fill buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = tcache.caches->l_ip.line_sz; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); - interface_ip.cache_sz = data*XML->sys.core[ithCore].tcache.buffer_sizes[1]; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 2; - interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].tcache.dcache_config[4]/clockRate; - interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].tcache.dcache_config[5]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - tcache.ifb = new ArrayST(&interface_ip, "tcacheFillBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); - tcache.area.set_area(tcache.area.get_area()+ tcache.ifb->local_result.area); - area.set_area(area.get_area()+ tcache.ifb->local_result.area); - //output_data_csv(tcache.ifb.local_result); - - //prefetch buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS;//check with previous entries to decide wthether to merge. - data = tcache.caches->l_ip.line_sz;//separate queue to prevent from cache polution. - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); - interface_ip.cache_sz = XML->sys.core[ithCore].tcache.buffer_sizes[2]*interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 2; - interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].tcache.dcache_config[4]/clockRate; - interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].tcache.dcache_config[5]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - tcache.prefetchb = new ArrayST(&interface_ip, "tcacheprefetchBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); - tcache.area.set_area(tcache.area.get_area()+ tcache.prefetchb->local_result.area); - area.set_area(area.get_area()+ tcache.prefetchb->local_result.area); - //output_data_csv(tcache.prefetchb.local_result); - - //WBB - if (cache_p==Write_back) - { - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = tcache.caches->l_ip.line_sz; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data; - interface_ip.cache_sz = XML->sys.core[ithCore].tcache.buffer_sizes[3]*interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 2; - interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].tcache.dcache_config[4]/clockRate; - interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].tcache.dcache_config[5]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = XML->sys.core[ithCore].memory_ports; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - tcache.wbb = new ArrayST(&interface_ip, "tcacheWBB", Core_device, coredynp.opt_local, coredynp.core_ty); - tcache.area.set_area(tcache.area.get_area()+ tcache.wbb->local_result.area); - area.set_area(area.get_area()+ tcache.wbb->local_result.area); - //output_data_csv(tcache.wbb.local_result); - } - - - - - /* - * dcache starts here - */ - //Dcache - size = (int)XML->sys.core[ithCore].dcache.dcache_config[0]; - line = (int)XML->sys.core[ithCore].dcache.dcache_config[1]; - assoc = (int)XML->sys.core[ithCore].dcache.dcache_config[2]; - idx = debug?9:int(ceil(log2(size/line/assoc))); - tag = debug?51:XML->sys.physical_address_width-idx-int(ceil(log2(line))) + EXTRA_TAG_BITS; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.cache_sz = debug?32768:(int)XML->sys.core[ithCore].dcache.dcache_config[0]; - interface_ip.line_sz = debug?64:(int)XML->sys.core[ithCore].dcache.dcache_config[1]; - interface_ip.assoc = debug?8:(int)XML->sys.core[ithCore].dcache.dcache_config[2]; - interface_ip.nbanks = debug?1:(int)XML->sys.core[ithCore].dcache.dcache_config[3]; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 0;//debug?0:XML->sys.core[ithCore].dcache.dcache_config[5]; - interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].dcache.dcache_config[4]/clockRate; - interface_ip.latency = debug?3.0/clockRate:XML->sys.core[ithCore].dcache.dcache_config[5]/clockRate; - interface_ip.is_cache = true; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;//usually In-order has 1 and OOO has 2 at least. - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - dcache.caches = new ArrayST(&interface_ip, "dcache", Core_device, coredynp.opt_local, coredynp.core_ty); - dcache.area.set_area(dcache.area.get_area()+ dcache.caches->local_result.area); - area.set_area(area.get_area()+ dcache.caches->local_result.area); - //output_data_csv(dcache.caches.local_result); - - - //dCache controllers - //miss buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = (XML->sys.physical_address_width) + int(ceil(log2(size/line))) + dcache.caches->l_ip.line_sz*8; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = int(ceil(data/8.0));//int(ceil(pow(2.0,ceil(log2(data)))/8.0)); - interface_ip.cache_sz = XML->sys.core[ithCore].dcache.buffer_sizes[0]*interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 2; - interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].dcache.dcache_config[4]/clockRate; - interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].dcache.dcache_config[5]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - dcache.missb = new ArrayST(&interface_ip, "dcacheMissBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); - dcache.area.set_area(dcache.area.get_area()+ dcache.missb->local_result.area); - area.set_area(area.get_area()+ dcache.missb->local_result.area); - //output_data_csv(dcache.missb.local_result); - - //fill buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = dcache.caches->l_ip.line_sz; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); - interface_ip.cache_sz = data*XML->sys.core[ithCore].dcache.buffer_sizes[1]; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 2; - interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].dcache.dcache_config[4]/clockRate; - interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].dcache.dcache_config[5]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - dcache.ifb = new ArrayST(&interface_ip, "dcacheFillBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); - dcache.area.set_area(dcache.area.get_area()+ dcache.ifb->local_result.area); - area.set_area(area.get_area()+ dcache.ifb->local_result.area); - //output_data_csv(dcache.ifb.local_result); - - //prefetch buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS;//check with previous entries to decide wthether to merge. - data = dcache.caches->l_ip.line_sz;//separate queue to prevent from cache polution. - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); - interface_ip.cache_sz = XML->sys.core[ithCore].dcache.buffer_sizes[2]*interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 2; - interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].dcache.dcache_config[4]/clockRate; - interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].dcache.dcache_config[5]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = debug?1:XML->sys.core[ithCore].memory_ports;; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - dcache.prefetchb = new ArrayST(&interface_ip, "dcacheprefetchBuffer", Core_device, coredynp.opt_local, coredynp.core_ty); - dcache.area.set_area(dcache.area.get_area()+ dcache.prefetchb->local_result.area); - area.set_area(area.get_area()+ dcache.prefetchb->local_result.area); - //output_data_csv(dcache.prefetchb.local_result); - - //WBB - if (cache_p==Write_back) - { - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = dcache.caches->l_ip.line_sz; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data; - interface_ip.cache_sz = XML->sys.core[ithCore].dcache.buffer_sizes[3]*interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 2; - interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].dcache.dcache_config[4]/clockRate; - interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].dcache.dcache_config[5]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = XML->sys.core[ithCore].memory_ports; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - dcache.wbb = new ArrayST(&interface_ip, "dcacheWBB", Core_device, coredynp.opt_local, coredynp.core_ty); - dcache.area.set_area(dcache.area.get_area()+ dcache.wbb->local_result.area); - area.set_area(area.get_area()+ dcache.wbb->local_result.area); - //output_data_csv(dcache.wbb.local_result); - } - - /* - * LSU--in-order processors do not have separate load queue: unified lsq - * partitioned among threads - * it is actually the store queue but for inorder processors it serves as both loadQ and StoreQ - */ - tag = ldst_opcode+XML->sys.virtual_address_width +int(ceil(log2(XML->sys.core[ithCore].number_hardware_threads))) + EXTRA_TAG_BITS; - data = XML->sys.machine_bits; - interface_ip.is_cache = true; - interface_ip.line_sz = int(ceil(data/32.0))*4; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.cache_sz = XML->sys.core[ithCore].store_buffer_size*interface_ip.line_sz*XML->sys.core[ithCore].number_hardware_threads; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 1; - interface_ip.throughput = 1.0/clockRate; - interface_ip.latency = 1.0/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = XML->sys.core[ithCore].memory_ports; - interface_ip.num_wr_ports = XML->sys.core[ithCore].memory_ports; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports =XML->sys.core[ithCore].memory_ports; - LSQ = new ArrayST(&interface_ip, "Load(Store)Queue", Core_device, coredynp.opt_local, coredynp.core_ty); - LSQ->area.set_area(LSQ->area.get_area()+ LSQ->local_result.area); - area.set_area(area.get_area()+ LSQ->local_result.area); - area.set_area(area.get_area()*cdb_overhead); - //output_data_csv(LSQ.LSQ.local_result); - lsq_height=LSQ->local_result.cache_ht*sqrt(cdb_overhead);/*XML->sys.core[ithCore].number_hardware_threads*/ - - if ((coredynp.core_ty==OOO) && (XML->sys.core[ithCore].load_buffer_size >0)) - { - interface_ip.line_sz = int(ceil(data/32.0))*4; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.cache_sz = XML->sys.core[ithCore].load_buffer_size*interface_ip.line_sz*XML->sys.core[ithCore].number_hardware_threads; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 1; - interface_ip.throughput = 1.0/clockRate; - interface_ip.latency = 1.0/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = XML->sys.core[ithCore].memory_ports; - interface_ip.num_wr_ports = XML->sys.core[ithCore].memory_ports; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports =XML->sys.core[ithCore].memory_ports; - LoadQ = new ArrayST(&interface_ip, "LoadQueue", Core_device, coredynp.opt_local, coredynp.core_ty); - LoadQ->area.set_area(LoadQ->area.get_area()+ LoadQ->local_result.area); - area.set_area(area.get_area()+ LoadQ->local_result.area); - area.set_area(area.get_area()*cdb_overhead); - //output_data_csv(LoadQ.LoadQ.local_result); - lsq_height=(LSQ->local_result.cache_ht + LoadQ->local_result.cache_ht)*sqrt(cdb_overhead);/*XML->sys.core[ithCore].number_hardware_threads*/ - } +LoadStoreU::LoadStoreU(ParseXML* XML_interface, int ithCore_, + InputParameter* interface_ip_, + const CoreDynParam& dyn_p_, bool exist_) + : XML(XML_interface), + ithCore(ithCore_), + interface_ip(*interface_ip_), + coredynp(dyn_p_), + LSQ(0), + exist(exist_) { + if (!exist) return; + int idx, tag, data, size, line, assoc; + bool debug = false; + int ldst_opcode = XML->sys.core[ithCore].opcode_width; // 16; + + clockRate = coredynp.clockRate; + executionTime = coredynp.executionTime; + cache_p = (Cache_policy)XML->sys.core[ithCore].dcache.dcache_config[7]; + + interface_ip.num_search_ports = XML->sys.core[ithCore].memory_ports; + interface_ip.is_cache = true; + interface_ip.pure_cam = false; + interface_ip.pure_ram = false; + + // Crossbar based interconnect for shared memory accesses, added by Syed + // Crossbar + + if (XML->sys.architecture == 1) { + xbar_shared = new Crossbar( + coredynp.num_fpus, coredynp.num_fpus, 32, + &(g_tp.peri_global)); // Syed: coredynp.num_fpus is used as simd_width + } else { + xbar_shared = new Crossbar( + coredynp.num_fpus, coredynp.num_fpus, 32, + &(g_tp.peri_global)); // Syed: coredynp.num_fpus is used as simd_width + } + + // TODO: Check if this line should be changed to + // new + // Crossbar(simd_width,shared_memory_banks,word_length*simd_width,&(g_tp.peri_global)); + + // shared memory added by Jingwen + size = (int)XML->sys.core[ithCore].sharedmemory.dcache_config[0]; + line = (int)XML->sys.core[ithCore].sharedmemory.dcache_config[1]; + assoc = (int)XML->sys.core[ithCore].sharedmemory.dcache_config[2]; + idx = debug ? 9 : int(ceil(log2(size / line / assoc))); + tag = debug ? 51 + : XML->sys.physical_address_width - idx - int(ceil(log2(line))) + + EXTRA_TAG_BITS; + interface_ip.specific_tag = 1; + interface_ip.tag_w = 1; + interface_ip.cache_sz = + debug ? 32768 : (int)XML->sys.core[ithCore].sharedmemory.dcache_config[0]; + interface_ip.line_sz = + debug ? 64 : (int)XML->sys.core[ithCore].sharedmemory.dcache_config[1]; + interface_ip.assoc = + debug ? 8 : (int)XML->sys.core[ithCore].sharedmemory.dcache_config[2]; + interface_ip.nbanks = + debug ? 1 : (int)XML->sys.core[ithCore].sharedmemory.dcache_config[3]; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = + 0; // debug?0:XML->sys.core[ithCore].sharedmemory.dcache_config[5]; + interface_ip.throughput = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].sharedmemory.dcache_config[4] / clockRate; + interface_ip.latency = + debug ? 3.0 / clockRate + : XML->sys.core[ithCore].sharedmemory.dcache_config[5] / clockRate; + interface_ip.is_cache = true; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = + debug ? 1 + : XML->sys.core[ithCore].memory_ports; // usually In-order has 1 + // and OOO has 2 at least. + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + sharedmemory.caches = new ArrayST(&interface_ip, "sharedmemory", Core_device, + coredynp.opt_local, coredynp.core_ty); + sharedmemory.area.set_area(sharedmemory.area.get_area() + + sharedmemory.caches->local_result.area); + area.set_area(area.get_area() + sharedmemory.caches->local_result.area + + xbar_shared->area.get_area()); + + // shared memory buffer + // miss buffer + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = (XML->sys.physical_address_width) + int(ceil(log2(size / line))) + + sharedmemory.caches->l_ip.line_sz * 8; + interface_ip.specific_tag = 1; + interface_ip.tag_w = 1; + interface_ip.line_sz = + int(ceil(data / 8.0)); // int(ceil(pow(2.0,ceil(log2(data)))/8.0)); + interface_ip.cache_sz = XML->sys.core[ithCore].sharedmemory.buffer_sizes[0] * + interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 2; + interface_ip.throughput = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].sharedmemory.dcache_config[4] / clockRate; + interface_ip.latency = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].sharedmemory.dcache_config[5] / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug ? 1 : XML->sys.core[ithCore].memory_ports; + ; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + sharedmemory.missb = + new ArrayST(&interface_ip, "SharedmemoryMissBuffer", Core_device, + coredynp.opt_local, coredynp.core_ty); + sharedmemory.area.set_area(sharedmemory.area.get_area() + + sharedmemory.missb->local_result.area); + area.set_area(area.get_area() + sharedmemory.missb->local_result.area); + + // sharedmemory fill buffer + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = sharedmemory.caches->l_ip.line_sz; + interface_ip.specific_tag = 1; + interface_ip.tag_w = 1; + interface_ip.line_sz = data; // int(pow(2.0,ceil(log2(data)))); + interface_ip.cache_sz = + data * XML->sys.core[ithCore].sharedmemory.buffer_sizes[1]; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 2; + interface_ip.throughput = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].sharedmemory.dcache_config[4] / clockRate; + interface_ip.latency = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].sharedmemory.dcache_config[5] / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug ? 1 : XML->sys.core[ithCore].memory_ports; + ; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + sharedmemory.ifb = + new ArrayST(&interface_ip, "SharedMemoryFillBuffer", Core_device, + coredynp.opt_local, coredynp.core_ty); + sharedmemory.area.set_area(sharedmemory.area.get_area() + + sharedmemory.ifb->local_result.area); + area.set_area(area.get_area() + sharedmemory.ifb->local_result.area); + + // sharedmemory prefetch buffer + tag = XML->sys.physical_address_width + + EXTRA_TAG_BITS; // check with previous entries to decide wthether to + // merge. + data = sharedmemory.caches->l_ip + .line_sz; // separate queue to prevent from cache polution. + interface_ip.specific_tag = 1; + interface_ip.tag_w = 1; + interface_ip.line_sz = data; // int(pow(2.0,ceil(log2(data)))); + interface_ip.cache_sz = XML->sys.core[ithCore].sharedmemory.buffer_sizes[2] * + interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 2; + interface_ip.throughput = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].sharedmemory.dcache_config[4] / clockRate; + interface_ip.latency = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].sharedmemory.dcache_config[5] / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug ? 1 : XML->sys.core[ithCore].memory_ports; + ; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + sharedmemory.prefetchb = + new ArrayST(&interface_ip, "dcacheprefetchBuffer", Core_device, + coredynp.opt_local, coredynp.core_ty); + sharedmemory.area.set_area(sharedmemory.area.get_area() + + sharedmemory.prefetchb->local_result.area); + area.set_area(area.get_area() + sharedmemory.prefetchb->local_result.area); + + // shared memory WBB + if (cache_p == Write_back) { + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = sharedmemory.caches->l_ip.line_sz; + interface_ip.specific_tag = 1; + interface_ip.tag_w = 1; + interface_ip.line_sz = data; + interface_ip.cache_sz = + XML->sys.core[ithCore].sharedmemory.buffer_sizes[3] * + interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 2; + interface_ip.throughput = + debug + ? 1.0 / clockRate + : XML->sys.core[ithCore].sharedmemory.dcache_config[4] / clockRate; + interface_ip.latency = + debug + ? 1.0 / clockRate + : XML->sys.core[ithCore].sharedmemory.dcache_config[5] / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = XML->sys.core[ithCore].memory_ports; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + sharedmemory.wbb = new ArrayST(&interface_ip, "dcacheWBB", Core_device, + coredynp.opt_local, coredynp.core_ty); + sharedmemory.area.set_area(sharedmemory.area.get_area() + + sharedmemory.wbb->local_result.area); + area.set_area(area.get_area() + sharedmemory.wbb->local_result.area); + // output_data_csv(sharedmemory.wbb.local_result); + } + + /* + * ccache starts here + */ + // Constant cache + size = (int)XML->sys.core[ithCore].ccache.dcache_config[0]; + line = (int)XML->sys.core[ithCore].ccache.dcache_config[1]; + assoc = (int)XML->sys.core[ithCore].ccache.dcache_config[2]; + idx = debug ? 9 : int(ceil(log2(size / line / assoc))); + tag = debug ? 51 + : XML->sys.physical_address_width - idx - int(ceil(log2(line))) + + EXTRA_TAG_BITS; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.cache_sz = + debug ? 32768 : (int)XML->sys.core[ithCore].ccache.dcache_config[0]; + interface_ip.line_sz = + debug ? 64 : (int)XML->sys.core[ithCore].ccache.dcache_config[1]; + interface_ip.assoc = + debug ? 8 : (int)XML->sys.core[ithCore].ccache.dcache_config[2]; + interface_ip.nbanks = + debug ? 1 : (int)XML->sys.core[ithCore].ccache.dcache_config[3]; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = + 0; // debug?0:XML->sys.core[ithCore].ccache.dcache_config[5]; + interface_ip.throughput = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].ccache.dcache_config[4] / clockRate; + interface_ip.latency = + debug ? 3.0 / clockRate + : XML->sys.core[ithCore].ccache.dcache_config[5] / clockRate; + interface_ip.is_cache = true; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = + debug ? 1 + : XML->sys.core[ithCore].memory_ports; // usually In-order has 1 + // and OOO has 2 at least. + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + ccache.caches = new ArrayST(&interface_ip, "ccache", Core_device, + coredynp.opt_local, coredynp.core_ty); + ccache.area.set_area(ccache.area.get_area() + + ccache.caches->local_result.area); + area.set_area(area.get_area() + ccache.caches->local_result.area); + // output_data_csv(ccache.caches.local_result); + + // cCache controllers + // miss buffer + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = (XML->sys.physical_address_width) + int(ceil(log2(size / line))) + + ccache.caches->l_ip.line_sz * 8; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = + int(ceil(data / 8.0)); // int(ceil(pow(2.0,ceil(log2(data)))/8.0)); + interface_ip.cache_sz = + XML->sys.core[ithCore].ccache.buffer_sizes[0] * interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 2; + interface_ip.throughput = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].ccache.dcache_config[4] / clockRate; + interface_ip.latency = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].ccache.dcache_config[5] / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug ? 1 : XML->sys.core[ithCore].memory_ports; + ; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + ccache.missb = new ArrayST(&interface_ip, "ccacheMissBuffer", Core_device, + coredynp.opt_local, coredynp.core_ty); + ccache.area.set_area(ccache.area.get_area() + + ccache.missb->local_result.area); + area.set_area(area.get_area() + ccache.missb->local_result.area); + // output_data_csv(ccache.missb.local_result); + + // fill buffer + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = ccache.caches->l_ip.line_sz; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data; // int(pow(2.0,ceil(log2(data)))); + interface_ip.cache_sz = data * XML->sys.core[ithCore].ccache.buffer_sizes[1]; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 2; + interface_ip.throughput = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].ccache.dcache_config[4] / clockRate; + interface_ip.latency = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].ccache.dcache_config[5] / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug ? 1 : XML->sys.core[ithCore].memory_ports; + ; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + ccache.ifb = new ArrayST(&interface_ip, "ccacheFillBuffer", Core_device, + coredynp.opt_local, coredynp.core_ty); + ccache.area.set_area(ccache.area.get_area() + ccache.ifb->local_result.area); + area.set_area(area.get_area() + ccache.ifb->local_result.area); + // output_data_csv(ccache.ifb.local_result); + + // prefetch buffer + tag = XML->sys.physical_address_width + + EXTRA_TAG_BITS; // check with previous entries to decide wthether to + // merge. + data = ccache.caches->l_ip + .line_sz; // separate queue to prevent from cache polution. + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data; // int(pow(2.0,ceil(log2(data)))); + interface_ip.cache_sz = + XML->sys.core[ithCore].ccache.buffer_sizes[2] * interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 2; + interface_ip.throughput = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].ccache.dcache_config[4] / clockRate; + interface_ip.latency = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].ccache.dcache_config[5] / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug ? 1 : XML->sys.core[ithCore].memory_ports; + ; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + ccache.prefetchb = + new ArrayST(&interface_ip, "ccacheprefetchBuffer", Core_device, + coredynp.opt_local, coredynp.core_ty); + ccache.area.set_area(ccache.area.get_area() + + ccache.prefetchb->local_result.area); + area.set_area(area.get_area() + ccache.prefetchb->local_result.area); + // output_data_csv(ccache.prefetchb.local_result); + + // WBB + if (cache_p == Write_back) { + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = ccache.caches->l_ip.line_sz; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data; + interface_ip.cache_sz = + XML->sys.core[ithCore].ccache.buffer_sizes[3] * interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 2; + interface_ip.throughput = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].ccache.dcache_config[4] / clockRate; + interface_ip.latency = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].ccache.dcache_config[5] / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = XML->sys.core[ithCore].memory_ports; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + ccache.wbb = new ArrayST(&interface_ip, "ccacheWBB", Core_device, + coredynp.opt_local, coredynp.core_ty); + ccache.area.set_area(ccache.area.get_area() + + ccache.wbb->local_result.area); + area.set_area(area.get_area() + ccache.wbb->local_result.area); + // output_data_csv(ccache.wbb.local_result); + } + + /* + * tcache starts here + */ + // Texture cache + size = (int)XML->sys.core[ithCore].tcache.dcache_config[0]; + line = (int)XML->sys.core[ithCore].tcache.dcache_config[1]; + assoc = (int)XML->sys.core[ithCore].tcache.dcache_config[2]; + idx = debug ? 9 : int(ceil(log2(size / line / assoc))); + tag = debug ? 51 + : XML->sys.physical_address_width - idx - int(ceil(log2(line))) + + EXTRA_TAG_BITS; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.cache_sz = + debug ? 32768 : (int)XML->sys.core[ithCore].tcache.dcache_config[0]; + interface_ip.line_sz = + debug ? 64 : (int)XML->sys.core[ithCore].tcache.dcache_config[1]; + interface_ip.assoc = + debug ? 8 : (int)XML->sys.core[ithCore].tcache.dcache_config[2]; + interface_ip.nbanks = + debug ? 1 : (int)XML->sys.core[ithCore].tcache.dcache_config[3]; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = + 0; // debug?0:XML->sys.core[ithCore].tcache.dcache_config[5]; + interface_ip.throughput = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].tcache.dcache_config[4] / clockRate; + interface_ip.latency = + debug ? 3.0 / clockRate + : XML->sys.core[ithCore].tcache.dcache_config[5] / clockRate; + interface_ip.is_cache = true; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = + debug ? 1 + : XML->sys.core[ithCore].memory_ports; // usually In-order has 1 + // and OOO has 2 at least. + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + tcache.caches = new ArrayST(&interface_ip, "tcache", Core_device, + coredynp.opt_local, coredynp.core_ty); + tcache.area.set_area(tcache.area.get_area() + + tcache.caches->local_result.area); + area.set_area(area.get_area() + tcache.caches->local_result.area); + // output_data_csv(tcache.caches.local_result); + + // tCache controllers + // miss buffer + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = (XML->sys.physical_address_width) + int(ceil(log2(size / line))) + + tcache.caches->l_ip.line_sz * 8; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = + int(ceil(data / 8.0)); // int(ceil(pow(2.0,ceil(log2(data)))/8.0)); + interface_ip.cache_sz = + XML->sys.core[ithCore].tcache.buffer_sizes[0] * interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 2; + interface_ip.throughput = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].tcache.dcache_config[4] / clockRate; + interface_ip.latency = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].tcache.dcache_config[5] / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug ? 1 : XML->sys.core[ithCore].memory_ports; + ; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + tcache.missb = new ArrayST(&interface_ip, "tcacheMissBuffer", Core_device, + coredynp.opt_local, coredynp.core_ty); + tcache.area.set_area(tcache.area.get_area() + + tcache.missb->local_result.area); + area.set_area(area.get_area() + tcache.missb->local_result.area); + // output_data_csv(tcache.missb.local_result); + + // fill buffer + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = tcache.caches->l_ip.line_sz; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data; // int(pow(2.0,ceil(log2(data)))); + interface_ip.cache_sz = data * XML->sys.core[ithCore].tcache.buffer_sizes[1]; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 2; + interface_ip.throughput = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].tcache.dcache_config[4] / clockRate; + interface_ip.latency = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].tcache.dcache_config[5] / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug ? 1 : XML->sys.core[ithCore].memory_ports; + ; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + tcache.ifb = new ArrayST(&interface_ip, "tcacheFillBuffer", Core_device, + coredynp.opt_local, coredynp.core_ty); + tcache.area.set_area(tcache.area.get_area() + tcache.ifb->local_result.area); + area.set_area(area.get_area() + tcache.ifb->local_result.area); + // output_data_csv(tcache.ifb.local_result); + + // prefetch buffer + tag = XML->sys.physical_address_width + + EXTRA_TAG_BITS; // check with previous entries to decide wthether to + // merge. + data = tcache.caches->l_ip + .line_sz; // separate queue to prevent from cache polution. + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data; // int(pow(2.0,ceil(log2(data)))); + interface_ip.cache_sz = + XML->sys.core[ithCore].tcache.buffer_sizes[2] * interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 2; + interface_ip.throughput = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].tcache.dcache_config[4] / clockRate; + interface_ip.latency = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].tcache.dcache_config[5] / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug ? 1 : XML->sys.core[ithCore].memory_ports; + ; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + tcache.prefetchb = + new ArrayST(&interface_ip, "tcacheprefetchBuffer", Core_device, + coredynp.opt_local, coredynp.core_ty); + tcache.area.set_area(tcache.area.get_area() + + tcache.prefetchb->local_result.area); + area.set_area(area.get_area() + tcache.prefetchb->local_result.area); + // output_data_csv(tcache.prefetchb.local_result); + + // WBB + if (cache_p == Write_back) { + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = tcache.caches->l_ip.line_sz; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data; + interface_ip.cache_sz = + XML->sys.core[ithCore].tcache.buffer_sizes[3] * interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 2; + interface_ip.throughput = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].tcache.dcache_config[4] / clockRate; + interface_ip.latency = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].tcache.dcache_config[5] / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = XML->sys.core[ithCore].memory_ports; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + tcache.wbb = new ArrayST(&interface_ip, "tcacheWBB", Core_device, + coredynp.opt_local, coredynp.core_ty); + tcache.area.set_area(tcache.area.get_area() + + tcache.wbb->local_result.area); + area.set_area(area.get_area() + tcache.wbb->local_result.area); + // output_data_csv(tcache.wbb.local_result); + } + + /* + * dcache starts here + */ + // Dcache + size = (int)XML->sys.core[ithCore].dcache.dcache_config[0]; + line = (int)XML->sys.core[ithCore].dcache.dcache_config[1]; + assoc = (int)XML->sys.core[ithCore].dcache.dcache_config[2]; + idx = debug ? 9 : int(ceil(log2(size / line / assoc))); + tag = debug ? 51 + : XML->sys.physical_address_width - idx - int(ceil(log2(line))) + + EXTRA_TAG_BITS; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.cache_sz = + debug ? 32768 : (int)XML->sys.core[ithCore].dcache.dcache_config[0]; + interface_ip.line_sz = + debug ? 64 : (int)XML->sys.core[ithCore].dcache.dcache_config[1]; + interface_ip.assoc = + debug ? 8 : (int)XML->sys.core[ithCore].dcache.dcache_config[2]; + interface_ip.nbanks = + debug ? 1 : (int)XML->sys.core[ithCore].dcache.dcache_config[3]; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = + 0; // debug?0:XML->sys.core[ithCore].dcache.dcache_config[5]; + interface_ip.throughput = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].dcache.dcache_config[4] / clockRate; + interface_ip.latency = + debug ? 3.0 / clockRate + : XML->sys.core[ithCore].dcache.dcache_config[5] / clockRate; + interface_ip.is_cache = true; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = + debug ? 1 + : XML->sys.core[ithCore].memory_ports; // usually In-order has 1 + // and OOO has 2 at least. + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + dcache.caches = new ArrayST(&interface_ip, "dcache", Core_device, + coredynp.opt_local, coredynp.core_ty); + dcache.area.set_area(dcache.area.get_area() + + dcache.caches->local_result.area); + area.set_area(area.get_area() + dcache.caches->local_result.area); + // output_data_csv(dcache.caches.local_result); + + // dCache controllers + // miss buffer + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = (XML->sys.physical_address_width) + int(ceil(log2(size / line))) + + dcache.caches->l_ip.line_sz * 8; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = + int(ceil(data / 8.0)); // int(ceil(pow(2.0,ceil(log2(data)))/8.0)); + interface_ip.cache_sz = + XML->sys.core[ithCore].dcache.buffer_sizes[0] * interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 2; + interface_ip.throughput = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].dcache.dcache_config[4] / clockRate; + interface_ip.latency = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].dcache.dcache_config[5] / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug ? 1 : XML->sys.core[ithCore].memory_ports; + ; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + dcache.missb = new ArrayST(&interface_ip, "dcacheMissBuffer", Core_device, + coredynp.opt_local, coredynp.core_ty); + dcache.area.set_area(dcache.area.get_area() + + dcache.missb->local_result.area); + area.set_area(area.get_area() + dcache.missb->local_result.area); + // output_data_csv(dcache.missb.local_result); + + // fill buffer + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = dcache.caches->l_ip.line_sz; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data; // int(pow(2.0,ceil(log2(data)))); + interface_ip.cache_sz = data * XML->sys.core[ithCore].dcache.buffer_sizes[1]; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 2; + interface_ip.throughput = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].dcache.dcache_config[4] / clockRate; + interface_ip.latency = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].dcache.dcache_config[5] / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug ? 1 : XML->sys.core[ithCore].memory_ports; + ; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + dcache.ifb = new ArrayST(&interface_ip, "dcacheFillBuffer", Core_device, + coredynp.opt_local, coredynp.core_ty); + dcache.area.set_area(dcache.area.get_area() + dcache.ifb->local_result.area); + area.set_area(area.get_area() + dcache.ifb->local_result.area); + // output_data_csv(dcache.ifb.local_result); + + // prefetch buffer + tag = XML->sys.physical_address_width + + EXTRA_TAG_BITS; // check with previous entries to decide wthether to + // merge. + data = dcache.caches->l_ip + .line_sz; // separate queue to prevent from cache polution. + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data; // int(pow(2.0,ceil(log2(data)))); + interface_ip.cache_sz = + XML->sys.core[ithCore].dcache.buffer_sizes[2] * interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 2; + interface_ip.throughput = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].dcache.dcache_config[4] / clockRate; + interface_ip.latency = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].dcache.dcache_config[5] / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = debug ? 1 : XML->sys.core[ithCore].memory_ports; + ; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + dcache.prefetchb = + new ArrayST(&interface_ip, "dcacheprefetchBuffer", Core_device, + coredynp.opt_local, coredynp.core_ty); + dcache.area.set_area(dcache.area.get_area() + + dcache.prefetchb->local_result.area); + area.set_area(area.get_area() + dcache.prefetchb->local_result.area); + // output_data_csv(dcache.prefetchb.local_result); + + // WBB + if (cache_p == Write_back) { + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = dcache.caches->l_ip.line_sz; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data; + interface_ip.cache_sz = + XML->sys.core[ithCore].dcache.buffer_sizes[3] * interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 2; + interface_ip.throughput = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].dcache.dcache_config[4] / clockRate; + interface_ip.latency = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].dcache.dcache_config[5] / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = XML->sys.core[ithCore].memory_ports; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + dcache.wbb = new ArrayST(&interface_ip, "dcacheWBB", Core_device, + coredynp.opt_local, coredynp.core_ty); + dcache.area.set_area(dcache.area.get_area() + + dcache.wbb->local_result.area); + area.set_area(area.get_area() + dcache.wbb->local_result.area); + // output_data_csv(dcache.wbb.local_result); + } + /* + * LSU--in-order processors do not have separate load queue: unified lsq + * partitioned among threads + * it is actually the store queue but for inorder processors it serves as both + * loadQ and StoreQ + */ + tag = ldst_opcode + XML->sys.virtual_address_width + + int(ceil(log2(XML->sys.core[ithCore].number_hardware_threads))) + + EXTRA_TAG_BITS; + data = XML->sys.machine_bits; + interface_ip.is_cache = true; + interface_ip.line_sz = int(ceil(data / 32.0)) * 4; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.cache_sz = XML->sys.core[ithCore].store_buffer_size * + interface_ip.line_sz * + XML->sys.core[ithCore].number_hardware_threads; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 1; + interface_ip.throughput = 1.0 / clockRate; + interface_ip.latency = 1.0 / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = XML->sys.core[ithCore].memory_ports; + interface_ip.num_wr_ports = XML->sys.core[ithCore].memory_ports; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = XML->sys.core[ithCore].memory_ports; + LSQ = new ArrayST(&interface_ip, "Load(Store)Queue", Core_device, + coredynp.opt_local, coredynp.core_ty); + LSQ->area.set_area(LSQ->area.get_area() + LSQ->local_result.area); + area.set_area(area.get_area() + LSQ->local_result.area); + area.set_area(area.get_area() * cdb_overhead); + // output_data_csv(LSQ.LSQ.local_result); + lsq_height = + LSQ->local_result.cache_ht * + sqrt(cdb_overhead); /*XML->sys.core[ithCore].number_hardware_threads*/ + + if ((coredynp.core_ty == OOO) && + (XML->sys.core[ithCore].load_buffer_size > 0)) { + interface_ip.line_sz = int(ceil(data / 32.0)) * 4; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.cache_sz = XML->sys.core[ithCore].load_buffer_size * + interface_ip.line_sz * + XML->sys.core[ithCore].number_hardware_threads; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 1; + interface_ip.throughput = 1.0 / clockRate; + interface_ip.latency = 1.0 / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = XML->sys.core[ithCore].memory_ports; + interface_ip.num_wr_ports = XML->sys.core[ithCore].memory_ports; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = XML->sys.core[ithCore].memory_ports; + LoadQ = new ArrayST(&interface_ip, "LoadQueue", Core_device, + coredynp.opt_local, coredynp.core_ty); + LoadQ->area.set_area(LoadQ->area.get_area() + LoadQ->local_result.area); + area.set_area(area.get_area() + LoadQ->local_result.area); + area.set_area(area.get_area() * cdb_overhead); + // output_data_csv(LoadQ.LoadQ.local_result); + lsq_height = + (LSQ->local_result.cache_ht + LoadQ->local_result.cache_ht) * + sqrt(cdb_overhead); /*XML->sys.core[ithCore].number_hardware_threads*/ + } } -MemManU::MemManU(ParseXML* XML_interface, int ithCore_, InputParameter* interface_ip_, const CoreDynParam & dyn_p_,bool exist_) -:XML(XML_interface), - ithCore(ithCore_), - interface_ip(*interface_ip_), - coredynp(dyn_p_), - itlb(0), - dtlb(0), - exist(exist_) -{ - if (!exist) return; - int tag, data; - bool debug= false; - - clockRate = coredynp.clockRate; - executionTime = coredynp.executionTime; - - interface_ip.is_cache = true; - interface_ip.pure_cam = false; - interface_ip.pure_ram = false; - interface_ip.specific_tag = 1; - //Itlb TLBs are partioned among threads according to Nigara and Nehalem - tag = XML->sys.virtual_address_width- int(floor(log2(XML->sys.virtual_memory_page_size))) + int(ceil(log2(XML->sys.core[ithCore].number_hardware_threads)))+ EXTRA_TAG_BITS; - data = XML->sys.physical_address_width- int(floor(log2(XML->sys.virtual_memory_page_size))); - interface_ip.tag_w = tag; - interface_ip.line_sz = int(ceil(data/8.0));//int(ceil(pow(2.0,ceil(log2(data)))/8.0)); - interface_ip.cache_sz = XML->sys.core[ithCore].itlb.number_entries*interface_ip.line_sz;//*XML->sys.core[ithCore].number_hardware_threads; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 0; - interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].icache.icache_config[4]/clockRate; - interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].icache.icache_config[5]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = debug?1:XML->sys.core[ithCore].number_instruction_fetch_ports; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = debug?1:XML->sys.core[ithCore].number_instruction_fetch_ports; - itlb = new ArrayST(&interface_ip, "ITLB", Core_device, coredynp.opt_local, coredynp.core_ty); - itlb->area.set_area(itlb->area.get_area()+ itlb->local_result.area); - area.set_area(area.get_area()+ itlb->local_result.area); - //output_data_csv(itlb.tlb.local_result); - - //dtlb - tag = XML->sys.virtual_address_width- int(floor(log2(XML->sys.virtual_memory_page_size))) +int(ceil(log2(XML->sys.core[ithCore].number_hardware_threads)))+ EXTRA_TAG_BITS; - data = XML->sys.physical_address_width- int(floor(log2(XML->sys.virtual_memory_page_size))); - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = int(ceil(data/8.0));//int(ceil(pow(2.0,ceil(log2(data)))/8.0)); - interface_ip.cache_sz = XML->sys.core[ithCore].dtlb.number_entries*interface_ip.line_sz;//*XML->sys.core[ithCore].number_hardware_threads; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 0; - interface_ip.throughput = debug?1.0/clockRate:XML->sys.core[ithCore].dcache.dcache_config[4]/clockRate; - interface_ip.latency = debug?1.0/clockRate:XML->sys.core[ithCore].dcache.dcache_config[5]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = XML->sys.core[ithCore].memory_ports; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = XML->sys.core[ithCore].memory_ports; - dtlb = new ArrayST(&interface_ip, "DTLB", Core_device, coredynp.opt_local, coredynp.core_ty); - dtlb->area.set_area(dtlb->area.get_area()+ dtlb->local_result.area); - area.set_area(area.get_area()+ dtlb->local_result.area); - //output_data_csv(dtlb.tlb.local_result); +MemManU::MemManU(ParseXML* XML_interface, int ithCore_, + InputParameter* interface_ip_, const CoreDynParam& dyn_p_, + bool exist_) + : XML(XML_interface), + ithCore(ithCore_), + interface_ip(*interface_ip_), + coredynp(dyn_p_), + itlb(0), + dtlb(0), + exist(exist_) { + if (!exist) return; + int tag, data; + bool debug = false; + clockRate = coredynp.clockRate; + executionTime = coredynp.executionTime; + + interface_ip.is_cache = true; + interface_ip.pure_cam = false; + interface_ip.pure_ram = false; + interface_ip.specific_tag = 1; + // Itlb TLBs are partioned among threads according to Nigara and Nehalem + tag = XML->sys.virtual_address_width - + int(floor(log2(XML->sys.virtual_memory_page_size))) + + int(ceil(log2(XML->sys.core[ithCore].number_hardware_threads))) + + EXTRA_TAG_BITS; + data = XML->sys.physical_address_width - + int(floor(log2(XML->sys.virtual_memory_page_size))); + interface_ip.tag_w = tag; + interface_ip.line_sz = + int(ceil(data / 8.0)); // int(ceil(pow(2.0,ceil(log2(data)))/8.0)); + interface_ip.cache_sz = + XML->sys.core[ithCore].itlb.number_entries * + interface_ip.line_sz; //*XML->sys.core[ithCore].number_hardware_threads; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 0; + interface_ip.throughput = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].icache.icache_config[4] / clockRate; + interface_ip.latency = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].icache.icache_config[5] / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = + debug ? 1 : XML->sys.core[ithCore].number_instruction_fetch_ports; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = + debug ? 1 : XML->sys.core[ithCore].number_instruction_fetch_ports; + itlb = new ArrayST(&interface_ip, "ITLB", Core_device, coredynp.opt_local, + coredynp.core_ty); + itlb->area.set_area(itlb->area.get_area() + itlb->local_result.area); + area.set_area(area.get_area() + itlb->local_result.area); + // output_data_csv(itlb.tlb.local_result); + + // dtlb + tag = XML->sys.virtual_address_width - + int(floor(log2(XML->sys.virtual_memory_page_size))) + + int(ceil(log2(XML->sys.core[ithCore].number_hardware_threads))) + + EXTRA_TAG_BITS; + data = XML->sys.physical_address_width - + int(floor(log2(XML->sys.virtual_memory_page_size))); + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = + int(ceil(data / 8.0)); // int(ceil(pow(2.0,ceil(log2(data)))/8.0)); + interface_ip.cache_sz = + XML->sys.core[ithCore].dtlb.number_entries * + interface_ip.line_sz; //*XML->sys.core[ithCore].number_hardware_threads; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 0; + interface_ip.throughput = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].dcache.dcache_config[4] / clockRate; + interface_ip.latency = + debug ? 1.0 / clockRate + : XML->sys.core[ithCore].dcache.dcache_config[5] / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = XML->sys.core[ithCore].memory_ports; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = XML->sys.core[ithCore].memory_ports; + dtlb = new ArrayST(&interface_ip, "DTLB", Core_device, coredynp.opt_local, + coredynp.core_ty); + dtlb->area.set_area(dtlb->area.get_area() + dtlb->local_result.area); + area.set_area(area.get_area() + dtlb->local_result.area); + // output_data_csv(dtlb.tlb.local_result); } //#define FERMI -RegFU::RegFU(ParseXML* XML_interface, int ithCore_, InputParameter* interface_ip_, const CoreDynParam & dyn_p_,double exClockRate,bool exist_) -:XML(XML_interface), - ithCore(ithCore_), - interface_ip(*interface_ip_), - coredynp(dyn_p_), - IRF (0), - FRF (0), - RFWIN (0), - exist(exist_) - { - /* - * processors have separate architectural register files for each thread. - * therefore, the bypass buses need to travel across all the register files. - */ - if (!exist) return; - int data; - clockRate = exClockRate;//coredynp.clockRate; - executionTime = coredynp.executionTime; +RegFU::RegFU(ParseXML* XML_interface, int ithCore_, + InputParameter* interface_ip_, const CoreDynParam& dyn_p_, + double exClockRate, bool exist_) + : XML(XML_interface), + ithCore(ithCore_), + interface_ip(*interface_ip_), + coredynp(dyn_p_), + IRF(0), + FRF(0), + RFWIN(0), + exist(exist_) { + /* + * processors have separate architectural register files for each thread. + * therefore, the bypass buses need to travel across all the register files. + */ + if (!exist) return; + int data; + clockRate = exClockRate; // coredynp.clockRate; + executionTime = coredynp.executionTime; /********************************************************************************* - * OC stage modelling (Syed Gilani) - *********************************************************************************/ - - //Crossbar - - if(XML->sys.architecture==1){ - xbar_rfu = new Crossbar(XML->sys.core[ithCore].rf_banks/2,XML->sys.core[ithCore].collector_units/2 - ,(128),&(g_tp.peri_global)); - }else{ - xbar_rfu = new Crossbar(XML->sys.core[ithCore].rf_banks,XML->sys.core[ithCore].collector_units - ,(128),&(g_tp.peri_global)); - } - - //new Crossbar(simd_width,shared_memory_banks,word_length*simd_width,&(g_tp.peri_global)); - - //Arbiter - arbiter_rfu = new MCPAT_Arbiter(XML->sys.core[ithCore].rf_banks,XML->sys.core[ithCore].collector_units , 1,&(g_tp.peri_global)); + * OC stage modelling (Syed Gilani) + *********************************************************************************/ + + // Crossbar + + if (XML->sys.architecture == 1) { + xbar_rfu = new Crossbar(XML->sys.core[ithCore].rf_banks / 2, + XML->sys.core[ithCore].collector_units / 2, (128), + &(g_tp.peri_global)); + } else { + xbar_rfu = new Crossbar(XML->sys.core[ithCore].rf_banks, + XML->sys.core[ithCore].collector_units, (128), + &(g_tp.peri_global)); + } + // new + // Crossbar(simd_width,shared_memory_banks,word_length*simd_width,&(g_tp.peri_global)); + + // Arbiter + arbiter_rfu = new MCPAT_Arbiter(XML->sys.core[ithCore].rf_banks, + XML->sys.core[ithCore].collector_units, 1, + &(g_tp.peri_global)); + + // RF banks modelled here for GPGPU-Sim (Syed Gilani) + // + //**********************************IRF*************************************** + data = coredynp.int_data_width; + // data *= 8; + interface_ip.is_cache = false; + interface_ip.pure_cam = false; + interface_ip.pure_ram = true; + + interface_ip.line_sz = + 16; // int(ceil(data/32.0))*4 * XML->sys.core[ithCore].simd_width/4 ;//2 + // for Tesla as RF width half of SIMD width + + interface_ip.line_sz = + 16; // int(ceil(data/32.0))*4 * XML->sys.core[ithCore].simd_width/2 ;//2 + // for Tesla as RF width half of SIMD width + + interface_ip.cache_sz = coredynp.num_IRF_entry * 4; + interface_ip.assoc = 1; + interface_ip.nbanks = XML->sys.core[ithCore].rf_banks; + + interface_ip.out_w = + interface_ip.line_sz * + 8; // interface_ip.line_sz*XML->sys.core[ithCore].simd_width/4; + // //2 for Tesla and 4 for Fermi + + interface_ip.out_w = + interface_ip.line_sz * + 8; // interface_ip.line_sz*XML->sys.core[ithCore].simd_width/2; + // //2 for Tesla and 4 for Fermi + + interface_ip.access_mode = 1; + interface_ip.throughput = 1 / (clockRate); + interface_ip.latency = 8.0 / (clockRate); + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 1; + interface_ip.obj_func_cycle_t = 0; + interface_ip.num_rw_ports = + 0; // this is the transfer port for saving/restoring states when + // exceptions happen. + interface_ip.num_rd_ports = 1; // 2*coredynp.peak_issueW; + interface_ip.num_wr_ports = 1; // coredynp.peak_issueW; + interface_ip.num_se_rd_ports = 0; + IRF = new ArrayST(&interface_ip, "Integer Register File", Core_device, + coredynp.opt_local, coredynp.core_ty); + + IRF->area.set_area(IRF->area.get_area() + IRF->local_result.area * + coredynp.num_pipelines * + cdb_overhead); + + area.set_area(area.get_area() + IRF->local_result.area + + xbar_rfu->area.get_area() + arbiter_rfu->area.get_area()); + if (XML->sys.architecture == 1) { + IRF->local_result.power.readOp.dynamic *= .33; + IRF->local_result.power.writeOp.dynamic *= .33; + } else { + IRF->local_result.power.readOp.dynamic *= .55; + IRF->local_result.power.writeOp.dynamic *= .55; + } + /** + * Operand collectors (32-bit wide, 8 entry banks ) + */ + data = 32; + // data *= 8; + interface_ip.is_cache = false; + interface_ip.pure_cam = false; + interface_ip.pure_ram = true; + + interface_ip.line_sz = + 4; // int(ceil(data/32.0))*4 * XML->sys.core[ithCore].simd_width/4 ;//2 + // for Tesla as RF width half of SIMD width + + interface_ip.line_sz = + 4; // int(ceil(data/32.0))*4 * XML->sys.core[ithCore].simd_width/2 ;//2 + // for Tesla as RF width half of SIMD width + + interface_ip.cache_sz = 8 * 4; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + + interface_ip.out_w = + interface_ip + .line_sz; // interface_ip.line_sz*XML->sys.core[ithCore].simd_width/4; + // //2 for Tesla and 4 for Fermi + + interface_ip.out_w = + interface_ip + .line_sz; // interface_ip.line_sz*XML->sys.core[ithCore].simd_width/2; + // //2 for Tesla and 4 for Fermi + + interface_ip.access_mode = 1; + interface_ip.throughput = 1.0 / (clockRate); + interface_ip.latency = 1.0 / (clockRate); + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 1; + interface_ip.obj_func_cycle_t = 0; + interface_ip.num_rw_ports = + 0; // this is the transfer port for saving/restoring states when + // exceptions happen. + interface_ip.num_rd_ports = 1; // 2*coredynp.peak_issueW; + interface_ip.num_wr_ports = 1; // coredynp.peak_issueW; + interface_ip.num_se_rd_ports = 0; + OPC = new ArrayST(&interface_ip, "Operand collectors", Core_device, + coredynp.opt_local, coredynp.core_ty); + + OPC->area.set_area(OPC->area.get_area() + OPC->local_result.area * + coredynp.num_pipelines * + cdb_overhead); + + area.set_area(area.get_area() + OPC->local_result.area); + + /******** + * For GPGPUSim (Syed Gilani) + * Do not include FRF in final results for GPU. Only model the IRF + ********/ + + //**********************************FRF*************************************** + data = coredynp.fp_data_width; + // data *= 8; + interface_ip.is_cache = false; + interface_ip.pure_cam = false; + interface_ip.pure_ram = true; + interface_ip.line_sz = int(ceil(data / 32.0)) * 4; + interface_ip.cache_sz = coredynp.num_FRF_entry * interface_ip.line_sz; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 1; + interface_ip.throughput = 1.0 / clockRate; + interface_ip.latency = 1.0 / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = + 1; // this is the transfer port for saving/restoring states when + // exceptions happen. + interface_ip.num_rd_ports = 2 * XML->sys.core[ithCore].issue_width; + // interface_ip.num_rd_ports = 1; + interface_ip.num_wr_ports = XML->sys.core[ithCore].issue_width; + // interface_ip.num_wr_ports = 1; + interface_ip.num_se_rd_ports = 0; + FRF = new ArrayST(&interface_ip, "Floating point Register File", Core_device, + coredynp.opt_local, coredynp.core_ty); + // FRF->area.set_area(FRF->area.get_area()+ + // FRF->local_result.area*XML->sys.core[ithCore].number_hardware_threads*coredynp.num_fp_pipelines*cdb_overhead); + // area.set_area(area.get_area()+ + // FRF->local_result.area*XML->sys.core[ithCore].number_hardware_threads*coredynp.num_fp_pipelines*cdb_overhead); + // area.set_area(area.get_area()*cdb_overhead); + // output_data_csv(FRF.RF.local_result); + int_regfile_height = IRF->local_result.cache_ht * + XML->sys.core[ithCore].number_hardware_threads * + sqrt(cdb_overhead); + fp_regfile_height = 0; + // fp_regfile_height = + // FRF->local_result.cache_ht*XML->sys.core[ithCore].number_hardware_threads*sqrt(cdb_overhead); + // since a EXU is associated with each pipeline, the cdb should not have + // longer length. + if (coredynp.regWindowing) { + //*********************************REG_WIN************************************ + data = + coredynp + .int_data_width; // ECC, and usually 2 regs are transfered together + // during window shifting.Niagara Mega cell + interface_ip.is_cache = false; + interface_ip.pure_cam = false; + interface_ip.pure_ram = true; + interface_ip.line_sz = int(ceil(data / 8.0)); + interface_ip.cache_sz = XML->sys.core[ithCore].register_windows_size * + IRF->l_ip.cache_sz * + XML->sys.core[ithCore].number_hardware_threads; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 1; + interface_ip.throughput = 4.0 / clockRate; + interface_ip.latency = 4.0 / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = + 1; // this is the transfer port for saving/restoring states when + // exceptions happen. + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + RFWIN = new ArrayST(&interface_ip, "RegWindow", Core_device, + coredynp.opt_local, coredynp.core_ty); + RFWIN->area.set_area(RFWIN->area.get_area() + + RFWIN->local_result.area * coredynp.num_pipelines); + area.set_area(area.get_area() + + RFWIN->local_result.area * coredynp.num_pipelines); + // output_data_csv(RFWIN.RF.local_result); + } +} - // RF banks modelled here for GPGPU-Sim (Syed Gilani) - // - //**********************************IRF*************************************** - data = coredynp.int_data_width; - //data *= 8; - interface_ip.is_cache = false; - interface_ip.pure_cam = false; - interface_ip.pure_ram = true; +EXECU::EXECU(ParseXML* XML_interface, int ithCore_, + InputParameter* interface_ip_, double lsq_height_, + const CoreDynParam& dyn_p_, double exClockRate, bool exist_) + : XML(XML_interface), + ithCore(ithCore_), + interface_ip(*interface_ip_), + lsq_height(lsq_height_), + coredynp(dyn_p_), + rfu(0), + scheu(0), + fp_u(0), + exeu(0), + mul(0), + int_bypass(0), + intTagBypass(0), + int_mul_bypass(0), + intTag_mul_Bypass(0), + fp_bypass(0), + fpTagBypass(0), + exist(exist_), + rf_fu_clockRate(exClockRate) { + if (!exist) return; + double fu_height = 0.0; + clockRate = coredynp.clockRate; + // cout <<"EXECU exClockRate: "<area.get_area() + rfu->area.get_area() + + scheu->area.get_area()); + fu_height = exeu->FU_height; + if (coredynp.num_fpus > 0) { + fp_u = new FunctionalUnit(XML, ithCore, &interface_ip, coredynp, FPU, + exClockRate); + area.set_area(area.get_area() + fp_u->area.get_area()); + } + if (coredynp.num_muls > 0) { + mul = new FunctionalUnit(XML, ithCore, &interface_ip, coredynp, MUL, + exClockRate); + area.set_area(area.get_area() + mul->area.get_area()); + fu_height += mul->FU_height; + } + /* + * broadcast logic, including int-broadcast; int_tag-broadcast; fp-broadcast; + * fp_tag-broadcast integer by pass has two paths and fp has 3 paths. on the + * same bus there are multiple tri-state drivers and muxes that go to + * different components on the same bus + */ + if (XML->sys.Embedded) { + interface_ip.wt = Global_30; + interface_ip.wire_is_mat_type = 0; + interface_ip.wire_os_mat_type = 0; + interface_ip.throughput = 1.0 / clockRate; + interface_ip.latency = 1.0 / clockRate; + } else { + interface_ip.wt = Global; + interface_ip.wire_is_mat_type = + 2; // start from semi-global since local wires are already used + interface_ip.wire_os_mat_type = 2; + interface_ip.throughput = 10.0 / clockRate; // Do not care + interface_ip.latency = 10.0 / clockRate; + } - interface_ip.line_sz = 16;//int(ceil(data/32.0))*4 * XML->sys.core[ithCore].simd_width/4 ;//2 for Tesla as RF width half of SIMD width + if (coredynp.core_ty == Inorder) { // + int_bypass = new interconnect( + "Int Bypass Data", Core_device, 1, 1, + int(ceil(XML->sys.machine_bits / 32.0) * 32), + rfu->int_regfile_height + exeu->FU_height + lsq_height, &interface_ip, + 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); + bypass.area.set_area(bypass.area.get_area() + int_bypass->area.get_area()); + intTagBypass = new interconnect( + "Int Bypass tag", Core_device, 1, 1, coredynp.perThreadState, + rfu->int_regfile_height + exeu->FU_height + lsq_height + + scheu->Iw_height, + &interface_ip, 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); + bypass.area.set_area(bypass.area.get_area() + + intTagBypass->area.get_area()); + + if (coredynp.num_muls > 0) { + int_mul_bypass = new interconnect( + "Mul Bypass Data", Core_device, 1, 1, + int(ceil(XML->sys.machine_bits / 32.0) * 32 * 1.5), + rfu->fp_regfile_height + exeu->FU_height + mul->FU_height + + lsq_height, + &interface_ip, 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); + bypass.area.set_area(bypass.area.get_area() + + int_mul_bypass->area.get_area()); + intTag_mul_Bypass = new interconnect( + "Mul Bypass tag", Core_device, 1, 1, coredynp.perThreadState, + rfu->fp_regfile_height + exeu->FU_height + mul->FU_height + + lsq_height + scheu->Iw_height, + &interface_ip, 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); + bypass.area.set_area(bypass.area.get_area() + + intTag_mul_Bypass->area.get_area()); + } - interface_ip.line_sz = 16;//int(ceil(data/32.0))*4 * XML->sys.core[ithCore].simd_width/2 ;//2 for Tesla as RF width half of SIMD width + /* + if (coredynp.num_fpus>0) + { + fp_bypass = new interconnect("FP Bypass Data" , Core_device, 1, + 1, int(ceil(XML->sys.machine_bits/32.0)*32*1.5), rfu->fp_regfile_height + + fp_u->FU_height, &interface_ip, 3, false, 1.0, coredynp.opt_local, + coredynp.core_ty); bypass.area.set_area(bypass.area.get_area() + +fp_bypass->area.get_area()); fpTagBypass = new interconnect("FP Bypass + tag" , Core_device, 1, 1, coredynp.perThreadState, rfu->fp_regfile_height + + fp_u->FU_height + lsq_height + scheu->Iw_height, &interface_ip, 3, + false, 1.0, coredynp.opt_local, coredynp.core_ty); + bypass.area.set_area(bypass.area.get_area() + +fpTagBypass->area.get_area()); + }*/ + } /* if (coredynp.core_ty==Inorder) */ + else { // OOO + if (coredynp.scheu_ty == PhysicalRegFile) { + /* For physical register based OOO, + * data broadcast interconnects cover across functional units, lsq, inst + * windows and register files, while tag broadcast interconnects also + * cover across ROB + */ + int_bypass = new interconnect( + "Int Bypass Data", Core_device, 1, 1, + int(ceil(coredynp.int_data_width)), + rfu->int_regfile_height + exeu->FU_height + lsq_height, &interface_ip, + 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); + bypass.area.set_area(bypass.area.get_area() + + int_bypass->area.get_area()); + intTagBypass = new interconnect( + "Int Bypass tag", Core_device, 1, 1, coredynp.phy_ireg_width, + rfu->int_regfile_height + exeu->FU_height + lsq_height + + scheu->Iw_height + scheu->ROB_height, + &interface_ip, 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); + + if (coredynp.num_muls > 0) { + int_mul_bypass = new interconnect( + "Mul Bypass Data", Core_device, 1, 1, + int(ceil(coredynp.int_data_width)), + rfu->int_regfile_height + exeu->FU_height + mul->FU_height + + lsq_height, + &interface_ip, 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); + intTag_mul_Bypass = new interconnect( + "Mul Bypass tag", Core_device, 1, 1, coredynp.phy_ireg_width, + rfu->int_regfile_height + exeu->FU_height + mul->FU_height + + lsq_height + scheu->Iw_height + scheu->ROB_height, + &interface_ip, 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); + bypass.area.set_area(bypass.area.get_area() + + int_mul_bypass->area.get_area()); + bypass.area.set_area(bypass.area.get_area() + + intTag_mul_Bypass->area.get_area()); + } - interface_ip.cache_sz = coredynp.num_IRF_entry*4; - interface_ip.assoc = 1; - interface_ip.nbanks = XML->sys.core[ithCore].rf_banks; + if (coredynp.num_fpus > 0) { + fp_bypass = new interconnect("FP Bypass Data", Core_device, 1, 1, + int(ceil(coredynp.fp_data_width)), + rfu->fp_regfile_height + fp_u->FU_height, + &interface_ip, 3, false, 1.0, + coredynp.opt_local, coredynp.core_ty); + fpTagBypass = new interconnect( + "FP Bypass tag", Core_device, 1, 1, coredynp.phy_freg_width, + rfu->fp_regfile_height + fp_u->FU_height + lsq_height + + scheu->fp_Iw_height + scheu->ROB_height, + &interface_ip, 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); + bypass.area.set_area(bypass.area.get_area() + + fp_bypass->area.get_area()); + bypass.area.set_area(bypass.area.get_area() + + fpTagBypass->area.get_area()); + } + } else { + /* + * In RS based processor both data and tag are broadcast together, + * covering functional units, lsq, nst windows, register files, and ROBs + */ + int_bypass = new interconnect( + "Int Bypass Data", Core_device, 1, 1, + int(ceil(coredynp.int_data_width)), + rfu->int_regfile_height + exeu->FU_height + lsq_height + + scheu->Iw_height + scheu->ROB_height, + &interface_ip, 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); + intTagBypass = new interconnect( + "Int Bypass tag", Core_device, 1, 1, coredynp.phy_ireg_width, + rfu->int_regfile_height + exeu->FU_height + lsq_height + + scheu->Iw_height + scheu->ROB_height, + &interface_ip, 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); + bypass.area.set_area(bypass.area.get_area() + + int_bypass->area.get_area()); + bypass.area.set_area(bypass.area.get_area() + + intTagBypass->area.get_area()); + if (coredynp.num_muls > 0) { + int_mul_bypass = new interconnect( + "Mul Bypass Data", Core_device, 1, 1, + int(ceil(coredynp.int_data_width)), + rfu->int_regfile_height + exeu->FU_height + mul->FU_height + + lsq_height + scheu->Iw_height + scheu->ROB_height, + &interface_ip, 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); + intTag_mul_Bypass = new interconnect( + "Mul Bypass tag", Core_device, 1, 1, coredynp.phy_ireg_width, + rfu->int_regfile_height + exeu->FU_height + mul->FU_height + + lsq_height + scheu->Iw_height + scheu->ROB_height, + &interface_ip, 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); + bypass.area.set_area(bypass.area.get_area() + + int_mul_bypass->area.get_area()); + bypass.area.set_area(bypass.area.get_area() + + intTag_mul_Bypass->area.get_area()); + } - interface_ip.out_w = interface_ip.line_sz*8;//interface_ip.line_sz*XML->sys.core[ithCore].simd_width/4; //2 for Tesla and 4 for Fermi + if (coredynp.num_fpus > 0) { + fp_bypass = new interconnect( + "FP Bypass Data", Core_device, 1, 1, + int(ceil(coredynp.fp_data_width)), + rfu->fp_regfile_height + fp_u->FU_height + lsq_height + + scheu->fp_Iw_height + scheu->ROB_height, + &interface_ip, 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); + fpTagBypass = new interconnect( + "FP Bypass tag", Core_device, 1, 1, coredynp.phy_freg_width, + rfu->fp_regfile_height + fp_u->FU_height + lsq_height + + scheu->fp_Iw_height + scheu->ROB_height, + &interface_ip, 3, false, 1.0, coredynp.opt_local, coredynp.core_ty); + bypass.area.set_area(bypass.area.get_area() + + fp_bypass->area.get_area()); + bypass.area.set_area(bypass.area.get_area() + + fpTagBypass->area.get_area()); + } + } /* else */ - interface_ip.out_w = interface_ip.line_sz*8;//interface_ip.line_sz*XML->sys.core[ithCore].simd_width/2; //2 for Tesla and 4 for Fermi - - - interface_ip.access_mode = 1; - interface_ip.throughput = 1/(clockRate); - interface_ip.latency = 8.0/(clockRate); - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 1; - interface_ip.obj_func_cycle_t = 0; - interface_ip.num_rw_ports = 0;//this is the transfer port for saving/restoring states when exceptions happen. - interface_ip.num_rd_ports = 1;//2*coredynp.peak_issueW; - interface_ip.num_wr_ports = 1;//coredynp.peak_issueW; - interface_ip.num_se_rd_ports = 0; - IRF = new ArrayST(&interface_ip, "Integer Register File", Core_device, coredynp.opt_local, coredynp.core_ty); - - IRF->area.set_area(IRF->area.get_area()+ IRF->local_result.area*coredynp.num_pipelines*cdb_overhead); - - - area.set_area(area.get_area()+ IRF->local_result.area - + xbar_rfu->area.get_area() + arbiter_rfu->area.get_area()); - if(XML->sys.architecture==1){ - IRF->local_result.power.readOp.dynamic *= .33; - IRF->local_result.power.writeOp.dynamic *= .33; - } - else { - IRF->local_result.power.readOp.dynamic *= .55; - IRF->local_result.power.writeOp.dynamic *= .55; - } - - - - - /** - * Operand collectors (32-bit wide, 8 entry banks ) - */ - data = 32; - //data *= 8; - interface_ip.is_cache = false; - interface_ip.pure_cam = false; - interface_ip.pure_ram = true; - - interface_ip.line_sz = 4;//int(ceil(data/32.0))*4 * XML->sys.core[ithCore].simd_width/4 ;//2 for Tesla as RF width half of SIMD width - - interface_ip.line_sz = 4;//int(ceil(data/32.0))*4 * XML->sys.core[ithCore].simd_width/2 ;//2 for Tesla as RF width half of SIMD width - - interface_ip.cache_sz = 8*4; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - - interface_ip.out_w = interface_ip.line_sz;//interface_ip.line_sz*XML->sys.core[ithCore].simd_width/4; //2 for Tesla and 4 for Fermi - - interface_ip.out_w = interface_ip.line_sz;//interface_ip.line_sz*XML->sys.core[ithCore].simd_width/2; //2 for Tesla and 4 for Fermi - - - interface_ip.access_mode = 1; - interface_ip.throughput = 1.0/(clockRate); - interface_ip.latency = 1.0/(clockRate); - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 1; - interface_ip.obj_func_cycle_t = 0; - interface_ip.num_rw_ports = 0;//this is the transfer port for saving/restoring states when exceptions happen. - interface_ip.num_rd_ports = 1;//2*coredynp.peak_issueW; - interface_ip.num_wr_ports = 1;//coredynp.peak_issueW; - interface_ip.num_se_rd_ports = 0; - OPC = new ArrayST(&interface_ip, "Operand collectors", Core_device, coredynp.opt_local, coredynp.core_ty); - - OPC->area.set_area(OPC->area.get_area()+ OPC->local_result.area*coredynp.num_pipelines*cdb_overhead); - - - area.set_area(area.get_area()+ OPC->local_result.area); - - - - - /******** - * For GPGPUSim (Syed Gilani) - * Do not include FRF in final results for GPU. Only model the IRF - ********/ - - //**********************************FRF*************************************** - data = coredynp.fp_data_width; - //data *= 8; - interface_ip.is_cache = false; - interface_ip.pure_cam = false; - interface_ip.pure_ram = true; - interface_ip.line_sz = int(ceil(data/32.0))*4; - interface_ip.cache_sz = coredynp.num_FRF_entry*interface_ip.line_sz; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 1; - interface_ip.throughput = 1.0/clockRate; - interface_ip.latency = 1.0/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1;//this is the transfer port for saving/restoring states when exceptions happen. - interface_ip.num_rd_ports = 2*XML->sys.core[ithCore].issue_width; - //interface_ip.num_rd_ports = 1; - interface_ip.num_wr_ports = XML->sys.core[ithCore].issue_width; - //interface_ip.num_wr_ports = 1; - interface_ip.num_se_rd_ports = 0; - FRF = new ArrayST(&interface_ip, "Floating point Register File", Core_device, coredynp.opt_local, coredynp.core_ty); - //FRF->area.set_area(FRF->area.get_area()+ FRF->local_result.area*XML->sys.core[ithCore].number_hardware_threads*coredynp.num_fp_pipelines*cdb_overhead); - //area.set_area(area.get_area()+ FRF->local_result.area*XML->sys.core[ithCore].number_hardware_threads*coredynp.num_fp_pipelines*cdb_overhead); - //area.set_area(area.get_area()*cdb_overhead); - //output_data_csv(FRF.RF.local_result); - int_regfile_height= IRF->local_result.cache_ht*XML->sys.core[ithCore].number_hardware_threads*sqrt(cdb_overhead); - fp_regfile_height=0; - //fp_regfile_height = FRF->local_result.cache_ht*XML->sys.core[ithCore].number_hardware_threads*sqrt(cdb_overhead); - //since a EXU is associated with each pipeline, the cdb should not have longer length. - if (coredynp.regWindowing) - { - //*********************************REG_WIN************************************ - data = coredynp.int_data_width; //ECC, and usually 2 regs are transfered together during window shifting.Niagara Mega cell - interface_ip.is_cache = false; - interface_ip.pure_cam = false; - interface_ip.pure_ram = true; - interface_ip.line_sz = int(ceil(data/8.0)); - interface_ip.cache_sz = XML->sys.core[ithCore].register_windows_size*IRF->l_ip.cache_sz*XML->sys.core[ithCore].number_hardware_threads; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 1; - interface_ip.throughput = 4.0/clockRate; - interface_ip.latency = 4.0/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1;//this is the transfer port for saving/restoring states when exceptions happen. - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - RFWIN = new ArrayST(&interface_ip, "RegWindow", Core_device, coredynp.opt_local, coredynp.core_ty); - RFWIN->area.set_area(RFWIN->area.get_area()+ RFWIN->local_result.area*coredynp.num_pipelines); - area.set_area(area.get_area()+ RFWIN->local_result.area*coredynp.num_pipelines); - //output_data_csv(RFWIN.RF.local_result); - } - - - } - -EXECU::EXECU(ParseXML* XML_interface, int ithCore_, InputParameter* interface_ip_, double lsq_height_, const CoreDynParam & dyn_p_, double exClockRate, bool exist_) -:XML(XML_interface), - ithCore(ithCore_), - interface_ip(*interface_ip_), - lsq_height(lsq_height_), - coredynp(dyn_p_), - rfu(0), - scheu(0), - fp_u(0), - exeu(0), - mul(0), - int_bypass(0), - intTagBypass(0), - int_mul_bypass(0), - intTag_mul_Bypass(0), - fp_bypass(0), - fpTagBypass(0), - exist(exist_), - rf_fu_clockRate(exClockRate) -{ - if (!exist) return; - double fu_height = 0.0; - clockRate = coredynp.clockRate; - //cout <<"EXECU exClockRate: "<area.get_area() + rfu->area.get_area() +scheu->area.get_area() ); - fu_height = exeu->FU_height; - if (coredynp.num_fpus >0) - { - fp_u = new FunctionalUnit(XML, ithCore,&interface_ip, coredynp, FPU, exClockRate); - area.set_area(area.get_area()+ fp_u->area.get_area()); - } - if (coredynp.num_muls >0) - { - mul = new FunctionalUnit(XML, ithCore,&interface_ip, coredynp, MUL, exClockRate); - area.set_area(area.get_area()+ mul->area.get_area()); - fu_height += mul->FU_height; - } - /* - * broadcast logic, including int-broadcast; int_tag-broadcast; fp-broadcast; fp_tag-broadcast - * integer by pass has two paths and fp has 3 paths. - * on the same bus there are multiple tri-state drivers and muxes that go to different components on the same bus - */ - if (XML->sys.Embedded) - { - interface_ip.wt =Global_30; - interface_ip.wire_is_mat_type = 0; - interface_ip.wire_os_mat_type = 0; - interface_ip.throughput = 1.0/clockRate; - interface_ip.latency = 1.0/clockRate; - } - else - { - interface_ip.wt =Global; - interface_ip.wire_is_mat_type = 2;//start from semi-global since local wires are already used - interface_ip.wire_os_mat_type = 2; - interface_ip.throughput = 10.0/clockRate; //Do not care - interface_ip.latency = 10.0/clockRate; - } - - if (coredynp.core_ty==Inorder) - {// - int_bypass = new interconnect("Int Bypass Data", Core_device, 1, 1, int(ceil(XML->sys.machine_bits/32.0)*32), - rfu->int_regfile_height + exeu->FU_height + lsq_height, &interface_ip, 3, - false, 1.0, coredynp.opt_local, coredynp.core_ty); - bypass.area.set_area(bypass.area.get_area() + int_bypass->area.get_area()); - intTagBypass = new interconnect("Int Bypass tag" , Core_device, 1, 1, coredynp.perThreadState, - rfu->int_regfile_height + exeu->FU_height + lsq_height + scheu->Iw_height, &interface_ip, 3, - false, 1.0, coredynp.opt_local, coredynp.core_ty); - bypass.area.set_area(bypass.area.get_area() +intTagBypass->area.get_area()); - - if (coredynp.num_muls>0) - { - int_mul_bypass = new interconnect("Mul Bypass Data" , Core_device, 1, 1, int(ceil(XML->sys.machine_bits/32.0)*32*1.5), - rfu->fp_regfile_height + exeu->FU_height + mul->FU_height + lsq_height, &interface_ip, 3, - false, 1.0, coredynp.opt_local, coredynp.core_ty); - bypass.area.set_area(bypass.area.get_area() +int_mul_bypass->area.get_area()); - intTag_mul_Bypass = new interconnect("Mul Bypass tag" , Core_device, 1, 1, coredynp.perThreadState, - rfu->fp_regfile_height + exeu->FU_height + mul->FU_height + lsq_height + scheu->Iw_height, &interface_ip, 3, - false, 1.0, coredynp.opt_local, coredynp.core_ty); - bypass.area.set_area(bypass.area.get_area() +intTag_mul_Bypass->area.get_area()); - } - - /* - if (coredynp.num_fpus>0) - { - fp_bypass = new interconnect("FP Bypass Data" , Core_device, 1, 1, int(ceil(XML->sys.machine_bits/32.0)*32*1.5), - rfu->fp_regfile_height + fp_u->FU_height, &interface_ip, 3, - false, 1.0, coredynp.opt_local, coredynp.core_ty); - bypass.area.set_area(bypass.area.get_area() +fp_bypass->area.get_area()); - fpTagBypass = new interconnect("FP Bypass tag" , Core_device, 1, 1, coredynp.perThreadState, - rfu->fp_regfile_height + fp_u->FU_height + lsq_height + scheu->Iw_height, &interface_ip, 3, - false, 1.0, coredynp.opt_local, coredynp.core_ty); - bypass.area.set_area(bypass.area.get_area() +fpTagBypass->area.get_area()); - }*/ - } /* if (coredynp.core_ty==Inorder) */ - else - {//OOO - if (coredynp.scheu_ty==PhysicalRegFile) - { - /* For physical register based OOO, - * data broadcast interconnects cover across functional units, lsq, inst windows and register files, - * while tag broadcast interconnects also cover across ROB - */ - int_bypass = new interconnect("Int Bypass Data", Core_device, 1, 1, int(ceil(coredynp.int_data_width)), - rfu->int_regfile_height + exeu->FU_height + lsq_height, &interface_ip, 3, - false, 1.0, coredynp.opt_local, coredynp.core_ty); - bypass.area.set_area(bypass.area.get_area() +int_bypass->area.get_area()); - intTagBypass = new interconnect("Int Bypass tag" , Core_device, 1, 1, coredynp.phy_ireg_width, - rfu->int_regfile_height + exeu->FU_height + lsq_height + scheu->Iw_height + scheu->ROB_height , &interface_ip, 3, - false, 1.0, coredynp.opt_local, coredynp.core_ty); - - if (coredynp.num_muls>0) - { - int_mul_bypass = new interconnect("Mul Bypass Data", Core_device, 1, 1, int(ceil(coredynp.int_data_width)), - rfu->int_regfile_height + exeu->FU_height + mul->FU_height + lsq_height, &interface_ip, 3, - false, 1.0, coredynp.opt_local, coredynp.core_ty); - intTag_mul_Bypass = new interconnect("Mul Bypass tag" , Core_device, 1, 1, coredynp.phy_ireg_width, - rfu->int_regfile_height + exeu->FU_height + mul->FU_height + lsq_height + scheu->Iw_height + scheu->ROB_height , &interface_ip, 3, - false, 1.0, coredynp.opt_local, coredynp.core_ty); - bypass.area.set_area(bypass.area.get_area() +int_mul_bypass->area.get_area()); - bypass.area.set_area(bypass.area.get_area() +intTag_mul_Bypass->area.get_area()); - } - - if (coredynp.num_fpus>0) - { - fp_bypass = new interconnect("FP Bypass Data" , Core_device, 1, 1, int(ceil(coredynp.fp_data_width)), - rfu->fp_regfile_height + fp_u->FU_height, &interface_ip, 3, - false, 1.0, coredynp.opt_local, coredynp.core_ty); - fpTagBypass = new interconnect("FP Bypass tag" , Core_device, 1, 1, coredynp.phy_freg_width, - rfu->fp_regfile_height + fp_u->FU_height + lsq_height + scheu->fp_Iw_height + scheu->ROB_height, &interface_ip, 3, - false, 1.0, coredynp.opt_local, coredynp.core_ty); - bypass.area.set_area(bypass.area.get_area() +fp_bypass->area.get_area()); - bypass.area.set_area(bypass.area.get_area() +fpTagBypass->area.get_area()); - } - } - else - { - /* - * In RS based processor both data and tag are broadcast together, - * covering functional units, lsq, nst windows, register files, and ROBs - */ - int_bypass = new interconnect("Int Bypass Data", Core_device, 1, 1, int(ceil(coredynp.int_data_width)), - rfu->int_regfile_height + exeu->FU_height + lsq_height + scheu->Iw_height + scheu->ROB_height, &interface_ip, 3, - false, 1.0, coredynp.opt_local, coredynp.core_ty); - intTagBypass = new interconnect("Int Bypass tag" , Core_device, 1, 1, coredynp.phy_ireg_width, - rfu->int_regfile_height + exeu->FU_height + lsq_height + scheu->Iw_height + scheu->ROB_height , &interface_ip, 3, - false, 1.0, coredynp.opt_local, coredynp.core_ty); - bypass.area.set_area(bypass.area.get_area() +int_bypass->area.get_area()); - bypass.area.set_area(bypass.area.get_area() +intTagBypass->area.get_area()); - if (coredynp.num_muls>0) - { - int_mul_bypass = new interconnect("Mul Bypass Data", Core_device, 1, 1, int(ceil(coredynp.int_data_width)), - rfu->int_regfile_height + exeu->FU_height + mul->FU_height + lsq_height + scheu->Iw_height + scheu->ROB_height, &interface_ip, 3, - false, 1.0, coredynp.opt_local, coredynp.core_ty); - intTag_mul_Bypass = new interconnect("Mul Bypass tag" , Core_device, 1, 1, coredynp.phy_ireg_width, - rfu->int_regfile_height + exeu->FU_height + mul->FU_height + lsq_height + scheu->Iw_height + scheu->ROB_height , &interface_ip, 3, - false, 1.0, coredynp.opt_local, coredynp.core_ty); - bypass.area.set_area(bypass.area.get_area() +int_mul_bypass->area.get_area()); - bypass.area.set_area(bypass.area.get_area() +intTag_mul_Bypass->area.get_area()); - } - - if (coredynp.num_fpus>0) - { - fp_bypass = new interconnect("FP Bypass Data" , Core_device, 1, 1, int(ceil(coredynp.fp_data_width)), - rfu->fp_regfile_height + fp_u->FU_height + lsq_height + scheu->fp_Iw_height + scheu->ROB_height, &interface_ip, 3, - false, 1.0, coredynp.opt_local, coredynp.core_ty); - fpTagBypass = new interconnect("FP Bypass tag" , Core_device, 1, 1, coredynp.phy_freg_width, - rfu->fp_regfile_height + fp_u->FU_height + lsq_height + scheu->fp_Iw_height + scheu->ROB_height, &interface_ip, 3, - false, 1.0, coredynp.opt_local, coredynp.core_ty); - bypass.area.set_area(bypass.area.get_area() +fp_bypass->area.get_area()); - bypass.area.set_area(bypass.area.get_area() +fpTagBypass->area.get_area()); - } - } /* else */ - - - } /* else */ - area.set_area(area.get_area()/*+ bypass.area.get_area()*/); + } /* else */ + area.set_area(area.get_area() /*+ bypass.area.get_area()*/); } -RENAMINGU::RENAMINGU(ParseXML* XML_interface, int ithCore_, InputParameter* interface_ip_, const CoreDynParam & dyn_p_,bool exist_) -:XML(XML_interface), - ithCore(ithCore_), - interface_ip(*interface_ip_), - coredynp(dyn_p_), - iFRAT(0), - fFRAT(0), - iRRAT(0), - fRRAT(0), - ifreeL(0), - ffreeL(0), - idcl(0), - fdcl(0), - RAHT(0), - exist(exist_) - { - /* - * Although renaming logic maybe be used in in-order processors, - * McPAT assumes no renaming logic is used since the performance gain is very limited and - * the only major inorder processor with renaming logic is Itainium - * that is a VLIW processor and different from current McPAT's model. - * physical register base OOO must have Dual-RAT architecture or equivalent structure.FRAT:FrontRAT, RRAT:RetireRAT; - * i,f prefix mean int and fp - * RAT for all Renaming logic, random accessible checkpointing is used, but only update when instruction retires. - * FRAT will be read twice and written once per instruction; - * RRAT will be write once per instruction when committing and reads out all when context switch - * checkpointing is implicit - * Renaming logic is duplicated for each different hardware threads - * - * No Dual-RAT is needed in RS-based OOO processors, - * however, RAT needs to do associative search in RAT, when instruction commits and ROB release the entry, - * to make sure all the renamings associated with the ROB to be released are updated at the same time. - * RAM scheme has # ARchi Reg entry with each entry hold phy reg tag, - * CAM scheme has # Phy Reg entry with each entry hold ARchi reg tag, - * - * Both RAM and CAM have same DCL - */ - if (!exist) return; - int tag, data, out_w; -// interface_ip.wire_is_mat_type = 0; -// interface_ip.wire_os_mat_type = 0; -// interface_ip.wt = Global_30; - clockRate = coredynp.clockRate; - executionTime = coredynp.executionTime; - if (coredynp.core_ty==OOO) - { - //integer pipeline - if (coredynp.scheu_ty==PhysicalRegFile) - { - if (coredynp.rm_ty ==RAMbased) - { //FRAT with global checkpointing (GCs) please see paper tech report for detailed explaintions - data = 33;//int(ceil(coredynp.phy_ireg_width*(1+coredynp.globalCheckpoint)/8.0)); -// data = int(ceil(coredynp.phy_ireg_width/8.0)); - out_w = 1;//int(ceil(coredynp.phy_ireg_width/8.0)); - interface_ip.is_cache = false; - interface_ip.pure_cam = false; - interface_ip.pure_ram = true; - interface_ip.line_sz = data; - interface_ip.cache_sz = data*XML->sys.core[ithCore].archi_Regs_IRF_size; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = out_w*8; - interface_ip.access_mode = 2; - interface_ip.throughput = 1.0/clockRate; - interface_ip.latency = 1.0/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1;//the extra one port is for GCs - interface_ip.num_rd_ports = 2*coredynp.decodeW; - interface_ip.num_wr_ports = coredynp.decodeW; - interface_ip.num_se_rd_ports = 0; - iFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, coredynp.opt_local, coredynp.core_ty); - iFRAT->area.set_area(iFRAT->area.get_area()+ iFRAT->local_result.area*XML->sys.core[ithCore].number_hardware_threads); - area.set_area(area.get_area()+ iFRAT->area.get_area()); - -// //RAHT According to Intel, combine GC with FRAT is very costly. -// data = int(ceil(coredynp.phy_ireg_width/8.0)*coredynp.num_IRF_entry); -// out_w = data; -// interface_ip.is_cache = false; -// interface_ip.pure_cam = false; -// interface_ip.pure_ram = true; -// interface_ip.line_sz = data; -// interface_ip.cache_sz = data*coredynp.globalCheckpoint; -// interface_ip.assoc = 1; -// interface_ip.nbanks = 1; -// interface_ip.out_w = out_w*8; -// interface_ip.access_mode = 0; -// interface_ip.throughput = 1.0/clockRate; -// interface_ip.latency = 1.0/clockRate; -// interface_ip.obj_func_dyn_energy = 0; -// interface_ip.obj_func_dyn_power = 0; -// interface_ip.obj_func_leak_power = 0; -// interface_ip.obj_func_cycle_t = 1; -// interface_ip.num_rw_ports = 1;//the extra one port is for GCs -// interface_ip.num_rd_ports = 2*coredynp.decodeW; -// interface_ip.num_wr_ports = coredynp.decodeW; -// interface_ip.num_se_rd_ports = 0; -// iFRAT = new ArrayST(&interface_ip, "Int FrontRAT"); -// iFRAT->area.set_area(iFRAT->area.get_area()+ iFRAT->local_result.area*XML->sys.core[ithCore].number_hardware_threads); -// area.set_area(area.get_area()+ iFRAT->area.get_area()); - - //FRAT floating point - data = int(ceil(coredynp.phy_freg_width*(1+coredynp.globalCheckpoint)/8.0)); - out_w = int(ceil(coredynp.phy_freg_width/8.0)); - interface_ip.is_cache = false; - interface_ip.pure_cam = false; - interface_ip.pure_ram = true; - interface_ip.line_sz = data; - interface_ip.cache_sz = data*XML->sys.core[ithCore].archi_Regs_FRF_size; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = out_w*8; - interface_ip.access_mode = 2; - interface_ip.throughput = 1.0/clockRate; - interface_ip.latency = 1.0/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1;//the extra one port is for GCs - interface_ip.num_rd_ports = 2*coredynp.fp_decodeW; - interface_ip.num_wr_ports = coredynp.fp_decodeW; - interface_ip.num_se_rd_ports = 0; - fFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, coredynp.opt_local, coredynp.core_ty); - fFRAT->area.set_area(fFRAT->area.get_area()+ fFRAT->local_result.area*XML->sys.core[ithCore].number_hardware_threads); - area.set_area(area.get_area()+ fFRAT->area.get_area()); - - } - else if ((coredynp.rm_ty ==CAMbased)) - { - //FRAT - tag = coredynp.arch_ireg_width; - data = int(ceil ((coredynp.arch_ireg_width+1*coredynp.globalCheckpoint)/8.0));//the address of CAM needed to be sent out - out_w = int(ceil (coredynp.arch_ireg_width/8.0)); - interface_ip.is_cache = true; - interface_ip.pure_cam = false; - interface_ip.pure_ram = false; - interface_ip.line_sz = data; - interface_ip.cache_sz = data*XML->sys.core[ithCore].phy_Regs_IRF_size; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = out_w*8; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.access_mode = 2; - interface_ip.throughput = 1.0/clockRate; - interface_ip.latency = 1.0/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1;//for GCs - interface_ip.num_rd_ports = coredynp.decodeW; - interface_ip.num_wr_ports = coredynp.decodeW; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports= 2*coredynp.decodeW; - iFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, coredynp.opt_local, coredynp.core_ty); - iFRAT->area.set_area(iFRAT->area.get_area()+ iFRAT->local_result.area*XML->sys.core[ithCore].number_hardware_threads); - area.set_area(area.get_area()+ iFRAT->area.get_area()); - - //FRAT for FP - tag = coredynp.arch_freg_width; - data = int(ceil ((coredynp.arch_freg_width+1*coredynp.globalCheckpoint)/8.0));//the address of CAM needed to be sent out - out_w = int(ceil (coredynp.arch_freg_width/8.0)); - interface_ip.is_cache = true; - interface_ip.pure_cam = false; - interface_ip.pure_ram = false; - interface_ip.line_sz = data; - interface_ip.cache_sz = data*XML->sys.core[ithCore].phy_Regs_FRF_size; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = out_w*8; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.access_mode = 2; - interface_ip.throughput = 1.0/clockRate; - interface_ip.latency = 1.0/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1;//for GCs - interface_ip.num_rd_ports = coredynp.fp_decodeW; - interface_ip.num_wr_ports = coredynp.fp_decodeW; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports= 2*coredynp.fp_decodeW; - fFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, coredynp.opt_local, coredynp.core_ty); - fFRAT->area.set_area(fFRAT->area.get_area()+ fFRAT->local_result.area*XML->sys.core[ithCore].number_hardware_threads); - area.set_area(area.get_area()+ fFRAT->area.get_area()); - - } - - //RRAT is always RAM based, does not have GCs, and is used only for record latest non-speculative mapping - data = int(ceil(coredynp.phy_ireg_width/8.0)); - interface_ip.is_cache = false; - interface_ip.pure_cam = false; - interface_ip.pure_ram = true; - interface_ip.line_sz = data; - interface_ip.cache_sz = data*XML->sys.core[ithCore].archi_Regs_IRF_size*2;//HACK to make it as least 64B - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 1; - interface_ip.throughput = 1.0/clockRate; - interface_ip.latency = 1.0/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = XML->sys.core[ithCore].commit_width; - interface_ip.num_wr_ports = XML->sys.core[ithCore].commit_width; - interface_ip.num_se_rd_ports = 0; - iRRAT = new ArrayST(&interface_ip, "Int RetireRAT", Core_device, coredynp.opt_local, coredynp.core_ty); - iRRAT->area.set_area(iRRAT->area.get_area()+ iRRAT->local_result.area*XML->sys.core[ithCore].number_hardware_threads); - area.set_area(area.get_area()+ iRRAT->area.get_area()); - - //RRAT for FP - data = int(ceil(coredynp.phy_freg_width/8.0)); - interface_ip.is_cache = false; - interface_ip.pure_cam = false; - interface_ip.pure_ram = true; - interface_ip.line_sz = data; - interface_ip.cache_sz = data*XML->sys.core[ithCore].archi_Regs_FRF_size*2;//HACK to make it as least 64B - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 1; - interface_ip.throughput = 1.0/clockRate; - interface_ip.latency = 1.0/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = coredynp.fp_decodeW; - interface_ip.num_wr_ports = coredynp.fp_decodeW; - interface_ip.num_se_rd_ports = 0; - fRRAT = new ArrayST(&interface_ip, "Int RetireRAT", Core_device, coredynp.opt_local, coredynp.core_ty); - fRRAT->area.set_area(fRRAT->area.get_area()+ fRRAT->local_result.area*XML->sys.core[ithCore].number_hardware_threads); - area.set_area(area.get_area()+ fRRAT->area.get_area()); - - //Freelist of renaming unit always RAM based - //Recycle happens at two places: 1)when DCL check there are WAW, the Phyregisters/ROB directly recycles into freelist - // 2)When instruction commits the Phyregisters/ROB needed to be recycled. - //therefore num_wr port = decode-1(-1 means at least one phy reg will be used for the current renaming group) + commit width - data = int(ceil(coredynp.phy_ireg_width/8.0)); - interface_ip.is_cache = false; - interface_ip.pure_cam = false; - interface_ip.pure_ram = true; - interface_ip.line_sz = data; - interface_ip.cache_sz = data*coredynp.num_ifreelist_entries; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 1; - interface_ip.throughput = 1.0/clockRate; - interface_ip.latency = 1.0/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1;//TODO - interface_ip.num_rd_ports = coredynp.decodeW; - interface_ip.num_wr_ports = coredynp.decodeW -1 + XML->sys.core[ithCore].commit_width; - //every cycle, (coredynp.decodeW -1) inst may need to send back it dest tags, committW insts needs to update freelist buffers - interface_ip.num_se_rd_ports = 0; - ifreeL = new ArrayST(&interface_ip, "Int Free List", Core_device, coredynp.opt_local, coredynp.core_ty); - ifreeL->area.set_area(ifreeL->area.get_area()+ ifreeL->local_result.area*XML->sys.core[ithCore].number_hardware_threads); - area.set_area(area.get_area()+ ifreeL->area.get_area()); - - //freelist for FP - data = int(ceil(coredynp.phy_freg_width/8.0)); - interface_ip.is_cache = false; - interface_ip.pure_cam = false; - interface_ip.pure_ram = true; - interface_ip.line_sz = data; - interface_ip.cache_sz = data*coredynp.num_ffreelist_entries; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 1; - interface_ip.throughput = 1.0/clockRate; - interface_ip.latency = 1.0/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; - interface_ip.num_rd_ports = coredynp.fp_decodeW; - interface_ip.num_wr_ports = coredynp.fp_decodeW -1 + XML->sys.core[ithCore].commit_width; - interface_ip.num_se_rd_ports = 0; - ffreeL = new ArrayST(&interface_ip, "Int Free List", Core_device, coredynp.opt_local, coredynp.core_ty); - ffreeL->area.set_area(ffreeL->area.get_area()+ ffreeL->local_result.area*XML->sys.core[ithCore].number_hardware_threads); - area.set_area(area.get_area()+ ffreeL->area.get_area()); - - idcl = new dep_resource_conflict_check(&interface_ip,coredynp,coredynp.phy_ireg_width);//TODO:Separate 2 sections See TR - fdcl = new dep_resource_conflict_check(&interface_ip,coredynp,coredynp.phy_freg_width); - - } - else if (coredynp.scheu_ty==ReservationStation){ - if (coredynp.rm_ty ==RAMbased){ - /* - * however, RAT needs to do associative search in RAT, when instruction commits and ROB release the entry, - * to make sure all the renamings associated with the ROB to be released are updated to ARF at the same time. - * RAM based RAT for RS base OOO does not save the search operations. Its advantage is to have less entries than - * CAM based RAT so that it is more scalable as number of ROB/physical regs increases. - */ - tag = coredynp.phy_ireg_width; - data = int(ceil(coredynp.phy_ireg_width*(1+coredynp.globalCheckpoint)/8.0)); - out_w = int(ceil(coredynp.phy_ireg_width/8.0)); - interface_ip.is_cache = true; - interface_ip.pure_cam = false; - interface_ip.pure_ram = false; - interface_ip.line_sz = data; - interface_ip.cache_sz = data*XML->sys.core[ithCore].archi_Regs_IRF_size; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = out_w*8; - interface_ip.access_mode = 2; - interface_ip.throughput = 1.0/clockRate; - interface_ip.latency = 1.0/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1;//the extra one port is for GCs - interface_ip.num_rd_ports = 2*coredynp.decodeW; - interface_ip.num_wr_ports = coredynp.decodeW; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports= coredynp.commitW;//TODO - iFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, coredynp.opt_local, coredynp.core_ty); - iFRAT->local_result.adjust_area(); - iFRAT->area.set_area(iFRAT->area.get_area()+ iFRAT->local_result.area*XML->sys.core[ithCore].number_hardware_threads); - area.set_area(area.get_area()+ iFRAT->area.get_area()); - - //FP - tag = coredynp.phy_freg_width; - data = int(ceil(coredynp.phy_freg_width*(1+coredynp.globalCheckpoint)/8.0)); - out_w = int(ceil(coredynp.phy_freg_width/8.0)); - interface_ip.is_cache = true; - interface_ip.pure_cam = false; - interface_ip.pure_ram = false; - interface_ip.line_sz = data; - interface_ip.cache_sz = data*XML->sys.core[ithCore].archi_Regs_FRF_size; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = out_w*8; - interface_ip.access_mode = 2; - interface_ip.throughput = 1.0/clockRate; - interface_ip.latency = 1.0/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1;//the extra one port is for GCs - interface_ip.num_rd_ports = 2*coredynp.fp_decodeW; - interface_ip.num_wr_ports = coredynp.fp_decodeW; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports= coredynp.fp_decodeW;//actually is fp commit width - fFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, coredynp.opt_local, coredynp.core_ty); - fFRAT->local_result.adjust_area(); - fFRAT->area.set_area(fFRAT->area.get_area()+ fFRAT->local_result.area*XML->sys.core[ithCore].number_hardware_threads); - area.set_area(area.get_area()+ fFRAT->area.get_area()); - - } - else if ((coredynp.rm_ty ==CAMbased)) - { - //FRAT - tag = coredynp.arch_ireg_width; - data = int(ceil (coredynp.arch_ireg_width+1*coredynp.globalCheckpoint/8.0));//the address of CAM needed to be sent out - out_w = int(ceil (coredynp.arch_ireg_width/8.0)); - interface_ip.is_cache = true; - interface_ip.pure_cam = false; - interface_ip.pure_ram = false; - interface_ip.line_sz = data; - interface_ip.cache_sz = data*XML->sys.core[ithCore].phy_Regs_IRF_size; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = out_w*8; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.access_mode = 2; - interface_ip.throughput = 1.0/clockRate; - interface_ip.latency = 1.0/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1;//for GCs - interface_ip.num_rd_ports = XML->sys.core[ithCore].decode_width;//0;TODO - interface_ip.num_wr_ports = XML->sys.core[ithCore].decode_width; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports= 2*XML->sys.core[ithCore].decode_width; - iFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, coredynp.opt_local, coredynp.core_ty); - iFRAT->area.set_area(iFRAT->area.get_area()+ iFRAT->local_result.area*XML->sys.core[ithCore].number_hardware_threads); - area.set_area(area.get_area()+ iFRAT->area.get_area()); - - //FRAT - tag = coredynp.arch_freg_width; - data = int(ceil (coredynp.arch_freg_width+1*coredynp.globalCheckpoint/8.0));//the address of CAM needed to be sent out - out_w = int(ceil (coredynp.arch_freg_width/8.0)); - interface_ip.is_cache = true; - interface_ip.pure_cam = false; - interface_ip.pure_ram = false; - interface_ip.line_sz = data; - interface_ip.cache_sz = data*XML->sys.core[ithCore].phy_Regs_FRF_size; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = out_w*8; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.access_mode = 2; - interface_ip.throughput = 1.0/clockRate; - interface_ip.latency = 1.0/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1;//for GCs - interface_ip.num_rd_ports = XML->sys.core[ithCore].decode_width;//0;TODO; - interface_ip.num_wr_ports = coredynp.fp_decodeW; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports= 2*coredynp.fp_decodeW; - fFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, coredynp.opt_local, coredynp.core_ty); - fFRAT->area.set_area(fFRAT->area.get_area()+ fFRAT->local_result.area*XML->sys.core[ithCore].number_hardware_threads); - area.set_area(area.get_area()+ fFRAT->area.get_area()); - - } - //No RRAT for RS based OOO - //Freelist of renaming unit of RS based OOO is unifed for both int and fp renaming unit since the ROB is unified - data = int(ceil(coredynp.phy_ireg_width/8.0)); - interface_ip.is_cache = false; - interface_ip.pure_cam = false; - interface_ip.pure_ram = true; - interface_ip.line_sz = data; - interface_ip.cache_sz = data*coredynp.num_ifreelist_entries; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 1; - interface_ip.throughput = 1.0/clockRate; - interface_ip.latency = 1.0/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1;//TODO - interface_ip.num_rd_ports = XML->sys.core[ithCore].decode_width; - interface_ip.num_wr_ports = XML->sys.core[ithCore].decode_width -1 + XML->sys.core[ithCore].commit_width; - interface_ip.num_se_rd_ports = 0; - ifreeL = new ArrayST(&interface_ip, "Unified Free List", Core_device, coredynp.opt_local, coredynp.core_ty); - ifreeL->area.set_area(ifreeL->area.get_area()+ ifreeL->local_result.area*XML->sys.core[ithCore].number_hardware_threads); - area.set_area(area.get_area()+ ifreeL->area.get_area()); - - idcl = new dep_resource_conflict_check(&interface_ip,coredynp,coredynp.phy_ireg_width);//TODO:Separate 2 sections See TR - fdcl = new dep_resource_conflict_check(&interface_ip,coredynp,coredynp.phy_freg_width); - } +RENAMINGU::RENAMINGU(ParseXML* XML_interface, int ithCore_, + InputParameter* interface_ip_, const CoreDynParam& dyn_p_, + bool exist_) + : XML(XML_interface), + ithCore(ithCore_), + interface_ip(*interface_ip_), + coredynp(dyn_p_), + iFRAT(0), + fFRAT(0), + iRRAT(0), + fRRAT(0), + ifreeL(0), + ffreeL(0), + idcl(0), + fdcl(0), + RAHT(0), + exist(exist_) { + /* + * Although renaming logic maybe be used in in-order processors, + * McPAT assumes no renaming logic is used since the performance gain is very + * limited and the only major inorder processor with renaming logic is + * Itainium that is a VLIW processor and different from current McPAT's model. + * physical register base OOO must have Dual-RAT architecture or equivalent + * structure.FRAT:FrontRAT, RRAT:RetireRAT; i,f prefix mean int and fp RAT for + * all Renaming logic, random accessible checkpointing is used, but only + * update when instruction retires. FRAT will be read twice and written once + * per instruction; RRAT will be write once per instruction when committing + * and reads out all when context switch checkpointing is implicit Renaming + * logic is duplicated for each different hardware threads + * + * No Dual-RAT is needed in RS-based OOO processors, + * however, RAT needs to do associative search in RAT, when instruction + * commits and ROB release the entry, to make sure all the renamings + * associated with the ROB to be released are updated at the same time. RAM + * scheme has # ARchi Reg entry with each entry hold phy reg tag, CAM scheme + * has # Phy Reg entry with each entry hold ARchi reg tag, + * + * Both RAM and CAM have same DCL + */ + if (!exist) return; + int tag, data, out_w; + // interface_ip.wire_is_mat_type = 0; + // interface_ip.wire_os_mat_type = 0; + // interface_ip.wt = Global_30; + clockRate = coredynp.clockRate; + executionTime = coredynp.executionTime; + if (coredynp.core_ty == OOO) { + // integer pipeline + if (coredynp.scheu_ty == PhysicalRegFile) { + if (coredynp.rm_ty == + RAMbased) { // FRAT with global checkpointing (GCs) please see paper + // tech report for detailed explaintions + data = + 33; // int(ceil(coredynp.phy_ireg_width*(1+coredynp.globalCheckpoint)/8.0)); + // data + //= int(ceil(coredynp.phy_ireg_width/8.0)); + out_w = 1; // int(ceil(coredynp.phy_ireg_width/8.0)); + interface_ip.is_cache = false; + interface_ip.pure_cam = false; + interface_ip.pure_ram = true; + interface_ip.line_sz = data; + interface_ip.cache_sz = + data * XML->sys.core[ithCore].archi_Regs_IRF_size; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = out_w * 8; + interface_ip.access_mode = 2; + interface_ip.throughput = 1.0 / clockRate; + interface_ip.latency = 1.0 / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1; // the extra one port is for GCs + interface_ip.num_rd_ports = 2 * coredynp.decodeW; + interface_ip.num_wr_ports = coredynp.decodeW; + interface_ip.num_se_rd_ports = 0; + iFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, + coredynp.opt_local, coredynp.core_ty); + iFRAT->area.set_area( + iFRAT->area.get_area() + + iFRAT->local_result.area * + XML->sys.core[ithCore].number_hardware_threads); + area.set_area(area.get_area() + iFRAT->area.get_area()); + + // //RAHT According to Intel, combine GC with FRAT + // is very costly. data = + // int(ceil(coredynp.phy_ireg_width/8.0)*coredynp.num_IRF_entry); + // out_w = data; interface_ip.is_cache + //= false; interface_ip.pure_cam = + //false; interface_ip.pure_ram = true; interface_ip.line_sz + //= data; interface_ip.cache_sz = + // data*coredynp.globalCheckpoint; interface_ip.assoc = 1; + // interface_ip.nbanks = 1; + // interface_ip.out_w = + // out_w*8; interface_ip.access_mode = 0; + // interface_ip.throughput = 1.0/clockRate; + //interface_ip.latency = 1.0/clockRate; interface_ip.obj_func_dyn_energy + //= 0; interface_ip.obj_func_dyn_power = 0; + // interface_ip.obj_func_leak_power = 0; + // interface_ip.obj_func_cycle_t = 1; + // interface_ip.num_rw_ports = 1;//the extra one + // port is for GCs interface_ip.num_rd_ports = + // 2*coredynp.decodeW; interface_ip.num_wr_ports = + // coredynp.decodeW; + // interface_ip.num_se_rd_ports = 0; + // iFRAT = new ArrayST(&interface_ip, "Int + // FrontRAT"); + // iFRAT->area.set_area(iFRAT->area.get_area()+ + // iFRAT->local_result.area*XML->sys.core[ithCore].number_hardware_threads); + // area.set_area(area.get_area()+ + // iFRAT->area.get_area()); + + // FRAT floating point + data = int(ceil(coredynp.phy_freg_width * + (1 + coredynp.globalCheckpoint) / 8.0)); + out_w = int(ceil(coredynp.phy_freg_width / 8.0)); + interface_ip.is_cache = false; + interface_ip.pure_cam = false; + interface_ip.pure_ram = true; + interface_ip.line_sz = data; + interface_ip.cache_sz = + data * XML->sys.core[ithCore].archi_Regs_FRF_size; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = out_w * 8; + interface_ip.access_mode = 2; + interface_ip.throughput = 1.0 / clockRate; + interface_ip.latency = 1.0 / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1; // the extra one port is for GCs + interface_ip.num_rd_ports = 2 * coredynp.fp_decodeW; + interface_ip.num_wr_ports = coredynp.fp_decodeW; + interface_ip.num_se_rd_ports = 0; + fFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, + coredynp.opt_local, coredynp.core_ty); + fFRAT->area.set_area( + fFRAT->area.get_area() + + fFRAT->local_result.area * + XML->sys.core[ithCore].number_hardware_threads); + area.set_area(area.get_area() + fFRAT->area.get_area()); + + } else if ((coredynp.rm_ty == CAMbased)) { + // FRAT + tag = coredynp.arch_ireg_width; + data = int( + ceil((coredynp.arch_ireg_width + 1 * coredynp.globalCheckpoint) / + 8.0)); // the address of CAM needed to be sent out + out_w = int(ceil(coredynp.arch_ireg_width / 8.0)); + interface_ip.is_cache = true; + interface_ip.pure_cam = false; + interface_ip.pure_ram = false; + interface_ip.line_sz = data; + interface_ip.cache_sz = data * XML->sys.core[ithCore].phy_Regs_IRF_size; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = out_w * 8; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.access_mode = 2; + interface_ip.throughput = 1.0 / clockRate; + interface_ip.latency = 1.0 / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1; // for GCs + interface_ip.num_rd_ports = coredynp.decodeW; + interface_ip.num_wr_ports = coredynp.decodeW; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = 2 * coredynp.decodeW; + iFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, + coredynp.opt_local, coredynp.core_ty); + iFRAT->area.set_area( + iFRAT->area.get_area() + + iFRAT->local_result.area * + XML->sys.core[ithCore].number_hardware_threads); + area.set_area(area.get_area() + iFRAT->area.get_area()); + + // FRAT for FP + tag = coredynp.arch_freg_width; + data = int( + ceil((coredynp.arch_freg_width + 1 * coredynp.globalCheckpoint) / + 8.0)); // the address of CAM needed to be sent out + out_w = int(ceil(coredynp.arch_freg_width / 8.0)); + interface_ip.is_cache = true; + interface_ip.pure_cam = false; + interface_ip.pure_ram = false; + interface_ip.line_sz = data; + interface_ip.cache_sz = data * XML->sys.core[ithCore].phy_Regs_FRF_size; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = out_w * 8; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.access_mode = 2; + interface_ip.throughput = 1.0 / clockRate; + interface_ip.latency = 1.0 / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1; // for GCs + interface_ip.num_rd_ports = coredynp.fp_decodeW; + interface_ip.num_wr_ports = coredynp.fp_decodeW; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = 2 * coredynp.fp_decodeW; + fFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, + coredynp.opt_local, coredynp.core_ty); + fFRAT->area.set_area( + fFRAT->area.get_area() + + fFRAT->local_result.area * + XML->sys.core[ithCore].number_hardware_threads); + area.set_area(area.get_area() + fFRAT->area.get_area()); + } -} - if (coredynp.core_ty==Inorder&& coredynp.issueW>1) - { - /* Dependency check logic will only present when decode(issue) width>1. - * Multiple issue in order processor can do without renaming, but dcl is a must. - */ - idcl = new dep_resource_conflict_check(&interface_ip,coredynp,coredynp.phy_ireg_width);//TODO:Separate 2 sections See TR - fdcl = new dep_resource_conflict_check(&interface_ip,coredynp,coredynp.phy_freg_width); + // RRAT is always RAM based, does not have GCs, and is used only for + // record latest non-speculative mapping + data = int(ceil(coredynp.phy_ireg_width / 8.0)); + interface_ip.is_cache = false; + interface_ip.pure_cam = false; + interface_ip.pure_ram = true; + interface_ip.line_sz = data; + interface_ip.cache_sz = data * + XML->sys.core[ithCore].archi_Regs_IRF_size * + 2; // HACK to make it as least 64B + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 1; + interface_ip.throughput = 1.0 / clockRate; + interface_ip.latency = 1.0 / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = XML->sys.core[ithCore].commit_width; + interface_ip.num_wr_ports = XML->sys.core[ithCore].commit_width; + interface_ip.num_se_rd_ports = 0; + iRRAT = new ArrayST(&interface_ip, "Int RetireRAT", Core_device, + coredynp.opt_local, coredynp.core_ty); + iRRAT->area.set_area(iRRAT->area.get_area() + + iRRAT->local_result.area * + XML->sys.core[ithCore].number_hardware_threads); + area.set_area(area.get_area() + iRRAT->area.get_area()); + + // RRAT for FP + data = int(ceil(coredynp.phy_freg_width / 8.0)); + interface_ip.is_cache = false; + interface_ip.pure_cam = false; + interface_ip.pure_ram = true; + interface_ip.line_sz = data; + interface_ip.cache_sz = data * + XML->sys.core[ithCore].archi_Regs_FRF_size * + 2; // HACK to make it as least 64B + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 1; + interface_ip.throughput = 1.0 / clockRate; + interface_ip.latency = 1.0 / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = coredynp.fp_decodeW; + interface_ip.num_wr_ports = coredynp.fp_decodeW; + interface_ip.num_se_rd_ports = 0; + fRRAT = new ArrayST(&interface_ip, "Int RetireRAT", Core_device, + coredynp.opt_local, coredynp.core_ty); + fRRAT->area.set_area(fRRAT->area.get_area() + + fRRAT->local_result.area * + XML->sys.core[ithCore].number_hardware_threads); + area.set_area(area.get_area() + fRRAT->area.get_area()); + + // Freelist of renaming unit always RAM based + // Recycle happens at two places: 1)when DCL check there are WAW, the + // Phyregisters/ROB directly recycles into freelist + // 2)When instruction commits the Phyregisters/ROB needed to be recycled. + // therefore num_wr port = decode-1(-1 means at least one phy reg will be + // used for the current renaming group) + commit width + data = int(ceil(coredynp.phy_ireg_width / 8.0)); + interface_ip.is_cache = false; + interface_ip.pure_cam = false; + interface_ip.pure_ram = true; + interface_ip.line_sz = data; + interface_ip.cache_sz = data * coredynp.num_ifreelist_entries; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 1; + interface_ip.throughput = 1.0 / clockRate; + interface_ip.latency = 1.0 / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1; // TODO + interface_ip.num_rd_ports = coredynp.decodeW; + interface_ip.num_wr_ports = + coredynp.decodeW - 1 + XML->sys.core[ithCore].commit_width; + // every cycle, (coredynp.decodeW -1) inst may need to send back it dest + // tags, committW insts needs to update freelist buffers + interface_ip.num_se_rd_ports = 0; + ifreeL = new ArrayST(&interface_ip, "Int Free List", Core_device, + coredynp.opt_local, coredynp.core_ty); + ifreeL->area.set_area(ifreeL->area.get_area() + + ifreeL->local_result.area * + XML->sys.core[ithCore].number_hardware_threads); + area.set_area(area.get_area() + ifreeL->area.get_area()); + + // freelist for FP + data = int(ceil(coredynp.phy_freg_width / 8.0)); + interface_ip.is_cache = false; + interface_ip.pure_cam = false; + interface_ip.pure_ram = true; + interface_ip.line_sz = data; + interface_ip.cache_sz = data * coredynp.num_ffreelist_entries; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 1; + interface_ip.throughput = 1.0 / clockRate; + interface_ip.latency = 1.0 / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1; + interface_ip.num_rd_ports = coredynp.fp_decodeW; + interface_ip.num_wr_ports = + coredynp.fp_decodeW - 1 + XML->sys.core[ithCore].commit_width; + interface_ip.num_se_rd_ports = 0; + ffreeL = new ArrayST(&interface_ip, "Int Free List", Core_device, + coredynp.opt_local, coredynp.core_ty); + ffreeL->area.set_area(ffreeL->area.get_area() + + ffreeL->local_result.area * + XML->sys.core[ithCore].number_hardware_threads); + area.set_area(area.get_area() + ffreeL->area.get_area()); + + idcl = new dep_resource_conflict_check( + &interface_ip, coredynp, + coredynp.phy_ireg_width); // TODO:Separate 2 sections See TR + fdcl = new dep_resource_conflict_check(&interface_ip, coredynp, + coredynp.phy_freg_width); + + } else if (coredynp.scheu_ty == ReservationStation) { + if (coredynp.rm_ty == RAMbased) { + /* + * however, RAT needs to do associative search in RAT, when instruction + * commits and ROB release the entry, to make sure all the renamings + * associated with the ROB to be released are updated to ARF at the same + * time. RAM based RAT for RS base OOO does not save the search + * operations. Its advantage is to have less entries than CAM based RAT + * so that it is more scalable as number of ROB/physical regs increases. + */ + tag = coredynp.phy_ireg_width; + data = int(ceil(coredynp.phy_ireg_width * + (1 + coredynp.globalCheckpoint) / 8.0)); + out_w = int(ceil(coredynp.phy_ireg_width / 8.0)); + interface_ip.is_cache = true; + interface_ip.pure_cam = false; + interface_ip.pure_ram = false; + interface_ip.line_sz = data; + interface_ip.cache_sz = + data * XML->sys.core[ithCore].archi_Regs_IRF_size; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = out_w * 8; + interface_ip.access_mode = 2; + interface_ip.throughput = 1.0 / clockRate; + interface_ip.latency = 1.0 / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1; // the extra one port is for GCs + interface_ip.num_rd_ports = 2 * coredynp.decodeW; + interface_ip.num_wr_ports = coredynp.decodeW; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = coredynp.commitW; // TODO + iFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, + coredynp.opt_local, coredynp.core_ty); + iFRAT->local_result.adjust_area(); + iFRAT->area.set_area( + iFRAT->area.get_area() + + iFRAT->local_result.area * + XML->sys.core[ithCore].number_hardware_threads); + area.set_area(area.get_area() + iFRAT->area.get_area()); + + // FP + tag = coredynp.phy_freg_width; + data = int(ceil(coredynp.phy_freg_width * + (1 + coredynp.globalCheckpoint) / 8.0)); + out_w = int(ceil(coredynp.phy_freg_width / 8.0)); + interface_ip.is_cache = true; + interface_ip.pure_cam = false; + interface_ip.pure_ram = false; + interface_ip.line_sz = data; + interface_ip.cache_sz = + data * XML->sys.core[ithCore].archi_Regs_FRF_size; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = out_w * 8; + interface_ip.access_mode = 2; + interface_ip.throughput = 1.0 / clockRate; + interface_ip.latency = 1.0 / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1; // the extra one port is for GCs + interface_ip.num_rd_ports = 2 * coredynp.fp_decodeW; + interface_ip.num_wr_ports = coredynp.fp_decodeW; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = + coredynp.fp_decodeW; // actually is fp commit width + fFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, + coredynp.opt_local, coredynp.core_ty); + fFRAT->local_result.adjust_area(); + fFRAT->area.set_area( + fFRAT->area.get_area() + + fFRAT->local_result.area * + XML->sys.core[ithCore].number_hardware_threads); + area.set_area(area.get_area() + fFRAT->area.get_area()); + + } else if ((coredynp.rm_ty == CAMbased)) { + // FRAT + tag = coredynp.arch_ireg_width; + data = int(ceil(coredynp.arch_ireg_width + + 1 * coredynp.globalCheckpoint / + 8.0)); // the address of CAM needed to be sent out + out_w = int(ceil(coredynp.arch_ireg_width / 8.0)); + interface_ip.is_cache = true; + interface_ip.pure_cam = false; + interface_ip.pure_ram = false; + interface_ip.line_sz = data; + interface_ip.cache_sz = data * XML->sys.core[ithCore].phy_Regs_IRF_size; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = out_w * 8; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.access_mode = 2; + interface_ip.throughput = 1.0 / clockRate; + interface_ip.latency = 1.0 / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1; // for GCs + interface_ip.num_rd_ports = + XML->sys.core[ithCore].decode_width; // 0;TODO + interface_ip.num_wr_ports = XML->sys.core[ithCore].decode_width; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = 2 * XML->sys.core[ithCore].decode_width; + iFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, + coredynp.opt_local, coredynp.core_ty); + iFRAT->area.set_area( + iFRAT->area.get_area() + + iFRAT->local_result.area * + XML->sys.core[ithCore].number_hardware_threads); + area.set_area(area.get_area() + iFRAT->area.get_area()); + + // FRAT + tag = coredynp.arch_freg_width; + data = int(ceil(coredynp.arch_freg_width + + 1 * coredynp.globalCheckpoint / + 8.0)); // the address of CAM needed to be sent out + out_w = int(ceil(coredynp.arch_freg_width / 8.0)); + interface_ip.is_cache = true; + interface_ip.pure_cam = false; + interface_ip.pure_ram = false; + interface_ip.line_sz = data; + interface_ip.cache_sz = data * XML->sys.core[ithCore].phy_Regs_FRF_size; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = out_w * 8; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.access_mode = 2; + interface_ip.throughput = 1.0 / clockRate; + interface_ip.latency = 1.0 / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1; // for GCs + interface_ip.num_rd_ports = + XML->sys.core[ithCore].decode_width; // 0;TODO; + interface_ip.num_wr_ports = coredynp.fp_decodeW; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = 2 * coredynp.fp_decodeW; + fFRAT = new ArrayST(&interface_ip, "Int FrontRAT", Core_device, + coredynp.opt_local, coredynp.core_ty); + fFRAT->area.set_area( + fFRAT->area.get_area() + + fFRAT->local_result.area * + XML->sys.core[ithCore].number_hardware_threads); + area.set_area(area.get_area() + fFRAT->area.get_area()); + } + // No RRAT for RS based OOO + // Freelist of renaming unit of RS based OOO is unifed for both int and fp + // renaming unit since the ROB is unified + data = int(ceil(coredynp.phy_ireg_width / 8.0)); + interface_ip.is_cache = false; + interface_ip.pure_cam = false; + interface_ip.pure_ram = true; + interface_ip.line_sz = data; + interface_ip.cache_sz = data * coredynp.num_ifreelist_entries; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 1; + interface_ip.throughput = 1.0 / clockRate; + interface_ip.latency = 1.0 / clockRate; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1; // TODO + interface_ip.num_rd_ports = XML->sys.core[ithCore].decode_width; + interface_ip.num_wr_ports = XML->sys.core[ithCore].decode_width - 1 + + XML->sys.core[ithCore].commit_width; + interface_ip.num_se_rd_ports = 0; + ifreeL = new ArrayST(&interface_ip, "Unified Free List", Core_device, + coredynp.opt_local, coredynp.core_ty); + ifreeL->area.set_area(ifreeL->area.get_area() + + ifreeL->local_result.area * + XML->sys.core[ithCore].number_hardware_threads); + area.set_area(area.get_area() + ifreeL->area.get_area()); + + idcl = new dep_resource_conflict_check( + &interface_ip, coredynp, + coredynp.phy_ireg_width); // TODO:Separate 2 sections See TR + fdcl = new dep_resource_conflict_check(&interface_ip, coredynp, + coredynp.phy_freg_width); } + } + if (coredynp.core_ty == Inorder && coredynp.issueW > 1) { + /* Dependency check logic will only present when decode(issue) width>1. + * Multiple issue in order processor can do without renaming, but dcl is a + * must. + */ + idcl = new dep_resource_conflict_check( + &interface_ip, coredynp, + coredynp.phy_ireg_width); // TODO:Separate 2 sections See TR + fdcl = new dep_resource_conflict_check(&interface_ip, coredynp, + coredynp.phy_freg_width); + } } Core::Core(ParseXML* XML_interface, int ithCore_, InputParameter* interface_ip_) -:XML(XML_interface), - ithCore(ithCore_), - interface_ip(*interface_ip_), - ifu (0), - lsu (0), - mmu (0), - exu (0), - rnu (0), - corepipe (0), - undiffCore (0), - l2cache (0) -{ - /** - * Testing: (to be removed) added by syed - */ - //XML->sys.core[ithCore].simd_width=8;// (8) - //XML->sys.core[ithCore].collector_units=4;// (4) - //XML->sys.core[ithCore].core_clock_ratio=2.0;// (2.0) - //XML->sys.core[ithCore].warp_size=32;// (32) - + : XML(XML_interface), + ithCore(ithCore_), + interface_ip(*interface_ip_), + ifu(0), + lsu(0), + mmu(0), + exu(0), + rnu(0), + corepipe(0), + undiffCore(0), + l2cache(0) { + /** + * Testing: (to be removed) added by syed + */ + // XML->sys.core[ithCore].simd_width=8;// (8) + // XML->sys.core[ithCore].collector_units=4;// (4) + // XML->sys.core[ithCore].core_clock_ratio=2.0;// (2.0) + // XML->sys.core[ithCore].warp_size=32;// (32) + /* - * initialize, compute and optimize individual components. - */ + * initialize, compute and optimize individual components. + */ - IdleCoreEnergy=0; - IdlePower_PerCore = 0; + IdleCoreEnergy = 0; + IdlePower_PerCore = 0; double pipeline_area_per_unit; - if (XML->sys.Private_L2) - { - l2cache = new SharedCache(XML,ithCore, &interface_ip); - + if (XML->sys.Private_L2) { + l2cache = new SharedCache(XML, ithCore, &interface_ip); } -// interface_ip.wire_is_mat_type = 2; -// interface_ip.wire_os_mat_type = 2; -// interface_ip.wt =Global_30; + // interface_ip.wire_is_mat_type = 2; + // interface_ip.wire_os_mat_type = 2; + // interface_ip.wt =Global_30; set_core_param(); clockRate = coredynp.clockRate; - exClockRate = clockRate*XML->sys.core[ithCore].core_clock_ratio; + exClockRate = clockRate * XML->sys.core[ithCore].core_clock_ratio; executionTime = coredynp.executionTime; - ifu = new InstFetchU(XML, ithCore, &interface_ip,coredynp); - lsu = new LoadStoreU(XML, ithCore, &interface_ip,coredynp); - mmu = new MemManU (XML, ithCore, &interface_ip,coredynp); - exu = new EXECU (XML, ithCore, &interface_ip,lsu->lsq_height, coredynp, exClockRate,true); - - - - - - undiffCore = new UndiffCore(XML, ithCore, &interface_ip,coredynp); - if (coredynp.core_ty==OOO) - { - rnu = new RENAMINGU(XML, ithCore, &interface_ip,coredynp); - } - corepipe = new Pipeline(&interface_ip,coredynp); - - if (coredynp.core_ty==OOO) - { - pipeline_area_per_unit = (corepipe->area.get_area()*coredynp.num_pipelines)/5.0; - if (rnu->exist) - { - rnu->area.set_area(rnu->area.get_area() + pipeline_area_per_unit); - } + ifu = new InstFetchU(XML, ithCore, &interface_ip, coredynp); + lsu = new LoadStoreU(XML, ithCore, &interface_ip, coredynp); + mmu = new MemManU(XML, ithCore, &interface_ip, coredynp); + exu = new EXECU(XML, ithCore, &interface_ip, lsu->lsq_height, coredynp, + exClockRate, true); + + undiffCore = new UndiffCore(XML, ithCore, &interface_ip, coredynp); + if (coredynp.core_ty == OOO) { + rnu = new RENAMINGU(XML, ithCore, &interface_ip, coredynp); } - else { - pipeline_area_per_unit = (corepipe->area.get_area()*coredynp.num_pipelines)/4.0; + corepipe = new Pipeline(&interface_ip, coredynp); + + if (coredynp.core_ty == OOO) { + pipeline_area_per_unit = + (corepipe->area.get_area() * coredynp.num_pipelines) / 5.0; + if (rnu->exist) { + rnu->area.set_area(rnu->area.get_area() + pipeline_area_per_unit); + } + } else { + pipeline_area_per_unit = + (corepipe->area.get_area() * coredynp.num_pipelines) / 4.0; } - //area.set_area(area.get_area()+ corepipe->area.get_area()); - if (ifu->exist) - { - ifu->area.set_area(ifu->area.get_area() + pipeline_area_per_unit); - area.set_area(area.get_area() + ifu->area.get_area()); + // area.set_area(area.get_area()+ corepipe->area.get_area()); + if (ifu->exist) { + ifu->area.set_area(ifu->area.get_area() + pipeline_area_per_unit); + area.set_area(area.get_area() + ifu->area.get_area()); } - if (lsu->exist) - { - lsu->area.set_area(lsu->area.get_area() + pipeline_area_per_unit); - area.set_area(area.get_area() + lsu->area.get_area()); + if (lsu->exist) { + lsu->area.set_area(lsu->area.get_area() + pipeline_area_per_unit); + area.set_area(area.get_area() + lsu->area.get_area()); } - if (exu->exist) - { - exu->area.set_area(exu->area.get_area() + pipeline_area_per_unit); - area.set_area(area.get_area()+exu->area.get_area()); + if (exu->exist) { + exu->area.set_area(exu->area.get_area() + pipeline_area_per_unit); + area.set_area(area.get_area() + exu->area.get_area()); } - if (mmu->exist) - { - mmu->area.set_area(mmu->area.get_area() + pipeline_area_per_unit); - area.set_area(area.get_area()+mmu->area.get_area()); + if (mmu->exist) { + mmu->area.set_area(mmu->area.get_area() + pipeline_area_per_unit); + area.set_area(area.get_area() + mmu->area.get_area()); } - if (coredynp.core_ty==OOO) - { - if (rnu->exist) - { + if (coredynp.core_ty == OOO) { + if (rnu->exist) { + area.set_area(area.get_area() + rnu->area.get_area()); + } + } - area.set_area(area.get_area() + rnu->area.get_area()); - } + if (undiffCore->exist) { + area.set_area(area.get_area() + undiffCore->area.get_area()); } - if (undiffCore->exist) - { - area.set_area(area.get_area() + undiffCore->area.get_area()); + if (XML->sys.Private_L2) { + area.set_area(area.get_area() + l2cache->area.get_area()); } + // //clock power + // clockNetwork.init_wire_external(is_default, &interface_ip); + // clockNetwork.clk_area =area*1.1;//10% of placement overhead. + // rule of thumb clockNetwork.end_wiring_level =5;//toplevel metal + // clockNetwork.start_wiring_level =5;//toplevel metal + // clockNetwork.num_regs = corepipe.tot_stage_vector; + // clockNetwork.optimize_wire(); +} - if (XML->sys.Private_L2) - { - area.set_area(area.get_area() + l2cache->area.get_area()); +void BranchPredictor::computeEnergy(bool is_tdp) { + if (!exist) return; + double r_access; + double w_access; + if (is_tdp) { + r_access = coredynp.predictionW * coredynp.BR_duty_cycle; + w_access = 0 * coredynp.BR_duty_cycle; + globalBPT->stats_t.readAc.access = r_access; + globalBPT->stats_t.writeAc.access = w_access; + globalBPT->tdp_stats = globalBPT->stats_t; + + L1_localBPT->stats_t.readAc.access = r_access; + L1_localBPT->stats_t.writeAc.access = w_access; + L1_localBPT->tdp_stats = L1_localBPT->stats_t; + + L2_localBPT->stats_t.readAc.access = r_access; + L2_localBPT->stats_t.writeAc.access = w_access; + L2_localBPT->tdp_stats = L2_localBPT->stats_t; + + chooser->stats_t.readAc.access = r_access; + chooser->stats_t.writeAc.access = w_access; + chooser->tdp_stats = chooser->stats_t; + + RAS->stats_t.readAc.access = r_access; + RAS->stats_t.writeAc.access = w_access; + RAS->tdp_stats = RAS->stats_t; + } else { + // The resolution of BPT accesses is coarse, but this is + // because most simulators cannot track finer grained details + r_access = XML->sys.core[ithCore].branch_instructions; + w_access = + XML->sys.core[ithCore].branch_mispredictions + + 0.1 * XML->sys.core[ithCore] + .branch_instructions; // 10% of BR will flip internal bits//0 + globalBPT->stats_t.readAc.access = r_access; + globalBPT->stats_t.writeAc.access = w_access; + globalBPT->rtp_stats = globalBPT->stats_t; + + L1_localBPT->stats_t.readAc.access = r_access; + L1_localBPT->stats_t.writeAc.access = w_access; + L1_localBPT->rtp_stats = L1_localBPT->stats_t; + + L2_localBPT->stats_t.readAc.access = r_access; + L2_localBPT->stats_t.writeAc.access = w_access; + L2_localBPT->rtp_stats = L2_localBPT->stats_t; + + chooser->stats_t.readAc.access = r_access; + chooser->stats_t.writeAc.access = w_access; + chooser->rtp_stats = chooser->stats_t; + + RAS->stats_t.readAc.access = XML->sys.core[ithCore].function_calls; + RAS->stats_t.writeAc.access = XML->sys.core[ithCore].function_calls; + RAS->rtp_stats = RAS->stats_t; + } + globalBPT->power_t.reset(); + L1_localBPT->power_t.reset(); + L2_localBPT->power_t.reset(); + chooser->power_t.reset(); + RAS->power_t.reset(); + + globalBPT->power_t.readOp.dynamic += + globalBPT->local_result.power.readOp.dynamic * + globalBPT->stats_t.readAc.access + + globalBPT->stats_t.writeAc.access * + globalBPT->local_result.power.writeOp.dynamic; + L1_localBPT->power_t.readOp.dynamic += + L1_localBPT->local_result.power.readOp.dynamic * + L1_localBPT->stats_t.readAc.access + + L1_localBPT->stats_t.writeAc.access * + L1_localBPT->local_result.power.writeOp.dynamic; + + L2_localBPT->power_t.readOp.dynamic += + L2_localBPT->local_result.power.readOp.dynamic * + L2_localBPT->stats_t.readAc.access + + L2_localBPT->stats_t.writeAc.access * + L2_localBPT->local_result.power.writeOp.dynamic; + + chooser->power_t.readOp.dynamic += + chooser->local_result.power.readOp.dynamic * + chooser->stats_t.readAc.access + + chooser->stats_t.writeAc.access * + chooser->local_result.power.writeOp.dynamic; + RAS->power_t.readOp.dynamic += + RAS->local_result.power.readOp.dynamic * RAS->stats_t.readAc.access + + RAS->stats_t.writeAc.access * RAS->local_result.power.writeOp.dynamic; + + if (is_tdp) { + globalBPT->power = + globalBPT->power_t + globalBPT->local_result.power * pppm_lkg; + L1_localBPT->power = + L1_localBPT->power_t + L1_localBPT->local_result.power * pppm_lkg; + L2_localBPT->power = + L2_localBPT->power_t + L2_localBPT->local_result.power * pppm_lkg; + chooser->power = chooser->power_t + chooser->local_result.power * pppm_lkg; + RAS->power = + RAS->power_t + RAS->local_result.power * coredynp.pppm_lkg_multhread; + + power = power + globalBPT->power + L1_localBPT->power + chooser->power + + RAS->power; + } else { + globalBPT->rt_power = + globalBPT->power_t + globalBPT->local_result.power * pppm_lkg; + L1_localBPT->rt_power = + L1_localBPT->power_t + L1_localBPT->local_result.power * pppm_lkg; + L2_localBPT->rt_power = + L2_localBPT->power_t + L2_localBPT->local_result.power * pppm_lkg; + chooser->rt_power = + chooser->power_t + chooser->local_result.power * pppm_lkg; + RAS->rt_power = + RAS->power_t + RAS->local_result.power * coredynp.pppm_lkg_multhread; + rt_power = rt_power + globalBPT->rt_power + L1_localBPT->rt_power + + chooser->rt_power + RAS->rt_power; } -// //clock power -// clockNetwork.init_wire_external(is_default, &interface_ip); -// clockNetwork.clk_area =area*1.1;//10% of placement overhead. rule of thumb -// clockNetwork.end_wiring_level =5;//toplevel metal -// clockNetwork.start_wiring_level =5;//toplevel metal -// clockNetwork.num_regs = corepipe.tot_stage_vector; -// clockNetwork.optimize_wire(); } +void BranchPredictor::displayEnergy(uint32_t indent, int plevel, bool is_tdp) { + if (!exist) return; + string indent_str(indent, ' '); + string indent_str_next(indent + 2, ' '); + bool long_channel = XML->sys.longer_channel_device; + if (is_tdp) { + cout << indent_str << "Global Predictor:" << endl; + cout << indent_str_next << "Area = " << globalBPT->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << globalBPT->power.readOp.dynamic * clockRate + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? globalBPT->power.readOp.longer_channel_leakage + : globalBPT->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << globalBPT->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << globalBPT->rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << endl; + cout << indent_str << "Local Predictor:" << endl; + cout << indent_str << "L1_Local Predictor:" << endl; + cout << indent_str_next << "Area = " << L1_localBPT->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << L1_localBPT->power.readOp.dynamic * clockRate + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? L1_localBPT->power.readOp.longer_channel_leakage + : L1_localBPT->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << L1_localBPT->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << L1_localBPT->rt_power.readOp.dynamic / executionTime << " W" + << endl; + cout << endl; + cout << indent_str << "L2_Local Predictor:" << endl; + cout << indent_str_next << "Area = " << L2_localBPT->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << L2_localBPT->power.readOp.dynamic * clockRate + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? L2_localBPT->power.readOp.longer_channel_leakage + : L2_localBPT->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << L2_localBPT->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << L2_localBPT->rt_power.readOp.dynamic / executionTime << " W" + << endl; + cout << endl; + + cout << indent_str << "Chooser:" << endl; + cout << indent_str_next << "Area = " << chooser->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << chooser->power.readOp.dynamic * clockRate + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? chooser->power.readOp.longer_channel_leakage + : chooser->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << chooser->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << chooser->rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << endl; + cout << indent_str << "RAS:" << endl; + cout << indent_str_next << "Area = " << RAS->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << RAS->power.readOp.dynamic * clockRate << " W" + << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? RAS->power.readOp.longer_channel_leakage + : RAS->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << RAS->power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next + << "Runtime Dynamic = " << RAS->rt_power.readOp.dynamic / executionTime + << " W" << endl; + cout << endl; + } else { + // cout << indent_str_next << "Global Predictor Peak Dynamic = " + //<< globalBPT->rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout << indent_str_next << "Global Predictor Subthreshold Leakage = " + // << globalBPT->rt_power.readOp.leakage <<" W" << endl; cout << + // indent_str_next + //<< "Global Predictor Gate Leakage = " << + // globalBPT->rt_power.readOp.gate_leakage << " W" << endl; + // cout + // << indent_str_next << "Local Predictor Peak Dynamic = " << + // L1_localBPT->rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout + // << indent_str_next << "Local Predictor Subthreshold Leakage = " << + // L1_localBPT->rt_power.readOp.leakage << " W" << endl; cout << + // indent_str_next << "Local Predictor Gate Leakage = " << + // L1_localBPT->rt_power.readOp.gate_leakage << " W" << endl; + // cout + // << indent_str_next << "Chooser Peak Dynamic = " << + // chooser->rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout + // << indent_str_next << "Chooser Subthreshold Leakage = " << + // chooser->rt_power.readOp.leakage << " W" << endl; cout << + // indent_str_next + //<< "Chooser Gate Leakage = " << chooser->rt_power.readOp.gate_leakage << + //" W" << endl; cout << indent_str_next << "RAS Peak Dynamic = + //" + //<< RAS->rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout << indent_str_next << "RAS Subthreshold Leakage = " << + // RAS->rt_power.readOp.leakage << " W" << endl; cout << + // indent_str_next + // << "RAS Gate Leakage = " << RAS->rt_power.readOp.gate_leakage << " W" + //<< endl; + } +} -void BranchPredictor::computeEnergy(bool is_tdp) -{ - if (!exist) return; - double r_access; - double w_access; - if (is_tdp) - { - r_access = coredynp.predictionW*coredynp.BR_duty_cycle; - w_access = 0*coredynp.BR_duty_cycle; - globalBPT->stats_t.readAc.access = r_access; - globalBPT->stats_t.writeAc.access = w_access; - globalBPT->tdp_stats = globalBPT->stats_t; - - L1_localBPT->stats_t.readAc.access = r_access; - L1_localBPT->stats_t.writeAc.access = w_access; - L1_localBPT->tdp_stats = L1_localBPT->stats_t; - - L2_localBPT->stats_t.readAc.access = r_access; - L2_localBPT->stats_t.writeAc.access = w_access; - L2_localBPT->tdp_stats = L2_localBPT->stats_t; - - chooser->stats_t.readAc.access = r_access; - chooser->stats_t.writeAc.access = w_access; - chooser->tdp_stats = chooser->stats_t; - - RAS->stats_t.readAc.access = r_access; - RAS->stats_t.writeAc.access = w_access; - RAS->tdp_stats = RAS->stats_t; +void InstFetchU::computeEnergy(bool is_tdp) { + executionTime = + XML->sys.total_cycles / (XML->sys.target_core_clockrate * 1e6); // Syed + // cout <<"IFU: execution time: + // "<sys.total_cycles/(XML->sys.target_core_clockrate*1e6)<sys.total_cycles<stats_t.readAc.access = + icache.caches->l_ip.num_rw_ports * coredynp.IFU_duty_cycle; + icache.caches->stats_t.readAc.miss = 0; + icache.caches->stats_t.readAc.hit = icache.caches->stats_t.readAc.access - + icache.caches->stats_t.readAc.miss; + icache.caches->tdp_stats = icache.caches->stats_t; + + icache.missb->stats_t.readAc.access = icache.missb->stats_t.readAc.hit = + icache.missb->l_ip.num_search_ports; + icache.missb->stats_t.writeAc.access = icache.missb->stats_t.writeAc.hit = + icache.missb->l_ip.num_search_ports; + icache.missb->tdp_stats = icache.missb->stats_t; + + icache.ifb->stats_t.readAc.access = icache.ifb->stats_t.readAc.hit = + icache.ifb->l_ip.num_search_ports; + icache.ifb->stats_t.writeAc.access = icache.ifb->stats_t.writeAc.hit = + icache.ifb->l_ip.num_search_ports; + icache.ifb->tdp_stats = icache.ifb->stats_t; + + icache.prefetchb->stats_t.readAc.access = + icache.prefetchb->stats_t.readAc.hit = + icache.prefetchb->l_ip.num_search_ports; + icache.prefetchb->stats_t.writeAc.access = icache.ifb->stats_t.writeAc.hit = + icache.ifb->l_ip.num_search_ports; + icache.prefetchb->tdp_stats = icache.prefetchb->stats_t; + + IB->stats_t.readAc.access = IB->stats_t.writeAc.access = + XML->sys.core[ithCore].peak_issue_width; + IB->tdp_stats = IB->stats_t; + + if (coredynp.predictionW > 0) { + BTB->stats_t.readAc.access = + coredynp.predictionW; // XML->sys.core[ithCore].BTB.read_accesses; + BTB->stats_t.writeAc.access = + 0; // XML->sys.core[ithCore].BTB.write_accesses; } - else - { - //The resolution of BPT accesses is coarse, but this is - //because most simulators cannot track finer grained details - r_access = XML->sys.core[ithCore].branch_instructions; - w_access = XML->sys.core[ithCore].branch_mispredictions + 0.1*XML->sys.core[ithCore].branch_instructions;//10% of BR will flip internal bits//0 - globalBPT->stats_t.readAc.access = r_access; - globalBPT->stats_t.writeAc.access = w_access; - globalBPT->rtp_stats = globalBPT->stats_t; - - L1_localBPT->stats_t.readAc.access = r_access; - L1_localBPT->stats_t.writeAc.access = w_access; - L1_localBPT->rtp_stats = L1_localBPT->stats_t; - - L2_localBPT->stats_t.readAc.access = r_access; - L2_localBPT->stats_t.writeAc.access = w_access; - L2_localBPT->rtp_stats = L2_localBPT->stats_t; - - chooser->stats_t.readAc.access = r_access; - chooser->stats_t.writeAc.access = w_access; - chooser->rtp_stats = chooser->stats_t; - - RAS->stats_t.readAc.access = XML->sys.core[ithCore].function_calls; - RAS->stats_t.writeAc.access = XML->sys.core[ithCore].function_calls; - RAS->rtp_stats = RAS->stats_t; - } - - globalBPT->power_t.reset(); - L1_localBPT->power_t.reset(); - L2_localBPT->power_t.reset(); - chooser->power_t.reset(); - RAS->power_t.reset(); - - globalBPT->power_t.readOp.dynamic += globalBPT->local_result.power.readOp.dynamic*globalBPT->stats_t.readAc.access + - globalBPT->stats_t.writeAc.access*globalBPT->local_result.power.writeOp.dynamic; - L1_localBPT->power_t.readOp.dynamic += L1_localBPT->local_result.power.readOp.dynamic*L1_localBPT->stats_t.readAc.access + - L1_localBPT->stats_t.writeAc.access*L1_localBPT->local_result.power.writeOp.dynamic; - - L2_localBPT->power_t.readOp.dynamic += L2_localBPT->local_result.power.readOp.dynamic*L2_localBPT->stats_t.readAc.access + - L2_localBPT->stats_t.writeAc.access*L2_localBPT->local_result.power.writeOp.dynamic; - - chooser->power_t.readOp.dynamic += chooser->local_result.power.readOp.dynamic*chooser->stats_t.readAc.access + - chooser->stats_t.writeAc.access*chooser->local_result.power.writeOp.dynamic; - RAS->power_t.readOp.dynamic += RAS->local_result.power.readOp.dynamic*RAS->stats_t.readAc.access + - RAS->stats_t.writeAc.access*RAS->local_result.power.writeOp.dynamic; - - if (is_tdp) - { - globalBPT->power = globalBPT->power_t + globalBPT->local_result.power*pppm_lkg; - L1_localBPT->power = L1_localBPT->power_t + L1_localBPT->local_result.power*pppm_lkg; - L2_localBPT->power = L2_localBPT->power_t + L2_localBPT->local_result.power*pppm_lkg; - chooser->power = chooser->power_t + chooser->local_result.power*pppm_lkg; - RAS->power = RAS->power_t + RAS->local_result.power*coredynp.pppm_lkg_multhread; - power = power + globalBPT->power + L1_localBPT->power + chooser->power + RAS->power; + ID_inst->stats_t.readAc.access = coredynp.decodeW; + ID_operand->stats_t.readAc.access = coredynp.decodeW; + ID_misc->stats_t.readAc.access = coredynp.decodeW; + ID_inst->tdp_stats = ID_inst->stats_t; + ID_operand->tdp_stats = ID_operand->stats_t; + ID_misc->tdp_stats = ID_misc->stats_t; + + } /* if (is_tdp) */ + else { + rt_power.reset(); + icache.rt_power.reset(); // Jingwen + // init stats for Runtime Dynamic (RTP) + // cout<< "****>>>>Icache stats:"<sys.core[ithCore].icache.read_accesses << + // " Read misses: "<sys.core[ithCore].icache.read_misses<stats_t.readAc.access = + XML->sys.core[ithCore].icache.read_accesses; + icache.caches->stats_t.readAc.miss = + XML->sys.core[ithCore].icache.read_misses; + // cout<sys.core[ithCore].icache.read_accesses; cout<stats_t.readAc.hit<stats_t.readAc.access = icache.caches->stats_t.readAc.miss; + icache.missb->stats_t.writeAc.access = icache.caches->stats_t.readAc.miss; + icache.missb->rtp_stats = icache.missb->stats_t; + + icache.ifb->stats_t.readAc.access = icache.caches->stats_t.readAc.miss; + icache.ifb->stats_t.writeAc.access = icache.caches->stats_t.readAc.miss; + icache.ifb->rtp_stats = icache.ifb->stats_t; + + icache.prefetchb->stats_t.readAc.access = + icache.caches->stats_t.readAc.miss; + icache.prefetchb->stats_t.writeAc.access = + icache.caches->stats_t.readAc.miss; + icache.prefetchb->rtp_stats = icache.prefetchb->stats_t; + + IB->stats_t.readAc.access = IB->stats_t.writeAc.access = + XML->sys.core[ithCore].total_instructions; + IB->rtp_stats = IB->stats_t; + // cout<<"IB: total instructions: "<stats_t.readAc.access < 0) { + BTB->stats_t.readAc.access = + XML->sys.core[ithCore] + .BTB + .read_accesses; // XML->sys.core[ithCore].branch_instructions; + BTB->stats_t.writeAc.access = + XML->sys.core[ithCore] + .BTB + .write_accesses; // XML->sys.core[ithCore].branch_mispredictions; + BTB->rtp_stats = BTB->stats_t; } - else - { - globalBPT->rt_power = globalBPT->power_t + globalBPT->local_result.power*pppm_lkg; - L1_localBPT->rt_power = L1_localBPT->power_t + L1_localBPT->local_result.power*pppm_lkg; - L2_localBPT->rt_power = L2_localBPT->power_t + L2_localBPT->local_result.power*pppm_lkg; - chooser->rt_power = chooser->power_t + chooser->local_result.power*pppm_lkg; - RAS->rt_power = RAS->power_t + RAS->local_result.power*coredynp.pppm_lkg_multhread; - rt_power = rt_power + globalBPT->rt_power + L1_localBPT->rt_power + chooser->rt_power + RAS->rt_power; + // cout<<"ID: total instructions: "<< + // XML->sys.core[ithCore].total_instructions<stats_t.readAc.access = XML->sys.core[ithCore].total_instructions; + ID_operand->stats_t.readAc.access = + XML->sys.core[ithCore].total_instructions; + ID_misc->stats_t.readAc.access = XML->sys.core[ithCore].total_instructions; + ID_inst->rtp_stats = ID_inst->stats_t; + ID_operand->rtp_stats = ID_operand->stats_t; + ID_misc->rtp_stats = ID_misc->stats_t; + } + + icache.power_t.reset(); + IB->power_t.reset(); + // ID_inst->power_t.reset(); + // ID_operand->power_t.reset(); + // ID_misc->power_t.reset(); + if (coredynp.predictionW > 0) { + BTB->power_t.reset(); + } + + icache.power_t.readOp.dynamic += + (icache.caches->stats_t.readAc.hit * + icache.caches->local_result.power.readOp.dynamic + + // icache.caches->stats_t.readAc.miss*icache.caches->local_result.tag_array2->power.readOp.dynamic+ + icache.caches->stats_t.readAc.miss * + icache.caches->local_result.power.readOp + .dynamic + // assume tag data accessed in parallel + icache.caches->stats_t.readAc.miss * + icache.caches->local_result.power.writeOp + .dynamic); // read miss in Icache cause a write to Icache + icache.power_t.readOp.dynamic += + icache.missb->stats_t.readAc.access * + icache.missb->local_result.power.searchOp.dynamic + + icache.missb->stats_t.writeAc.access * + icache.missb->local_result.power.writeOp + .dynamic; // each access to missb involves a CAM and a write + icache.power_t.readOp.dynamic += + icache.ifb->stats_t.readAc.access * + icache.ifb->local_result.power.searchOp.dynamic + + icache.ifb->stats_t.writeAc.access * + icache.ifb->local_result.power.writeOp.dynamic; + icache.power_t.readOp.dynamic += + icache.prefetchb->stats_t.readAc.access * + icache.prefetchb->local_result.power.searchOp.dynamic + + icache.prefetchb->stats_t.writeAc.access * + icache.prefetchb->local_result.power.writeOp.dynamic; + // cout<<"Icache power: "<power_t.readOp.dynamic += + IB->local_result.power.readOp.dynamic * IB->stats_t.readAc.access + + IB->stats_t.writeAc.access * IB->local_result.power.writeOp.dynamic; + // cout << "IB power: "<power_t.readOp.dynamic< 0) { + BTB->power_t.readOp.dynamic += + BTB->local_result.power.readOp.dynamic * BTB->stats_t.readAc.access + + BTB->stats_t.writeAc.access * BTB->local_result.power.writeOp.dynamic; + + BPT->computeEnergy(is_tdp); + } + + if (is_tdp) { + // icache.power = icache.power_t + + // (icache.caches->local_result.power)*pppm_lkg + + // (icache.missb->local_result.power + + // icache.ifb->local_result.power + + // icache.prefetchb->local_result.power)*pppm_Isub; + icache.power = icache.power_t + (icache.caches->local_result.power + + icache.missb->local_result.power + + icache.ifb->local_result.power + + icache.prefetchb->local_result.power) * + pppm_lkg; + + IB->power = IB->power_t + IB->local_result.power * pppm_lkg; + power = power + icache.power + IB->power; + if (coredynp.predictionW > 0) { + BTB->power = BTB->power_t + BTB->local_result.power * pppm_lkg; + power = power + BTB->power + BPT->power; } -} -void BranchPredictor::displayEnergy(uint32_t indent,int plevel,bool is_tdp) -{ - if (!exist) return; - string indent_str(indent, ' '); - string indent_str_next(indent+2, ' '); - bool long_channel = XML->sys.longer_channel_device; - if (is_tdp) - { - cout << indent_str<< "Global Predictor:" << endl; - cout << indent_str_next << "Area = " << globalBPT->area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << globalBPT->power.readOp.dynamic*clockRate << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? globalBPT->power.readOp.longer_channel_leakage:globalBPT->power.readOp.leakage) <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << globalBPT->power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << globalBPT->rt_power.readOp.dynamic/executionTime << " W" << endl; - cout <power_t.readOp.dynamic = ID_inst->power.readOp.dynamic; + ID_operand->power_t.readOp.dynamic = ID_operand->power.readOp.dynamic; + ID_misc->power_t.readOp.dynamic = ID_misc->power.readOp.dynamic; + ID_inst->power.readOp.dynamic *= ID_inst->tdp_stats.readAc.access; + ID_operand->power.readOp.dynamic *= ID_operand->tdp_stats.readAc.access; + ID_misc->power.readOp.dynamic *= ID_misc->tdp_stats.readAc.access; + + power = power + (ID_inst->power + ID_operand->power + ID_misc->power); + } /* if (is_tdp) */ + else { + // icache.rt_power = icache.power_t + + // (icache.caches->local_result.power)*pppm_lkg + + // (icache.missb->local_result.power + + // icache.ifb->local_result.power + + // icache.prefetchb->local_result.power)*pppm_Isub; + + icache.rt_power = icache.power_t + (icache.caches->local_result.power + + icache.missb->local_result.power + + icache.ifb->local_result.power + + icache.prefetchb->local_result.power) * + pppm_lkg; + + // IB->rt_power = IB->power_t + IB->local_result.power*pppm_lkg; + IB->rt_power.readOp.dynamic = + IB->local_result.power.readOp.dynamic * IB->rtp_stats.readAc.access; + IB->rt_power.readOp.dynamic += + IB->local_result.power.writeOp.dynamic * IB->rtp_stats.writeAc.access; + rt_power = rt_power + icache.rt_power + IB->rt_power; + if (coredynp.predictionW > 0) { + BTB->rt_power = BTB->power_t + BTB->local_result.power * pppm_lkg; + rt_power = rt_power + BTB->rt_power + BPT->rt_power; + } + + ID_inst->rt_power.readOp.dynamic = + ID_inst->power_t.readOp.dynamic * ID_inst->rtp_stats.readAc.access; + ID_operand->rt_power.readOp.dynamic = ID_operand->power_t.readOp.dynamic * + ID_operand->rtp_stats.readAc.access; + ID_misc->rt_power.readOp.dynamic = + ID_misc->power_t.readOp.dynamic * ID_misc->rtp_stats.readAc.access; + + rt_power = rt_power + + (ID_inst->rt_power + ID_operand->rt_power + ID_misc->rt_power); + // cout<<"ID inst: "<rt_power.readOp.dynamic << " ID operand: + // "<rt_power.readOp.dynamic<<" ID misc: + // "<rt_power.readOp.dynamic<sys.total_cycles/(XML->sys.target_core_clockrate*1e6);//Syed - //cout <<"IFU: execution time: "<sys.total_cycles/(XML->sys.target_core_clockrate*1e6)<sys.total_cycles<stats_t.readAc.access = icache.caches->l_ip.num_rw_ports*coredynp.IFU_duty_cycle; - icache.caches->stats_t.readAc.miss = 0; - icache.caches->stats_t.readAc.hit = icache.caches->stats_t.readAc.access - icache.caches->stats_t.readAc.miss; - icache.caches->tdp_stats = icache.caches->stats_t; - - icache.missb->stats_t.readAc.access = icache.missb->stats_t.readAc.hit= icache.missb->l_ip.num_search_ports; - icache.missb->stats_t.writeAc.access = icache.missb->stats_t.writeAc.hit= icache.missb->l_ip.num_search_ports; - icache.missb->tdp_stats = icache.missb->stats_t; - - icache.ifb->stats_t.readAc.access = icache.ifb->stats_t.readAc.hit= icache.ifb->l_ip.num_search_ports; - icache.ifb->stats_t.writeAc.access = icache.ifb->stats_t.writeAc.hit= icache.ifb->l_ip.num_search_ports; - icache.ifb->tdp_stats = icache.ifb->stats_t; - - icache.prefetchb->stats_t.readAc.access = icache.prefetchb->stats_t.readAc.hit= icache.prefetchb->l_ip.num_search_ports; - icache.prefetchb->stats_t.writeAc.access = icache.ifb->stats_t.writeAc.hit= icache.ifb->l_ip.num_search_ports; - icache.prefetchb->tdp_stats = icache.prefetchb->stats_t; - - IB->stats_t.readAc.access = IB->stats_t.writeAc.access = XML->sys.core[ithCore].peak_issue_width; - IB->tdp_stats = IB->stats_t; - - if (coredynp.predictionW>0) - { - BTB->stats_t.readAc.access = coredynp.predictionW;//XML->sys.core[ithCore].BTB.read_accesses; - BTB->stats_t.writeAc.access = 0;//XML->sys.core[ithCore].BTB.write_accesses; - } - - ID_inst->stats_t.readAc.access = coredynp.decodeW; - ID_operand->stats_t.readAc.access = coredynp.decodeW; - ID_misc->stats_t.readAc.access = coredynp.decodeW; - ID_inst->tdp_stats = ID_inst->stats_t; - ID_operand->tdp_stats = ID_operand->stats_t; - ID_misc->tdp_stats = ID_misc->stats_t; - - - - } /* if (is_tdp) */ - else - { - rt_power.reset(); - icache.rt_power.reset(); //Jingwen - //init stats for Runtime Dynamic (RTP) - //cout<< "****>>>>Icache stats:"<sys.core[ithCore].icache.read_accesses << " Read misses: "<sys.core[ithCore].icache.read_misses<stats_t.readAc.access = XML->sys.core[ithCore].icache.read_accesses; - icache.caches->stats_t.readAc.miss = XML->sys.core[ithCore].icache.read_misses; - //cout<stats_t.readAc.access <0) - { - BTB->stats_t.readAc.access = XML->sys.core[ithCore].BTB.read_accesses;//XML->sys.core[ithCore].branch_instructions; - BTB->stats_t.writeAc.access = XML->sys.core[ithCore].BTB.write_accesses;//XML->sys.core[ithCore].branch_mispredictions; - BTB->rtp_stats = BTB->stats_t; - } - //cout<<"ID: total instructions: "<< XML->sys.core[ithCore].total_instructions<stats_t.readAc.access = XML->sys.core[ithCore].total_instructions; - ID_operand->stats_t.readAc.access = XML->sys.core[ithCore].total_instructions; - ID_misc->stats_t.readAc.access = XML->sys.core[ithCore].total_instructions; - ID_inst->rtp_stats = ID_inst->stats_t; - ID_operand->rtp_stats = ID_operand->stats_t; - ID_misc->rtp_stats = ID_misc->stats_t; +void InstFetchU::displayEnergy(uint32_t indent, int plevel, bool is_tdp) { + if (!exist) return; + string indent_str(indent, ' '); + string indent_str_next(indent + 2, ' '); + bool long_channel = XML->sys.longer_channel_device; + + if (is_tdp) { + cout << indent_str << "Instruction Cache:" << endl; + cout << indent_str_next << "Area = " << icache.area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << icache.power.readOp.dynamic * clockRate << " W" + << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? icache.power.readOp.longer_channel_leakage + : icache.power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << icache.power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << icache.rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << endl; + if (coredynp.predictionW > 0) { + cout << indent_str << "Branch Target Buffer:" << endl; + cout << indent_str_next << "Area = " << BTB->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << BTB->power.readOp.dynamic * clockRate << " W" + << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? BTB->power.readOp.longer_channel_leakage + : BTB->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << BTB->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << BTB->rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << endl; + if (BPT->exist) { + cout << indent_str << "Branch Predictor:" << endl; + cout << indent_str_next << "Area = " << BPT->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << BPT->power.readOp.dynamic * clockRate + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? BPT->power.readOp.longer_channel_leakage + : BPT->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << BPT->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << BPT->rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << endl; + if (plevel > 3) { + BPT->displayEnergy(indent + 4, plevel, is_tdp); + } + } + } + cout << indent_str << "Instruction Buffer:" << endl; + cout << indent_str_next << "Area = " << IB->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << IB->power.readOp.dynamic * clockRate << " W" + << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? IB->power.readOp.longer_channel_leakage + : IB->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << IB->power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next + << "Runtime Dynamic = " << IB->rt_power.readOp.dynamic / executionTime + << " W" << endl; + cout << endl; + cout << indent_str << "Instruction Decoder:" << endl; + cout << indent_str_next << "Area = " + << (ID_inst->area.get_area() + ID_operand->area.get_area() + + ID_misc->area.get_area()) * + coredynp.decodeW * 1e-6 + << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " + << (ID_inst->power.readOp.dynamic + ID_operand->power.readOp.dynamic + + ID_misc->power.readOp.dynamic) * + clockRate + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? (ID_inst->power.readOp.longer_channel_leakage + + ID_operand->power.readOp.longer_channel_leakage + + ID_misc->power.readOp.longer_channel_leakage) + : (ID_inst->power.readOp.leakage + + ID_operand->power.readOp.leakage + + ID_misc->power.readOp.leakage)) + << " W" << endl; + cout << indent_str_next << "Gate Leakage = " + << (ID_inst->power.readOp.gate_leakage + + ID_operand->power.readOp.gate_leakage + + ID_misc->power.readOp.gate_leakage) + << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " + << (ID_inst->rt_power.readOp.dynamic + + ID_operand->rt_power.readOp.dynamic + + ID_misc->rt_power.readOp.dynamic) / + executionTime + << " W" << endl; + cout << endl; + } else { + // cout << indent_str_next << "Instruction Cache Peak Dynamic = + //" + //<< icache.rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout << indent_str_next << "Instruction Cache Subthreshold Leakage = " + // << icache.rt_power.readOp.leakage <<" W" << endl; cout << + // indent_str_next << "Instruction Cache Gate Leakage = " << + // icache.rt_power.readOp.gate_leakage << " W" << endl; cout << + // indent_str_next << "Instruction Buffer Peak Dynamic = " << + // IB->rt_power.readOp.dynamic*clockRate << " W" << endl; cout << + // indent_str_next << "Instruction Buffer Subthreshold Leakage = " << + // IB->rt_power.readOp.leakage << " W" << endl; cout << + // indent_str_next + // << "Instruction Buffer Gate Leakage = " << + // IB->rt_power.readOp.gate_leakage + //<< " W" << endl; cout << indent_str_next << "Branch Target Buffer + // Peak Dynamic = " << BTB->rt_power.readOp.dynamic*clockRate << " W" << + // endl; cout << indent_str_next << "Branch Target Buffer + // Subthreshold Leakage = " << BTB->rt_power.readOp.leakage << " W" << + // endl; cout + // << indent_str_next << "Branch Target Buffer Gate Leakage = " << + // BTB->rt_power.readOp.gate_leakage << " W" << endl; cout << + // indent_str_next << "Branch Predictor Peak Dynamic = " << + // BPT->rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout + // << indent_str_next << "Branch Predictor Subthreshold Leakage = " << + // BPT->rt_power.readOp.leakage << " W" << endl; cout << + // indent_str_next + // << "Branch Predictor Gate Leakage = " << + // BPT->rt_power.readOp.gate_leakage + //<< " W" << endl; + } +} +void RENAMINGU::computeEnergy(bool is_tdp) { + if (!exist) return; + double pppm_t[4] = {1, 1, 1, 1}; + if (is_tdp) { // init stats for Peak + if (coredynp.core_ty == OOO) { + if (coredynp.scheu_ty == PhysicalRegFile) { + if (coredynp.rm_ty == RAMbased) { + iFRAT->stats_t.readAc.access = iFRAT->l_ip.num_rd_ports; + iFRAT->stats_t.writeAc.access = iFRAT->l_ip.num_wr_ports; + iFRAT->tdp_stats = iFRAT->stats_t; + + fFRAT->stats_t.readAc.access = fFRAT->l_ip.num_rd_ports; + fFRAT->stats_t.writeAc.access = fFRAT->l_ip.num_wr_ports; + fFRAT->tdp_stats = fFRAT->stats_t; + + } else if ((coredynp.rm_ty == CAMbased)) { + iFRAT->stats_t.readAc.access = iFRAT->l_ip.num_search_ports; + iFRAT->stats_t.writeAc.access = iFRAT->l_ip.num_wr_ports; + iFRAT->tdp_stats = iFRAT->stats_t; + + fFRAT->stats_t.readAc.access = fFRAT->l_ip.num_search_ports; + fFRAT->stats_t.writeAc.access = fFRAT->l_ip.num_wr_ports; + fFRAT->tdp_stats = fFRAT->stats_t; + } + + iRRAT->stats_t.readAc.access = iRRAT->l_ip.num_rd_ports; + iRRAT->stats_t.writeAc.access = iRRAT->l_ip.num_wr_ports; + iRRAT->tdp_stats = iRRAT->stats_t; + + fRRAT->stats_t.readAc.access = fRRAT->l_ip.num_rd_ports; + fRRAT->stats_t.writeAc.access = fRRAT->l_ip.num_wr_ports; + fRRAT->tdp_stats = fRRAT->stats_t; + + ifreeL->stats_t.readAc.access = + coredynp.decodeW; // ifreeL->l_ip.num_rd_ports;; + ifreeL->stats_t.writeAc.access = + coredynp.decodeW; // ifreeL->l_ip.num_wr_ports; + ifreeL->tdp_stats = ifreeL->stats_t; + + ffreeL->stats_t.readAc.access = + coredynp.decodeW; // ffreeL->l_ip.num_rd_ports; + ffreeL->stats_t.writeAc.access = + coredynp.decodeW; // ffreeL->l_ip.num_wr_ports; + ffreeL->tdp_stats = ffreeL->stats_t; + } else if (coredynp.scheu_ty == ReservationStation) { + if (coredynp.rm_ty == RAMbased) { + iFRAT->stats_t.readAc.access = iFRAT->l_ip.num_rd_ports; + iFRAT->stats_t.writeAc.access = iFRAT->l_ip.num_wr_ports; + iFRAT->stats_t.searchAc.access = iFRAT->l_ip.num_search_ports; + iFRAT->tdp_stats = iFRAT->stats_t; + + fFRAT->stats_t.readAc.access = fFRAT->l_ip.num_rd_ports; + fFRAT->stats_t.writeAc.access = fFRAT->l_ip.num_wr_ports; + fFRAT->stats_t.searchAc.access = fFRAT->l_ip.num_search_ports; + fFRAT->tdp_stats = fFRAT->stats_t; + + } else if ((coredynp.rm_ty == CAMbased)) { + iFRAT->stats_t.readAc.access = iFRAT->l_ip.num_search_ports; + iFRAT->stats_t.writeAc.access = iFRAT->l_ip.num_wr_ports; + iFRAT->tdp_stats = iFRAT->stats_t; + + fFRAT->stats_t.readAc.access = fFRAT->l_ip.num_search_ports; + fFRAT->stats_t.writeAc.access = fFRAT->l_ip.num_wr_ports; + fFRAT->tdp_stats = fFRAT->stats_t; + } + // Unified free list for both int and fp + ifreeL->stats_t.readAc.access = + coredynp.decodeW; // ifreeL->l_ip.num_rd_ports; + ifreeL->stats_t.writeAc.access = + coredynp.decodeW; // ifreeL->l_ip.num_wr_ports; + ifreeL->tdp_stats = ifreeL->stats_t; + } + idcl->stats_t.readAc.access = coredynp.decodeW; + fdcl->stats_t.readAc.access = coredynp.decodeW; + idcl->tdp_stats = idcl->stats_t; + fdcl->tdp_stats = fdcl->stats_t; + } else { + if (coredynp.issueW > 1) { + idcl->stats_t.readAc.access = coredynp.decodeW; + fdcl->stats_t.readAc.access = coredynp.decodeW; + idcl->tdp_stats = idcl->stats_t; + fdcl->tdp_stats = fdcl->stats_t; + } } - icache.power_t.reset(); - IB->power_t.reset(); -// ID_inst->power_t.reset(); -// ID_operand->power_t.reset(); -// ID_misc->power_t.reset(); - if (coredynp.predictionW>0) - { - BTB->power_t.reset(); + } else { // init stats for Runtime Dynamic (RTP) + if (coredynp.core_ty == OOO) { + if (coredynp.scheu_ty == PhysicalRegFile) { + if (coredynp.rm_ty == RAMbased) { + iFRAT->stats_t.readAc.access = XML->sys.core[ithCore].rename_reads; + iFRAT->stats_t.writeAc.access = XML->sys.core[ithCore].rename_writes; + iFRAT->rtp_stats = iFRAT->stats_t; + + fFRAT->stats_t.readAc.access = XML->sys.core[ithCore].fp_rename_reads; + fFRAT->stats_t.writeAc.access = + XML->sys.core[ithCore].fp_rename_writes; + fFRAT->rtp_stats = fFRAT->stats_t; + } else if ((coredynp.rm_ty == CAMbased)) { + iFRAT->stats_t.readAc.access = XML->sys.core[ithCore].rename_reads; + iFRAT->stats_t.writeAc.access = XML->sys.core[ithCore].rename_writes; + iFRAT->rtp_stats = iFRAT->stats_t; + + fFRAT->stats_t.readAc.access = XML->sys.core[ithCore].fp_rename_reads; + fFRAT->stats_t.writeAc.access = + XML->sys.core[ithCore].fp_rename_writes; + fFRAT->rtp_stats = fFRAT->stats_t; + } + + iRRAT->stats_t.readAc.access = + XML->sys.core[ithCore] + .rename_writes; // Hack, should be (context switch + branch + // mispredictions)*16 + iRRAT->stats_t.writeAc.access = XML->sys.core[ithCore].rename_writes; + iRRAT->rtp_stats = iRRAT->stats_t; + + fRRAT->stats_t.readAc.access = + XML->sys.core[ithCore] + .fp_rename_writes; // Hack, should be (context switch + branch + // mispredictions)*16 + fRRAT->stats_t.writeAc.access = XML->sys.core[ithCore].fp_rename_writes; + fRRAT->rtp_stats = fRRAT->stats_t; + + ifreeL->stats_t.readAc.access = XML->sys.core[ithCore].rename_reads; + ifreeL->stats_t.writeAc.access = + 2 * XML->sys.core[ithCore].rename_writes; + ifreeL->rtp_stats = ifreeL->stats_t; + + ffreeL->stats_t.readAc.access = XML->sys.core[ithCore].fp_rename_reads; + ffreeL->stats_t.writeAc.access = + 2 * XML->sys.core[ithCore].fp_rename_writes; + ffreeL->rtp_stats = ffreeL->stats_t; + } else if (coredynp.scheu_ty == ReservationStation) { + if (coredynp.rm_ty == RAMbased) { + iFRAT->stats_t.readAc.access = XML->sys.core[ithCore].rename_reads; + iFRAT->stats_t.writeAc.access = XML->sys.core[ithCore].rename_writes; + iFRAT->stats_t.searchAc.access = + XML->sys.core[ithCore] + .committed_int_instructions; // hack: not all committed + // instructions use regs. + iFRAT->rtp_stats = iFRAT->stats_t; + + fFRAT->stats_t.readAc.access = XML->sys.core[ithCore].fp_rename_reads; + fFRAT->stats_t.writeAc.access = + XML->sys.core[ithCore].fp_rename_writes; + fFRAT->stats_t.searchAc.access = + XML->sys.core[ithCore].committed_fp_instructions; + fFRAT->rtp_stats = fFRAT->stats_t; + } else if ((coredynp.rm_ty == CAMbased)) { + iFRAT->stats_t.readAc.access = XML->sys.core[ithCore].rename_reads; + iFRAT->stats_t.writeAc.access = XML->sys.core[ithCore].rename_writes; + iFRAT->rtp_stats = iFRAT->stats_t; + + fFRAT->stats_t.readAc.access = XML->sys.core[ithCore].fp_rename_reads; + fFRAT->stats_t.writeAc.access = + XML->sys.core[ithCore].fp_rename_writes; + fFRAT->rtp_stats = fFRAT->stats_t; + } + // Unified free list for both int and fp since the ROB act as physcial + // registers + ifreeL->stats_t.readAc.access = XML->sys.core[ithCore].rename_reads + + XML->sys.core[ithCore].fp_rename_reads; + ifreeL->stats_t.writeAc.access = + 2 * (XML->sys.core[ithCore].rename_writes + + XML->sys.core[ithCore] + .fp_rename_writes); // HACK: 2-> since some of renaming in + // the same group are terminated early + ifreeL->rtp_stats = ifreeL->stats_t; + } + idcl->stats_t.readAc.access = 3 * coredynp.decodeW * coredynp.decodeW * + XML->sys.core[ithCore].rename_reads; + fdcl->stats_t.readAc.access = 3 * coredynp.fp_issueW * + coredynp.fp_issueW * + XML->sys.core[ithCore].fp_rename_writes; + idcl->rtp_stats = idcl->stats_t; + fdcl->rtp_stats = fdcl->stats_t; + } else { + if (coredynp.issueW > 1) { + idcl->stats_t.readAc.access = + 2 * XML->sys.core[ithCore].int_instructions; + fdcl->stats_t.readAc.access = XML->sys.core[ithCore].fp_instructions; + idcl->rtp_stats = idcl->stats_t; + fdcl->rtp_stats = fdcl->stats_t; + } + } + } + /* Compute engine */ + if (coredynp.core_ty == OOO) { + if (coredynp.scheu_ty == PhysicalRegFile) { + if (coredynp.rm_ty == RAMbased) { + iFRAT->power_t.reset(); + fFRAT->power_t.reset(); + + iFRAT->power_t.readOp.dynamic += + (iFRAT->stats_t.readAc.access * + (iFRAT->local_result.power.readOp.dynamic + + idcl->power.readOp.dynamic) + + iFRAT->stats_t.writeAc.access * + iFRAT->local_result.power.writeOp.dynamic); + fFRAT->power_t.readOp.dynamic += + (fFRAT->stats_t.readAc.access * + (fFRAT->local_result.power.readOp.dynamic + + fdcl->power.readOp.dynamic) + + fFRAT->stats_t.writeAc.access * + fFRAT->local_result.power.writeOp.dynamic); + } else if ((coredynp.rm_ty == CAMbased)) { + iFRAT->power_t.reset(); + fFRAT->power_t.reset(); + iFRAT->power_t.readOp.dynamic += + (iFRAT->stats_t.readAc.access * + (iFRAT->local_result.power.searchOp.dynamic + + idcl->power.readOp.dynamic) + + iFRAT->stats_t.writeAc.access * + iFRAT->local_result.power.writeOp.dynamic); + fFRAT->power_t.readOp.dynamic += + (fFRAT->stats_t.readAc.access * + (fFRAT->local_result.power.searchOp.dynamic + + fdcl->power.readOp.dynamic) + + fFRAT->stats_t.writeAc.access * + fFRAT->local_result.power.writeOp.dynamic); + } + + iRRAT->power_t.reset(); + fRRAT->power_t.reset(); + ifreeL->power_t.reset(); + ffreeL->power_t.reset(); + + iRRAT->power_t.readOp.dynamic += + (iRRAT->stats_t.readAc.access * + iRRAT->local_result.power.readOp.dynamic + + iRRAT->stats_t.writeAc.access * + iRRAT->local_result.power.writeOp.dynamic); + fRRAT->power_t.readOp.dynamic += + (fRRAT->stats_t.readAc.access * + fRRAT->local_result.power.readOp.dynamic + + fRRAT->stats_t.writeAc.access * + fRRAT->local_result.power.writeOp.dynamic); + ifreeL->power_t.readOp.dynamic += + (ifreeL->stats_t.readAc.access * + ifreeL->local_result.power.readOp.dynamic + + ifreeL->stats_t.writeAc.access * + ifreeL->local_result.power.writeOp.dynamic); + ffreeL->power_t.readOp.dynamic += + (ffreeL->stats_t.readAc.access * + ffreeL->local_result.power.readOp.dynamic + + ffreeL->stats_t.writeAc.access * + ffreeL->local_result.power.writeOp.dynamic); + + } else if (coredynp.scheu_ty == ReservationStation) { + if (coredynp.rm_ty == RAMbased) { + iFRAT->power_t.reset(); + fFRAT->power_t.reset(); + + iFRAT->power_t.readOp.dynamic += + (iFRAT->stats_t.readAc.access * + (iFRAT->local_result.power.readOp.dynamic + + idcl->power.readOp.dynamic) + + iFRAT->stats_t.writeAc.access * + iFRAT->local_result.power.writeOp.dynamic + + iFRAT->stats_t.searchAc.access * + iFRAT->local_result.power.searchOp.dynamic); + fFRAT->power_t.readOp.dynamic += + (fFRAT->stats_t.readAc.access * + (fFRAT->local_result.power.readOp.dynamic + + fdcl->power.readOp.dynamic) + + fFRAT->stats_t.writeAc.access * + fFRAT->local_result.power.writeOp.dynamic + + fFRAT->stats_t.searchAc.access * + fFRAT->local_result.power.searchOp.dynamic); + } else if ((coredynp.rm_ty == CAMbased)) { + iFRAT->power_t.reset(); + fFRAT->power_t.reset(); + iFRAT->power_t.readOp.dynamic += + (iFRAT->stats_t.readAc.access * + (iFRAT->local_result.power.searchOp.dynamic + + idcl->power.readOp.dynamic) + + iFRAT->stats_t.writeAc.access * + iFRAT->local_result.power.writeOp.dynamic); + fFRAT->power_t.readOp.dynamic += + (fFRAT->stats_t.readAc.access * + (fFRAT->local_result.power.searchOp.dynamic + + fdcl->power.readOp.dynamic) + + fFRAT->stats_t.writeAc.access * + fFRAT->local_result.power.writeOp.dynamic); + } + ifreeL->power_t.reset(); + ifreeL->power_t.readOp.dynamic += + (ifreeL->stats_t.readAc.access * + ifreeL->local_result.power.readOp.dynamic + + ifreeL->stats_t.writeAc.access * + ifreeL->local_result.power.writeOp.dynamic); } - icache.power_t.readOp.dynamic += (icache.caches->stats_t.readAc.hit*icache.caches->local_result.power.readOp.dynamic+ - //icache.caches->stats_t.readAc.miss*icache.caches->local_result.tag_array2->power.readOp.dynamic+ - icache.caches->stats_t.readAc.miss*icache.caches->local_result.power.readOp.dynamic+ //assume tag data accessed in parallel - icache.caches->stats_t.readAc.miss*icache.caches->local_result.power.writeOp.dynamic); //read miss in Icache cause a write to Icache - icache.power_t.readOp.dynamic += icache.missb->stats_t.readAc.access*icache.missb->local_result.power.searchOp.dynamic + - icache.missb->stats_t.writeAc.access*icache.missb->local_result.power.writeOp.dynamic;//each access to missb involves a CAM and a write - icache.power_t.readOp.dynamic += icache.ifb->stats_t.readAc.access*icache.ifb->local_result.power.searchOp.dynamic + - icache.ifb->stats_t.writeAc.access*icache.ifb->local_result.power.writeOp.dynamic; - icache.power_t.readOp.dynamic += icache.prefetchb->stats_t.readAc.access*icache.prefetchb->local_result.power.searchOp.dynamic + - icache.prefetchb->stats_t.writeAc.access*icache.prefetchb->local_result.power.writeOp.dynamic; - //cout<<"Icache power: "<power_t.readOp.dynamic += IB->local_result.power.readOp.dynamic*IB->stats_t.readAc.access + - IB->stats_t.writeAc.access*IB->local_result.power.writeOp.dynamic; - //cout << "IB power: "<power_t.readOp.dynamic<0) - { - BTB->power_t.readOp.dynamic += BTB->local_result.power.readOp.dynamic*BTB->stats_t.readAc.access + - BTB->stats_t.writeAc.access*BTB->local_result.power.writeOp.dynamic; - - BPT->computeEnergy(is_tdp); - } - - if (is_tdp) - { -// icache.power = icache.power_t + -// (icache.caches->local_result.power)*pppm_lkg + -// (icache.missb->local_result.power + -// icache.ifb->local_result.power + -// icache.prefetchb->local_result.power)*pppm_Isub; - icache.power = icache.power_t + - (icache.caches->local_result.power + - icache.missb->local_result.power + - icache.ifb->local_result.power + - icache.prefetchb->local_result.power)*pppm_lkg; - - IB->power = IB->power_t + IB->local_result.power*pppm_lkg; - power = power + icache.power + IB->power; - if (coredynp.predictionW>0) - { - BTB->power = BTB->power_t + BTB->local_result.power*pppm_lkg; - power = power + BTB->power + BPT->power; - } - - ID_inst->power_t.readOp.dynamic = ID_inst->power.readOp.dynamic; - ID_operand->power_t.readOp.dynamic = ID_operand->power.readOp.dynamic; - ID_misc->power_t.readOp.dynamic = ID_misc->power.readOp.dynamic; - - ID_inst->power.readOp.dynamic *= ID_inst->tdp_stats.readAc.access; - ID_operand->power.readOp.dynamic *= ID_operand->tdp_stats.readAc.access; - ID_misc->power.readOp.dynamic *= ID_misc->tdp_stats.readAc.access; - - power = power + (ID_inst->power + - ID_operand->power + - ID_misc->power); - } /* if (is_tdp) */ - else - { -// icache.rt_power = icache.power_t + -// (icache.caches->local_result.power)*pppm_lkg + -// (icache.missb->local_result.power + -// icache.ifb->local_result.power + -// icache.prefetchb->local_result.power)*pppm_Isub; - - icache.rt_power = icache.power_t + - (icache.caches->local_result.power + - icache.missb->local_result.power + - icache.ifb->local_result.power + - icache.prefetchb->local_result.power)*pppm_lkg; - - //IB->rt_power = IB->power_t + IB->local_result.power*pppm_lkg; - IB->rt_power.readOp.dynamic = IB->local_result.power.readOp.dynamic * IB->rtp_stats.readAc.access; - IB->rt_power.readOp.dynamic += IB->local_result.power.writeOp.dynamic * IB->rtp_stats.writeAc.access; - rt_power = rt_power + icache.rt_power + IB->rt_power; - if (coredynp.predictionW>0) - { - BTB->rt_power = BTB->power_t + BTB->local_result.power*pppm_lkg; - rt_power = rt_power + BTB->rt_power + BPT->rt_power; - } - - ID_inst->rt_power.readOp.dynamic = ID_inst->power_t.readOp.dynamic*ID_inst->rtp_stats.readAc.access; - ID_operand->rt_power.readOp.dynamic = ID_operand->power_t.readOp.dynamic * ID_operand->rtp_stats.readAc.access; - ID_misc->rt_power.readOp.dynamic = ID_misc->power_t.readOp.dynamic * ID_misc->rtp_stats.readAc.access; - - rt_power = rt_power + (ID_inst->rt_power + - ID_operand->rt_power + - ID_misc->rt_power); - //cout<<"ID inst: "<rt_power.readOp.dynamic << " ID operand: "<rt_power.readOp.dynamic<<" ID misc: "<rt_power.readOp.dynamic< 1) { + idcl->power_t.reset(); + fdcl->power_t.reset(); + set_pppm(pppm_t, idcl->stats_t.readAc.access, coredynp.num_hthreads, + coredynp.num_hthreads, idcl->stats_t.readAc.access); + idcl->power_t = idcl->power * pppm_t; + set_pppm(pppm_t, fdcl->stats_t.readAc.access, coredynp.num_hthreads, + coredynp.num_hthreads, idcl->stats_t.readAc.access); + fdcl->power_t = fdcl->power * pppm_t; } -} + } -void InstFetchU::displayEnergy(uint32_t indent,int plevel,bool is_tdp) -{ - if (!exist) return; - string indent_str(indent, ' '); - string indent_str_next(indent+2, ' '); - bool long_channel = XML->sys.longer_channel_device; - - - if (is_tdp) - { - - cout << indent_str<< "Instruction Cache:" << endl; - cout << indent_str_next << "Area = " << icache.area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << icache.power.readOp.dynamic*clockRate << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? icache.power.readOp.longer_channel_leakage:icache.power.readOp.leakage) <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << icache.power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << icache.rt_power.readOp.dynamic/executionTime << " W" << endl; - cout <0) - { - cout << indent_str<< "Branch Target Buffer:" << endl; - cout << indent_str_next << "Area = " << BTB->area.get_area() *1e-6 << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << BTB->power.readOp.dynamic*clockRate << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? BTB->power.readOp.longer_channel_leakage:BTB->power.readOp.leakage) << " W" << endl; - cout << indent_str_next << "Gate Leakage = " << BTB->power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << BTB->rt_power.readOp.dynamic/executionTime << " W" << endl; - cout <exist) - { - cout << indent_str<< "Branch Predictor:" << endl; - cout << indent_str_next << "Area = " << BPT->area.get_area() *1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << BPT->power.readOp.dynamic*clockRate << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? BPT->power.readOp.longer_channel_leakage:BPT->power.readOp.leakage) << " W" << endl; - cout << indent_str_next << "Gate Leakage = " << BPT->power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << BPT->rt_power.readOp.dynamic/executionTime << " W" << endl; - cout <3) - { - BPT->displayEnergy(indent+4, plevel, is_tdp); - } - } - } - cout << indent_str<< "Instruction Buffer:" << endl; - cout << indent_str_next << "Area = " << IB->area.get_area()*1e-6 << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << IB->power.readOp.dynamic*clockRate << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? IB->power.readOp.longer_channel_leakage:IB->power.readOp.leakage) << " W" << endl; - cout << indent_str_next << "Gate Leakage = " << IB->power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << IB->rt_power.readOp.dynamic/executionTime << " W" << endl; - cout <power = + iFRAT->power_t + + (iFRAT->local_result.power) * coredynp.pppm_lkg_multhread + + idcl->power_t; + fFRAT->power = + fFRAT->power_t + + (fFRAT->local_result.power) * coredynp.pppm_lkg_multhread + + fdcl->power_t; + iRRAT->power = iRRAT->power_t + + iRRAT->local_result.power * coredynp.pppm_lkg_multhread; + fRRAT->power = fRRAT->power_t + + fRRAT->local_result.power * coredynp.pppm_lkg_multhread; + ifreeL->power = ifreeL->power_t + ifreeL->local_result.power * + coredynp.pppm_lkg_multhread; + ffreeL->power = ffreeL->power_t + ffreeL->local_result.power * + coredynp.pppm_lkg_multhread; + power = power + (iFRAT->power + fFRAT->power) + + (iRRAT->power + fRRAT->power) + (ifreeL->power + ffreeL->power); + } else if (coredynp.scheu_ty == ReservationStation) { + iFRAT->power = + iFRAT->power_t + + (iFRAT->local_result.power) * coredynp.pppm_lkg_multhread + + idcl->power_t; + fFRAT->power = + fFRAT->power_t + + (fFRAT->local_result.power) * coredynp.pppm_lkg_multhread + + fdcl->power_t; + ifreeL->power = ifreeL->power_t + ifreeL->local_result.power * + coredynp.pppm_lkg_multhread; + power = power + (iFRAT->power + fFRAT->power) + ifreeL->power; + } + } else { + power = power + idcl->power_t + fdcl->power_t; + } + } else { + if (coredynp.core_ty == OOO) { + if (coredynp.scheu_ty == PhysicalRegFile) { + iFRAT->rt_power = + iFRAT->power_t + + (iFRAT->local_result.power) * coredynp.pppm_lkg_multhread + + idcl->power_t; + fFRAT->rt_power = + fFRAT->power_t + + (fFRAT->local_result.power) * coredynp.pppm_lkg_multhread + + fdcl->power_t; + iRRAT->rt_power = iRRAT->power_t + iRRAT->local_result.power * + coredynp.pppm_lkg_multhread; + fRRAT->rt_power = fRRAT->power_t + fRRAT->local_result.power * + coredynp.pppm_lkg_multhread; + ifreeL->rt_power = ifreeL->power_t + ifreeL->local_result.power * + coredynp.pppm_lkg_multhread; + ffreeL->rt_power = ffreeL->power_t + ffreeL->local_result.power * + coredynp.pppm_lkg_multhread; + rt_power = rt_power + (iFRAT->rt_power + fFRAT->rt_power) + + (iRRAT->rt_power + fRRAT->rt_power) + + (ifreeL->rt_power + ffreeL->rt_power); + } else if (coredynp.scheu_ty == ReservationStation) { + iFRAT->rt_power = + iFRAT->power_t + + (iFRAT->local_result.power) * coredynp.pppm_lkg_multhread + + idcl->power_t; + fFRAT->rt_power = + fFRAT->power_t + + (fFRAT->local_result.power) * coredynp.pppm_lkg_multhread + + fdcl->power_t; + ifreeL->rt_power = ifreeL->power_t + ifreeL->local_result.power * + coredynp.pppm_lkg_multhread; + rt_power = + rt_power + (iFRAT->rt_power + fFRAT->rt_power) + ifreeL->rt_power; + } + } else { + rt_power = rt_power + idcl->power_t + fdcl->power_t; + } + } } -void RENAMINGU::computeEnergy(bool is_tdp) -{ - if (!exist) return; - double pppm_t[4] = {1,1,1,1}; - if (is_tdp) - {//init stats for Peak - if (coredynp.core_ty==OOO){ - if (coredynp.scheu_ty==PhysicalRegFile) - { - if (coredynp.rm_ty ==RAMbased) - { - iFRAT->stats_t.readAc.access = iFRAT->l_ip.num_rd_ports; - iFRAT->stats_t.writeAc.access = iFRAT->l_ip.num_wr_ports; - iFRAT->tdp_stats = iFRAT->stats_t; - - fFRAT->stats_t.readAc.access = fFRAT->l_ip.num_rd_ports; - fFRAT->stats_t.writeAc.access = fFRAT->l_ip.num_wr_ports; - fFRAT->tdp_stats = fFRAT->stats_t; - - } - else if ((coredynp.rm_ty ==CAMbased)) - { - iFRAT->stats_t.readAc.access = iFRAT->l_ip.num_search_ports; - iFRAT->stats_t.writeAc.access = iFRAT->l_ip.num_wr_ports; - iFRAT->tdp_stats = iFRAT->stats_t; - - fFRAT->stats_t.readAc.access = fFRAT->l_ip.num_search_ports; - fFRAT->stats_t.writeAc.access = fFRAT->l_ip.num_wr_ports; - fFRAT->tdp_stats = fFRAT->stats_t; - } - - iRRAT->stats_t.readAc.access = iRRAT->l_ip.num_rd_ports; - iRRAT->stats_t.writeAc.access = iRRAT->l_ip.num_wr_ports; - iRRAT->tdp_stats = iRRAT->stats_t; - - fRRAT->stats_t.readAc.access = fRRAT->l_ip.num_rd_ports; - fRRAT->stats_t.writeAc.access = fRRAT->l_ip.num_wr_ports; - fRRAT->tdp_stats = fRRAT->stats_t; - - ifreeL->stats_t.readAc.access = coredynp.decodeW;//ifreeL->l_ip.num_rd_ports;; - ifreeL->stats_t.writeAc.access = coredynp.decodeW;//ifreeL->l_ip.num_wr_ports; - ifreeL->tdp_stats = ifreeL->stats_t; - - ffreeL->stats_t.readAc.access = coredynp.decodeW;//ffreeL->l_ip.num_rd_ports; - ffreeL->stats_t.writeAc.access = coredynp.decodeW;//ffreeL->l_ip.num_wr_ports; - ffreeL->tdp_stats = ffreeL->stats_t; - } - else if (coredynp.scheu_ty==ReservationStation){ - if (coredynp.rm_ty ==RAMbased) - { - iFRAT->stats_t.readAc.access = iFRAT->l_ip.num_rd_ports; - iFRAT->stats_t.writeAc.access = iFRAT->l_ip.num_wr_ports; - iFRAT->stats_t.searchAc.access = iFRAT->l_ip.num_search_ports; - iFRAT->tdp_stats = iFRAT->stats_t; - - fFRAT->stats_t.readAc.access = fFRAT->l_ip.num_rd_ports; - fFRAT->stats_t.writeAc.access = fFRAT->l_ip.num_wr_ports; - fFRAT->stats_t.searchAc.access = fFRAT->l_ip.num_search_ports; - fFRAT->tdp_stats = fFRAT->stats_t; - - } - else if ((coredynp.rm_ty ==CAMbased)) - { - iFRAT->stats_t.readAc.access = iFRAT->l_ip.num_search_ports; - iFRAT->stats_t.writeAc.access = iFRAT->l_ip.num_wr_ports; - iFRAT->tdp_stats = iFRAT->stats_t; - - fFRAT->stats_t.readAc.access = fFRAT->l_ip.num_search_ports; - fFRAT->stats_t.writeAc.access = fFRAT->l_ip.num_wr_ports; - fFRAT->tdp_stats = fFRAT->stats_t; - } - //Unified free list for both int and fp - ifreeL->stats_t.readAc.access = coredynp.decodeW;//ifreeL->l_ip.num_rd_ports; - ifreeL->stats_t.writeAc.access = coredynp.decodeW;//ifreeL->l_ip.num_wr_ports; - ifreeL->tdp_stats = ifreeL->stats_t; - } - idcl->stats_t.readAc.access = coredynp.decodeW; - fdcl->stats_t.readAc.access = coredynp.decodeW; - idcl->tdp_stats = idcl->stats_t; - fdcl->tdp_stats = fdcl->stats_t; - } - else - { - if (coredynp.issueW>1) - { - idcl->stats_t.readAc.access = coredynp.decodeW; - fdcl->stats_t.readAc.access = coredynp.decodeW; - idcl->tdp_stats = idcl->stats_t; - fdcl->tdp_stats = fdcl->stats_t; - } - } - - } - else - {//init stats for Runtime Dynamic (RTP) - if (coredynp.core_ty==OOO){ - if (coredynp.scheu_ty==PhysicalRegFile) - { - if (coredynp.rm_ty ==RAMbased) - { - iFRAT->stats_t.readAc.access = XML->sys.core[ithCore].rename_reads; - iFRAT->stats_t.writeAc.access = XML->sys.core[ithCore].rename_writes; - iFRAT->rtp_stats = iFRAT->stats_t; - - fFRAT->stats_t.readAc.access = XML->sys.core[ithCore].fp_rename_reads; - fFRAT->stats_t.writeAc.access = XML->sys.core[ithCore].fp_rename_writes; - fFRAT->rtp_stats = fFRAT->stats_t; - } - else if ((coredynp.rm_ty ==CAMbased)) - { - iFRAT->stats_t.readAc.access = XML->sys.core[ithCore].rename_reads; - iFRAT->stats_t.writeAc.access = XML->sys.core[ithCore].rename_writes; - iFRAT->rtp_stats = iFRAT->stats_t; - - fFRAT->stats_t.readAc.access = XML->sys.core[ithCore].fp_rename_reads; - fFRAT->stats_t.writeAc.access = XML->sys.core[ithCore].fp_rename_writes; - fFRAT->rtp_stats = fFRAT->stats_t; - } - - iRRAT->stats_t.readAc.access = XML->sys.core[ithCore].rename_writes;//Hack, should be (context switch + branch mispredictions)*16 - iRRAT->stats_t.writeAc.access = XML->sys.core[ithCore].rename_writes; - iRRAT->rtp_stats = iRRAT->stats_t; - - fRRAT->stats_t.readAc.access = XML->sys.core[ithCore].fp_rename_writes;//Hack, should be (context switch + branch mispredictions)*16 - fRRAT->stats_t.writeAc.access = XML->sys.core[ithCore].fp_rename_writes; - fRRAT->rtp_stats = fRRAT->stats_t; - - ifreeL->stats_t.readAc.access = XML->sys.core[ithCore].rename_reads; - ifreeL->stats_t.writeAc.access = 2*XML->sys.core[ithCore].rename_writes; - ifreeL->rtp_stats = ifreeL->stats_t; - - ffreeL->stats_t.readAc.access = XML->sys.core[ithCore].fp_rename_reads; - ffreeL->stats_t.writeAc.access = 2*XML->sys.core[ithCore].fp_rename_writes; - ffreeL->rtp_stats = ffreeL->stats_t; - } - else if (coredynp.scheu_ty==ReservationStation){ - if (coredynp.rm_ty ==RAMbased) - { - iFRAT->stats_t.readAc.access = XML->sys.core[ithCore].rename_reads; - iFRAT->stats_t.writeAc.access = XML->sys.core[ithCore].rename_writes; - iFRAT->stats_t.searchAc.access = XML->sys.core[ithCore].committed_int_instructions;//hack: not all committed instructions use regs. - iFRAT->rtp_stats = iFRAT->stats_t; - - fFRAT->stats_t.readAc.access = XML->sys.core[ithCore].fp_rename_reads; - fFRAT->stats_t.writeAc.access = XML->sys.core[ithCore].fp_rename_writes; - fFRAT->stats_t.searchAc.access = XML->sys.core[ithCore].committed_fp_instructions; - fFRAT->rtp_stats = fFRAT->stats_t; - } - else if ((coredynp.rm_ty ==CAMbased)) - { - iFRAT->stats_t.readAc.access = XML->sys.core[ithCore].rename_reads; - iFRAT->stats_t.writeAc.access = XML->sys.core[ithCore].rename_writes; - iFRAT->rtp_stats = iFRAT->stats_t; - - fFRAT->stats_t.readAc.access = XML->sys.core[ithCore].fp_rename_reads; - fFRAT->stats_t.writeAc.access = XML->sys.core[ithCore].fp_rename_writes; - fFRAT->rtp_stats = fFRAT->stats_t; - } - //Unified free list for both int and fp since the ROB act as physcial registers - ifreeL->stats_t.readAc.access = XML->sys.core[ithCore].rename_reads + - XML->sys.core[ithCore].fp_rename_reads; - ifreeL->stats_t.writeAc.access = 2*(XML->sys.core[ithCore].rename_writes + - XML->sys.core[ithCore].fp_rename_writes);//HACK: 2-> since some of renaming in the same group - //are terminated early - ifreeL->rtp_stats = ifreeL->stats_t; - } - idcl->stats_t.readAc.access = 3*coredynp.decodeW*coredynp.decodeW*XML->sys.core[ithCore].rename_reads; - fdcl->stats_t.readAc.access = 3*coredynp.fp_issueW*coredynp.fp_issueW*XML->sys.core[ithCore].fp_rename_writes; - idcl->rtp_stats = idcl->stats_t; - fdcl->rtp_stats = fdcl->stats_t; - } - else - { - if (coredynp.issueW>1) - { - idcl->stats_t.readAc.access = 2*XML->sys.core[ithCore].int_instructions; - fdcl->stats_t.readAc.access = XML->sys.core[ithCore].fp_instructions; - idcl->rtp_stats = idcl->stats_t; - fdcl->rtp_stats = fdcl->stats_t; - } - } - - } - /* Compute engine */ - if (coredynp.core_ty==OOO) - { - if (coredynp.scheu_ty==PhysicalRegFile) - { - if (coredynp.rm_ty ==RAMbased) - { - iFRAT->power_t.reset(); - fFRAT->power_t.reset(); - - iFRAT->power_t.readOp.dynamic += (iFRAT->stats_t.readAc.access - *(iFRAT->local_result.power.readOp.dynamic + idcl->power.readOp.dynamic) - +iFRAT->stats_t.writeAc.access*iFRAT->local_result.power.writeOp.dynamic); - fFRAT->power_t.readOp.dynamic += (fFRAT->stats_t.readAc.access - *(fFRAT->local_result.power.readOp.dynamic + fdcl->power.readOp.dynamic) - +fFRAT->stats_t.writeAc.access*fFRAT->local_result.power.writeOp.dynamic); - } - else if ((coredynp.rm_ty ==CAMbased)) - { - iFRAT->power_t.reset(); - fFRAT->power_t.reset(); - iFRAT->power_t.readOp.dynamic += (iFRAT->stats_t.readAc.access - *(iFRAT->local_result.power.searchOp.dynamic + idcl->power.readOp.dynamic) - +iFRAT->stats_t.writeAc.access*iFRAT->local_result.power.writeOp.dynamic); - fFRAT->power_t.readOp.dynamic += (fFRAT->stats_t.readAc.access - *(fFRAT->local_result.power.searchOp.dynamic + fdcl->power.readOp.dynamic) - +fFRAT->stats_t.writeAc.access*fFRAT->local_result.power.writeOp.dynamic); - } - - iRRAT->power_t.reset(); - fRRAT->power_t.reset(); - ifreeL->power_t.reset(); - ffreeL->power_t.reset(); - - iRRAT->power_t.readOp.dynamic += (iRRAT->stats_t.readAc.access*iRRAT->local_result.power.readOp.dynamic - +iRRAT->stats_t.writeAc.access*iRRAT->local_result.power.writeOp.dynamic); - fRRAT->power_t.readOp.dynamic += (fRRAT->stats_t.readAc.access*fRRAT->local_result.power.readOp.dynamic - +fRRAT->stats_t.writeAc.access*fRRAT->local_result.power.writeOp.dynamic); - ifreeL->power_t.readOp.dynamic += (ifreeL->stats_t.readAc.access*ifreeL->local_result.power.readOp.dynamic - +ifreeL->stats_t.writeAc.access*ifreeL->local_result.power.writeOp.dynamic); - ffreeL->power_t.readOp.dynamic += (ffreeL->stats_t.readAc.access*ffreeL->local_result.power.readOp.dynamic - +ffreeL->stats_t.writeAc.access*ffreeL->local_result.power.writeOp.dynamic); - - } - else if (coredynp.scheu_ty==ReservationStation) - { - if (coredynp.rm_ty ==RAMbased) - { - iFRAT->power_t.reset(); - fFRAT->power_t.reset(); - - iFRAT->power_t.readOp.dynamic += (iFRAT->stats_t.readAc.access - *(iFRAT->local_result.power.readOp.dynamic + idcl->power.readOp.dynamic) - +iFRAT->stats_t.writeAc.access*iFRAT->local_result.power.writeOp.dynamic - +iFRAT->stats_t.searchAc.access*iFRAT->local_result.power.searchOp.dynamic); - fFRAT->power_t.readOp.dynamic += (fFRAT->stats_t.readAc.access - *(fFRAT->local_result.power.readOp.dynamic + fdcl->power.readOp.dynamic) - +fFRAT->stats_t.writeAc.access*fFRAT->local_result.power.writeOp.dynamic - +fFRAT->stats_t.searchAc.access*fFRAT->local_result.power.searchOp.dynamic); - } - else if ((coredynp.rm_ty ==CAMbased)) - { - iFRAT->power_t.reset(); - fFRAT->power_t.reset(); - iFRAT->power_t.readOp.dynamic += (iFRAT->stats_t.readAc.access - *(iFRAT->local_result.power.searchOp.dynamic + idcl->power.readOp.dynamic) - +iFRAT->stats_t.writeAc.access*iFRAT->local_result.power.writeOp.dynamic); - fFRAT->power_t.readOp.dynamic += (fFRAT->stats_t.readAc.access - *(fFRAT->local_result.power.searchOp.dynamic + fdcl->power.readOp.dynamic) - +fFRAT->stats_t.writeAc.access*fFRAT->local_result.power.writeOp.dynamic); - } - ifreeL->power_t.reset(); - ifreeL->power_t.readOp.dynamic += (ifreeL->stats_t.readAc.access*ifreeL->local_result.power.readOp.dynamic - +ifreeL->stats_t.writeAc.access*ifreeL->local_result.power.writeOp.dynamic); - } - - } - else - { - if (coredynp.issueW>1) - { - idcl->power_t.reset(); - fdcl->power_t.reset(); - set_pppm(pppm_t, idcl->stats_t.readAc.access, coredynp.num_hthreads, coredynp.num_hthreads, idcl->stats_t.readAc.access); - idcl->power_t = idcl->power * pppm_t; - set_pppm(pppm_t, fdcl->stats_t.readAc.access, coredynp.num_hthreads, coredynp.num_hthreads, idcl->stats_t.readAc.access); - fdcl->power_t = fdcl->power * pppm_t; - } - - } - - //assign value to tpd and rtp - if (is_tdp) - { - if (coredynp.core_ty==OOO) - { - if (coredynp.scheu_ty==PhysicalRegFile) - { - iFRAT->power = iFRAT->power_t + (iFRAT->local_result.power ) * coredynp.pppm_lkg_multhread + idcl->power_t; - fFRAT->power = fFRAT->power_t + (fFRAT->local_result.power ) * coredynp.pppm_lkg_multhread + fdcl->power_t; - iRRAT->power = iRRAT->power_t + iRRAT->local_result.power * coredynp.pppm_lkg_multhread; - fRRAT->power = fRRAT->power_t + fRRAT->local_result.power * coredynp.pppm_lkg_multhread; - ifreeL->power = ifreeL->power_t + ifreeL->local_result.power * coredynp.pppm_lkg_multhread; - ffreeL->power = ffreeL->power_t + ffreeL->local_result.power * coredynp.pppm_lkg_multhread; - power = power + (iFRAT->power + fFRAT->power) - + (iRRAT->power + fRRAT->power) - + (ifreeL->power + ffreeL->power); - } - else if (coredynp.scheu_ty==ReservationStation) - { - iFRAT->power = iFRAT->power_t + (iFRAT->local_result.power ) * coredynp.pppm_lkg_multhread + idcl->power_t; - fFRAT->power = fFRAT->power_t + (fFRAT->local_result.power ) * coredynp.pppm_lkg_multhread + fdcl->power_t; - ifreeL->power = ifreeL->power_t + ifreeL->local_result.power * coredynp.pppm_lkg_multhread; - power = power + (iFRAT->power + fFRAT->power) - + ifreeL->power; - } - } - else - { - power = power + idcl->power_t + fdcl->power_t; - } - - } - else - { - if (coredynp.core_ty==OOO) - { - if (coredynp.scheu_ty==PhysicalRegFile) - { - iFRAT->rt_power = iFRAT->power_t + (iFRAT->local_result.power ) * coredynp.pppm_lkg_multhread + idcl->power_t; - fFRAT->rt_power = fFRAT->power_t + (fFRAT->local_result.power ) * coredynp.pppm_lkg_multhread + fdcl->power_t; - iRRAT->rt_power = iRRAT->power_t + iRRAT->local_result.power * coredynp.pppm_lkg_multhread; - fRRAT->rt_power = fRRAT->power_t + fRRAT->local_result.power * coredynp.pppm_lkg_multhread; - ifreeL->rt_power = ifreeL->power_t + ifreeL->local_result.power * coredynp.pppm_lkg_multhread; - ffreeL->rt_power = ffreeL->power_t + ffreeL->local_result.power * coredynp.pppm_lkg_multhread; - rt_power = rt_power + (iFRAT->rt_power + fFRAT->rt_power) - + (iRRAT->rt_power + fRRAT->rt_power) - + (ifreeL->rt_power + ffreeL->rt_power); - } - else if (coredynp.scheu_ty==ReservationStation) - { - iFRAT->rt_power = iFRAT->power_t + (iFRAT->local_result.power ) * coredynp.pppm_lkg_multhread + idcl->power_t; - fFRAT->rt_power = fFRAT->power_t + (fFRAT->local_result.power ) * coredynp.pppm_lkg_multhread + fdcl->power_t; - ifreeL->rt_power = ifreeL->power_t + ifreeL->local_result.power * coredynp.pppm_lkg_multhread; - rt_power = rt_power + (iFRAT->rt_power + fFRAT->rt_power) - + ifreeL->rt_power; - } - } - else - { - rt_power = rt_power + idcl->power_t + fdcl->power_t; - } - - } +void RENAMINGU::displayEnergy(uint32_t indent, int plevel, bool is_tdp) { + if (!exist) return; + string indent_str(indent, ' '); + string indent_str_next(indent + 2, ' '); + bool long_channel = XML->sys.longer_channel_device; + + if (is_tdp) { + if (coredynp.core_ty == OOO) { + cout << indent_str << "Int Front End RAT:" << endl; + cout << indent_str_next << "Area = " << iFRAT->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << iFRAT->power.readOp.dynamic * clockRate + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? iFRAT->power.readOp.longer_channel_leakage + : iFRAT->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << iFRAT->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << iFRAT->rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << endl; + cout << indent_str << "FP Front End RAT:" << endl; + cout << indent_str_next << "Area = " << fFRAT->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << fFRAT->power.readOp.dynamic * clockRate + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? fFRAT->power.readOp.longer_channel_leakage + : fFRAT->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << fFRAT->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << fFRAT->rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << endl; + cout << indent_str << "Free List:" << endl; + cout << indent_str_next << "Area = " << ifreeL->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << ifreeL->power.readOp.dynamic * clockRate + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? ifreeL->power.readOp.longer_channel_leakage + : ifreeL->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << ifreeL->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << ifreeL->rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << endl; + + if (coredynp.scheu_ty == PhysicalRegFile) { + cout << indent_str << "Int Retire RAT: " << endl; + cout << indent_str_next << "Area = " << iRRAT->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << iRRAT->power.readOp.dynamic * clockRate + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? iRRAT->power.readOp.longer_channel_leakage + : iRRAT->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << iRRAT->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << iRRAT->rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << endl; + cout << indent_str << "FP Retire RAT:" << endl; + cout << indent_str_next << "Area = " << fRRAT->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << fRRAT->power.readOp.dynamic * clockRate + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? fRRAT->power.readOp.longer_channel_leakage + : fRRAT->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << fRRAT->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << fRRAT->rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << endl; + cout << indent_str << "FP Free List:" << endl; + cout << indent_str_next << "Area = " << ffreeL->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << ffreeL->power.readOp.dynamic * clockRate + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? ffreeL->power.readOp.longer_channel_leakage + : ffreeL->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << ffreeL->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << ffreeL->rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << endl; + } + } else { + cout << indent_str << "Int DCL:" << endl; + cout << indent_str_next + << "Peak Dynamic = " << idcl->power.readOp.dynamic * clockRate + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? idcl->power.readOp.longer_channel_leakage + : idcl->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << idcl->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << idcl->rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << indent_str << "FP DCL:" << endl; + cout << indent_str_next + << "Peak Dynamic = " << fdcl->power.readOp.dynamic * clockRate + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? fdcl->power.readOp.longer_channel_leakage + : fdcl->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << fdcl->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << fdcl->rt_power.readOp.dynamic / executionTime << " W" << endl; + } + } else { + if (coredynp.core_ty == OOO) { + cout << indent_str_next << "Int Front End RAT Peak Dynamic = " + << iFRAT->rt_power.readOp.dynamic * clockRate << " W" << endl; + cout << indent_str_next << "Int Front End RAT Subthreshold Leakage = " + << iFRAT->rt_power.readOp.leakage << " W" << endl; + cout << indent_str_next << "Int Front End RAT Gate Leakage = " + << iFRAT->rt_power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "FP Front End RAT Peak Dynamic = " + << fFRAT->rt_power.readOp.dynamic * clockRate << " W" << endl; + cout << indent_str_next << "FP Front End RAT Subthreshold Leakage = " + << fFRAT->rt_power.readOp.leakage << " W" << endl; + cout << indent_str_next << "FP Front End RAT Gate Leakage = " + << fFRAT->rt_power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Free List Peak Dynamic = " + << ifreeL->rt_power.readOp.dynamic * clockRate << " W" << endl; + cout << indent_str_next << "Free List Subthreshold Leakage = " + << ifreeL->rt_power.readOp.leakage << " W" << endl; + cout << indent_str_next << "Free List Gate Leakage = " + << fFRAT->rt_power.readOp.gate_leakage << " W" << endl; + if (coredynp.scheu_ty == PhysicalRegFile) { + cout << indent_str_next << "Int Retire RAT Peak Dynamic = " + << iRRAT->rt_power.readOp.dynamic * clockRate << " W" << endl; + cout << indent_str_next << "Int Retire RAT Subthreshold Leakage = " + << iRRAT->rt_power.readOp.leakage << " W" << endl; + cout << indent_str_next << "Int Retire RAT Gate Leakage = " + << iRRAT->rt_power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "FP Retire RAT Peak Dynamic = " + << fRRAT->rt_power.readOp.dynamic * clockRate << " W" << endl; + cout << indent_str_next << "FP Retire RAT Subthreshold Leakage = " + << fRRAT->rt_power.readOp.leakage << " W" << endl; + cout << indent_str_next << "FP Retire RAT Gate Leakage = " + << fRRAT->rt_power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "FP Free List Peak Dynamic = " + << ffreeL->rt_power.readOp.dynamic * clockRate << " W" << endl; + cout << indent_str_next << "FP Free List Subthreshold Leakage = " + << ffreeL->rt_power.readOp.leakage << " W" << endl; + cout << indent_str_next << "FP Free List Gate Leakage = " + << fFRAT->rt_power.readOp.gate_leakage << " W" << endl; + } + } else { + cout << indent_str_next << "Int DCL Peak Dynamic = " + << idcl->rt_power.readOp.dynamic * clockRate << " W" << endl; + cout << indent_str_next << "Int DCL Subthreshold Leakage = " + << idcl->rt_power.readOp.leakage << " W" << endl; + cout << indent_str_next + << "Int DCL Gate Leakage = " << idcl->rt_power.readOp.gate_leakage + << " W" << endl; + cout << indent_str_next << "FP DCL Peak Dynamic = " + << fdcl->rt_power.readOp.dynamic * clockRate << " W" << endl; + cout << indent_str_next << "FP DCL Subthreshold Leakage = " + << fdcl->rt_power.readOp.leakage << " W" << endl; + cout << indent_str_next + << "FP DCL Gate Leakage = " << fdcl->rt_power.readOp.gate_leakage + << " W" << endl; + } + } } -void RENAMINGU::displayEnergy(uint32_t indent,int plevel,bool is_tdp) -{ - if (!exist) return; - string indent_str(indent, ' '); - string indent_str_next(indent+2, ' '); - bool long_channel = XML->sys.longer_channel_device; - - - if (is_tdp) - { - - if (coredynp.core_ty==OOO) - { - cout << indent_str<< "Int Front End RAT:" << endl; - cout << indent_str_next << "Area = " << iFRAT->area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << iFRAT->power.readOp.dynamic*clockRate << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? iFRAT->power.readOp.longer_channel_leakage:iFRAT->power.readOp.leakage) <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << iFRAT->power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << iFRAT->rt_power.readOp.dynamic/executionTime << " W" << endl; - cout <0?coredynp.MUL_duty_cycle:0 + // + coredynp.num_fpus>0?coredynp.FPU_duty_cycle:0))*1.1<1 + //? (coredynp.ALU_duty_cycle + coredynp.num_muls>0?coredynp.MUL_duty_cycle:0 + // + + // coredynp.num_fpus>0?coredynp.FPU_duty_cycle:0)*1.1:1; + ROB_duty_cycle = 1; + // init stats + if (is_tdp) { + if (coredynp.core_ty == OOO) { + int_inst_window->stats_t.readAc.access = + coredynp.issueW * + coredynp.num_pipelines; // int_inst_window->l_ip.num_search_ports; + int_inst_window->stats_t.writeAc.access = + coredynp.issueW * + coredynp.num_pipelines; // int_inst_window->l_ip.num_wr_ports; + int_inst_window->stats_t.searchAc.access = + coredynp.issueW * coredynp.num_pipelines; + int_inst_window->tdp_stats = int_inst_window->stats_t; + fp_inst_window->stats_t.readAc.access = + fp_inst_window->l_ip.num_rd_ports * coredynp.num_fp_pipelines; + fp_inst_window->stats_t.writeAc.access = + fp_inst_window->l_ip.num_wr_ports * coredynp.num_fp_pipelines; + fp_inst_window->stats_t.searchAc.access = + fp_inst_window->l_ip.num_search_ports * coredynp.num_fp_pipelines; + fp_inst_window->tdp_stats = fp_inst_window->stats_t; + + if (XML->sys.core[ithCore].ROB_size > 0) { + ROB->stats_t.readAc.access = + coredynp.commitW * coredynp.num_pipelines * ROB_duty_cycle; + ROB->stats_t.writeAc.access = + coredynp.issueW * coredynp.num_pipelines * ROB_duty_cycle; + ROB->tdp_stats = ROB->stats_t; + + /* + * When inst commits, ROB must be read. + * Because for Physcial register based cores, physical register tag in + * ROB need to be read out and write into RRAT/CAM based RAT. For RS + * based cores, register content that stored in ROB must be read out and + * stored in architectural registers. + * + * if no-register is involved, the ROB read out operation when + * instruction commits can be ignored. assuming 20% insts. belong this + * type. + * TODO: ROB duty_cycle need to be revisited + */ + } -} + } else if (coredynp.multithreaded) { + int_inst_window->stats_t.readAc.access = + coredynp.issueW * + coredynp.num_pipelines; // int_inst_window->l_ip.num_search_ports; + int_inst_window->stats_t.writeAc.access = + coredynp.issueW * + coredynp.num_pipelines; // int_inst_window->l_ip.num_wr_ports; + int_inst_window->stats_t.searchAc.access = + coredynp.issueW * coredynp.num_pipelines; + int_inst_window->tdp_stats = int_inst_window->stats_t; + } + + } else { // rtp + if (coredynp.core_ty == OOO) { + int_inst_window->stats_t.readAc.access = + XML->sys.core[ithCore].inst_window_reads; + int_inst_window->stats_t.writeAc.access = + XML->sys.core[ithCore].inst_window_writes; + int_inst_window->stats_t.searchAc.access = + XML->sys.core[ithCore].inst_window_wakeup_accesses; + int_inst_window->rtp_stats = int_inst_window->stats_t; + fp_inst_window->stats_t.readAc.access = + XML->sys.core[ithCore].fp_inst_window_reads; + fp_inst_window->stats_t.writeAc.access = + XML->sys.core[ithCore].fp_inst_window_writes; + fp_inst_window->stats_t.searchAc.access = + XML->sys.core[ithCore].fp_inst_window_wakeup_accesses; + fp_inst_window->rtp_stats = fp_inst_window->stats_t; + + if (XML->sys.core[ithCore].ROB_size > 0) { + ROB->stats_t.readAc.access = XML->sys.core[ithCore].ROB_reads; + ROB->stats_t.writeAc.access = XML->sys.core[ithCore].ROB_writes; + /* ROB need to be updated in RS based OOO when new values are produced, + * this update may happen before the commit stage when ROB entry is + * released + * 1. ROB write at instruction inserted in + * 2. ROB write as results produced (for RS based OOO only) + * 3. ROB read as instruction committed. For RS based OOO, data values + * are read out and sent to ARF For Physical reg based OOO, no data + * stored in ROB, but register tags need to be read out and used to set + * the RRAT and to recycle the register tag to free list buffer + */ + ROB->rtp_stats = ROB->stats_t; + } + } else if (coredynp.multithreaded) { + int_inst_window->stats_t.readAc.access = + XML->sys.core[ithCore].int_instructions + + XML->sys.core[ithCore].fp_instructions; + int_inst_window->stats_t.writeAc.access = + XML->sys.core[ithCore].int_instructions + + XML->sys.core[ithCore].fp_instructions; + int_inst_window->stats_t.searchAc.access = + 2 * (XML->sys.core[ithCore].int_instructions + + XML->sys.core[ithCore].fp_instructions); + int_inst_window->rtp_stats = int_inst_window->stats_t; + } + } -void SchedulerU::computeEnergy(bool is_tdp) -{ - if (!exist) return; - double ROB_duty_cycle; -// ROB_duty_cycle = ((coredynp.ALU_duty_cycle + coredynp.num_muls>0?coredynp.MUL_duty_cycle:0 -// + coredynp.num_fpus>0?coredynp.FPU_duty_cycle:0))*1.1<1 ? (coredynp.ALU_duty_cycle + coredynp.num_muls>0?coredynp.MUL_duty_cycle:0 -// + coredynp.num_fpus>0?coredynp.FPU_duty_cycle:0)*1.1:1; - ROB_duty_cycle = 1; - //init stats - if (is_tdp) - { - if (coredynp.core_ty==OOO) - { - int_inst_window->stats_t.readAc.access = coredynp.issueW*coredynp.num_pipelines;//int_inst_window->l_ip.num_search_ports; - int_inst_window->stats_t.writeAc.access = coredynp.issueW*coredynp.num_pipelines;//int_inst_window->l_ip.num_wr_ports; - int_inst_window->stats_t.searchAc.access = coredynp.issueW*coredynp.num_pipelines; - int_inst_window->tdp_stats = int_inst_window->stats_t; - fp_inst_window->stats_t.readAc.access = fp_inst_window->l_ip.num_rd_ports*coredynp.num_fp_pipelines; - fp_inst_window->stats_t.writeAc.access = fp_inst_window->l_ip.num_wr_ports*coredynp.num_fp_pipelines; - fp_inst_window->stats_t.searchAc.access = fp_inst_window->l_ip.num_search_ports*coredynp.num_fp_pipelines; - fp_inst_window->tdp_stats = fp_inst_window->stats_t; - - if (XML->sys.core[ithCore].ROB_size >0) - { - ROB->stats_t.readAc.access = coredynp.commitW*coredynp.num_pipelines*ROB_duty_cycle; - ROB->stats_t.writeAc.access = coredynp.issueW*coredynp.num_pipelines*ROB_duty_cycle; - ROB->tdp_stats = ROB->stats_t; - - /* - * When inst commits, ROB must be read. - * Because for Physcial register based cores, physical register tag in ROB - * need to be read out and write into RRAT/CAM based RAT. - * For RS based cores, register content that stored in ROB must be - * read out and stored in architectural registers. - * - * if no-register is involved, the ROB read out operation when instruction commits can be ignored. - * assuming 20% insts. belong this type. - * TODO: ROB duty_cycle need to be revisited - */ - } - - } - else if (coredynp.multithreaded) - { - int_inst_window->stats_t.readAc.access = coredynp.issueW*coredynp.num_pipelines;//int_inst_window->l_ip.num_search_ports; - int_inst_window->stats_t.writeAc.access = coredynp.issueW*coredynp.num_pipelines;//int_inst_window->l_ip.num_wr_ports; - int_inst_window->stats_t.searchAc.access = coredynp.issueW*coredynp.num_pipelines; - int_inst_window->tdp_stats = int_inst_window->stats_t; - } - - } - else - {//rtp - if (coredynp.core_ty==OOO) - { - int_inst_window->stats_t.readAc.access = XML->sys.core[ithCore].inst_window_reads; - int_inst_window->stats_t.writeAc.access = XML->sys.core[ithCore].inst_window_writes; - int_inst_window->stats_t.searchAc.access = XML->sys.core[ithCore].inst_window_wakeup_accesses; - int_inst_window->rtp_stats = int_inst_window->stats_t; - fp_inst_window->stats_t.readAc.access = XML->sys.core[ithCore].fp_inst_window_reads; - fp_inst_window->stats_t.writeAc.access = XML->sys.core[ithCore].fp_inst_window_writes; - fp_inst_window->stats_t.searchAc.access = XML->sys.core[ithCore].fp_inst_window_wakeup_accesses; - fp_inst_window->rtp_stats = fp_inst_window->stats_t; - - if (XML->sys.core[ithCore].ROB_size >0) - { - - ROB->stats_t.readAc.access = XML->sys.core[ithCore].ROB_reads; - ROB->stats_t.writeAc.access = XML->sys.core[ithCore].ROB_writes; - /* ROB need to be updated in RS based OOO when new values are produced, - * this update may happen before the commit stage when ROB entry is released - * 1. ROB write at instruction inserted in - * 2. ROB write as results produced (for RS based OOO only) - * 3. ROB read as instruction committed. For RS based OOO, data values are read out and sent to ARF - * For Physical reg based OOO, no data stored in ROB, but register tags need to be - * read out and used to set the RRAT and to recycle the register tag to free list buffer - */ - ROB->rtp_stats = ROB->stats_t; - } - - } - else if (coredynp.multithreaded) - { - int_inst_window->stats_t.readAc.access = XML->sys.core[ithCore].int_instructions + XML->sys.core[ithCore].fp_instructions; - int_inst_window->stats_t.writeAc.access = XML->sys.core[ithCore].int_instructions + XML->sys.core[ithCore].fp_instructions; - int_inst_window->stats_t.searchAc.access = 2*(XML->sys.core[ithCore].int_instructions + XML->sys.core[ithCore].fp_instructions); - int_inst_window->rtp_stats = int_inst_window->stats_t; - } + // computation engine + if (coredynp.core_ty == OOO) { + int_inst_window->power_t.reset(); + fp_inst_window->power_t.reset(); + + /* each instruction needs to write to scheduler, read out when all resources + * and source operands are ready two search ops with one for each source + * operand + * + */ + int_inst_window->power_t.readOp.dynamic += + int_inst_window->local_result.power.readOp.dynamic * + int_inst_window->stats_t.readAc.access + + int_inst_window->local_result.power.searchOp.dynamic * + int_inst_window->stats_t.searchAc.access + + int_inst_window->local_result.power.writeOp.dynamic * + int_inst_window->stats_t.writeAc.access + + int_inst_window->stats_t.readAc.access * + instruction_selection->power.readOp.dynamic; + + fp_inst_window->power_t.readOp.dynamic += + fp_inst_window->local_result.power.readOp.dynamic * + fp_inst_window->stats_t.readAc.access + + fp_inst_window->local_result.power.searchOp.dynamic * + fp_inst_window->stats_t.searchAc.access + + fp_inst_window->local_result.power.writeOp.dynamic * + fp_inst_window->stats_t.writeAc.access + + fp_inst_window->stats_t.writeAc.access * + instruction_selection->power.readOp.dynamic; + + if (XML->sys.core[ithCore].ROB_size > 0) { + ROB->power_t.reset(); + ROB->power_t.readOp.dynamic += + ROB->local_result.power.readOp.dynamic * ROB->stats_t.readAc.access + + ROB->stats_t.writeAc.access * ROB->local_result.power.writeOp.dynamic; } - //computation engine - if (coredynp.core_ty==OOO) - { - int_inst_window->power_t.reset(); - fp_inst_window->power_t.reset(); - - /* each instruction needs to write to scheduler, read out when all resources and source operands are ready - * two search ops with one for each source operand - * - */ - int_inst_window->power_t.readOp.dynamic += int_inst_window->local_result.power.readOp.dynamic * int_inst_window->stats_t.readAc.access - + int_inst_window->local_result.power.searchOp.dynamic * int_inst_window->stats_t.searchAc.access - + int_inst_window->local_result.power.writeOp.dynamic * int_inst_window->stats_t.writeAc.access - + int_inst_window->stats_t.readAc.access * instruction_selection->power.readOp.dynamic; - - fp_inst_window->power_t.readOp.dynamic += fp_inst_window->local_result.power.readOp.dynamic * fp_inst_window->stats_t.readAc.access - + fp_inst_window->local_result.power.searchOp.dynamic * fp_inst_window->stats_t.searchAc.access - + fp_inst_window->local_result.power.writeOp.dynamic * fp_inst_window->stats_t.writeAc.access - + fp_inst_window->stats_t.writeAc.access * instruction_selection->power.readOp.dynamic; - - if (XML->sys.core[ithCore].ROB_size >0) - { - ROB->power_t.reset(); - ROB->power_t.readOp.dynamic += ROB->local_result.power.readOp.dynamic*ROB->stats_t.readAc.access + - ROB->stats_t.writeAc.access*ROB->local_result.power.writeOp.dynamic; - } - - - - - } - else if (coredynp.multithreaded) - { - int_inst_window->power_t.reset(); - int_inst_window->power_t.readOp.dynamic += int_inst_window->local_result.power.readOp.dynamic * int_inst_window->stats_t.readAc.access - + int_inst_window->local_result.power.searchOp.dynamic * int_inst_window->stats_t.searchAc.access - + int_inst_window->local_result.power.writeOp.dynamic * int_inst_window->stats_t.writeAc.access - + int_inst_window->stats_t.writeAc.access * instruction_selection->power.readOp.dynamic; - } - - //assign values - if (is_tdp) - { - if (coredynp.core_ty==OOO) - { - int_inst_window->power = int_inst_window->power_t + (int_inst_window->local_result.power +instruction_selection->power) *pppm_lkg; - fp_inst_window->power = fp_inst_window->power_t + (fp_inst_window->local_result.power +instruction_selection->power) *pppm_lkg; - power = power + int_inst_window->power + fp_inst_window->power; - if (XML->sys.core[ithCore].ROB_size >0) - { - ROB->power = ROB->power_t + ROB->local_result.power*pppm_lkg; - power = power + ROB->power; - } - - } - else if (coredynp.multithreaded) - { - // set_pppm(pppm_t, XML->sys.core[ithCore].issue_width,1, 1, 1); - int_inst_window->power = int_inst_window->power_t + (int_inst_window->local_result.power +instruction_selection->power) *pppm_lkg; - power = power + int_inst_window->power; - } - - } - else - {//rtp - if (coredynp.core_ty==OOO) - { - int_inst_window->rt_power = int_inst_window->power_t + (int_inst_window->local_result.power +instruction_selection->power) *pppm_lkg; - fp_inst_window->rt_power = fp_inst_window->power_t + (fp_inst_window->local_result.power +instruction_selection->power) *pppm_lkg; - rt_power = rt_power + int_inst_window->rt_power + fp_inst_window->rt_power; - if (XML->sys.core[ithCore].ROB_size >0) - { - ROB->rt_power = ROB->power_t + ROB->local_result.power*pppm_lkg; - rt_power = rt_power + ROB->rt_power; - } - - } - else if (coredynp.multithreaded) - { - // set_pppm(pppm_t, XML->sys.core[ithCore].issue_width,1, 1, 1); - int_inst_window->rt_power = int_inst_window->power_t + (int_inst_window->local_result.power +instruction_selection->power) *pppm_lkg; - rt_power = rt_power + int_inst_window->rt_power; - } + } else if (coredynp.multithreaded) { + int_inst_window->power_t.reset(); + int_inst_window->power_t.readOp.dynamic += + int_inst_window->local_result.power.readOp.dynamic * + int_inst_window->stats_t.readAc.access + + int_inst_window->local_result.power.searchOp.dynamic * + int_inst_window->stats_t.searchAc.access + + int_inst_window->local_result.power.writeOp.dynamic * + int_inst_window->stats_t.writeAc.access + + int_inst_window->stats_t.writeAc.access * + instruction_selection->power.readOp.dynamic; + } + + // assign values + if (is_tdp) { + if (coredynp.core_ty == OOO) { + int_inst_window->power = + int_inst_window->power_t + + (int_inst_window->local_result.power + instruction_selection->power) * + pppm_lkg; + fp_inst_window->power = + fp_inst_window->power_t + + (fp_inst_window->local_result.power + instruction_selection->power) * + pppm_lkg; + power = power + int_inst_window->power + fp_inst_window->power; + if (XML->sys.core[ithCore].ROB_size > 0) { + ROB->power = ROB->power_t + ROB->local_result.power * pppm_lkg; + power = power + ROB->power; + } + + } else if (coredynp.multithreaded) { + // set_pppm(pppm_t, + // XML->sys.core[ithCore].issue_width,1, 1, 1); + int_inst_window->power = + int_inst_window->power_t + + (int_inst_window->local_result.power + instruction_selection->power) * + pppm_lkg; + power = power + int_inst_window->power; } -// set_pppm(pppm_t, XML->sys.core[ithCore].issue_width,1, 1, 1); -// cout<<"Scheduler power="<power.readOp.dynamic<<"leakage"<power.readOp.leakage<sys.longer_channel_device; - - - if (is_tdp) - { - if (coredynp.core_ty==OOO) - { - cout << indent_str << "Instruction Window:" << endl; - cout << indent_str_next << "Area = " << int_inst_window->area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << int_inst_window->power.readOp.dynamic*clockRate << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? int_inst_window->power.readOp.longer_channel_leakage:int_inst_window->power.readOp.leakage) <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << int_inst_window->power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << int_inst_window->rt_power.readOp.dynamic/executionTime << " W" << endl; - cout <sys.core[ithCore].ROB_size >0) - { - cout << indent_str<<"ROB:" << endl; - cout << indent_str_next << "Area = " << ROB->area.get_area() *1e-6 << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << ROB->power.readOp.dynamic*clockRate << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? ROB->power.readOp.longer_channel_leakage:ROB->power.readOp.leakage) << " W" << endl; - cout << indent_str_next << "Gate Leakage = " << ROB->power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << ROB->rt_power.readOp.dynamic/executionTime << " W" << endl; - cout <sys.core[ithCore].ROB_size >0) - { - cout << indent_str_next << "ROB Peak Dynamic = " << ROB->rt_power.readOp.dynamic*clockRate << " W" << endl; - cout << indent_str_next << "ROB Subthreshold Leakage = " << ROB->rt_power.readOp.leakage << " W" << endl; - cout << indent_str_next << "ROB Gate Leakage = " << ROB->rt_power.readOp.gate_leakage << " W" << endl; - } - } - else if (coredynp.multithreaded) - { - cout << indent_str_next << "Instruction Window Peak Dynamic = " << int_inst_window->rt_power.readOp.dynamic*clockRate << " W" << endl; - cout << indent_str_next << "Instruction Window Subthreshold Leakage = " << int_inst_window->rt_power.readOp.leakage <<" W" << endl; - cout << indent_str_next << "Instruction Window Gate Leakage = " << int_inst_window->rt_power.readOp.gate_leakage << " W" << endl; - } - } + } else { // rtp + if (coredynp.core_ty == OOO) { + int_inst_window->rt_power = + int_inst_window->power_t + + (int_inst_window->local_result.power + instruction_selection->power) * + pppm_lkg; + fp_inst_window->rt_power = + fp_inst_window->power_t + + (fp_inst_window->local_result.power + instruction_selection->power) * + pppm_lkg; + rt_power = + rt_power + int_inst_window->rt_power + fp_inst_window->rt_power; + if (XML->sys.core[ithCore].ROB_size > 0) { + ROB->rt_power = ROB->power_t + ROB->local_result.power * pppm_lkg; + rt_power = rt_power + ROB->rt_power; + } + } else if (coredynp.multithreaded) { + // set_pppm(pppm_t, + // XML->sys.core[ithCore].issue_width,1, 1, 1); + int_inst_window->rt_power = + int_inst_window->power_t + + (int_inst_window->local_result.power + instruction_selection->power) * + pppm_lkg; + rt_power = rt_power + int_inst_window->rt_power; + } + } + // set_pppm(pppm_t, XML->sys.core[ithCore].issue_width,1, 1, 1); + // cout<<"Scheduler + // power="<power.readOp.dynamic<<"leakage"<power.readOp.leakage<sys.total_cycles/(XML->sys.target_core_clockrate*1e6);//Syed - - //RF crossbar power (Syed) - xbar_shared->compute_power(); - - if (is_tdp) - { - - //init stats for Peak - // added by Jingwen - sharedmemory.caches->stats_t.readAc.access = 0.67*sharedmemory.caches->l_ip.num_rw_ports*coredynp.LSU_duty_cycle; - sharedmemory.caches->stats_t.readAc.miss = 0; - sharedmemory.caches->stats_t.readAc.hit = sharedmemory.caches->stats_t.readAc.access - sharedmemory.caches->stats_t.readAc.miss; - sharedmemory.caches->stats_t.writeAc.access = 0.33*sharedmemory.caches->l_ip.num_rw_ports*coredynp.LSU_duty_cycle; - sharedmemory.caches->stats_t.writeAc.miss = 0; - sharedmemory.caches->stats_t.writeAc.hit = sharedmemory.caches->stats_t.writeAc.access - sharedmemory.caches->stats_t.writeAc.miss; - sharedmemory.caches->tdp_stats = sharedmemory.caches->stats_t; - - sharedmemory.missb->stats_t.readAc.access = sharedmemory.missb->l_ip.num_search_ports; - sharedmemory.missb->stats_t.writeAc.access = sharedmemory.missb->l_ip.num_search_ports; - sharedmemory.missb->tdp_stats = sharedmemory.missb->stats_t; - - sharedmemory.ifb->stats_t.readAc.access = sharedmemory.ifb->l_ip.num_search_ports; - sharedmemory.ifb->stats_t.writeAc.access = sharedmemory.ifb->l_ip.num_search_ports; - sharedmemory.ifb->tdp_stats = sharedmemory.ifb->stats_t; - - sharedmemory.prefetchb->stats_t.readAc.access = sharedmemory.prefetchb->l_ip.num_search_ports; - sharedmemory.prefetchb->stats_t.writeAc.access = sharedmemory.ifb->l_ip.num_search_ports; - sharedmemory.prefetchb->tdp_stats = sharedmemory.prefetchb->stats_t; - if (cache_p==Write_back) - { - sharedmemory.wbb->stats_t.readAc.access = sharedmemory.wbb->l_ip.num_search_ports; - sharedmemory.wbb->stats_t.writeAc.access = sharedmemory.wbb->l_ip.num_search_ports; - sharedmemory.wbb->tdp_stats = sharedmemory.wbb->stats_t; - } - - - - //init stats for Peak - dcache.caches->stats_t.readAc.access = 0.67*dcache.caches->l_ip.num_rw_ports*coredynp.LSU_duty_cycle; - dcache.caches->stats_t.readAc.miss = 0; - dcache.caches->stats_t.readAc.hit = dcache.caches->stats_t.readAc.access - dcache.caches->stats_t.readAc.miss; - dcache.caches->stats_t.writeAc.access = 0.33*dcache.caches->l_ip.num_rw_ports*coredynp.LSU_duty_cycle; - dcache.caches->stats_t.writeAc.miss = 0; - dcache.caches->stats_t.writeAc.hit = dcache.caches->stats_t.writeAc.access - dcache.caches->stats_t.writeAc.miss; - dcache.caches->tdp_stats = dcache.caches->stats_t; - - dcache.missb->stats_t.readAc.access = dcache.missb->l_ip.num_search_ports; - dcache.missb->stats_t.writeAc.access = dcache.missb->l_ip.num_search_ports; - dcache.missb->tdp_stats = dcache.missb->stats_t; - - dcache.ifb->stats_t.readAc.access = dcache.ifb->l_ip.num_search_ports; - dcache.ifb->stats_t.writeAc.access = dcache.ifb->l_ip.num_search_ports; - dcache.ifb->tdp_stats = dcache.ifb->stats_t; - - dcache.prefetchb->stats_t.readAc.access = dcache.prefetchb->l_ip.num_search_ports; - dcache.prefetchb->stats_t.writeAc.access = dcache.ifb->l_ip.num_search_ports; - dcache.prefetchb->tdp_stats = dcache.prefetchb->stats_t; - if (cache_p==Write_back) - { - dcache.wbb->stats_t.readAc.access = dcache.wbb->l_ip.num_search_ports; - dcache.wbb->stats_t.writeAc.access = dcache.wbb->l_ip.num_search_ports; - dcache.wbb->tdp_stats = dcache.wbb->stats_t; - } - - - //init stats for Peak - ccache - ccache.caches->stats_t.readAc.access = 0.67*ccache.caches->l_ip.num_rw_ports*coredynp.LSU_duty_cycle; - ccache.caches->stats_t.readAc.miss = 0; - ccache.caches->stats_t.readAc.hit = ccache.caches->stats_t.readAc.access - ccache.caches->stats_t.readAc.miss; - ccache.caches->stats_t.writeAc.access = 0.33*ccache.caches->l_ip.num_rw_ports*coredynp.LSU_duty_cycle; - ccache.caches->stats_t.writeAc.miss = 0; - ccache.caches->stats_t.writeAc.hit = ccache.caches->stats_t.writeAc.access - ccache.caches->stats_t.writeAc.miss; - ccache.caches->tdp_stats = ccache.caches->stats_t; - - ccache.missb->stats_t.readAc.access = ccache.missb->l_ip.num_search_ports; - ccache.missb->stats_t.writeAc.access = ccache.missb->l_ip.num_search_ports; - ccache.missb->tdp_stats = ccache.missb->stats_t; - - ccache.ifb->stats_t.readAc.access = ccache.ifb->l_ip.num_search_ports; - ccache.ifb->stats_t.writeAc.access = ccache.ifb->l_ip.num_search_ports; - ccache.ifb->tdp_stats = ccache.ifb->stats_t; - - ccache.prefetchb->stats_t.readAc.access = ccache.prefetchb->l_ip.num_search_ports; - ccache.prefetchb->stats_t.writeAc.access = ccache.ifb->l_ip.num_search_ports; - ccache.prefetchb->tdp_stats = ccache.prefetchb->stats_t; - if (cache_p==Write_back) - { - ccache.wbb->stats_t.readAc.access = ccache.wbb->l_ip.num_search_ports; - ccache.wbb->stats_t.writeAc.access = ccache.wbb->l_ip.num_search_ports; - ccache.wbb->tdp_stats = ccache.wbb->stats_t; - } - - - //init stats for Peak - tcache - tcache.caches->stats_t.readAc.access = 0.67*tcache.caches->l_ip.num_rw_ports*coredynp.LSU_duty_cycle; - tcache.caches->stats_t.readAc.miss = 0; - tcache.caches->stats_t.readAc.hit = tcache.caches->stats_t.readAc.access - tcache.caches->stats_t.readAc.miss; - tcache.caches->stats_t.writeAc.access = 0.33*tcache.caches->l_ip.num_rw_ports*coredynp.LSU_duty_cycle; - tcache.caches->stats_t.writeAc.miss = 0; - tcache.caches->stats_t.writeAc.hit = tcache.caches->stats_t.writeAc.access - tcache.caches->stats_t.writeAc.miss; - tcache.caches->tdp_stats = tcache.caches->stats_t; - - tcache.missb->stats_t.readAc.access = tcache.missb->l_ip.num_search_ports; - tcache.missb->stats_t.writeAc.access = tcache.missb->l_ip.num_search_ports; - tcache.missb->tdp_stats = tcache.missb->stats_t; - - tcache.ifb->stats_t.readAc.access = tcache.ifb->l_ip.num_search_ports; - tcache.ifb->stats_t.writeAc.access = tcache.ifb->l_ip.num_search_ports; - tcache.ifb->tdp_stats = tcache.ifb->stats_t; - - tcache.prefetchb->stats_t.readAc.access = tcache.prefetchb->l_ip.num_search_ports; - tcache.prefetchb->stats_t.writeAc.access = tcache.ifb->l_ip.num_search_ports; - tcache.prefetchb->tdp_stats = tcache.prefetchb->stats_t; - if (cache_p==Write_back) - { - tcache.wbb->stats_t.readAc.access = tcache.wbb->l_ip.num_search_ports; - tcache.wbb->stats_t.writeAc.access = tcache.wbb->l_ip.num_search_ports; - tcache.wbb->tdp_stats = tcache.wbb->stats_t; - } - - - - LSQ->stats_t.readAc.access = LSQ->stats_t.writeAc.access = LSQ->l_ip.num_search_ports*coredynp.LSU_duty_cycle; - LSQ->tdp_stats = LSQ->stats_t; - if ((coredynp.core_ty==OOO) && (XML->sys.core[ithCore].load_buffer_size >0)) - { - LoadQ->stats_t.readAc.access = LoadQ->stats_t.writeAc.access = LoadQ->l_ip.num_search_ports*coredynp.LSU_duty_cycle; - LoadQ->tdp_stats = LoadQ->stats_t; - } - } - else - { - //init stats for Runtime Dynamic (RTP) - - sharedmemory.caches->stats_t.readAc.access = XML->sys.core[ithCore].sharedmemory.read_accesses; - sharedmemory.caches->stats_t.readAc.miss = XML->sys.core[ithCore].sharedmemory.read_misses; - sharedmemory.caches->stats_t.readAc.hit = sharedmemory.caches->stats_t.readAc.access - sharedmemory.caches->stats_t.readAc.miss; - sharedmemory.caches->stats_t.writeAc.access = XML->sys.core[ithCore].sharedmemory.write_accesses; - sharedmemory.caches->stats_t.writeAc.miss = XML->sys.core[ithCore].sharedmemory.write_misses; - sharedmemory.caches->stats_t.writeAc.hit = sharedmemory.caches->stats_t.writeAc.access - sharedmemory.caches->stats_t.writeAc.miss; - sharedmemory.caches->rtp_stats = sharedmemory.caches->stats_t; - - - - dcache.caches->stats_t.readAc.access = XML->sys.core[ithCore].dcache.read_accesses; - dcache.caches->stats_t.readAc.miss = XML->sys.core[ithCore].dcache.read_misses; - dcache.caches->stats_t.readAc.hit = dcache.caches->stats_t.readAc.access - dcache.caches->stats_t.readAc.miss; - dcache.caches->stats_t.writeAc.access = XML->sys.core[ithCore].dcache.write_accesses; - dcache.caches->stats_t.writeAc.miss = XML->sys.core[ithCore].dcache.write_misses; - dcache.caches->stats_t.writeAc.hit = dcache.caches->stats_t.writeAc.access - dcache.caches->stats_t.writeAc.miss; - dcache.caches->rtp_stats = dcache.caches->stats_t; - - ccache.caches->stats_t.readAc.access = XML->sys.core[ithCore].ccache.read_accesses; - ccache.caches->stats_t.readAc.miss = XML->sys.core[ithCore].ccache.read_misses; - ccache.caches->stats_t.readAc.hit = ccache.caches->stats_t.readAc.access - ccache.caches->stats_t.readAc.miss; - ccache.caches->stats_t.writeAc.access = XML->sys.core[ithCore].ccache.write_accesses; - ccache.caches->stats_t.writeAc.miss = XML->sys.core[ithCore].ccache.write_misses; - ccache.caches->stats_t.writeAc.hit = ccache.caches->stats_t.writeAc.access - ccache.caches->stats_t.writeAc.miss; - ccache.caches->rtp_stats = ccache.caches->stats_t; - - tcache.caches->stats_t.readAc.access = XML->sys.core[ithCore].tcache.read_accesses; - tcache.caches->stats_t.readAc.miss = XML->sys.core[ithCore].tcache.read_misses; - tcache.caches->stats_t.readAc.hit = tcache.caches->stats_t.readAc.access - tcache.caches->stats_t.readAc.miss; - tcache.caches->stats_t.writeAc.access = XML->sys.core[ithCore].tcache.write_accesses; - tcache.caches->stats_t.writeAc.miss = XML->sys.core[ithCore].tcache.write_misses; - tcache.caches->stats_t.writeAc.hit = tcache.caches->stats_t.writeAc.access - tcache.caches->stats_t.writeAc.miss; - tcache.caches->rtp_stats = tcache.caches->stats_t; - - if (cache_p==Write_back) - { - - sharedmemory.missb->stats_t.readAc.access = sharedmemory.caches->stats_t.writeAc.miss; - sharedmemory.missb->stats_t.writeAc.access = sharedmemory.caches->stats_t.writeAc.miss; - sharedmemory.missb->rtp_stats = sharedmemory.missb->stats_t; - sharedmemory.ifb->stats_t.readAc.access = sharedmemory.caches->stats_t.writeAc.miss; - sharedmemory.ifb->stats_t.writeAc.access = sharedmemory.caches->stats_t.writeAc.miss; - sharedmemory.ifb->rtp_stats = sharedmemory.ifb->stats_t; - sharedmemory.prefetchb->stats_t.readAc.access = sharedmemory.caches->stats_t.writeAc.miss; - sharedmemory.prefetchb->stats_t.writeAc.access = sharedmemory.caches->stats_t.writeAc.miss; - sharedmemory.prefetchb->rtp_stats = sharedmemory.prefetchb->stats_t; - sharedmemory.wbb->stats_t.readAc.access = sharedmemory.caches->stats_t.writeAc.miss; - sharedmemory.wbb->stats_t.writeAc.access = sharedmemory.caches->stats_t.writeAc.miss; - sharedmemory.wbb->rtp_stats = sharedmemory.wbb->stats_t; - - - dcache.missb->stats_t.readAc.access = dcache.caches->stats_t.writeAc.miss; - dcache.missb->stats_t.writeAc.access = dcache.caches->stats_t.writeAc.miss; - dcache.missb->rtp_stats = dcache.missb->stats_t; - dcache.ifb->stats_t.readAc.access = dcache.caches->stats_t.writeAc.miss; - dcache.ifb->stats_t.writeAc.access = dcache.caches->stats_t.writeAc.miss; - dcache.ifb->rtp_stats = dcache.ifb->stats_t; - dcache.prefetchb->stats_t.readAc.access = dcache.caches->stats_t.writeAc.miss; - dcache.prefetchb->stats_t.writeAc.access = dcache.caches->stats_t.writeAc.miss; - dcache.prefetchb->rtp_stats = dcache.prefetchb->stats_t; - dcache.wbb->stats_t.readAc.access = dcache.caches->stats_t.writeAc.miss; - dcache.wbb->stats_t.writeAc.access = dcache.caches->stats_t.writeAc.miss; - dcache.wbb->rtp_stats = dcache.wbb->stats_t; - - ccache.missb->stats_t.readAc.access = ccache.caches->stats_t.writeAc.miss; - ccache.missb->stats_t.writeAc.access = ccache.caches->stats_t.writeAc.miss; - ccache.missb->rtp_stats = ccache.missb->stats_t; - ccache.ifb->stats_t.readAc.access = ccache.caches->stats_t.writeAc.miss; - ccache.ifb->stats_t.writeAc.access = ccache.caches->stats_t.writeAc.miss; - ccache.ifb->rtp_stats = ccache.ifb->stats_t; - ccache.prefetchb->stats_t.readAc.access = ccache.caches->stats_t.writeAc.miss; - ccache.prefetchb->stats_t.writeAc.access = ccache.caches->stats_t.writeAc.miss; - ccache.prefetchb->rtp_stats = ccache.prefetchb->stats_t; - ccache.wbb->stats_t.readAc.access = ccache.caches->stats_t.writeAc.miss; - ccache.wbb->stats_t.writeAc.access = ccache.caches->stats_t.writeAc.miss; - ccache.wbb->rtp_stats = ccache.wbb->stats_t; - - tcache.missb->stats_t.readAc.access = tcache.caches->stats_t.writeAc.miss; - tcache.missb->stats_t.writeAc.access = tcache.caches->stats_t.writeAc.miss; - tcache.missb->rtp_stats = tcache.missb->stats_t; - tcache.ifb->stats_t.readAc.access = tcache.caches->stats_t.writeAc.miss; - tcache.ifb->stats_t.writeAc.access = tcache.caches->stats_t.writeAc.miss; - tcache.ifb->rtp_stats = tcache.ifb->stats_t; - tcache.prefetchb->stats_t.readAc.access = tcache.caches->stats_t.writeAc.miss; - tcache.prefetchb->stats_t.writeAc.access = tcache.caches->stats_t.writeAc.miss; - tcache.prefetchb->rtp_stats = tcache.prefetchb->stats_t; - tcache.wbb->stats_t.readAc.access = tcache.caches->stats_t.writeAc.miss; - tcache.wbb->stats_t.writeAc.access = tcache.caches->stats_t.writeAc.miss; - tcache.wbb->rtp_stats = tcache.wbb->stats_t; - } - else - { - sharedmemory.missb->stats_t.readAc.access = sharedmemory.caches->stats_t.readAc.miss; - sharedmemory.missb->stats_t.writeAc.access = sharedmemory.caches->stats_t.readAc.miss; - sharedmemory.missb->rtp_stats = sharedmemory.missb->stats_t; - sharedmemory.ifb->stats_t.readAc.access = sharedmemory.caches->stats_t.readAc.miss; - sharedmemory.ifb->stats_t.writeAc.access = sharedmemory.caches->stats_t.readAc.miss; - sharedmemory.ifb->rtp_stats = sharedmemory.ifb->stats_t; - sharedmemory.prefetchb->stats_t.readAc.access = sharedmemory.caches->stats_t.readAc.miss; - sharedmemory.prefetchb->stats_t.writeAc.access = sharedmemory.caches->stats_t.readAc.miss; - sharedmemory.prefetchb->rtp_stats = sharedmemory.prefetchb->stats_t; - - - dcache.missb->stats_t.readAc.access = dcache.caches->stats_t.readAc.miss; - dcache.missb->stats_t.writeAc.access = dcache.caches->stats_t.readAc.miss; - dcache.missb->rtp_stats = dcache.missb->stats_t; - dcache.ifb->stats_t.readAc.access = dcache.caches->stats_t.readAc.miss; - dcache.ifb->stats_t.writeAc.access = dcache.caches->stats_t.readAc.miss; - dcache.ifb->rtp_stats = dcache.ifb->stats_t; - dcache.prefetchb->stats_t.readAc.access = dcache.caches->stats_t.readAc.miss; - dcache.prefetchb->stats_t.writeAc.access = dcache.caches->stats_t.readAc.miss; - dcache.prefetchb->rtp_stats = dcache.prefetchb->stats_t; - - - ccache.missb->stats_t.readAc.access = ccache.caches->stats_t.readAc.miss; - ccache.missb->stats_t.writeAc.access = ccache.caches->stats_t.readAc.miss; - ccache.missb->rtp_stats = ccache.missb->stats_t; - ccache.ifb->stats_t.readAc.access = ccache.caches->stats_t.readAc.miss; - ccache.ifb->stats_t.writeAc.access = ccache.caches->stats_t.readAc.miss; - ccache.ifb->rtp_stats = ccache.ifb->stats_t; - ccache.prefetchb->stats_t.readAc.access = ccache.caches->stats_t.readAc.miss; - ccache.prefetchb->stats_t.writeAc.access = ccache.caches->stats_t.readAc.miss; - ccache.prefetchb->rtp_stats = ccache.prefetchb->stats_t; - - tcache.missb->stats_t.readAc.access = tcache.caches->stats_t.readAc.miss; - tcache.missb->stats_t.writeAc.access = tcache.caches->stats_t.readAc.miss; - tcache.missb->rtp_stats = tcache.missb->stats_t; - tcache.ifb->stats_t.readAc.access = tcache.caches->stats_t.readAc.miss; - tcache.ifb->stats_t.writeAc.access = tcache.caches->stats_t.readAc.miss; - tcache.ifb->rtp_stats = tcache.ifb->stats_t; - tcache.prefetchb->stats_t.readAc.access = tcache.caches->stats_t.readAc.miss; - tcache.prefetchb->stats_t.writeAc.access = tcache.caches->stats_t.readAc.miss; - tcache.prefetchb->rtp_stats = tcache.prefetchb->stats_t; - - } - - LSQ->stats_t.readAc.access = (XML->sys.core[ithCore].load_instructions + XML->sys.core[ithCore].store_instructions)*2;//flush overhead considered - LSQ->stats_t.writeAc.access = (XML->sys.core[ithCore].load_instructions + XML->sys.core[ithCore].store_instructions)*2; - LSQ->rtp_stats = LSQ->stats_t; - - if ((coredynp.core_ty==OOO) && (XML->sys.core[ithCore].load_buffer_size >0)) - { - LoadQ->stats_t.readAc.access = XML->sys.core[ithCore].load_instructions + XML->sys.core[ithCore].store_instructions; - LoadQ->stats_t.writeAc.access = XML->sys.core[ithCore].load_instructions + XML->sys.core[ithCore].store_instructions; - LoadQ->rtp_stats = LoadQ->stats_t; - } - - } - - sharedmemory.power_t.reset(); - dcache.power_t.reset(); - ccache.power_t.reset(); - tcache.power_t.reset(); - LSQ->power_t.reset(); - - sharedmemory.power_t.readOp.dynamic += (sharedmemory.caches->stats_t.readAc.hit*sharedmemory.caches->local_result.power.readOp.dynamic+ - sharedmemory.caches->stats_t.readAc.miss*sharedmemory.caches->local_result.power.readOp.dynamic+ - sharedmemory.caches->stats_t.writeAc.miss*sharedmemory.caches->local_result.tag_array2->power.readOp.dynamic+ - sharedmemory.caches->stats_t.writeAc.access*sharedmemory.caches->local_result.power.writeOp.dynamic + - xbar_shared->power.readOp.dynamic*(sharedmemory.caches->stats_t.readAc.hit+ sharedmemory.caches->stats_t.writeAc.hit)); - - - dcache.power_t.readOp.dynamic += (dcache.caches->stats_t.readAc.hit*dcache.caches->local_result.power.readOp.dynamic+ - dcache.caches->stats_t.readAc.miss*dcache.caches->local_result.power.readOp.dynamic+ - dcache.caches->stats_t.writeAc.miss*dcache.caches->local_result.tag_array2->power.readOp.dynamic+ - dcache.caches->stats_t.writeAc.access*dcache.caches->local_result.power.writeOp.dynamic + - xbar_shared->power.readOp.dynamic*(dcache.caches->stats_t.readAc.hit+ dcache.caches->stats_t.writeAc.hit)); - ccache.power_t.readOp.dynamic += (ccache.caches->stats_t.readAc.hit*ccache.caches->local_result.power.readOp.dynamic+ - ccache.caches->stats_t.readAc.miss*ccache.caches->local_result.power.readOp.dynamic+ - ccache.caches->stats_t.writeAc.miss*ccache.caches->local_result.tag_array2->power.readOp.dynamic+ - ccache.caches->stats_t.writeAc.access*ccache.caches->local_result.power.writeOp.dynamic + - xbar_shared->power.readOp.dynamic*(ccache.caches->stats_t.readAc.hit)); - - tcache.power_t.readOp.dynamic += (tcache.caches->stats_t.readAc.hit*tcache.caches->local_result.power.readOp.dynamic+ - tcache.caches->stats_t.readAc.miss*tcache.caches->local_result.power.readOp.dynamic+ - tcache.caches->stats_t.writeAc.miss*tcache.caches->local_result.tag_array2->power.readOp.dynamic+ - tcache.caches->stats_t.writeAc.access*tcache.caches->local_result.power.writeOp.dynamic+ - xbar_shared->power.readOp.dynamic*(tcache.caches->stats_t.readAc.hit+ tcache.caches->stats_t.writeAc.hit)); - - if (cache_p==Write_back) - {//write miss will generate a write later - dcache.power_t.readOp.dynamic += dcache.caches->stats_t.writeAc.miss*dcache.caches->local_result.power.writeOp.dynamic; - ccache.power_t.readOp.dynamic += ccache.caches->stats_t.writeAc.miss*ccache.caches->local_result.power.writeOp.dynamic; - tcache.power_t.readOp.dynamic += tcache.caches->stats_t.writeAc.miss*tcache.caches->local_result.power.writeOp.dynamic; - sharedmemory.power_t.readOp.dynamic += sharedmemory.caches->stats_t.writeAc.miss*sharedmemory.caches->local_result.power.writeOp.dynamic; +void SchedulerU::displayEnergy(uint32_t indent, int plevel, bool is_tdp) { + if (!exist) return; + string indent_str(indent, ' '); + string indent_str_next(indent + 2, ' '); + bool long_channel = XML->sys.longer_channel_device; + + if (is_tdp) { + if (coredynp.core_ty == OOO) { + cout << indent_str << "Instruction Window:" << endl; + cout << indent_str_next + << "Area = " << int_inst_window->area.get_area() * 1e-6 << " mm^2" + << endl; + cout << indent_str_next << "Peak Dynamic = " + << int_inst_window->power.readOp.dynamic * clockRate << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel + ? int_inst_window->power.readOp.longer_channel_leakage + : int_inst_window->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << int_inst_window->power.readOp.gate_leakage + << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " + << int_inst_window->rt_power.readOp.dynamic / executionTime << " W" + << endl; + cout << endl; + cout << indent_str << "FP Instruction Window:" << endl; + cout << indent_str_next + << "Area = " << fp_inst_window->area.get_area() * 1e-6 << " mm^2" + << endl; + cout << indent_str_next << "Peak Dynamic = " + << fp_inst_window->power.readOp.dynamic * clockRate << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel + ? fp_inst_window->power.readOp.longer_channel_leakage + : fp_inst_window->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << fp_inst_window->power.readOp.gate_leakage + << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " + << fp_inst_window->rt_power.readOp.dynamic / executionTime << " W" + << endl; + cout << endl; + if (XML->sys.core[ithCore].ROB_size > 0) { + cout << indent_str << "ROB:" << endl; + cout << indent_str_next << "Area = " << ROB->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << ROB->power.readOp.dynamic * clockRate + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? ROB->power.readOp.longer_channel_leakage + : ROB->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << ROB->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << ROB->rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << endl; + } + } else if (coredynp.multithreaded) { + cout << indent_str << "Instruction Window:" << endl; + cout << indent_str_next + << "Area = " << int_inst_window->area.get_area() * 1e-6 << " mm^2" + << endl; + cout << indent_str_next << "Peak Dynamic = " + << int_inst_window->power.readOp.dynamic * clockRate << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel + ? int_inst_window->power.readOp.longer_channel_leakage + : int_inst_window->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << int_inst_window->power.readOp.gate_leakage + << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " + << int_inst_window->rt_power.readOp.dynamic / executionTime << " W" + << endl; + cout << endl; } + } else { + if (coredynp.core_ty == OOO) { + cout << indent_str_next << "Instruction Window Peak Dynamic = " + << int_inst_window->rt_power.readOp.dynamic * clockRate << " W" + << endl; + cout << indent_str_next << "Instruction Window Subthreshold Leakage = " + << int_inst_window->rt_power.readOp.leakage << " W" << endl; + cout << indent_str_next << "Instruction Window Gate Leakage = " + << int_inst_window->rt_power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "FP Instruction Window Peak Dynamic = " + << fp_inst_window->rt_power.readOp.dynamic * clockRate << " W" + << endl; + cout << indent_str_next + << "FP Instruction Window Subthreshold Leakage = " + << fp_inst_window->rt_power.readOp.leakage << " W" << endl; + cout << indent_str_next << "FP Instruction Window Gate Leakage = " + << fp_inst_window->rt_power.readOp.gate_leakage << " W" << endl; + if (XML->sys.core[ithCore].ROB_size > 0) { + cout << indent_str_next << "ROB Peak Dynamic = " + << ROB->rt_power.readOp.dynamic * clockRate << " W" << endl; + cout << indent_str_next + << "ROB Subthreshold Leakage = " << ROB->rt_power.readOp.leakage + << " W" << endl; + cout << indent_str_next + << "ROB Gate Leakage = " << ROB->rt_power.readOp.gate_leakage + << " W" << endl; + } + } else if (coredynp.multithreaded) { + cout << indent_str_next << "Instruction Window Peak Dynamic = " + << int_inst_window->rt_power.readOp.dynamic * clockRate << " W" + << endl; + cout << indent_str_next << "Instruction Window Subthreshold Leakage = " + << int_inst_window->rt_power.readOp.leakage << " W" << endl; + cout << indent_str_next << "Instruction Window Gate Leakage = " + << int_inst_window->rt_power.readOp.gate_leakage << " W" << endl; + } + } +} +void LoadStoreU::computeEnergy(bool is_tdp) { + if (!exist) return; + + executionTime = + XML->sys.total_cycles / (XML->sys.target_core_clockrate * 1e6); // Syed + + // RF crossbar power (Syed) + xbar_shared->compute_power(); + + if (is_tdp) { + // init stats for Peak + // added by Jingwen + sharedmemory.caches->stats_t.readAc.access = + 0.67 * sharedmemory.caches->l_ip.num_rw_ports * coredynp.LSU_duty_cycle; + sharedmemory.caches->stats_t.readAc.miss = 0; + sharedmemory.caches->stats_t.readAc.hit = + sharedmemory.caches->stats_t.readAc.access - + sharedmemory.caches->stats_t.readAc.miss; + sharedmemory.caches->stats_t.writeAc.access = + 0.33 * sharedmemory.caches->l_ip.num_rw_ports * coredynp.LSU_duty_cycle; + sharedmemory.caches->stats_t.writeAc.miss = 0; + sharedmemory.caches->stats_t.writeAc.hit = + sharedmemory.caches->stats_t.writeAc.access - + sharedmemory.caches->stats_t.writeAc.miss; + sharedmemory.caches->tdp_stats = sharedmemory.caches->stats_t; + + sharedmemory.missb->stats_t.readAc.access = + sharedmemory.missb->l_ip.num_search_ports; + sharedmemory.missb->stats_t.writeAc.access = + sharedmemory.missb->l_ip.num_search_ports; + sharedmemory.missb->tdp_stats = sharedmemory.missb->stats_t; + + sharedmemory.ifb->stats_t.readAc.access = + sharedmemory.ifb->l_ip.num_search_ports; + sharedmemory.ifb->stats_t.writeAc.access = + sharedmemory.ifb->l_ip.num_search_ports; + sharedmemory.ifb->tdp_stats = sharedmemory.ifb->stats_t; + + sharedmemory.prefetchb->stats_t.readAc.access = + sharedmemory.prefetchb->l_ip.num_search_ports; + sharedmemory.prefetchb->stats_t.writeAc.access = + sharedmemory.ifb->l_ip.num_search_ports; + sharedmemory.prefetchb->tdp_stats = sharedmemory.prefetchb->stats_t; + if (cache_p == Write_back) { + sharedmemory.wbb->stats_t.readAc.access = + sharedmemory.wbb->l_ip.num_search_ports; + sharedmemory.wbb->stats_t.writeAc.access = + sharedmemory.wbb->l_ip.num_search_ports; + sharedmemory.wbb->tdp_stats = sharedmemory.wbb->stats_t; + } - sharedmemory.power_t.readOp.dynamic += sharedmemory.missb->stats_t.readAc.access*sharedmemory.missb->local_result.power.searchOp.dynamic + - sharedmemory.missb->stats_t.writeAc.access*sharedmemory.missb->local_result.power.writeOp.dynamic;//each access to missb involves a CAM and a write - sharedmemory.power_t.readOp.dynamic += sharedmemory.ifb->stats_t.readAc.access*sharedmemory.ifb->local_result.power.searchOp.dynamic + - sharedmemory.ifb->stats_t.writeAc.access*sharedmemory.ifb->local_result.power.writeOp.dynamic; - sharedmemory.power_t.readOp.dynamic += sharedmemory.prefetchb->stats_t.readAc.access*sharedmemory.prefetchb->local_result.power.searchOp.dynamic + - sharedmemory.prefetchb->stats_t.writeAc.access*sharedmemory.prefetchb->local_result.power.writeOp.dynamic; - if (cache_p==Write_back) - { - sharedmemory.power_t.readOp.dynamic += sharedmemory.wbb->stats_t.readAc.access*sharedmemory.wbb->local_result.power.searchOp.dynamic - + sharedmemory.wbb->stats_t.writeAc.access*sharedmemory.wbb->local_result.power.writeOp.dynamic; + // init stats for Peak + dcache.caches->stats_t.readAc.access = + 0.67 * dcache.caches->l_ip.num_rw_ports * coredynp.LSU_duty_cycle; + dcache.caches->stats_t.readAc.miss = 0; + dcache.caches->stats_t.readAc.hit = dcache.caches->stats_t.readAc.access - + dcache.caches->stats_t.readAc.miss; + dcache.caches->stats_t.writeAc.access = + 0.33 * dcache.caches->l_ip.num_rw_ports * coredynp.LSU_duty_cycle; + dcache.caches->stats_t.writeAc.miss = 0; + dcache.caches->stats_t.writeAc.hit = dcache.caches->stats_t.writeAc.access - + dcache.caches->stats_t.writeAc.miss; + dcache.caches->tdp_stats = dcache.caches->stats_t; + + dcache.missb->stats_t.readAc.access = dcache.missb->l_ip.num_search_ports; + dcache.missb->stats_t.writeAc.access = dcache.missb->l_ip.num_search_ports; + dcache.missb->tdp_stats = dcache.missb->stats_t; + + dcache.ifb->stats_t.readAc.access = dcache.ifb->l_ip.num_search_ports; + dcache.ifb->stats_t.writeAc.access = dcache.ifb->l_ip.num_search_ports; + dcache.ifb->tdp_stats = dcache.ifb->stats_t; + + dcache.prefetchb->stats_t.readAc.access = + dcache.prefetchb->l_ip.num_search_ports; + dcache.prefetchb->stats_t.writeAc.access = + dcache.ifb->l_ip.num_search_ports; + dcache.prefetchb->tdp_stats = dcache.prefetchb->stats_t; + if (cache_p == Write_back) { + dcache.wbb->stats_t.readAc.access = dcache.wbb->l_ip.num_search_ports; + dcache.wbb->stats_t.writeAc.access = dcache.wbb->l_ip.num_search_ports; + dcache.wbb->tdp_stats = dcache.wbb->stats_t; } + // init stats for Peak - ccache + ccache.caches->stats_t.readAc.access = + 0.67 * ccache.caches->l_ip.num_rw_ports * coredynp.LSU_duty_cycle; + ccache.caches->stats_t.readAc.miss = 0; + ccache.caches->stats_t.readAc.hit = ccache.caches->stats_t.readAc.access - + ccache.caches->stats_t.readAc.miss; + ccache.caches->stats_t.writeAc.access = + 0.33 * ccache.caches->l_ip.num_rw_ports * coredynp.LSU_duty_cycle; + ccache.caches->stats_t.writeAc.miss = 0; + ccache.caches->stats_t.writeAc.hit = ccache.caches->stats_t.writeAc.access - + ccache.caches->stats_t.writeAc.miss; + ccache.caches->tdp_stats = ccache.caches->stats_t; + + ccache.missb->stats_t.readAc.access = ccache.missb->l_ip.num_search_ports; + ccache.missb->stats_t.writeAc.access = ccache.missb->l_ip.num_search_ports; + ccache.missb->tdp_stats = ccache.missb->stats_t; + + ccache.ifb->stats_t.readAc.access = ccache.ifb->l_ip.num_search_ports; + ccache.ifb->stats_t.writeAc.access = ccache.ifb->l_ip.num_search_ports; + ccache.ifb->tdp_stats = ccache.ifb->stats_t; + + ccache.prefetchb->stats_t.readAc.access = + ccache.prefetchb->l_ip.num_search_ports; + ccache.prefetchb->stats_t.writeAc.access = + ccache.ifb->l_ip.num_search_ports; + ccache.prefetchb->tdp_stats = ccache.prefetchb->stats_t; + if (cache_p == Write_back) { + ccache.wbb->stats_t.readAc.access = ccache.wbb->l_ip.num_search_ports; + ccache.wbb->stats_t.writeAc.access = ccache.wbb->l_ip.num_search_ports; + ccache.wbb->tdp_stats = ccache.wbb->stats_t; + } - dcache.power_t.readOp.dynamic += dcache.missb->stats_t.readAc.access*dcache.missb->local_result.power.searchOp.dynamic + - dcache.missb->stats_t.writeAc.access*dcache.missb->local_result.power.writeOp.dynamic;//each access to missb involves a CAM and a write - dcache.power_t.readOp.dynamic += dcache.ifb->stats_t.readAc.access*dcache.ifb->local_result.power.searchOp.dynamic + - dcache.ifb->stats_t.writeAc.access*dcache.ifb->local_result.power.writeOp.dynamic; - dcache.power_t.readOp.dynamic += dcache.prefetchb->stats_t.readAc.access*dcache.prefetchb->local_result.power.searchOp.dynamic + - dcache.prefetchb->stats_t.writeAc.access*dcache.prefetchb->local_result.power.writeOp.dynamic; - if (cache_p==Write_back) - { - dcache.power_t.readOp.dynamic += dcache.wbb->stats_t.readAc.access*dcache.wbb->local_result.power.searchOp.dynamic - + dcache.wbb->stats_t.writeAc.access*dcache.wbb->local_result.power.writeOp.dynamic; + // init stats for Peak - tcache + tcache.caches->stats_t.readAc.access = + 0.67 * tcache.caches->l_ip.num_rw_ports * coredynp.LSU_duty_cycle; + tcache.caches->stats_t.readAc.miss = 0; + tcache.caches->stats_t.readAc.hit = tcache.caches->stats_t.readAc.access - + tcache.caches->stats_t.readAc.miss; + tcache.caches->stats_t.writeAc.access = + 0.33 * tcache.caches->l_ip.num_rw_ports * coredynp.LSU_duty_cycle; + tcache.caches->stats_t.writeAc.miss = 0; + tcache.caches->stats_t.writeAc.hit = tcache.caches->stats_t.writeAc.access - + tcache.caches->stats_t.writeAc.miss; + tcache.caches->tdp_stats = tcache.caches->stats_t; + + tcache.missb->stats_t.readAc.access = tcache.missb->l_ip.num_search_ports; + tcache.missb->stats_t.writeAc.access = tcache.missb->l_ip.num_search_ports; + tcache.missb->tdp_stats = tcache.missb->stats_t; + + tcache.ifb->stats_t.readAc.access = tcache.ifb->l_ip.num_search_ports; + tcache.ifb->stats_t.writeAc.access = tcache.ifb->l_ip.num_search_ports; + tcache.ifb->tdp_stats = tcache.ifb->stats_t; + + tcache.prefetchb->stats_t.readAc.access = + tcache.prefetchb->l_ip.num_search_ports; + tcache.prefetchb->stats_t.writeAc.access = + tcache.ifb->l_ip.num_search_ports; + tcache.prefetchb->tdp_stats = tcache.prefetchb->stats_t; + if (cache_p == Write_back) { + tcache.wbb->stats_t.readAc.access = tcache.wbb->l_ip.num_search_ports; + tcache.wbb->stats_t.writeAc.access = tcache.wbb->l_ip.num_search_ports; + tcache.wbb->tdp_stats = tcache.wbb->stats_t; } - ccache.power_t.readOp.dynamic += ccache.missb->stats_t.readAc.access*ccache.missb->local_result.power.searchOp.dynamic + - ccache.missb->stats_t.writeAc.access*ccache.missb->local_result.power.writeOp.dynamic;//each access to missb involves a CAM and a write - ccache.power_t.readOp.dynamic += ccache.ifb->stats_t.readAc.access*ccache.ifb->local_result.power.searchOp.dynamic + - ccache.ifb->stats_t.writeAc.access*ccache.ifb->local_result.power.writeOp.dynamic; - ccache.power_t.readOp.dynamic += ccache.prefetchb->stats_t.readAc.access*ccache.prefetchb->local_result.power.searchOp.dynamic + - ccache.prefetchb->stats_t.writeAc.access*ccache.prefetchb->local_result.power.writeOp.dynamic; - if (cache_p==Write_back) - { - ccache.power_t.readOp.dynamic += ccache.wbb->stats_t.readAc.access*ccache.wbb->local_result.power.searchOp.dynamic - + ccache.wbb->stats_t.writeAc.access*ccache.wbb->local_result.power.writeOp.dynamic; + LSQ->stats_t.readAc.access = LSQ->stats_t.writeAc.access = + LSQ->l_ip.num_search_ports * coredynp.LSU_duty_cycle; + LSQ->tdp_stats = LSQ->stats_t; + if ((coredynp.core_ty == OOO) && + (XML->sys.core[ithCore].load_buffer_size > 0)) { + LoadQ->stats_t.readAc.access = LoadQ->stats_t.writeAc.access = + LoadQ->l_ip.num_search_ports * coredynp.LSU_duty_cycle; + LoadQ->tdp_stats = LoadQ->stats_t; + } + } else { + // init stats for Runtime Dynamic (RTP) + + sharedmemory.caches->stats_t.readAc.access = + XML->sys.core[ithCore].sharedmemory.read_accesses; + sharedmemory.caches->stats_t.readAc.miss = + XML->sys.core[ithCore].sharedmemory.read_misses; + sharedmemory.caches->stats_t.readAc.hit = + sharedmemory.caches->stats_t.readAc.access - + sharedmemory.caches->stats_t.readAc.miss; + sharedmemory.caches->stats_t.writeAc.access = + XML->sys.core[ithCore].sharedmemory.write_accesses; + sharedmemory.caches->stats_t.writeAc.miss = + XML->sys.core[ithCore].sharedmemory.write_misses; + sharedmemory.caches->stats_t.writeAc.hit = + sharedmemory.caches->stats_t.writeAc.access - + sharedmemory.caches->stats_t.writeAc.miss; + sharedmemory.caches->rtp_stats = sharedmemory.caches->stats_t; + + dcache.caches->stats_t.readAc.access = + XML->sys.core[ithCore].dcache.read_accesses; + dcache.caches->stats_t.readAc.miss = + XML->sys.core[ithCore].dcache.read_misses; + dcache.caches->stats_t.readAc.hit = dcache.caches->stats_t.readAc.access - + dcache.caches->stats_t.readAc.miss; + dcache.caches->stats_t.writeAc.access = + XML->sys.core[ithCore].dcache.write_accesses; + dcache.caches->stats_t.writeAc.miss = + XML->sys.core[ithCore].dcache.write_misses; + dcache.caches->stats_t.writeAc.hit = dcache.caches->stats_t.writeAc.access - + dcache.caches->stats_t.writeAc.miss; + dcache.caches->rtp_stats = dcache.caches->stats_t; + + ccache.caches->stats_t.readAc.access = + XML->sys.core[ithCore].ccache.read_accesses; + ccache.caches->stats_t.readAc.miss = + XML->sys.core[ithCore].ccache.read_misses; + ccache.caches->stats_t.readAc.hit = ccache.caches->stats_t.readAc.access - + ccache.caches->stats_t.readAc.miss; + ccache.caches->stats_t.writeAc.access = + XML->sys.core[ithCore].ccache.write_accesses; + ccache.caches->stats_t.writeAc.miss = + XML->sys.core[ithCore].ccache.write_misses; + ccache.caches->stats_t.writeAc.hit = ccache.caches->stats_t.writeAc.access - + ccache.caches->stats_t.writeAc.miss; + ccache.caches->rtp_stats = ccache.caches->stats_t; + + tcache.caches->stats_t.readAc.access = + XML->sys.core[ithCore].tcache.read_accesses; + tcache.caches->stats_t.readAc.miss = + XML->sys.core[ithCore].tcache.read_misses; + tcache.caches->stats_t.readAc.hit = tcache.caches->stats_t.readAc.access - + tcache.caches->stats_t.readAc.miss; + tcache.caches->stats_t.writeAc.access = + XML->sys.core[ithCore].tcache.write_accesses; + tcache.caches->stats_t.writeAc.miss = + XML->sys.core[ithCore].tcache.write_misses; + tcache.caches->stats_t.writeAc.hit = tcache.caches->stats_t.writeAc.access - + tcache.caches->stats_t.writeAc.miss; + tcache.caches->rtp_stats = tcache.caches->stats_t; + + if (cache_p == Write_back) { + sharedmemory.missb->stats_t.readAc.access = + sharedmemory.caches->stats_t.writeAc.miss; + sharedmemory.missb->stats_t.writeAc.access = + sharedmemory.caches->stats_t.writeAc.miss; + sharedmemory.missb->rtp_stats = sharedmemory.missb->stats_t; + sharedmemory.ifb->stats_t.readAc.access = + sharedmemory.caches->stats_t.writeAc.miss; + sharedmemory.ifb->stats_t.writeAc.access = + sharedmemory.caches->stats_t.writeAc.miss; + sharedmemory.ifb->rtp_stats = sharedmemory.ifb->stats_t; + sharedmemory.prefetchb->stats_t.readAc.access = + sharedmemory.caches->stats_t.writeAc.miss; + sharedmemory.prefetchb->stats_t.writeAc.access = + sharedmemory.caches->stats_t.writeAc.miss; + sharedmemory.prefetchb->rtp_stats = sharedmemory.prefetchb->stats_t; + sharedmemory.wbb->stats_t.readAc.access = + sharedmemory.caches->stats_t.writeAc.miss; + sharedmemory.wbb->stats_t.writeAc.access = + sharedmemory.caches->stats_t.writeAc.miss; + sharedmemory.wbb->rtp_stats = sharedmemory.wbb->stats_t; + + dcache.missb->stats_t.readAc.access = dcache.caches->stats_t.writeAc.miss; + dcache.missb->stats_t.writeAc.access = + dcache.caches->stats_t.writeAc.miss; + dcache.missb->rtp_stats = dcache.missb->stats_t; + dcache.ifb->stats_t.readAc.access = dcache.caches->stats_t.writeAc.miss; + dcache.ifb->stats_t.writeAc.access = dcache.caches->stats_t.writeAc.miss; + dcache.ifb->rtp_stats = dcache.ifb->stats_t; + dcache.prefetchb->stats_t.readAc.access = + dcache.caches->stats_t.writeAc.miss; + dcache.prefetchb->stats_t.writeAc.access = + dcache.caches->stats_t.writeAc.miss; + dcache.prefetchb->rtp_stats = dcache.prefetchb->stats_t; + dcache.wbb->stats_t.readAc.access = dcache.caches->stats_t.writeAc.miss; + dcache.wbb->stats_t.writeAc.access = dcache.caches->stats_t.writeAc.miss; + dcache.wbb->rtp_stats = dcache.wbb->stats_t; + + ccache.missb->stats_t.readAc.access = ccache.caches->stats_t.writeAc.miss; + ccache.missb->stats_t.writeAc.access = + ccache.caches->stats_t.writeAc.miss; + ccache.missb->rtp_stats = ccache.missb->stats_t; + ccache.ifb->stats_t.readAc.access = ccache.caches->stats_t.writeAc.miss; + ccache.ifb->stats_t.writeAc.access = ccache.caches->stats_t.writeAc.miss; + ccache.ifb->rtp_stats = ccache.ifb->stats_t; + ccache.prefetchb->stats_t.readAc.access = + ccache.caches->stats_t.writeAc.miss; + ccache.prefetchb->stats_t.writeAc.access = + ccache.caches->stats_t.writeAc.miss; + ccache.prefetchb->rtp_stats = ccache.prefetchb->stats_t; + ccache.wbb->stats_t.readAc.access = ccache.caches->stats_t.writeAc.miss; + ccache.wbb->stats_t.writeAc.access = ccache.caches->stats_t.writeAc.miss; + ccache.wbb->rtp_stats = ccache.wbb->stats_t; + + tcache.missb->stats_t.readAc.access = tcache.caches->stats_t.writeAc.miss; + tcache.missb->stats_t.writeAc.access = + tcache.caches->stats_t.writeAc.miss; + tcache.missb->rtp_stats = tcache.missb->stats_t; + tcache.ifb->stats_t.readAc.access = tcache.caches->stats_t.writeAc.miss; + tcache.ifb->stats_t.writeAc.access = tcache.caches->stats_t.writeAc.miss; + tcache.ifb->rtp_stats = tcache.ifb->stats_t; + tcache.prefetchb->stats_t.readAc.access = + tcache.caches->stats_t.writeAc.miss; + tcache.prefetchb->stats_t.writeAc.access = + tcache.caches->stats_t.writeAc.miss; + tcache.prefetchb->rtp_stats = tcache.prefetchb->stats_t; + tcache.wbb->stats_t.readAc.access = tcache.caches->stats_t.writeAc.miss; + tcache.wbb->stats_t.writeAc.access = tcache.caches->stats_t.writeAc.miss; + tcache.wbb->rtp_stats = tcache.wbb->stats_t; + } else { + sharedmemory.missb->stats_t.readAc.access = + sharedmemory.caches->stats_t.readAc.miss; + sharedmemory.missb->stats_t.writeAc.access = + sharedmemory.caches->stats_t.readAc.miss; + sharedmemory.missb->rtp_stats = sharedmemory.missb->stats_t; + sharedmemory.ifb->stats_t.readAc.access = + sharedmemory.caches->stats_t.readAc.miss; + sharedmemory.ifb->stats_t.writeAc.access = + sharedmemory.caches->stats_t.readAc.miss; + sharedmemory.ifb->rtp_stats = sharedmemory.ifb->stats_t; + sharedmemory.prefetchb->stats_t.readAc.access = + sharedmemory.caches->stats_t.readAc.miss; + sharedmemory.prefetchb->stats_t.writeAc.access = + sharedmemory.caches->stats_t.readAc.miss; + sharedmemory.prefetchb->rtp_stats = sharedmemory.prefetchb->stats_t; + + dcache.missb->stats_t.readAc.access = dcache.caches->stats_t.readAc.miss; + dcache.missb->stats_t.writeAc.access = dcache.caches->stats_t.readAc.miss; + dcache.missb->rtp_stats = dcache.missb->stats_t; + dcache.ifb->stats_t.readAc.access = dcache.caches->stats_t.readAc.miss; + dcache.ifb->stats_t.writeAc.access = dcache.caches->stats_t.readAc.miss; + dcache.ifb->rtp_stats = dcache.ifb->stats_t; + dcache.prefetchb->stats_t.readAc.access = + dcache.caches->stats_t.readAc.miss; + dcache.prefetchb->stats_t.writeAc.access = + dcache.caches->stats_t.readAc.miss; + dcache.prefetchb->rtp_stats = dcache.prefetchb->stats_t; + + ccache.missb->stats_t.readAc.access = ccache.caches->stats_t.readAc.miss; + ccache.missb->stats_t.writeAc.access = ccache.caches->stats_t.readAc.miss; + ccache.missb->rtp_stats = ccache.missb->stats_t; + ccache.ifb->stats_t.readAc.access = ccache.caches->stats_t.readAc.miss; + ccache.ifb->stats_t.writeAc.access = ccache.caches->stats_t.readAc.miss; + ccache.ifb->rtp_stats = ccache.ifb->stats_t; + ccache.prefetchb->stats_t.readAc.access = + ccache.caches->stats_t.readAc.miss; + ccache.prefetchb->stats_t.writeAc.access = + ccache.caches->stats_t.readAc.miss; + ccache.prefetchb->rtp_stats = ccache.prefetchb->stats_t; + + tcache.missb->stats_t.readAc.access = tcache.caches->stats_t.readAc.miss; + tcache.missb->stats_t.writeAc.access = tcache.caches->stats_t.readAc.miss; + tcache.missb->rtp_stats = tcache.missb->stats_t; + tcache.ifb->stats_t.readAc.access = tcache.caches->stats_t.readAc.miss; + tcache.ifb->stats_t.writeAc.access = tcache.caches->stats_t.readAc.miss; + tcache.ifb->rtp_stats = tcache.ifb->stats_t; + tcache.prefetchb->stats_t.readAc.access = + tcache.caches->stats_t.readAc.miss; + tcache.prefetchb->stats_t.writeAc.access = + tcache.caches->stats_t.readAc.miss; + tcache.prefetchb->rtp_stats = tcache.prefetchb->stats_t; } - tcache.power_t.readOp.dynamic += tcache.missb->stats_t.readAc.access*tcache.missb->local_result.power.searchOp.dynamic + - tcache.missb->stats_t.writeAc.access*tcache.missb->local_result.power.writeOp.dynamic;//each access to missb involves a CAM and a write - tcache.power_t.readOp.dynamic += tcache.ifb->stats_t.readAc.access*tcache.ifb->local_result.power.searchOp.dynamic + - tcache.ifb->stats_t.writeAc.access*tcache.ifb->local_result.power.writeOp.dynamic; - tcache.power_t.readOp.dynamic += tcache.prefetchb->stats_t.readAc.access*tcache.prefetchb->local_result.power.searchOp.dynamic + - tcache.prefetchb->stats_t.writeAc.access*tcache.prefetchb->local_result.power.writeOp.dynamic; - if (cache_p==Write_back) - { - tcache.power_t.readOp.dynamic += tcache.wbb->stats_t.readAc.access*tcache.wbb->local_result.power.searchOp.dynamic - + tcache.wbb->stats_t.writeAc.access*tcache.wbb->local_result.power.writeOp.dynamic; + LSQ->stats_t.readAc.access = (XML->sys.core[ithCore].load_instructions + + XML->sys.core[ithCore].store_instructions) * + 2; // flush overhead considered + LSQ->stats_t.writeAc.access = (XML->sys.core[ithCore].load_instructions + + XML->sys.core[ithCore].store_instructions) * + 2; + LSQ->rtp_stats = LSQ->stats_t; + + if ((coredynp.core_ty == OOO) && + (XML->sys.core[ithCore].load_buffer_size > 0)) { + LoadQ->stats_t.readAc.access = XML->sys.core[ithCore].load_instructions + + XML->sys.core[ithCore].store_instructions; + LoadQ->stats_t.writeAc.access = XML->sys.core[ithCore].load_instructions + + XML->sys.core[ithCore].store_instructions; + LoadQ->rtp_stats = LoadQ->stats_t; } + } + sharedmemory.power_t.reset(); + dcache.power_t.reset(); + ccache.power_t.reset(); + tcache.power_t.reset(); + LSQ->power_t.reset(); + + sharedmemory.power_t.readOp.dynamic += + (sharedmemory.caches->stats_t.readAc.hit * + sharedmemory.caches->local_result.power.readOp.dynamic + + sharedmemory.caches->stats_t.readAc.miss * + sharedmemory.caches->local_result.power.readOp.dynamic + + sharedmemory.caches->stats_t.writeAc.miss * + sharedmemory.caches->local_result.tag_array2->power.readOp.dynamic + + sharedmemory.caches->stats_t.writeAc.access * + sharedmemory.caches->local_result.power.writeOp.dynamic + + xbar_shared->power.readOp.dynamic * + (sharedmemory.caches->stats_t.readAc.hit + + sharedmemory.caches->stats_t.writeAc.hit)); + + dcache.power_t.readOp.dynamic += + (dcache.caches->stats_t.readAc.hit * + dcache.caches->local_result.power.readOp.dynamic + + dcache.caches->stats_t.readAc.miss * + dcache.caches->local_result.power.readOp.dynamic + + dcache.caches->stats_t.writeAc.miss * + dcache.caches->local_result.tag_array2->power.readOp.dynamic + + dcache.caches->stats_t.writeAc.access * + dcache.caches->local_result.power.writeOp.dynamic + + xbar_shared->power.readOp.dynamic * + (dcache.caches->stats_t.readAc.hit + + dcache.caches->stats_t.writeAc.hit)); + ccache.power_t.readOp.dynamic += + (ccache.caches->stats_t.readAc.hit * + ccache.caches->local_result.power.readOp.dynamic + + ccache.caches->stats_t.readAc.miss * + ccache.caches->local_result.power.readOp.dynamic + + ccache.caches->stats_t.writeAc.miss * + ccache.caches->local_result.tag_array2->power.readOp.dynamic + + ccache.caches->stats_t.writeAc.access * + ccache.caches->local_result.power.writeOp.dynamic + + xbar_shared->power.readOp.dynamic * (ccache.caches->stats_t.readAc.hit)); + + tcache.power_t.readOp.dynamic += + (tcache.caches->stats_t.readAc.hit * + tcache.caches->local_result.power.readOp.dynamic + + tcache.caches->stats_t.readAc.miss * + tcache.caches->local_result.power.readOp.dynamic + + tcache.caches->stats_t.writeAc.miss * + tcache.caches->local_result.tag_array2->power.readOp.dynamic + + tcache.caches->stats_t.writeAc.access * + tcache.caches->local_result.power.writeOp.dynamic + + xbar_shared->power.readOp.dynamic * + (tcache.caches->stats_t.readAc.hit + + tcache.caches->stats_t.writeAc.hit)); + + if (cache_p == Write_back) { // write miss will generate a write later + dcache.power_t.readOp.dynamic += + dcache.caches->stats_t.writeAc.miss * + dcache.caches->local_result.power.writeOp.dynamic; + ccache.power_t.readOp.dynamic += + ccache.caches->stats_t.writeAc.miss * + ccache.caches->local_result.power.writeOp.dynamic; + tcache.power_t.readOp.dynamic += + tcache.caches->stats_t.writeAc.miss * + tcache.caches->local_result.power.writeOp.dynamic; + sharedmemory.power_t.readOp.dynamic += + sharedmemory.caches->stats_t.writeAc.miss * + sharedmemory.caches->local_result.power.writeOp.dynamic; + } - if ((coredynp.core_ty==OOO) && (XML->sys.core[ithCore].load_buffer_size >0)) - { - LoadQ->power_t.reset(); - LoadQ->power_t.readOp.dynamic += LoadQ->stats_t.readAc.access*(LoadQ->local_result.power.searchOp.dynamic+ LoadQ->local_result.power.readOp.dynamic)+ - LoadQ->stats_t.writeAc.access*LoadQ->local_result.power.writeOp.dynamic;//every memory access invloves at least two operations on LoadQ + sharedmemory.power_t.readOp.dynamic += + sharedmemory.missb->stats_t.readAc.access * + sharedmemory.missb->local_result.power.searchOp.dynamic + + sharedmemory.missb->stats_t.writeAc.access * + sharedmemory.missb->local_result.power.writeOp + .dynamic; // each access to missb involves a CAM and a write + sharedmemory.power_t.readOp.dynamic += + sharedmemory.ifb->stats_t.readAc.access * + sharedmemory.ifb->local_result.power.searchOp.dynamic + + sharedmemory.ifb->stats_t.writeAc.access * + sharedmemory.ifb->local_result.power.writeOp.dynamic; + sharedmemory.power_t.readOp.dynamic += + sharedmemory.prefetchb->stats_t.readAc.access * + sharedmemory.prefetchb->local_result.power.searchOp.dynamic + + sharedmemory.prefetchb->stats_t.writeAc.access * + sharedmemory.prefetchb->local_result.power.writeOp.dynamic; + if (cache_p == Write_back) { + sharedmemory.power_t.readOp.dynamic += + sharedmemory.wbb->stats_t.readAc.access * + sharedmemory.wbb->local_result.power.searchOp.dynamic + + sharedmemory.wbb->stats_t.writeAc.access * + sharedmemory.wbb->local_result.power.writeOp.dynamic; + } - LSQ->power_t.readOp.dynamic += LSQ->stats_t.readAc.access*(LSQ->local_result.power.searchOp.dynamic + LSQ->local_result.power.readOp.dynamic) - + LSQ->stats_t.writeAc.access*LSQ->local_result.power.writeOp.dynamic;//every memory access invloves at least two operations on LSQ + dcache.power_t.readOp.dynamic += + dcache.missb->stats_t.readAc.access * + dcache.missb->local_result.power.searchOp.dynamic + + dcache.missb->stats_t.writeAc.access * + dcache.missb->local_result.power.writeOp + .dynamic; // each access to missb involves a CAM and a write + dcache.power_t.readOp.dynamic += + dcache.ifb->stats_t.readAc.access * + dcache.ifb->local_result.power.searchOp.dynamic + + dcache.ifb->stats_t.writeAc.access * + dcache.ifb->local_result.power.writeOp.dynamic; + dcache.power_t.readOp.dynamic += + dcache.prefetchb->stats_t.readAc.access * + dcache.prefetchb->local_result.power.searchOp.dynamic + + dcache.prefetchb->stats_t.writeAc.access * + dcache.prefetchb->local_result.power.writeOp.dynamic; + if (cache_p == Write_back) { + dcache.power_t.readOp.dynamic += + dcache.wbb->stats_t.readAc.access * + dcache.wbb->local_result.power.searchOp.dynamic + + dcache.wbb->stats_t.writeAc.access * + dcache.wbb->local_result.power.writeOp.dynamic; + } - } - else - { - // LSQ->power_t.readOp.dynamic += LSQ->stats_t.readAc.access*(LSQ->local_result.power.searchOp.dynamic + LSQ->local_result.power.readOp.dynamic) - // + LSQ->stats_t.writeAc.access*LSQ->local_result.power.writeOp.dynamic;//every memory access invloves at least two operations on LSQ - // No LSQ in GPUs (Syed) + ccache.power_t.readOp.dynamic += + ccache.missb->stats_t.readAc.access * + ccache.missb->local_result.power.searchOp.dynamic + + ccache.missb->stats_t.writeAc.access * + ccache.missb->local_result.power.writeOp + .dynamic; // each access to missb involves a CAM and a write + ccache.power_t.readOp.dynamic += + ccache.ifb->stats_t.readAc.access * + ccache.ifb->local_result.power.searchOp.dynamic + + ccache.ifb->stats_t.writeAc.access * + ccache.ifb->local_result.power.writeOp.dynamic; + ccache.power_t.readOp.dynamic += + ccache.prefetchb->stats_t.readAc.access * + ccache.prefetchb->local_result.power.searchOp.dynamic + + ccache.prefetchb->stats_t.writeAc.access * + ccache.prefetchb->local_result.power.writeOp.dynamic; + if (cache_p == Write_back) { + ccache.power_t.readOp.dynamic += + ccache.wbb->stats_t.readAc.access * + ccache.wbb->local_result.power.searchOp.dynamic + + ccache.wbb->stats_t.writeAc.access * + ccache.wbb->local_result.power.writeOp.dynamic; + } - } + tcache.power_t.readOp.dynamic += + tcache.missb->stats_t.readAc.access * + tcache.missb->local_result.power.searchOp.dynamic + + tcache.missb->stats_t.writeAc.access * + tcache.missb->local_result.power.writeOp + .dynamic; // each access to missb involves a CAM and a write + tcache.power_t.readOp.dynamic += + tcache.ifb->stats_t.readAc.access * + tcache.ifb->local_result.power.searchOp.dynamic + + tcache.ifb->stats_t.writeAc.access * + tcache.ifb->local_result.power.writeOp.dynamic; + tcache.power_t.readOp.dynamic += + tcache.prefetchb->stats_t.readAc.access * + tcache.prefetchb->local_result.power.searchOp.dynamic + + tcache.prefetchb->stats_t.writeAc.access * + tcache.prefetchb->local_result.power.writeOp.dynamic; + if (cache_p == Write_back) { + tcache.power_t.readOp.dynamic += + tcache.wbb->stats_t.readAc.access * + tcache.wbb->local_result.power.searchOp.dynamic + + tcache.wbb->stats_t.writeAc.access * + tcache.wbb->local_result.power.writeOp.dynamic; + } - if (is_tdp) - { -// dcache.power = dcache.power_t + (dcache.caches->local_result.power)*pppm_lkg + -// (dcache.missb->local_result.power + -// dcache.ifb->local_result.power + -// dcache.prefetchb->local_result.power + -// dcache.wbb->local_result.power)*pppm_Isub; - - - sharedmemory.power = sharedmemory.power_t + (sharedmemory.caches->local_result.power + - sharedmemory.missb->local_result.power + - sharedmemory.ifb->local_result.power + - sharedmemory.prefetchb->local_result.power + xbar_shared->power) *pppm_lkg; - if (cache_p==Write_back) - { - sharedmemory.power = sharedmemory.power + sharedmemory.wbb->local_result.power*pppm_lkg; - } - - - dcache.power = dcache.power_t + (dcache.caches->local_result.power + - dcache.missb->local_result.power + - dcache.ifb->local_result.power + - dcache.prefetchb->local_result.power) *pppm_lkg; - if (cache_p==Write_back) - { - dcache.power = dcache.power + dcache.wbb->local_result.power*pppm_lkg; - } - - ccache.power = ccache.power_t + (ccache.caches->local_result.power + - ccache.missb->local_result.power + - ccache.ifb->local_result.power + - ccache.prefetchb->local_result.power) *pppm_lkg; - if (cache_p==Write_back) - { - ccache.power = ccache.power + ccache.wbb->local_result.power*pppm_lkg; - } - - tcache.power = tcache.power_t + (tcache.caches->local_result.power + - tcache.missb->local_result.power + - tcache.ifb->local_result.power + - tcache.prefetchb->local_result.power) *pppm_lkg; - if (cache_p==Write_back) - { - tcache.power = tcache.power + tcache.wbb->local_result.power*pppm_lkg; - } - - - LSQ->power = LSQ->power_t + LSQ->local_result.power *pppm_lkg; - //No LSQ in GPUs (Syed) - LSQ->power.reset(); - power = power + dcache.power + LSQ->power +sharedmemory.power + ccache.power + tcache.power; - - if ((coredynp.core_ty==OOO) && (XML->sys.core[ithCore].load_buffer_size >0)) - { - LoadQ->power = LoadQ->power_t + LoadQ->local_result.power *pppm_lkg; - power = power + LoadQ->power; - } + if ((coredynp.core_ty == OOO) && + (XML->sys.core[ithCore].load_buffer_size > 0)) { + LoadQ->power_t.reset(); + LoadQ->power_t.readOp.dynamic += + LoadQ->stats_t.readAc.access * + (LoadQ->local_result.power.searchOp.dynamic + + LoadQ->local_result.power.readOp.dynamic) + + LoadQ->stats_t.writeAc.access * + LoadQ->local_result.power.writeOp + .dynamic; // every memory access invloves at least two + // operations on LoadQ + + LSQ->power_t.readOp.dynamic += + LSQ->stats_t.readAc.access * (LSQ->local_result.power.searchOp.dynamic + + LSQ->local_result.power.readOp.dynamic) + + LSQ->stats_t.writeAc.access * + LSQ->local_result.power.writeOp + .dynamic; // every memory access invloves at least two + // operations on LSQ + + } else { + // LSQ->power_t.readOp.dynamic += + // LSQ->stats_t.readAc.access*(LSQ->local_result.power.searchOp.dynamic + + // LSQ->local_result.power.readOp.dynamic) + // + + // LSQ->stats_t.writeAc.access*LSQ->local_result.power.writeOp.dynamic;//every + // memory access invloves at least two operations on LSQ No LSQ in GPUs + //(Syed) + } + + if (is_tdp) { + // dcache.power = dcache.power_t + + // (dcache.caches->local_result.power)*pppm_lkg + + // (dcache.missb->local_result.power + + // dcache.ifb->local_result.power + + // dcache.prefetchb->local_result.power + + // dcache.wbb->local_result.power)*pppm_Isub; + + sharedmemory.power = + sharedmemory.power_t + + (sharedmemory.caches->local_result.power + + sharedmemory.missb->local_result.power + + sharedmemory.ifb->local_result.power + + sharedmemory.prefetchb->local_result.power + xbar_shared->power) * + pppm_lkg; + if (cache_p == Write_back) { + sharedmemory.power = + sharedmemory.power + sharedmemory.wbb->local_result.power * pppm_lkg; } - else - { -// dcache.rt_power = dcache.power_t + (dcache.caches->local_result.power + -// dcache.missb->local_result.power + -// dcache.ifb->local_result.power + -// dcache.prefetchb->local_result.power + -// dcache.wbb->local_result.power)*pppm_lkg; - rt_power.reset(); - sharedmemory.rt_power.reset(); //Jingwen - tcache.rt_power.reset(); - ccache.rt_power.reset(); - dcache.rt_power.reset(); - LSQ->rt_power.reset(); - - - sharedmemory.rt_power = sharedmemory.power_t + (sharedmemory.caches->local_result.power + - sharedmemory.missb->local_result.power + - sharedmemory.ifb->local_result.power + - sharedmemory.prefetchb->local_result.power )*pppm_lkg; - - if (cache_p==Write_back) - { - sharedmemory.rt_power = sharedmemory.rt_power + sharedmemory.wbb->local_result.power*pppm_lkg; - } - - dcache.rt_power = dcache.power_t + (dcache.caches->local_result.power + - dcache.missb->local_result.power + - dcache.ifb->local_result.power + - dcache.prefetchb->local_result.power )*pppm_lkg; - if (cache_p==Write_back) - { - dcache.rt_power = dcache.rt_power + dcache.wbb->local_result.power*pppm_lkg; - } - - ccache.rt_power = ccache.power_t + (ccache.caches->local_result.power + - ccache.missb->local_result.power + - ccache.ifb->local_result.power + - ccache.prefetchb->local_result.power )*pppm_lkg; - if (cache_p==Write_back) - { - ccache.rt_power = ccache.rt_power + ccache.wbb->local_result.power*pppm_lkg; - } - - tcache.rt_power = tcache.power_t + (tcache.caches->local_result.power + - tcache.missb->local_result.power + - tcache.ifb->local_result.power + - tcache.prefetchb->local_result.power )*pppm_lkg; - if (cache_p==Write_back) - { - tcache.rt_power = tcache.rt_power + tcache.wbb->local_result.power*pppm_lkg; - } - - - - LSQ->rt_power = LSQ->power_t + LSQ->local_result.power *pppm_lkg; - LSQ->rt_power.reset(); - rt_power = rt_power + dcache.rt_power + LSQ->rt_power + sharedmemory.rt_power + ccache.rt_power + tcache.rt_power; - - if ((coredynp.core_ty==OOO) && (XML->sys.core[ithCore].load_buffer_size >0)) - { - LoadQ->rt_power = LoadQ->power_t + LoadQ->local_result.power *pppm_lkg; - rt_power = rt_power + LoadQ->rt_power; - } + + dcache.power = dcache.power_t + (dcache.caches->local_result.power + + dcache.missb->local_result.power + + dcache.ifb->local_result.power + + dcache.prefetchb->local_result.power) * + pppm_lkg; + if (cache_p == Write_back) { + dcache.power = dcache.power + dcache.wbb->local_result.power * pppm_lkg; } -} + ccache.power = ccache.power_t + (ccache.caches->local_result.power + + ccache.missb->local_result.power + + ccache.ifb->local_result.power + + ccache.prefetchb->local_result.power) * + pppm_lkg; + if (cache_p == Write_back) { + ccache.power = ccache.power + ccache.wbb->local_result.power * pppm_lkg; + } -void LoadStoreU::displayEnergy(uint32_t indent,int plevel,bool is_tdp) -{ - if (!exist) return; - string indent_str(indent, ' '); - string indent_str_next(indent+2, ' '); - bool long_channel = XML->sys.longer_channel_device; - - - if (is_tdp) - { - - cout << indent_str << "Shared Memory:" << endl; - cout << indent_str_next << "Area = " << sharedmemory.area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << sharedmemory.power.readOp.dynamic*clockRate << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? sharedmemory.power.readOp.longer_channel_leakage:sharedmemory.power.readOp.leakage )<<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << sharedmemory.power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << sharedmemory.rt_power.readOp.dynamic/executionTime << " W" << endl; - cout <sys.core[ithCore].load_buffer_size >0) - { - cout << indent_str << "LoadQ:" << endl; - cout << indent_str_next << "Area = " << LoadQ->area.get_area() *1e-6 << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << LoadQ->power.readOp.dynamic*clockRate << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? LoadQ->power.readOp.longer_channel_leakage:LoadQ->power.readOp.leakage) << " W" << endl; - cout << indent_str_next << "Gate Leakage = " << LoadQ->power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << LoadQ->rt_power.readOp.dynamic/executionTime << " W" << endl; - cout <local_result.power + + tcache.missb->local_result.power + + tcache.ifb->local_result.power + + tcache.prefetchb->local_result.power) * + pppm_lkg; + if (cache_p == Write_back) { + tcache.power = tcache.power + tcache.wbb->local_result.power * pppm_lkg; + } -} + LSQ->power = LSQ->power_t + LSQ->local_result.power * pppm_lkg; + // No LSQ in GPUs (Syed) + LSQ->power.reset(); + power = power + dcache.power + LSQ->power + sharedmemory.power + + ccache.power + tcache.power; -void MemManU::computeEnergy(bool is_tdp) -{ + if ((coredynp.core_ty == OOO) && + (XML->sys.core[ithCore].load_buffer_size > 0)) { + LoadQ->power = LoadQ->power_t + LoadQ->local_result.power * pppm_lkg; + power = power + LoadQ->power; + } + } else { + // dcache.rt_power = dcache.power_t + + // (dcache.caches->local_result.power + + // dcache.missb->local_result.power + // + dcache.ifb->local_result.power + + // dcache.prefetchb->local_result.power + + // dcache.wbb->local_result.power)*pppm_lkg; + rt_power.reset(); + sharedmemory.rt_power.reset(); // Jingwen + tcache.rt_power.reset(); + ccache.rt_power.reset(); + dcache.rt_power.reset(); + LSQ->rt_power.reset(); + + sharedmemory.rt_power = + sharedmemory.power_t + (sharedmemory.caches->local_result.power + + sharedmemory.missb->local_result.power + + sharedmemory.ifb->local_result.power + + sharedmemory.prefetchb->local_result.power) * + pppm_lkg; + + if (cache_p == Write_back) { + sharedmemory.rt_power = sharedmemory.rt_power + + sharedmemory.wbb->local_result.power * pppm_lkg; + } - if (!exist) return; - if (is_tdp) - { - //init stats for Peak - itlb->stats_t.readAc.access = itlb->l_ip.num_search_ports; - itlb->stats_t.readAc.miss = 0; - itlb->stats_t.readAc.hit = itlb->stats_t.readAc.access - itlb->stats_t.readAc.miss; - itlb->tdp_stats = itlb->stats_t; - - dtlb->stats_t.readAc.access = dtlb->l_ip.num_search_ports*coredynp.LSU_duty_cycle; - dtlb->stats_t.readAc.miss = 0; - dtlb->stats_t.readAc.hit = dtlb->stats_t.readAc.access - dtlb->stats_t.readAc.miss; - dtlb->tdp_stats = dtlb->stats_t; - } - else - { - //init stats for Runtime Dynamic (RTP) - itlb->stats_t.readAc.access = XML->sys.core[ithCore].itlb.total_accesses; - itlb->stats_t.readAc.miss = XML->sys.core[ithCore].itlb.total_misses; - itlb->stats_t.readAc.hit = itlb->stats_t.readAc.access - itlb->stats_t.readAc.miss; - itlb->rtp_stats = itlb->stats_t; - - dtlb->stats_t.readAc.access = XML->sys.core[ithCore].dtlb.total_accesses; - dtlb->stats_t.readAc.miss = XML->sys.core[ithCore].dtlb.total_misses; - dtlb->stats_t.readAc.hit = dtlb->stats_t.readAc.access - dtlb->stats_t.readAc.miss; - dtlb->rtp_stats = dtlb->stats_t; + dcache.rt_power = dcache.power_t + (dcache.caches->local_result.power + + dcache.missb->local_result.power + + dcache.ifb->local_result.power + + dcache.prefetchb->local_result.power) * + pppm_lkg; + if (cache_p == Write_back) { + dcache.rt_power = + dcache.rt_power + dcache.wbb->local_result.power * pppm_lkg; } - itlb->power_t.reset(); - dtlb->power_t.reset(); - itlb->power_t.readOp.dynamic += itlb->stats_t.readAc.access*itlb->local_result.power.searchOp.dynamic//FA spent most power in tag, so use total access not hits - +itlb->stats_t.readAc.miss*itlb->local_result.power.writeOp.dynamic; - dtlb->power_t.readOp.dynamic += dtlb->stats_t.readAc.access*dtlb->local_result.power.searchOp.dynamic//FA spent most power in tag, so use total access not hits - +dtlb->stats_t.readAc.miss*dtlb->local_result.power.writeOp.dynamic; - - if (is_tdp) - { - itlb->power = itlb->power_t + itlb->local_result.power *pppm_lkg; - dtlb->power = dtlb->power_t + dtlb->local_result.power *pppm_lkg; - power = power + itlb->power + dtlb->power; - } - else - { - itlb->rt_power = itlb->power_t + itlb->local_result.power *pppm_lkg; - dtlb->rt_power = dtlb->power_t + dtlb->local_result.power *pppm_lkg; - rt_power = rt_power + itlb->rt_power + dtlb->rt_power; - } + ccache.rt_power = ccache.power_t + (ccache.caches->local_result.power + + ccache.missb->local_result.power + + ccache.ifb->local_result.power + + ccache.prefetchb->local_result.power) * + pppm_lkg; + if (cache_p == Write_back) { + ccache.rt_power = + ccache.rt_power + ccache.wbb->local_result.power * pppm_lkg; + } -} + tcache.rt_power = tcache.power_t + (tcache.caches->local_result.power + + tcache.missb->local_result.power + + tcache.ifb->local_result.power + + tcache.prefetchb->local_result.power) * + pppm_lkg; + if (cache_p == Write_back) { + tcache.rt_power = + tcache.rt_power + tcache.wbb->local_result.power * pppm_lkg; + } -void MemManU::displayEnergy(uint32_t indent,int plevel,bool is_tdp) -{ - if (!exist) return; - string indent_str(indent, ' '); - string indent_str_next(indent+2, ' '); - bool long_channel = XML->sys.longer_channel_device; - - - - - if (is_tdp) - { - cout << indent_str << "Itlb:" << endl; - cout << indent_str_next << "Area = " << itlb->area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << itlb->power.readOp.dynamic*clockRate << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? itlb->power.readOp.longer_channel_leakage:itlb->power.readOp.leakage) <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << itlb->power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << itlb->rt_power.readOp.dynamic/executionTime << " W" << endl; - cout <rt_power = LSQ->power_t + LSQ->local_result.power * pppm_lkg; + LSQ->rt_power.reset(); + rt_power = rt_power + dcache.rt_power + LSQ->rt_power + + sharedmemory.rt_power + ccache.rt_power + tcache.rt_power; + if ((coredynp.core_ty == OOO) && + (XML->sys.core[ithCore].load_buffer_size > 0)) { + LoadQ->rt_power = LoadQ->power_t + LoadQ->local_result.power * pppm_lkg; + rt_power = rt_power + LoadQ->rt_power; + } + } } -void RegFU::computeEnergy(bool is_tdp) -{ -/* - * Architecture RF and physical RF cannot be present at the same time. - * Therefore, the RF stats can only refer to either ARF or PRF; - * And the same stats can be used for both. - */ - if (!exist) return; - - executionTime=XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6);//Syed - //RF crossbar power (Syed Gilani) - xbar_rfu->compute_power(); +void LoadStoreU::displayEnergy(uint32_t indent, int plevel, bool is_tdp) { + if (!exist) return; + string indent_str(indent, ' '); + string indent_str_next(indent + 2, ' '); + bool long_channel = XML->sys.longer_channel_device; + + if (is_tdp) { + cout << indent_str << "Shared Memory:" << endl; + cout << indent_str_next << "Area = " << sharedmemory.area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << sharedmemory.power.readOp.dynamic * clockRate + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? sharedmemory.power.readOp.longer_channel_leakage + : sharedmemory.power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << sharedmemory.power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << sharedmemory.rt_power.readOp.dynamic / executionTime << " W" + << endl; + cout << endl; + + cout << indent_str << "Data Cache:" << endl; + cout << indent_str_next << "Area = " << dcache.area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << dcache.power.readOp.dynamic * clockRate << " W" + << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? dcache.power.readOp.longer_channel_leakage + : dcache.power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << dcache.power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << dcache.rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << endl; + + cout << indent_str << "Constant Cache:" << endl; + cout << indent_str_next << "Area = " << ccache.area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << ccache.power.readOp.dynamic * clockRate << " W" + << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? dcache.power.readOp.longer_channel_leakage + : dcache.power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << ccache.power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << ccache.rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << indent_str_next + << "Runtime Dynamic Energy = " << ccache.rt_power.readOp.dynamic + << " J" << endl; + cout << indent_str_next << "Execution Time = " << executionTime << " s" + << endl; + cout << endl; + + cout << indent_str << "Texture Cache:" << endl; + cout << indent_str_next << "Area = " << tcache.area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << tcache.power.readOp.dynamic * clockRate << " W" + << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? dcache.power.readOp.longer_channel_leakage + : dcache.power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << tcache.power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << tcache.rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << endl; + + if (coredynp.core_ty == Inorder) { + cout << indent_str << "Load/Store Queue:" << endl; + cout << indent_str_next << "Area = " << LSQ->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << LSQ->power.readOp.dynamic * clockRate << " W" + << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? LSQ->power.readOp.longer_channel_leakage + : LSQ->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << LSQ->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << LSQ->rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << endl; + } else - - //Arbiter power - arbiter_rfu->compute_power(); - - if (is_tdp) - { - //RF power -- modified by Syed - //init stats for Peak - - IRF->stats_t.readAc.access = 4; - IRF->stats_t.writeAc.access = 4; - IRF->tdp_stats = IRF->stats_t; - - IRF->stats_t.readAc.access = 2; - IRF->stats_t.writeAc.access = 1; - IRF->tdp_stats = IRF->stats_t; - - - OPC->stats_t.readAc.access = 32; - OPC->stats_t.writeAc.access = 32; - OPC->tdp_stats = OPC->stats_t; - - //Commented by Syed (GPUs have a single RF which we model by IRF) - //FRF->stats_t.readAc.access = FRF->l_ip.num_rd_ports*coredynp.FPU_duty_cycle*1.05*coredynp.num_fp_pipelines; - //FRF->stats_t.writeAc.access = FRF->l_ip.num_wr_ports*coredynp.FPU_duty_cycle*1.05*coredynp.num_fp_pipelines; - //FRF->tdp_stats = FRF->stats_t; - if (coredynp.regWindowing) - { - RFWIN->stats_t.readAc.access = 0;//0.5*RFWIN->l_ip.num_rw_ports; - RFWIN->stats_t.writeAc.access = 0;//0.5*RFWIN->l_ip.num_rw_ports; - RFWIN->tdp_stats = RFWIN->stats_t; - } - } /* if (is_tdp) */ - else { - //init stats for Runtime Dynamic (RTP) - //in Tesla each RF operand accesses 2 banks, so multiply acceses by 2 - // (read and write energies of reg_file are per bank)(Tesla) : Syed - // Also, for a SIMD width of 8 and warp size of 32 threads, 4 accesses - // (each accessing 2 banks) need to be performed per operand -if (XML->sys.architecture==1){ - IRF->stats_t.readAc.access = (XML->sys.core[ithCore].int_regfile_reads/32)*(4*2);///1.5; - IRF->stats_t.writeAc.access = (XML->sys.core[ithCore].int_regfile_writes/32)*(4*2);///1.5; -} else { - IRF->stats_t.readAc.access = (XML->sys.core[ithCore].int_regfile_reads/32)*(2*4);///1.5;//TODO: no diff on archi and phy - IRF->stats_t.writeAc.access = (XML->sys.core[ithCore].int_regfile_writes/32)*(2*4);///1.5; -} - IRF->rtp_stats = IRF->stats_t; - - OPC->stats_t.readAc.access = (XML->sys.core[ithCore].int_regfile_reads)/*/1.5*/+XML->sys.core[ithCore].non_rf_operands;///1.5;//TODO: no diff on archi and phy - OPC->stats_t.writeAc.access = 0; - OPC->rtp_stats = OPC->stats_t; - - //cout<< "IRF read energy: "<< IRF->local_result.power.readOp.dynamic<local_result.power.writeOp.dynamic<stats_t.readAc.access = XML->sys.core[ithCore].float_regfile_reads; - //FRF->stats_t.writeAc.access = XML->sys.core[ithCore].float_regfile_writes; - //FRF->rtp_stats = FRF->stats_t; - if (coredynp.regWindowing) - { - RFWIN->stats_t.readAc.access = XML->sys.core[ithCore].function_calls*16; - RFWIN->stats_t.writeAc.access = XML->sys.core[ithCore].function_calls*16; - RFWIN->rtp_stats = RFWIN->stats_t; - - IRF->stats_t.readAc.access = XML->sys.core[ithCore].int_regfile_reads + - XML->sys.core[ithCore].function_calls*16; - IRF->stats_t.writeAc.access = XML->sys.core[ithCore].int_regfile_writes + - XML->sys.core[ithCore].function_calls*16; - IRF->rtp_stats = IRF->stats_t; - - } + if (XML->sys.core[ithCore].load_buffer_size > 0) { + cout << indent_str << "LoadQ:" << endl; + cout << indent_str_next << "Area = " << LoadQ->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << LoadQ->power.readOp.dynamic * clockRate + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? LoadQ->power.readOp.longer_channel_leakage + : LoadQ->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << LoadQ->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << LoadQ->rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << endl; + } + cout << indent_str << "StoreQ:" << endl; + cout << indent_str_next << "Area = " << LSQ->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << LSQ->power.readOp.dynamic * clockRate << " W" + << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? LSQ->power.readOp.longer_channel_leakage + : LSQ->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << LSQ->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << LSQ->rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << endl; + } + } else { + cout << indent_str_next << "Shared Memory Peak Dynamic = " + << sharedmemory.rt_power.readOp.dynamic * clockRate << " W" << endl; + cout << indent_str_next << "Shared Memory Subthreshold Leakage = " + << sharedmemory.rt_power.readOp.leakage << " W" << endl; + cout << indent_str_next << "Shared Memory Gate Leakage = " + << sharedmemory.rt_power.readOp.gate_leakage << " W" << endl; + + cout << indent_str_next << "Data Cache Peak Dynamic = " + << dcache.rt_power.readOp.dynamic * clockRate << " W" << endl; + cout << indent_str_next << "Data Cache Subthreshold Leakage = " + << dcache.rt_power.readOp.leakage << " W" << endl; + cout << indent_str_next << "Data Cache Gate Leakage = " + << dcache.rt_power.readOp.gate_leakage << " W" << endl; + + cout << indent_str_next << "Constant Cache Peak Dynamic = " + << ccache.rt_power.readOp.dynamic * clockRate << " W" << endl; + cout << indent_str_next << "Constant Cache Subthreshold Leakage = " + << ccache.rt_power.readOp.leakage << " W" << endl; + cout << indent_str_next << "Constant Cache Gate Leakage = " + << ccache.rt_power.readOp.gate_leakage << " W" << endl; + + cout << indent_str_next << "Texture Cache Peak Dynamic = " + << tcache.rt_power.readOp.dynamic * clockRate << " W" << endl; + cout << indent_str_next << "Texture Cache Subthreshold Leakage = " + << tcache.rt_power.readOp.leakage << " W" << endl; + cout << indent_str_next << "Texture Cache Gate Leakage = " + << tcache.rt_power.readOp.gate_leakage << " W" << endl; + + if (coredynp.core_ty == Inorder) { + cout << indent_str_next << "Load/Store Queue Peak Dynamic = " + << LSQ->rt_power.readOp.dynamic * clockRate << " W" << endl; + cout << indent_str_next << "Load/Store Queue Subthreshold Leakage = " + << LSQ->rt_power.readOp.leakage << " W" << endl; + cout << indent_str_next << "Load/Store Queue Gate Leakage = " + << LSQ->rt_power.readOp.gate_leakage << " W" << endl; + } else { + cout << indent_str_next << "LoadQ Peak Dynamic = " + << LoadQ->rt_power.readOp.dynamic * clockRate << " W" << endl; + cout << indent_str_next << "LoadQ Subthreshold Leakage = " + << LoadQ->rt_power.readOp.leakage << " W" << endl; + cout << indent_str_next + << "LoadQ Gate Leakage = " << LoadQ->rt_power.readOp.gate_leakage + << " W" << endl; + cout << indent_str_next << "StoreQ Peak Dynamic = " + << LSQ->rt_power.readOp.dynamic * clockRate << " W" << endl; + cout << indent_str_next + << "StoreQ Subthreshold Leakage = " << LSQ->rt_power.readOp.leakage + << " W" << endl; + cout << indent_str_next + << "StoreQ Gate Leakage = " << LSQ->rt_power.readOp.gate_leakage + << " W" << endl; } - IRF->power_t.reset(); - FRF->power_t.reset(); - OPC->power_t.reset(); - //IRF->power_t = IRF->power_t + IRF->local_result.power;// + xbar_rfu->power + arbiter_rfu->power; - - - - IRF->power_t.readOp.dynamic = (IRF->stats_t.readAc.access*IRF->local_result.power.readOp.dynamic - +IRF->stats_t.writeAc.access*IRF->local_result.power.writeOp.dynamic); - OPC->power_t.readOp.dynamic = (OPC->stats_t.readAc.access*OPC->local_result.power.readOp.dynamic); - - if (coredynp.regWindowing) - { - RFWIN->power_t.reset(); - RFWIN->power_t.readOp.dynamic += (RFWIN->stats_t.readAc.access*RFWIN->local_result.power.readOp.dynamic + - RFWIN->stats_t.writeAc.access*RFWIN->local_result.power.writeOp.dynamic); - } - - if (is_tdp) - { - - //cout<<"pre: IRF_power_t: "<power.readOp.dynamic<<" ("<power.readOp.dynamic*clockRate<<") "<<" IRF_localresult: "<< - // IRF->local_result.power.readOp.dynamic<power = FRF->power_t + FRF->local_result.power *coredynp.pppm_lkg_multhread; - - double pppm_lkg_banks[4]; - set_pppm(pppm_lkg_banks, 0,XML->sys.core[ithCore].collector_units,XML->sys.core[ithCore].collector_units ); - IRF->power = (IRF->power_t) + IRF->local_result.power*pppm_lkg; - IRF->power.readOp.dynamic=IRF->power_t.readOp.dynamic*1; - OPC->power = (OPC->power_t) + OPC->local_result.power *pppm_lkg_banks; - OPC->power.readOp.dynamic=OPC->power_t.readOp.dynamic*1; - - - power = power + (IRF->power+OPC->power); - - - if (coredynp.regWindowing) - { - RFWIN->power = RFWIN->power_t + RFWIN->local_result.power *pppm_lkg; - power = power + RFWIN->power; - } - } /* if (is_tdp) */ - else - { - //Removed *coredynp.pppm_lkg_multhread since all hardware threads shared the same IRF - IRF->rt_power = IRF->power_t + IRF->local_result.power*pppm_lkg;/* *coredynp.pppm_lkg_multhread;*/ - OPC->rt_power = OPC->power_t + OPC->local_result.power*pppm_lkg; -if(XML->sys.architecture==1){ - //Each warp operand accesses the crossbar - xbar_rfu->rt_power.readOp.dynamic=((XML->sys.core[ithCore].int_regfile_reads/(32/**1.5*/))+(XML->sys.core[ithCore].non_rf_operands/(32/**1.5*/)))*xbar_rfu->power.readOp.dynamic; -} else { - xbar_rfu->rt_power.readOp.dynamic=((XML->sys.core[ithCore].int_regfile_reads/(32/**1.5*/))+(XML->sys.core[ithCore].non_rf_operands/(32/**1.5*/)))*xbar_rfu->power.readOp.dynamic; + } } - arbiter_rfu->rt_power.readOp.dynamic=((XML->sys.core[ithCore].int_regfile_reads/(32/**1.5*/))+(XML->sys.core[ithCore].non_rf_operands/(32/**1.5*/)))*arbiter_rfu->power.readOp.dynamic; +void MemManU::computeEnergy(bool is_tdp) { + if (!exist) return; + if (is_tdp) { + // init stats for Peak + itlb->stats_t.readAc.access = itlb->l_ip.num_search_ports; + itlb->stats_t.readAc.miss = 0; + itlb->stats_t.readAc.hit = + itlb->stats_t.readAc.access - itlb->stats_t.readAc.miss; + itlb->tdp_stats = itlb->stats_t; + + dtlb->stats_t.readAc.access = + dtlb->l_ip.num_search_ports * coredynp.LSU_duty_cycle; + dtlb->stats_t.readAc.miss = 0; + dtlb->stats_t.readAc.hit = + dtlb->stats_t.readAc.access - dtlb->stats_t.readAc.miss; + dtlb->tdp_stats = dtlb->stats_t; + } else { + // init stats for Runtime Dynamic (RTP) + itlb->stats_t.readAc.access = XML->sys.core[ithCore].itlb.total_accesses; + itlb->stats_t.readAc.miss = XML->sys.core[ithCore].itlb.total_misses; + itlb->stats_t.readAc.hit = + itlb->stats_t.readAc.access - itlb->stats_t.readAc.miss; + itlb->rtp_stats = itlb->stats_t; + + dtlb->stats_t.readAc.access = XML->sys.core[ithCore].dtlb.total_accesses; + dtlb->stats_t.readAc.miss = XML->sys.core[ithCore].dtlb.total_misses; + dtlb->stats_t.readAc.hit = + dtlb->stats_t.readAc.access - dtlb->stats_t.readAc.miss; + dtlb->rtp_stats = dtlb->stats_t; + } - rt_power = rt_power + (IRF->power_t /*+ FRF->power_t*/+xbar_rfu->rt_power+arbiter_rfu->rt_power+OPC->power_t); - if (coredynp.regWindowing) - { - RFWIN->rt_power = RFWIN->power_t + RFWIN->local_result.power *pppm_lkg; - rt_power = rt_power + RFWIN->rt_power; - } - } + itlb->power_t.reset(); + dtlb->power_t.reset(); + itlb->power_t.readOp.dynamic += + itlb->stats_t.readAc.access * + itlb->local_result.power.searchOp + .dynamic // FA spent most power in tag, + // so use total access not hits + + itlb->stats_t.readAc.miss * itlb->local_result.power.writeOp.dynamic; + dtlb->power_t.readOp.dynamic += + dtlb->stats_t.readAc.access * + dtlb->local_result.power.searchOp + .dynamic // FA spent most power in tag, + // so use total access not hits + + dtlb->stats_t.readAc.miss * dtlb->local_result.power.writeOp.dynamic; + + if (is_tdp) { + itlb->power = itlb->power_t + itlb->local_result.power * pppm_lkg; + dtlb->power = dtlb->power_t + dtlb->local_result.power * pppm_lkg; + power = power + itlb->power + dtlb->power; + } else { + itlb->rt_power = itlb->power_t + itlb->local_result.power * pppm_lkg; + dtlb->rt_power = dtlb->power_t + dtlb->local_result.power * pppm_lkg; + rt_power = rt_power + itlb->rt_power + dtlb->rt_power; + } } - -void RegFU::displayEnergy(uint32_t indent,int plevel,bool is_tdp) -{ - if (!exist) return; - string indent_str(indent, ' '); - string indent_str_next(indent+2, ' '); - bool long_channel = XML->sys.longer_channel_device; - - if (is_tdp) - { cout << indent_str << "Register file banks: " << endl; - cout << indent_str_next << "Area = " << IRF->area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << IRF->power.readOp.dynamic*clockRate << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? IRF->power.readOp.longer_channel_leakage:IRF->power.readOp.leakage) <<" W" << endl; - - cout << indent_str_next << "Gate Leakage = " << IRF->power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << IRF->rt_power.readOp.dynamic/executionTime << " W" << endl; - cout <sys.longer_channel_device; + + if (is_tdp) { + cout << indent_str << "Itlb:" << endl; + cout << indent_str_next << "Area = " << itlb->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << itlb->power.readOp.dynamic * clockRate << " W" + << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? itlb->power.readOp.longer_channel_leakage + : itlb->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << itlb->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << itlb->rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << endl; + cout << indent_str << "Dtlb:" << endl; + cout << indent_str_next << "Area = " << dtlb->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << dtlb->power.readOp.dynamic * clockRate << " W" + << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? dtlb->power.readOp.longer_channel_leakage + : dtlb->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << dtlb->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << dtlb->rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << endl; + } else { + cout << indent_str_next << "Itlb Peak Dynamic = " + << itlb->rt_power.readOp.dynamic * clockRate << " W" << endl; + cout << indent_str_next + << "Itlb Subthreshold Leakage = " << itlb->rt_power.readOp.leakage + << " W" << endl; + cout << indent_str_next + << "Itlb Gate Leakage = " << itlb->rt_power.readOp.gate_leakage + << " W" << endl; + cout << indent_str_next << "Dtlb Peak Dynamic = " + << dtlb->rt_power.readOp.dynamic * clockRate << " W" << endl; + cout << indent_str_next + << "Dtlb Subthreshold Leakage = " << dtlb->rt_power.readOp.leakage + << " W" << endl; + cout << indent_str_next + << "Dtlb Gate Leakage = " << dtlb->rt_power.readOp.gate_leakage + << " W" << endl; + } } +void RegFU::computeEnergy(bool is_tdp) { + /* + * Architecture RF and physical RF cannot be present at the same time. + * Therefore, the RF stats can only refer to either ARF or PRF; + * And the same stats can be used for both. + */ + if (!exist) return; + + executionTime = + XML->sys.total_cycles / (XML->sys.target_core_clockrate * 1e6); // Syed + // RF crossbar power (Syed Gilani) + xbar_rfu->compute_power(); + + // Arbiter power + arbiter_rfu->compute_power(); + + if (is_tdp) { + // RF power -- modified by Syed + // init stats for Peak + + IRF->stats_t.readAc.access = 4; + IRF->stats_t.writeAc.access = 4; + IRF->tdp_stats = IRF->stats_t; + + IRF->stats_t.readAc.access = 2; + IRF->stats_t.writeAc.access = 1; + IRF->tdp_stats = IRF->stats_t; + + OPC->stats_t.readAc.access = 32; + OPC->stats_t.writeAc.access = 32; + OPC->tdp_stats = OPC->stats_t; + + // Commented by Syed (GPUs have a single RF which we model by IRF) + // FRF->stats_t.readAc.access = + // FRF->l_ip.num_rd_ports*coredynp.FPU_duty_cycle*1.05*coredynp.num_fp_pipelines; + // FRF->stats_t.writeAc.access = + // FRF->l_ip.num_wr_ports*coredynp.FPU_duty_cycle*1.05*coredynp.num_fp_pipelines; + // FRF->tdp_stats = FRF->stats_t; + if (coredynp.regWindowing) { + RFWIN->stats_t.readAc.access = 0; // 0.5*RFWIN->l_ip.num_rw_ports; + RFWIN->stats_t.writeAc.access = 0; // 0.5*RFWIN->l_ip.num_rw_ports; + RFWIN->tdp_stats = RFWIN->stats_t; + } + } /* if (is_tdp) */ + else { + // init stats for Runtime Dynamic (RTP) + // in Tesla each RF operand accesses 2 banks, so multiply acceses by 2 + // (read and write energies of reg_file are per bank)(Tesla) : Syed + // Also, for a SIMD width of 8 and warp size of 32 threads, 4 accesses + // (each accessing 2 banks) need to be performed per operand + if (XML->sys.architecture == 1) { + IRF->stats_t.readAc.access = + (XML->sys.core[ithCore].int_regfile_reads / 32) * (4 * 2); /// 1.5; + IRF->stats_t.writeAc.access = + (XML->sys.core[ithCore].int_regfile_writes / 32) * (4 * 2); /// 1.5; + } else { + IRF->stats_t.readAc.access = + (XML->sys.core[ithCore].int_regfile_reads / 32) * + (2 * 4); /// 1.5;//TODO: no diff on archi and phy + IRF->stats_t.writeAc.access = + (XML->sys.core[ithCore].int_regfile_writes / 32) * (2 * 4); /// 1.5; + } + IRF->rtp_stats = IRF->stats_t; + + OPC->stats_t.readAc.access = + (XML->sys.core[ithCore].int_regfile_reads) /*/1.5*/ + + XML->sys.core[ithCore] + .non_rf_operands; /// 1.5;//TODO: no diff on archi and phy + OPC->stats_t.writeAc.access = 0; + OPC->rtp_stats = OPC->stats_t; + + // cout<< "IRF read energy: "<< + // IRF->local_result.power.readOp.dynamic<local_result.power.writeOp.dynamic<stats_t.readAc.access = XML->sys.core[ithCore].float_regfile_reads; + // FRF->stats_t.writeAc.access = + // XML->sys.core[ithCore].float_regfile_writes; FRF->rtp_stats = + // FRF->stats_t; + if (coredynp.regWindowing) { + RFWIN->stats_t.readAc.access = XML->sys.core[ithCore].function_calls * 16; + RFWIN->stats_t.writeAc.access = + XML->sys.core[ithCore].function_calls * 16; + RFWIN->rtp_stats = RFWIN->stats_t; + + IRF->stats_t.readAc.access = XML->sys.core[ithCore].int_regfile_reads + + XML->sys.core[ithCore].function_calls * 16; + IRF->stats_t.writeAc.access = XML->sys.core[ithCore].int_regfile_writes + + XML->sys.core[ithCore].function_calls * 16; + IRF->rtp_stats = IRF->stats_t; + } + } + IRF->power_t.reset(); + FRF->power_t.reset(); + OPC->power_t.reset(); + // IRF->power_t = IRF->power_t + IRF->local_result.power;// + + // xbar_rfu->power + arbiter_rfu->power; + + IRF->power_t.readOp.dynamic = + (IRF->stats_t.readAc.access * IRF->local_result.power.readOp.dynamic + + IRF->stats_t.writeAc.access * IRF->local_result.power.writeOp.dynamic); + OPC->power_t.readOp.dynamic = + (OPC->stats_t.readAc.access * OPC->local_result.power.readOp.dynamic); + + if (coredynp.regWindowing) { + RFWIN->power_t.reset(); + RFWIN->power_t.readOp.dynamic += + (RFWIN->stats_t.readAc.access * + RFWIN->local_result.power.readOp.dynamic + + RFWIN->stats_t.writeAc.access * + RFWIN->local_result.power.writeOp.dynamic); + } + + if (is_tdp) { + // cout<<"pre: IRF_power_t: "<power.readOp.dynamic<<" + // ("<power.readOp.dynamic*clockRate<<") "<<" IRF_localresult: "<< + // IRF->local_result.power.readOp.dynamic<power = FRF->power_t + FRF->local_result.power + // *coredynp.pppm_lkg_multhread; + + double pppm_lkg_banks[4]; + set_pppm(pppm_lkg_banks, 0, XML->sys.core[ithCore].collector_units, + XML->sys.core[ithCore].collector_units); + IRF->power = (IRF->power_t) + IRF->local_result.power * pppm_lkg; + IRF->power.readOp.dynamic = IRF->power_t.readOp.dynamic * 1; + OPC->power = (OPC->power_t) + OPC->local_result.power * pppm_lkg_banks; + OPC->power.readOp.dynamic = OPC->power_t.readOp.dynamic * 1; + + power = power + (IRF->power + OPC->power); + + if (coredynp.regWindowing) { + RFWIN->power = RFWIN->power_t + RFWIN->local_result.power * pppm_lkg; + power = power + RFWIN->power; + } + } /* if (is_tdp) */ + else { + // Removed *coredynp.pppm_lkg_multhread since all hardware threads shared + // the same IRF + IRF->rt_power = + IRF->power_t + + IRF->local_result.power * pppm_lkg; /* *coredynp.pppm_lkg_multhread;*/ + OPC->rt_power = OPC->power_t + OPC->local_result.power * pppm_lkg; + if (XML->sys.architecture == 1) { + // Each warp operand accesses the crossbar + xbar_rfu->rt_power.readOp.dynamic = + ((XML->sys.core[ithCore].int_regfile_reads / (32 /**1.5*/)) + + (XML->sys.core[ithCore].non_rf_operands / (32 /**1.5*/))) * + xbar_rfu->power.readOp.dynamic; + } else { + xbar_rfu->rt_power.readOp.dynamic = + ((XML->sys.core[ithCore].int_regfile_reads / (32 /**1.5*/)) + + (XML->sys.core[ithCore].non_rf_operands / (32 /**1.5*/))) * + xbar_rfu->power.readOp.dynamic; + } + arbiter_rfu->rt_power.readOp.dynamic = + ((XML->sys.core[ithCore].int_regfile_reads / (32 /**1.5*/)) + + (XML->sys.core[ithCore].non_rf_operands / (32 /**1.5*/))) * + arbiter_rfu->power.readOp.dynamic; + + rt_power = + rt_power + (IRF->power_t /*+ FRF->power_t*/ + xbar_rfu->rt_power + + arbiter_rfu->rt_power + OPC->power_t); + if (coredynp.regWindowing) { + RFWIN->rt_power = RFWIN->power_t + RFWIN->local_result.power * pppm_lkg; + rt_power = rt_power + RFWIN->rt_power; + } + } +} -void EXECU::computeEnergy(bool is_tdp) -{ - if (!exist) return; - //Syed - double pppm_t[4] = {1,1,1,1}; - double pppm_freqScaling[4] = {rf_fu_clockRate/clockRate,1,1,1}; - executionTime=XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6);//Syed +void RegFU::displayEnergy(uint32_t indent, int plevel, bool is_tdp) { + if (!exist) return; + string indent_str(indent, ' '); + string indent_str_next(indent + 2, ' '); + bool long_channel = XML->sys.longer_channel_device; + + if (is_tdp) { + cout << indent_str << "Register file banks: " << endl; + cout << indent_str_next << "Area = " << IRF->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << IRF->power.readOp.dynamic * clockRate << " W" + << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? IRF->power.readOp.longer_channel_leakage + : IRF->power.readOp.leakage) + << " W" << endl; + + cout << indent_str_next + << "Gate Leakage = " << IRF->power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next + << "Runtime Dynamic = " << IRF->rt_power.readOp.dynamic / executionTime + << " W" << endl; + cout << endl; + cout << indent_str << "Crossbar (Integer RF):" << endl; + cout << indent_str_next << "Area = " << xbar_rfu->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << xbar_rfu->power.readOp.dynamic * clockRate + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? xbar_rfu->power.readOp.longer_channel_leakage + : xbar_rfu->power.readOp.leakage) + << " W" << endl; + + cout << indent_str_next + << "Gate Leakage = " << xbar_rfu->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << xbar_rfu->rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << endl; + + cout << indent_str << "Arbiter (Integer RF):" << endl; + cout << indent_str_next << "Area = " << arbiter_rfu->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << arbiter_rfu->power.readOp.dynamic * clockRate + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? arbiter_rfu->power.readOp.longer_channel_leakage + : arbiter_rfu->power.readOp.leakage) + << " W" << endl; + + cout << indent_str_next + << "Gate Leakage = " << arbiter_rfu->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << arbiter_rfu->rt_power.readOp.dynamic / executionTime << " W" + << endl; + cout << endl; + + /* + cout << indent_str<< "Floating Point RF:" << endl; + cout << indent_str_next << "Area = " << FRF->area.get_area()*1e-6 << " + mm^2" << endl; cout << indent_str_next << "Peak Dynamic = " << + FRF->power.readOp.dynamic*clockRate << " W" << endl; cout << + indent_str_next << "Subthreshold Leakage = " + << (long_channel? + FRF->power.readOp.longer_channel_leakage:FRF->power.readOp.leakage) << " W" + << endl; cout << indent_str_next << "Gate Leakage = " << + FRF->power.readOp.gate_leakage << " W" << endl; cout << indent_str_next << + "Runtime Dynamic = " << FRF->rt_power.readOp.dynamic/executionTime << " W" + << endl; cout <sys.total_cycles / (XML->sys.target_core_clockrate * 1e6); // Syed -// rfu->power.reset(); + // rfu->power.reset(); rfu->rt_power.reset(); -// scheu->power.reset(); - scheu->rt_power.reset(); -// exeu->power.reset(); - exeu->rt_power.reset(); - - rfu->computeEnergy(is_tdp); - scheu->computeEnergy(is_tdp); - exeu->computeEnergy(is_tdp); - if (coredynp.num_fpus >0) - { + // scheu->power.reset(); + scheu->rt_power.reset(); + // exeu->power.reset(); + exeu->rt_power.reset(); + + rfu->computeEnergy(is_tdp); + scheu->computeEnergy(is_tdp); + exeu->computeEnergy(is_tdp); + if (coredynp.num_fpus > 0) { fp_u->rt_power.reset(); - fp_u->computeEnergy(is_tdp); - } - if (coredynp.num_muls >0) - { + fp_u->computeEnergy(is_tdp); + } + if (coredynp.num_muls > 0) { mul->rt_power.reset(); - mul->computeEnergy(is_tdp); - } + mul->computeEnergy(is_tdp); + } bypass.rt_power.reset(); - if (is_tdp) - { - set_pppm(pppm_t, 2*coredynp.ALU_cdb_duty_cycle, 2, 2, 2*coredynp.ALU_cdb_duty_cycle);//2 means two source operands needs to be passed for each int instruction. - //bypass.power = bypass.power + intTagBypass->power*pppm_t + int_bypass->power*pppm_t; - if (coredynp.num_muls >0) - { - set_pppm(pppm_t, 2*coredynp.MUL_cdb_duty_cycle, 2, 2, 2*coredynp.MUL_cdb_duty_cycle);//2 means two source operands needs to be passed for each int instruction. - //No conventional bypassing in GPU (Syed) - //bypass.power = bypass.power + intTag_mul_Bypass->power*pppm_t + int_mul_bypass->power*pppm_t; - power = power + mul->power*pppm_freqScaling; - } - - if (coredynp.num_fpus>0) - { - set_pppm(pppm_t, 3*coredynp.FPU_cdb_duty_cycle, 3, 3, 3*coredynp.FPU_cdb_duty_cycle);//3 means three source operands needs to be passed for each fp instruction. - //No conventional bypassing in GPU (Syed) - //bypass.power = bypass.power + fp_bypass->power*pppm_t + fpTagBypass->power*pppm_t ; - power = power + fp_u->power*pppm_freqScaling; - - } - //No conventional bypassing in GPU (Syed) - - power = power + rfu->power*pppm_freqScaling + exeu->power*pppm_freqScaling /*+ bypass.power*/ + scheu->power - ; - - - } - else - { - set_pppm(pppm_t, XML->sys.core[ithCore].cdb_alu_accesses, 2, 2, XML->sys.core[ithCore].cdb_alu_accesses); - //bypass.rt_power = bypass.rt_power + intTagBypass->power*pppm_t; - //bypass.rt_power = bypass.rt_power + int_bypass->power*pppm_t; - - if (coredynp.num_muls >0) - { - set_pppm(pppm_t, XML->sys.core[ithCore].cdb_mul_accesses, 2, 2, XML->sys.core[ithCore].cdb_mul_accesses);//2 means two source operands needs to be passed for each int instruction. - //bypass.rt_power = bypass.rt_power + intTag_mul_Bypass->power*pppm_t + int_mul_bypass->power*pppm_t; - rt_power = rt_power + mul->rt_power; - } - - if (coredynp.num_fpus>0) - { - set_pppm(pppm_t, XML->sys.core[ithCore].cdb_fpu_accesses, 3, 3, XML->sys.core[ithCore].cdb_fpu_accesses); - //bypass.rt_power = bypass.rt_power + fp_bypass->power*pppm_t; - //bypass.rt_power = bypass.rt_power + fpTagBypass->power*pppm_t; - rt_power = rt_power + fp_u->rt_power; - } - //No conventional bypassing in GPU (Syed) - rt_power = rt_power + rfu->rt_power*pppm_freqScaling + exeu->rt_power*pppm_freqScaling + /*bypass.rt_power +*/ scheu->rt_power; - } -} + if (is_tdp) { + set_pppm( + pppm_t, 2 * coredynp.ALU_cdb_duty_cycle, 2, 2, + 2 * coredynp + .ALU_cdb_duty_cycle); // 2 means two source operands needs to + // be passed for each int instruction. + // bypass.power = bypass.power + intTagBypass->power*pppm_t + + // int_bypass->power*pppm_t; + if (coredynp.num_muls > 0) { + set_pppm( + pppm_t, 2 * coredynp.MUL_cdb_duty_cycle, 2, 2, + 2 * coredynp + .MUL_cdb_duty_cycle); // 2 means two source operands needs to + // be passed for each int instruction. + // No conventional bypassing in GPU (Syed) + // bypass.power = bypass.power + intTag_mul_Bypass->power*pppm_t + + // int_mul_bypass->power*pppm_t; + power = power + mul->power * pppm_freqScaling; + } -void EXECU::displayEnergy(uint32_t indent,int plevel,bool is_tdp) -{ - if (!exist) return; - 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) - { - cout << indent_str << "Register Files:" << endl; - cout << indent_str_next << "Area = " << rfu->area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << rfu->power.readOp.dynamic*rf_fu_clockRate << " W" << endl; - //cout << "rf_fu Clock rate: "<< rf_fu_clockRate<3){ - rfu->displayEnergy(indent+4,is_tdp); - } - cout << indent_str << "Instruction Scheduler:" << endl; - cout << indent_str_next << "Area = " << scheu->area.get_area()*1e-6 << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << scheu->power.readOp.dynamic*clockRate << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? scheu->power.readOp.longer_channel_leakage:scheu->power.readOp.leakage) << " W" << endl; - cout << indent_str_next << "Gate Leakage = " << scheu->power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << scheu->rt_power.readOp.dynamic/executionTime << " W" << endl; - cout <3){ - scheu->displayEnergy(indent+4,is_tdp); - } - exeu->displayEnergy(indent,is_tdp); - if (coredynp.num_fpus>0) - { - fp_u->displayEnergy(indent,is_tdp); - } - if (coredynp.num_muls >0) - { - mul->displayEnergy(indent,is_tdp); - } - cout << indent_str << "Results Broadcast Bus:" << endl; - cout << indent_str_next << "Area Overhead = " << bypass.area.get_area()*1e-6 << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << bypass.power.readOp.dynamic*clockRate << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? bypass.power.readOp.longer_channel_leakage:bypass.power.readOp.leakage ) << " W" << endl; - cout << indent_str_next << "Gate Leakage = " << bypass.power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << bypass.rt_power.readOp.dynamic/executionTime << " W" << endl; - cout < 0) { + set_pppm(pppm_t, 3 * coredynp.FPU_cdb_duty_cycle, 3, 3, + 3 * coredynp.FPU_cdb_duty_cycle); // 3 means three source + // operands needs to be passed + // for each fp instruction. + // No conventional bypassing in GPU (Syed) + // bypass.power = bypass.power + fp_bypass->power*pppm_t + + // fpTagBypass->power*pppm_t ; + power = power + fp_u->power * pppm_freqScaling; + } + // No conventional bypassing in GPU (Syed) + + power = power + rfu->power * pppm_freqScaling + + exeu->power * pppm_freqScaling /*+ bypass.power*/ + scheu->power; + + } else { + set_pppm(pppm_t, XML->sys.core[ithCore].cdb_alu_accesses, 2, 2, + XML->sys.core[ithCore].cdb_alu_accesses); + // bypass.rt_power = bypass.rt_power + intTagBypass->power*pppm_t; + // bypass.rt_power = bypass.rt_power + int_bypass->power*pppm_t; + + if (coredynp.num_muls > 0) { + set_pppm(pppm_t, XML->sys.core[ithCore].cdb_mul_accesses, 2, 2, + XML->sys.core[ithCore] + .cdb_mul_accesses); // 2 means two source operands needs to + // be passed for each int instruction. + // bypass.rt_power = bypass.rt_power + intTag_mul_Bypass->power*pppm_t + + // int_mul_bypass->power*pppm_t; + rt_power = rt_power + mul->rt_power; + } + if (coredynp.num_fpus > 0) { + set_pppm(pppm_t, XML->sys.core[ithCore].cdb_fpu_accesses, 3, 3, + XML->sys.core[ithCore].cdb_fpu_accesses); + // bypass.rt_power = bypass.rt_power + fp_bypass->power*pppm_t; + // bypass.rt_power = bypass.rt_power + fpTagBypass->power*pppm_t; + rt_power = rt_power + fp_u->rt_power; + } + // No conventional bypassing in GPU (Syed) + rt_power = rt_power + rfu->rt_power * pppm_freqScaling + + exeu->rt_power * pppm_freqScaling + + /*bypass.rt_power +*/ scheu->rt_power; + } +} + +void EXECU::displayEnergy(uint32_t indent, int plevel, bool is_tdp) { + if (!exist) return; + 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) { + cout << indent_str << "Register Files:" << endl; + cout << indent_str_next << "Area = " << rfu->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << rfu->power.readOp.dynamic * rf_fu_clockRate + << " W" << endl; + // cout << "rf_fu Clock rate: "<< rf_fu_clockRate< 3) { + rfu->displayEnergy(indent + 4, is_tdp); + } + cout << indent_str << "Instruction Scheduler:" << endl; + cout << indent_str_next << "Area = " << scheu->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << scheu->power.readOp.dynamic * clockRate << " W" + << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? scheu->power.readOp.longer_channel_leakage + : scheu->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << scheu->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << scheu->rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << endl; + if (plevel > 3) { + scheu->displayEnergy(indent + 4, is_tdp); + } + exeu->displayEnergy(indent, is_tdp); + if (coredynp.num_fpus > 0) { + fp_u->displayEnergy(indent, is_tdp); + } + if (coredynp.num_muls > 0) { + mul->displayEnergy(indent, is_tdp); + } + cout << indent_str << "Results Broadcast Bus:" << endl; + cout << indent_str_next + << "Area Overhead = " << bypass.area.get_area() * 1e-6 << " mm^2" + << endl; + cout << indent_str_next + << "Peak Dynamic = " << bypass.power.readOp.dynamic * clockRate << " W" + << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? bypass.power.readOp.longer_channel_leakage + : bypass.power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << bypass.power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << bypass.rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << endl; + } else { + cout << indent_str_next << "Register Files Peak Dynamic = " + << rfu->rt_power.readOp.dynamic * clockRate << " W" << endl; + cout << indent_str_next << "Register Files Subthreshold Leakage = " + << rfu->rt_power.readOp.leakage << " W" << endl; + cout << indent_str_next << "Register Files Gate Leakage = " + << rfu->rt_power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Instruction Sheduler Peak Dynamic = " + << scheu->rt_power.readOp.dynamic * clockRate << " W" << endl; + cout << indent_str_next << "Instruction Sheduler Subthreshold Leakage = " + << scheu->rt_power.readOp.leakage << " W" << endl; + cout << indent_str_next << "Instruction Sheduler Gate Leakage = " + << scheu->rt_power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Results Broadcast Bus Peak Dynamic = " + << bypass.rt_power.readOp.dynamic * clockRate << " W" << endl; + cout << indent_str_next << "Results Broadcast Bus Subthreshold Leakage = " + << bypass.rt_power.readOp.leakage << " W" << endl; + cout << indent_str_next << "Results Broadcast Bus Gate Leakage = " + << bypass.rt_power.readOp.gate_leakage << " W" << endl; + } } +// Jingwen +void Core::compute() { + // power_point_product_masks + double pppm_t[4] = {1, 1, 1, 1}; + double rtp_pipeline_coe; + double num_units = 4.0; + Pipeline_energy = 0; + + // Set pipeline duty cycle for this inteval + coredynp.pipeline_duty_cycle = XML->sys.core[ithCore].pipeline_duty_cycle; + rt_power.reset(); + ifu->rt_power.reset(); + lsu->rt_power.reset(); + mmu->rt_power.reset(); + exu->rt_power.reset(); + + ifu->computeEnergy(false); + lsu->computeEnergy(false); + mmu->computeEnergy(false); + exu->computeEnergy(false); + + if (XML->sys.homogeneous_cores == 1) { + rtp_pipeline_coe = coredynp.pipeline_duty_cycle * XML->sys.total_cycles * + XML->sys.number_of_cores; + } else { + rtp_pipeline_coe = coredynp.pipeline_duty_cycle * coredynp.total_cycles; + // Jingwen + if (coredynp.total_cycles != XML->sys.total_cycles) { + cout << "total cycle not match!" << endl; + exit(1); + } + } + set_pppm(pppm_t, coredynp.num_pipelines * rtp_pipeline_coe / num_units, + coredynp.num_pipelines / num_units, + coredynp.num_pipelines / num_units, + coredynp.num_pipelines / num_units); + if (ifu->exist) { + Pipeline_energy += corepipe->power.readOp.dynamic * + (coredynp.num_pipelines * rtp_pipeline_coe / num_units); + ifu->rt_power = ifu->rt_power + corepipe->power * pppm_t; + rt_power = rt_power + ifu->rt_power; + } + if (lsu->exist) { + Pipeline_energy += corepipe->power.readOp.dynamic * + (coredynp.num_pipelines * rtp_pipeline_coe / num_units); + lsu->rt_power = lsu->rt_power + corepipe->power * pppm_t; + rt_power = rt_power + lsu->rt_power; + } + if (exu->exist) { + Pipeline_energy += corepipe->power.readOp.dynamic * + (coredynp.num_pipelines * rtp_pipeline_coe / num_units); + exu->rt_power = exu->rt_power + corepipe->power * pppm_t; + rt_power = rt_power + exu->rt_power; + } + if (mmu->exist) { + Pipeline_energy += corepipe->power.readOp.dynamic * + (coredynp.num_pipelines * rtp_pipeline_coe / num_units); + mmu->rt_power = mmu->rt_power + corepipe->power * pppm_t; + rt_power = rt_power + mmu->rt_power; + } + rt_power = rt_power + undiffCore->power; -//Jingwen -void Core::compute() -{ - //power_point_product_masks - double pppm_t[4] = {1,1,1,1}; - double rtp_pipeline_coe; - double num_units = 4.0; - Pipeline_energy=0; + if (XML->sys.Private_L2) { + l2cache->computeEnergy(false); + rt_power = rt_power + l2cache->rt_power; + } - //Set pipeline duty cycle for this inteval - coredynp.pipeline_duty_cycle=XML->sys.core[ithCore].pipeline_duty_cycle; - rt_power.reset(); - ifu->rt_power.reset(); - lsu->rt_power.reset(); - mmu->rt_power.reset(); - exu->rt_power.reset(); - - - ifu->computeEnergy(false); - lsu->computeEnergy(false); - mmu->computeEnergy(false); - exu->computeEnergy(false); - - - if (XML->sys.homogeneous_cores==1) - { - rtp_pipeline_coe = coredynp.pipeline_duty_cycle * XML->sys.total_cycles * XML->sys.number_of_cores; - } - else - { - - rtp_pipeline_coe = coredynp.pipeline_duty_cycle * coredynp.total_cycles; - //Jingwen - if (coredynp.total_cycles != XML->sys.total_cycles) - { - cout << "total cycle not match!" << endl; - exit(1); - } - } - - set_pppm(pppm_t, coredynp.num_pipelines*rtp_pipeline_coe/num_units, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units); - - if (ifu->exist) - { - Pipeline_energy+=corepipe->power.readOp.dynamic* (coredynp.num_pipelines*rtp_pipeline_coe/num_units); - ifu->rt_power = ifu->rt_power + corepipe->power*pppm_t; - rt_power = rt_power + ifu->rt_power ; - } - - if (lsu->exist) - { - Pipeline_energy+=corepipe->power.readOp.dynamic* (coredynp.num_pipelines*rtp_pipeline_coe/num_units); - lsu->rt_power = lsu->rt_power + corepipe->power*pppm_t; - rt_power = rt_power + lsu->rt_power; - } - if (exu->exist) - { - Pipeline_energy+=corepipe->power.readOp.dynamic* (coredynp.num_pipelines*rtp_pipeline_coe/num_units); - exu->rt_power = exu->rt_power + corepipe->power*pppm_t; - rt_power = rt_power + exu->rt_power; - } - if (mmu->exist) - { - Pipeline_energy+=corepipe->power.readOp.dynamic* (coredynp.num_pipelines*rtp_pipeline_coe/num_units); - mmu->rt_power = mmu->rt_power + corepipe->power*pppm_t; - rt_power = rt_power + mmu->rt_power ; - } - - rt_power = rt_power + undiffCore->power; - - - if (XML->sys.Private_L2) - { - - l2cache->computeEnergy(false); - rt_power = rt_power + l2cache->rt_power; - } - - IdleCoreEnergy=XML->sys.num_idle_cores * XML->sys.idle_core_power* executionTime; - - rt_power.readOp.dynamic += IdleCoreEnergy; + IdleCoreEnergy = + XML->sys.num_idle_cores * XML->sys.idle_core_power * executionTime; + rt_power.readOp.dynamic += IdleCoreEnergy; } +void Core::computeEnergy(bool is_tdp) { + // power_point_product_masks + double pppm_t[4] = {1, 1, 1, 1}; + double rtp_pipeline_coe; + double num_units = 4.0; + Pipeline_energy = 0; + + if (XML->sys.homogeneous_cores == 1) { + rtp_pipeline_coe = coredynp.pipeline_duty_cycle * XML->sys.total_cycles * + XML->sys.number_of_cores; + } else { + rtp_pipeline_coe = coredynp.pipeline_duty_cycle * coredynp.total_cycles; + } + if (is_tdp) { + ifu->computeEnergy(is_tdp); + lsu->computeEnergy(is_tdp); + mmu->computeEnergy(is_tdp); + exu->computeEnergy(is_tdp); + + if (coredynp.core_ty == OOO) { + num_units = 5.0; + rnu->computeEnergy(is_tdp); + set_pppm(pppm_t, coredynp.num_pipelines / num_units, + coredynp.num_pipelines / num_units, + coredynp.num_pipelines / num_units, + coredynp.num_pipelines / num_units); + if (rnu->exist) { + rnu->power = rnu->power + corepipe->power * pppm_t; + power = power + rnu->power; + } + } + if (ifu->exist) { + Pipeline_energy += + corepipe->power.readOp.dynamic * + (coredynp.num_pipelines * rtp_pipeline_coe / num_units); + set_pppm(pppm_t, + coredynp.num_pipelines / num_units * coredynp.IFU_duty_cycle, + coredynp.num_pipelines / num_units, + coredynp.num_pipelines / num_units, + coredynp.num_pipelines / num_units); + // cout << "IFU = " << + // ifu->power.readOp.dynamic*clockRate << " W" << endl; + ifu->power = ifu->power + corepipe->power * pppm_t; + // cout << "IFU = " << + // ifu->power.readOp.dynamic*clockRate << " W" << endl; + // cout << "1/4 pipe = " << + // corepipe->power.readOp.dynamic*clockRate/num_units << " W" << endl; + power = power + ifu->power; + // cout << "core = " << + // power.readOp.dynamic*clockRate << " W" << endl; + } + if (lsu->exist) { + Pipeline_energy += + corepipe->power.readOp.dynamic * + (coredynp.num_pipelines * rtp_pipeline_coe / num_units); + set_pppm(pppm_t, + coredynp.num_pipelines / num_units * coredynp.LSU_duty_cycle, + coredynp.num_pipelines / num_units, + coredynp.num_pipelines / num_units, + coredynp.num_pipelines / num_units); + lsu->power = lsu->power + corepipe->power * pppm_t; + // cout << "LSU = " << + // lsu->power.readOp.dynamic*clockRate << " W" << endl; + power = power + lsu->power; + // cout << "core = " << + // power.readOp.dynamic*clockRate << " W" << endl; + } + if (exu->exist) { + Pipeline_energy += + corepipe->power.readOp.dynamic * + (coredynp.num_pipelines * rtp_pipeline_coe / num_units); + set_pppm(pppm_t, + coredynp.num_pipelines / num_units * coredynp.ALU_duty_cycle, + coredynp.num_pipelines / num_units, + coredynp.num_pipelines / num_units, + coredynp.num_pipelines / num_units); + // cout<<"ExPowerScalingFactor:"<power = exu->power + corepipe->power * pppm_t; + // cout << "EXE = " << + // exu->power.readOp.dynamic*clockRate << " W" << endl; + power = power + exu->power; + // cout << "core = " << + // power.readOp.dynamic*clockRate << " W" << endl; + } + if (mmu->exist) { + Pipeline_energy += + corepipe->power.readOp.dynamic * + (coredynp.num_pipelines * rtp_pipeline_coe / num_units); + set_pppm(pppm_t, + coredynp.num_pipelines / num_units * + (0.5 + 0.5 * coredynp.LSU_duty_cycle), + coredynp.num_pipelines / num_units, + coredynp.num_pipelines / num_units, + coredynp.num_pipelines / num_units); + mmu->power = mmu->power + corepipe->power * pppm_t; + // cout << "MMU = " << + // mmu->power.readOp.dynamic*clockRate << " W" << endl; + power = power + mmu->power; + // cout << "core = " << + // power.readOp.dynamic*clockRate << " W" << endl; + } -void Core::computeEnergy(bool is_tdp) -{ - //power_point_product_masks - double pppm_t[4] = {1,1,1,1}; - double rtp_pipeline_coe; - double num_units = 4.0; - Pipeline_energy=0; + power = power + undiffCore->power; - if (XML->sys.homogeneous_cores==1) - { - rtp_pipeline_coe = coredynp.pipeline_duty_cycle * XML->sys.total_cycles * XML->sys.number_of_cores; + if (XML->sys.Private_L2) { + l2cache->computeEnergy(is_tdp); + set_pppm(pppm_t, l2cache->cachep.clockRate / clockRate, 1, 1, 1); + // l2cache->power = l2cache->power*pppm_t; + power = power + l2cache->power * pppm_t; } - else - { - rtp_pipeline_coe = coredynp.pipeline_duty_cycle * coredynp.total_cycles; - } - - - if (is_tdp) - { - ifu->computeEnergy(is_tdp); - lsu->computeEnergy(is_tdp); - mmu->computeEnergy(is_tdp); - exu->computeEnergy(is_tdp); - - if (coredynp.core_ty==OOO) - { - num_units = 5.0; - rnu->computeEnergy(is_tdp); - set_pppm(pppm_t, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units); - if (rnu->exist) - { - rnu->power = rnu->power + corepipe->power*pppm_t; - power = power + rnu->power; - } - } - - if (ifu->exist) - { - Pipeline_energy+=corepipe->power.readOp.dynamic* (coredynp.num_pipelines*rtp_pipeline_coe/num_units); - set_pppm(pppm_t, coredynp.num_pipelines/num_units*coredynp.IFU_duty_cycle, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units); -// cout << "IFU = " << ifu->power.readOp.dynamic*clockRate << " W" << endl; - ifu->power = ifu->power + corepipe->power*pppm_t; -// cout << "IFU = " << ifu->power.readOp.dynamic*clockRate << " W" << endl; -// cout << "1/4 pipe = " << corepipe->power.readOp.dynamic*clockRate/num_units << " W" << endl; - power = power + ifu->power; -// cout << "core = " << power.readOp.dynamic*clockRate << " W" << endl; - } - if (lsu->exist) - { - Pipeline_energy+=corepipe->power.readOp.dynamic* (coredynp.num_pipelines*rtp_pipeline_coe/num_units); - set_pppm(pppm_t, coredynp.num_pipelines/num_units*coredynp.LSU_duty_cycle, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units); - lsu->power = lsu->power + corepipe->power*pppm_t; -// cout << "LSU = " << lsu->power.readOp.dynamic*clockRate << " W" << endl; - power = power + lsu->power; -// cout << "core = " << power.readOp.dynamic*clockRate << " W" << endl; - } - if (exu->exist) - { - Pipeline_energy+=corepipe->power.readOp.dynamic* (coredynp.num_pipelines*rtp_pipeline_coe/num_units); - set_pppm(pppm_t, coredynp.num_pipelines/num_units*coredynp.ALU_duty_cycle, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units); - //cout<<"ExPowerScalingFactor:"<power = exu->power + corepipe->power*pppm_t; -// cout << "EXE = " << exu->power.readOp.dynamic*clockRate << " W" << endl; - power = power + exu->power; -// cout << "core = " << power.readOp.dynamic*clockRate << " W" << endl; - } - if (mmu->exist) - { - Pipeline_energy+=corepipe->power.readOp.dynamic* (coredynp.num_pipelines*rtp_pipeline_coe/num_units); - set_pppm(pppm_t, coredynp.num_pipelines/num_units*(0.5+0.5*coredynp.LSU_duty_cycle), coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units); - mmu->power = mmu->power + corepipe->power*pppm_t; -// cout << "MMU = " << mmu->power.readOp.dynamic*clockRate << " W" << endl; - power = power + mmu->power; -// cout << "core = " << power.readOp.dynamic*clockRate << " W" << endl; - } - - power = power + undiffCore->power; - - if (XML->sys.Private_L2) - { - - l2cache->computeEnergy(is_tdp); - set_pppm(pppm_t,l2cache->cachep.clockRate/clockRate, 1,1,1); - //l2cache->power = l2cache->power*pppm_t; - power = power + l2cache->power*pppm_t; - } - - } - else - { + + } else { rt_power.reset(); + ifu->computeEnergy(is_tdp); + lsu->computeEnergy(is_tdp); + mmu->computeEnergy(is_tdp); + exu->computeEnergy(is_tdp); + if (coredynp.core_ty == OOO) { + num_units = 5.0; + rnu->computeEnergy(is_tdp); + set_pppm(pppm_t, coredynp.num_pipelines / num_units, + coredynp.num_pipelines / num_units, + coredynp.num_pipelines / num_units, + coredynp.num_pipelines / num_units); + if (rnu->exist) { + rnu->rt_power = rnu->rt_power + corepipe->power * pppm_t; + + rt_power = rt_power + rnu->rt_power; + } + } else { + set_pppm(pppm_t, coredynp.num_pipelines * rtp_pipeline_coe / num_units, + coredynp.num_pipelines / num_units, + coredynp.num_pipelines / num_units, + coredynp.num_pipelines / num_units); + } + if (ifu->exist) { + Pipeline_energy += + corepipe->power.readOp.dynamic * + (coredynp.num_pipelines * rtp_pipeline_coe / num_units); + ifu->rt_power = ifu->rt_power + corepipe->power * pppm_t; + rt_power = rt_power + ifu->rt_power; + } + if (lsu->exist) { + Pipeline_energy += + corepipe->power.readOp.dynamic * + (coredynp.num_pipelines * rtp_pipeline_coe / num_units); + lsu->rt_power = lsu->rt_power + corepipe->power * pppm_t; + rt_power = rt_power + lsu->rt_power; + } + if (exu->exist) { + Pipeline_energy += + corepipe->power.readOp.dynamic * + (coredynp.num_pipelines * rtp_pipeline_coe / num_units); + exu->rt_power = exu->rt_power + corepipe->power * pppm_t; + rt_power = rt_power + exu->rt_power; + } + if (mmu->exist) { + Pipeline_energy += + corepipe->power.readOp.dynamic * + (coredynp.num_pipelines * rtp_pipeline_coe / num_units); + mmu->rt_power = mmu->rt_power + corepipe->power * pppm_t; + rt_power = rt_power + mmu->rt_power; + } + rt_power = rt_power + undiffCore->power; + // cout << "EXE = " << exu->power.readOp.dynamic*clockRate << " W" + //<< endl; + if (XML->sys.Private_L2) { + l2cache->computeEnergy(is_tdp); + // set_pppm(pppm_t,1/l2cache->cachep.executionTime, 1,1,1); + // l2cache->rt_power = l2cache->rt_power*pppm_t; + rt_power = rt_power + l2cache->rt_power; + } + } +} - ifu->computeEnergy(is_tdp); - lsu->computeEnergy(is_tdp); - mmu->computeEnergy(is_tdp); - exu->computeEnergy(is_tdp); - if (coredynp.core_ty==OOO) - { - num_units = 5.0; - rnu->computeEnergy(is_tdp); - set_pppm(pppm_t, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units); - if (rnu->exist) - { - rnu->rt_power = rnu->rt_power + corepipe->power*pppm_t; - - rt_power = rt_power + rnu->rt_power; - } - } - else - { - - set_pppm(pppm_t, coredynp.num_pipelines*rtp_pipeline_coe/num_units, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units, coredynp.num_pipelines/num_units); - } - - if (ifu->exist) - { - Pipeline_energy+=corepipe->power.readOp.dynamic* (coredynp.num_pipelines*rtp_pipeline_coe/num_units); - ifu->rt_power = ifu->rt_power + corepipe->power*pppm_t; - rt_power = rt_power + ifu->rt_power ; - } - if (lsu->exist) - { - Pipeline_energy+=corepipe->power.readOp.dynamic* (coredynp.num_pipelines*rtp_pipeline_coe/num_units); - lsu->rt_power = lsu->rt_power + corepipe->power*pppm_t; - rt_power = rt_power + lsu->rt_power; - } - if (exu->exist) - { - Pipeline_energy+=corepipe->power.readOp.dynamic* (coredynp.num_pipelines*rtp_pipeline_coe/num_units); - exu->rt_power = exu->rt_power + corepipe->power*pppm_t; - rt_power = rt_power + exu->rt_power; - } - if (mmu->exist) - { - Pipeline_energy+=corepipe->power.readOp.dynamic* (coredynp.num_pipelines*rtp_pipeline_coe/num_units); - mmu->rt_power = mmu->rt_power + corepipe->power*pppm_t; - rt_power = rt_power + mmu->rt_power ; - } - - rt_power = rt_power + undiffCore->power; -// cout << "EXE = " << exu->power.readOp.dynamic*clockRate << " W" << endl; - if (XML->sys.Private_L2) - { - l2cache->computeEnergy(is_tdp); - //set_pppm(pppm_t,1/l2cache->cachep.executionTime, 1,1,1); - //l2cache->rt_power = l2cache->rt_power*pppm_t; - rt_power = rt_power + l2cache->rt_power; - } - - } +void Core::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 << "Core:" << endl; + cout << indent_str << "Area = " << area.get_area() * 1e-6 << " mm^2" + << endl; + cout << indent_str << "Peak Dynamic = " << power.readOp.dynamic * clockRate + << " W" << endl; + cout << indent_str << "Subthreshold Leakage = " + << (long_channel ? power.readOp.longer_channel_leakage + : power.readOp.leakage) + << " W" << endl; + // cout << indent_str << "Subthreshold Leakage = " << + // power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str << "Gate Leakage = " << power.readOp.gate_leakage << " W" + << endl; + cout << indent_str + << "Runtime Dynamic = " << rt_power.readOp.dynamic / executionTime + << " W" << endl; + cout << endl; + if (ifu->exist) { + cout << indent_str << "Instruction Fetch Unit:" << endl; + cout << indent_str_next << "Area = " << ifu->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << ifu->power.readOp.dynamic * clockRate << " W" + << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? ifu->power.readOp.longer_channel_leakage + : ifu->power.readOp.leakage) + << " W" << endl; + // cout << indent_str_next << "Subthreshold Leakage = " << + // ifu->power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str_next + << "Gate Leakage = " << ifu->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << ifu->rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << endl; + if (plevel > 2) { + ifu->displayEnergy(indent + 4, plevel, is_tdp); + } + } + if (coredynp.core_ty == OOO) { + if (rnu->exist) { + cout << indent_str << "Renaming Unit:" << endl; + cout << indent_str_next << "Area = " << rnu->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << rnu->power.readOp.dynamic * clockRate + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? rnu->power.readOp.longer_channel_leakage + : rnu->power.readOp.leakage) + << " W" << endl; + // cout << indent_str_next << "Subthreshold Leakage = " << + // rnu->power.readOp.longer_channel_leakage << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << rnu->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << rnu->rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << endl; + if (plevel > 2) { + rnu->displayEnergy(indent + 4, plevel, is_tdp); + } + } + } + if (lsu->exist) { + cout << indent_str << "Load Store Unit:" << endl; + cout << indent_str_next << "Area = " << lsu->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << lsu->power.readOp.dynamic * clockRate << " W" + << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? lsu->power.readOp.longer_channel_leakage + : lsu->power.readOp.leakage) + << " W" << endl; + // cout << indent_str_next << "Subthreshold Leakage = " << + // lsu->power.readOp.longer_channel_leakage << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << lsu->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << lsu->rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << endl; + if (plevel > 2) { + lsu->displayEnergy(indent + 4, plevel, is_tdp); + } + } + if (mmu->exist) { + cout << indent_str << "Memory Management Unit:" << endl; + cout << indent_str_next << "Area = " << mmu->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << mmu->power.readOp.dynamic * clockRate << " W" + << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? mmu->power.readOp.longer_channel_leakage + : mmu->power.readOp.leakage) + << " W" << endl; + // cout << indent_str_next << "Subthreshold Leakage = " << + // mmu->power.readOp.longer_channel_leakage << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << mmu->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << mmu->rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << endl; + if (plevel > 2) { + mmu->displayEnergy(indent + 4, plevel, is_tdp); + } + } + if (exu->exist) { + cout << indent_str << "Execution Unit:" << endl; + cout << indent_str_next << "Area = " << exu->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << exu->power.readOp.dynamic * clockRate << " W" + << endl; + cout << indent_str_next + << "Peak Dynamic Energy = " << exu->power.readOp.dynamic << " W" + << endl; + cout << indent_str_next << "clock Rate = " << clockRate << " W" << endl; + + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? exu->power.readOp.longer_channel_leakage + : exu->power.readOp.leakage) + << " W" << endl; + // cout << indent_str_next << "Subthreshold Leakage = " << + // exu->power.readOp.longer_channel_leakage << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << exu->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << exu->rt_power.readOp.dynamic / executionTime << " W" << endl; + cout << endl; + if (plevel > 2) { + exu->displayEnergy(indent + 4, plevel, is_tdp); + } + } + // if (plevel >2) + // { + // if (undiffCore->exist) + // { + // cout << indent_str << "Undifferentiated Core" << + // endl; cout << indent_str_next << "Area = " << + // undiffCore->area.get_area()*1e-6<< " mm^2" << endl; + // cout + // << indent_str_next << "Peak Dynamic = " << + // undiffCore->power.readOp.dynamic*clockRate << " W" << endl; + //// cout << indent_str_next << "Subthreshold Leakage = + ///" + ///<< undiffCore->power.readOp.leakage <<" W" << endl; + // cout << indent_str_next << "Subthreshold Leakage + //= + //" + // << + //(long_channel? + // undiffCore->power.readOp.longer_channel_leakage:undiffCore->power.readOp.leakage) + //<< " W" << endl; cout << indent_str_next << "Gate Leakage = + //" + //<< undiffCore->power.readOp.gate_leakage << " W" << endl; + // // cout << indent_str_next << "Runtime Dynamic = + //" + //<< undiffCore->rt_power.readOp.dynamic/executionTime << " W" << endl; + // cout + //<sys.Private_L2) { + l2cache->displayEnergy(4, is_tdp); + } + cout << indent_str << "Idle Core: " << endl; + cout << indent_str_next + << "Runtime Dynamic = " << IdleCoreEnergy / executionTime << " W\n" + << endl; + + } else { + // cout << indent_str_next << "Instruction Fetch Unit Peak Dynamic + //= + //" + //<< ifu->rt_power.readOp.dynamic*clockRate << " W" << endl; + //cout + //<< indent_str_next << "Instruction Fetch Unit Subthreshold Leakage = " + // << ifu->rt_power.readOp.leakage <<" W" << endl; cout << + // indent_str_next << "Instruction Fetch Unit Gate Leakage = " << + // ifu->rt_power.readOp.gate_leakage << " W" << endl; cout << + // indent_str_next + //<< "Load Store Unit Peak Dynamic = " << + // lsu->rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout + // << indent_str_next << "Load Store Unit Subthreshold Leakage = " << + // lsu->rt_power.readOp.leakage << " W" << endl; cout << + // indent_str_next + // << "Load Store Unit Gate Leakage = " << + // lsu->rt_power.readOp.gate_leakage + //<< " W" << endl; cout << indent_str_next << "Memory Management + //Unit Peak Dynamic = " << mmu->rt_power.readOp.dynamic*clockRate << " W" + // << + // endl; cout << indent_str_next << "Memory Management Unit + // Subthreshold Leakage = " << mmu->rt_power.readOp.leakage << " W" << + // endl; cout + // << indent_str_next << "Memory Management Unit Gate Leakage = " << + // mmu->rt_power.readOp.gate_leakage << " W" << endl; cout << + // indent_str_next << "Execution Unit Peak Dynamic = " << + // exu->rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout + // << indent_str_next << "Execution Unit Subthreshold Leakage = " << + // exu->rt_power.readOp.leakage << " W" << endl; cout << + // indent_str_next + // << "Execution Unit Gate Leakage = " << + // exu->rt_power.readOp.gate_leakage + //<< " W" << endl; + } +} +InstFetchU ::~InstFetchU() { + if (!exist) return; + if (IB) { + delete IB; + IB = 0; + } + if (ID_inst) { + delete ID_inst; + ID_inst = 0; + } + if (ID_operand) { + delete ID_operand; + ID_operand = 0; + } + if (ID_misc) { + delete ID_misc; + ID_misc = 0; + } + if (coredynp.predictionW > 0) { + if (BTB) { + delete BTB; + BTB = 0; + } + if (BPT) { + delete BPT; + BPT = 0; + } + } } -void Core::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 << "Core:" << endl; - cout << indent_str << "Area = " << area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str << "Peak Dynamic = " << power.readOp.dynamic*clockRate << " W" << endl; - cout << indent_str << "Subthreshold Leakage = " - << (long_channel? power.readOp.longer_channel_leakage:power.readOp.leakage) <<" W" << endl; - //cout << indent_str << "Subthreshold Leakage = " << power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str << "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl; - cout << indent_str << "Runtime Dynamic = " << rt_power.readOp.dynamic/executionTime << " W" << endl; - cout<exist) - { - cout << indent_str << "Instruction Fetch Unit:" << endl; - cout << indent_str_next << "Area = " << ifu->area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << ifu->power.readOp.dynamic*clockRate << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? ifu->power.readOp.longer_channel_leakage:ifu->power.readOp.leakage) <<" W" << endl; - //cout << indent_str_next << "Subthreshold Leakage = " << ifu->power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << ifu->power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << ifu->rt_power.readOp.dynamic/executionTime << " W" << endl; - cout <2){ - ifu->displayEnergy(indent+4,plevel,is_tdp); - } - } - if (coredynp.core_ty==OOO) - { - if (rnu->exist) - { - cout << indent_str<< "Renaming Unit:" << endl; - cout << indent_str_next << "Area = " << rnu->area.get_area()*1e-6 << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << rnu->power.readOp.dynamic*clockRate << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? rnu->power.readOp.longer_channel_leakage:rnu->power.readOp.leakage) << " W" << endl; - //cout << indent_str_next << "Subthreshold Leakage = " << rnu->power.readOp.longer_channel_leakage << " W" << endl; - cout << indent_str_next << "Gate Leakage = " << rnu->power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << rnu->rt_power.readOp.dynamic/executionTime << " W" << endl; - cout <2){ - rnu->displayEnergy(indent+4,plevel,is_tdp); - } - } - - } - if (lsu->exist) - { - cout << indent_str<< "Load Store Unit:" << endl; - cout << indent_str_next << "Area = " << lsu->area.get_area()*1e-6 << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << lsu->power.readOp.dynamic*clockRate << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? lsu->power.readOp.longer_channel_leakage:lsu->power.readOp.leakage ) << " W" << endl; - //cout << indent_str_next << "Subthreshold Leakage = " << lsu->power.readOp.longer_channel_leakage << " W" << endl; - cout << indent_str_next << "Gate Leakage = " << lsu->power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << lsu->rt_power.readOp.dynamic/executionTime << " W" << endl; - cout <2){ - lsu->displayEnergy(indent+4,plevel,is_tdp); - } - } - if (mmu->exist) - { - cout << indent_str<< "Memory Management Unit:" << endl; - cout << indent_str_next << "Area = " << mmu->area.get_area() *1e-6 << " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << mmu->power.readOp.dynamic*clockRate << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? mmu->power.readOp.longer_channel_leakage:mmu->power.readOp.leakage) << " W" << endl; - //cout << indent_str_next << "Subthreshold Leakage = " << mmu->power.readOp.longer_channel_leakage << " W" << endl; - cout << indent_str_next << "Gate Leakage = " << mmu->power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << mmu->rt_power.readOp.dynamic/executionTime << " W" << endl; - cout <2){ - mmu->displayEnergy(indent+4,plevel,is_tdp); - } - } - if (exu->exist) - { - cout << indent_str<< "Execution Unit:" << endl; - cout << indent_str_next << "Area = " << exu->area.get_area() *1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << exu->power.readOp.dynamic*clockRate << " W" << endl; - cout << indent_str_next << "Peak Dynamic Energy = " << exu->power.readOp.dynamic << " W" << endl; - cout << indent_str_next << "clock Rate = " << clockRate << " W" << endl; - - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? exu->power.readOp.longer_channel_leakage:exu->power.readOp.leakage) << " W" << endl; - //cout << indent_str_next << "Subthreshold Leakage = " << exu->power.readOp.longer_channel_leakage << " W" << endl; - cout << indent_str_next << "Gate Leakage = " << exu->power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << exu->rt_power.readOp.dynamic/executionTime << " W" << endl; - cout <2){ - exu->displayEnergy(indent+4,plevel,is_tdp); - } - } -// if (plevel >2) -// { -// if (undiffCore->exist) -// { -// cout << indent_str << "Undifferentiated Core" << endl; -// cout << indent_str_next << "Area = " << undiffCore->area.get_area()*1e-6<< " mm^2" << endl; -// cout << indent_str_next << "Peak Dynamic = " << undiffCore->power.readOp.dynamic*clockRate << " W" << endl; -//// cout << indent_str_next << "Subthreshold Leakage = " << undiffCore->power.readOp.leakage <<" W" << endl; -// cout << indent_str_next << "Subthreshold Leakage = " -// << (long_channel? undiffCore->power.readOp.longer_channel_leakage:undiffCore->power.readOp.leakage) << " W" << endl; -// cout << indent_str_next << "Gate Leakage = " << undiffCore->power.readOp.gate_leakage << " W" << endl; -// // cout << indent_str_next << "Runtime Dynamic = " << undiffCore->rt_power.readOp.dynamic/executionTime << " W" << endl; -// cout <sys.Private_L2) - { - - l2cache->displayEnergy(4,is_tdp); - } - - cout << indent_str<< "Idle Core: " << endl; - cout << indent_str_next << "Runtime Dynamic = " << IdleCoreEnergy/executionTime << " W\n" << endl; - - } - else - { -// cout << indent_str_next << "Instruction Fetch Unit Peak Dynamic = " << ifu->rt_power.readOp.dynamic*clockRate << " W" << endl; -// cout << indent_str_next << "Instruction Fetch Unit Subthreshold Leakage = " << ifu->rt_power.readOp.leakage <<" W" << endl; -// cout << indent_str_next << "Instruction Fetch Unit Gate Leakage = " << ifu->rt_power.readOp.gate_leakage << " W" << endl; -// cout << indent_str_next << "Load Store Unit Peak Dynamic = " << lsu->rt_power.readOp.dynamic*clockRate << " W" << endl; -// cout << indent_str_next << "Load Store Unit Subthreshold Leakage = " << lsu->rt_power.readOp.leakage << " W" << endl; -// cout << indent_str_next << "Load Store Unit Gate Leakage = " << lsu->rt_power.readOp.gate_leakage << " W" << endl; -// cout << indent_str_next << "Memory Management Unit Peak Dynamic = " << mmu->rt_power.readOp.dynamic*clockRate << " W" << endl; -// cout << indent_str_next << "Memory Management Unit Subthreshold Leakage = " << mmu->rt_power.readOp.leakage << " W" << endl; -// cout << indent_str_next << "Memory Management Unit Gate Leakage = " << mmu->rt_power.readOp.gate_leakage << " W" << endl; -// cout << indent_str_next << "Execution Unit Peak Dynamic = " << exu->rt_power.readOp.dynamic*clockRate << " W" << endl; -// cout << indent_str_next << "Execution Unit Subthreshold Leakage = " << exu->rt_power.readOp.leakage << " W" << endl; -// cout << indent_str_next << "Execution Unit Gate Leakage = " << exu->rt_power.readOp.gate_leakage << " W" << endl; - } +BranchPredictor ::~BranchPredictor() { + if (!exist) return; + if (globalBPT) { + delete globalBPT; + globalBPT = 0; + } + if (localBPT) { + delete localBPT; + localBPT = 0; + } + if (L1_localBPT) { + delete L1_localBPT; + L1_localBPT = 0; + } + if (L2_localBPT) { + delete L2_localBPT; + L2_localBPT = 0; + } + if (chooser) { + delete chooser; + chooser = 0; + } + if (RAS) { + delete RAS; + RAS = 0; + } } -InstFetchU ::~InstFetchU(){ - - if (!exist) return; - if(IB) {delete IB; IB = 0;} - if(ID_inst) {delete ID_inst; ID_inst = 0;} - if(ID_operand) {delete ID_operand; ID_operand = 0;} - if(ID_misc) {delete ID_misc; ID_misc = 0;} - if (coredynp.predictionW>0) - { - if(BTB) {delete BTB; BTB = 0;} - if(BPT) {delete BPT; BPT = 0;} - } + +RENAMINGU ::~RENAMINGU() { + if (!exist) return; + if (iFRAT) { + delete iFRAT; + iFRAT = 0; + } + if (fFRAT) { + delete fFRAT; + fFRAT = 0; + } + if (iRRAT) { + delete iRRAT; + iRRAT = 0; + } + if (iFRAT) { + delete iFRAT; + iFRAT = 0; + } + if (ifreeL) { + delete ifreeL; + ifreeL = 0; + } + if (ffreeL) { + delete ffreeL; + ffreeL = 0; + } + if (idcl) { + delete idcl; + idcl = 0; + } + if (fdcl) { + delete fdcl; + fdcl = 0; + } + if (RAHT) { + delete RAHT; + RAHT = 0; + } } -BranchPredictor ::~BranchPredictor(){ - - if (!exist) return; - if(globalBPT) {delete globalBPT; globalBPT = 0;} - if(localBPT) {delete localBPT; localBPT = 0;} - if(L1_localBPT) {delete L1_localBPT; L1_localBPT = 0;} - if(L2_localBPT) {delete L2_localBPT; L2_localBPT = 0;} - if(chooser) {delete chooser; chooser = 0;} - if(RAS) {delete RAS; RAS = 0;} - } - -RENAMINGU ::~RENAMINGU(){ - - if (!exist) return; - if(iFRAT ) {delete iFRAT; iFRAT = 0;} - if(fFRAT ) {delete fFRAT; fFRAT =0;} - if(iRRAT) {delete iRRAT; iRRAT = 0;} - if(iFRAT) {delete iFRAT; iFRAT = 0;} - if(ifreeL) {delete ifreeL;ifreeL= 0;} - if(ffreeL) {delete ffreeL;ffreeL= 0;} - if(idcl) {delete idcl; idcl = 0;} - if(fdcl) {delete fdcl; fdcl = 0;} - if(RAHT) {delete RAHT; RAHT = 0;} - } - -LoadStoreU ::~LoadStoreU(){ - - if (!exist) return; - if(LSQ) {delete LSQ; LSQ = 0;} - } - -MemManU ::~MemManU(){ - - if (!exist) return; - if(itlb) {delete itlb; itlb = 0;} - if(dtlb) {delete dtlb; dtlb = 0;} - } - -RegFU ::~RegFU(){ - - if (!exist) return; - if(IRF) {delete IRF; IRF = 0;} - if(FRF) {delete FRF; FRF = 0;} - if(RFWIN) {delete RFWIN; RFWIN = 0;} - } - -SchedulerU ::~SchedulerU(){ - - if (!exist) return; - if(int_inst_window) {delete int_inst_window; int_inst_window = 0;} - if(fp_inst_window) {delete int_inst_window; int_inst_window = 0;} - if(ROB) {delete ROB; ROB = 0;} - if(instruction_selection) {delete instruction_selection;instruction_selection = 0;} - } - -EXECU ::~EXECU(){ - - if (!exist) return; - if(int_bypass) {delete int_bypass; int_bypass = 0;} - if(intTagBypass) {delete intTagBypass; intTagBypass =0;} - if(int_mul_bypass) {delete int_mul_bypass; int_mul_bypass = 0;} - if(intTag_mul_Bypass) {delete intTag_mul_Bypass; intTag_mul_Bypass =0;} - if(fp_bypass) {delete fp_bypass;fp_bypass = 0;} - if(fpTagBypass) {delete fpTagBypass;fpTagBypass = 0;} - if(fp_u) {delete fp_u;fp_u = 0;} - if(exeu) {delete exeu;exeu = 0;} - if(mul) {delete mul;mul = 0;} - if(rfu) {delete rfu;rfu = 0;} - if(scheu) {delete scheu; scheu = 0;} - } - -Core ::~Core(){ - - if(ifu) {delete ifu; ifu = 0;} - if(lsu) {delete lsu; lsu = 0;} - if(rnu) {delete rnu; rnu = 0;} - if(mmu) {delete mmu; mmu = 0;} - if(exu) {delete exu; exu = 0;} - if(corepipe) {delete corepipe; corepipe = 0;} - if(undiffCore) {delete undiffCore;undiffCore = 0;} - if(l2cache) {delete l2cache;l2cache = 0;} - } - -void Core::set_core_param() -{ - coredynp.opt_local = XML->sys.core[ithCore].opt_local; - coredynp.x86 = XML->sys.core[ithCore].x86; - coredynp.Embedded = XML->sys.Embedded; - coredynp.core_ty = (enum Core_type)XML->sys.core[ithCore].machine_type; - coredynp.rm_ty = (enum Renaming_type)XML->sys.core[ithCore].rename_scheme; - coredynp.fetchW = XML->sys.core[ithCore].fetch_width; - coredynp.decodeW = XML->sys.core[ithCore].decode_width; - coredynp.issueW = XML->sys.core[ithCore].issue_width; - coredynp.peak_issueW = XML->sys.core[ithCore].peak_issue_width; - coredynp.commitW = XML->sys.core[ithCore].commit_width; - coredynp.peak_commitW = XML->sys.core[ithCore].peak_issue_width; - coredynp.predictionW = XML->sys.core[ithCore].prediction_width; - coredynp.fp_issueW = XML->sys.core[ithCore].fp_issue_width; - coredynp.fp_decodeW = XML->sys.core[ithCore].fp_issue_width; - coredynp.num_alus = XML->sys.core[ithCore].ALU_per_core; - coredynp.num_fpus = XML->sys.core[ithCore].FPU_per_core; - coredynp.num_muls = XML->sys.core[ithCore].MUL_per_core; - - - coredynp.num_hthreads = XML->sys.core[ithCore].number_hardware_threads; - coredynp.multithreaded = coredynp.num_hthreads>1? true:false; - coredynp.instruction_length = XML->sys.core[ithCore].instruction_length; - coredynp.pc_width = XML->sys.virtual_address_width; - - coredynp.opcode_length = XML->sys.core[ithCore].opcode_width; - coredynp.micro_opcode_length = XML->sys.core[ithCore].micro_opcode_width; - coredynp.num_pipelines = XML->sys.core[ithCore].pipelines_per_core[0]; - coredynp.pipeline_stages = XML->sys.core[ithCore].pipeline_depth[0]; - coredynp.num_fp_pipelines = XML->sys.core[ithCore].pipelines_per_core[1]; - coredynp.fp_pipeline_stages = XML->sys.core[ithCore].pipeline_depth[1]; - coredynp.int_data_width = int(ceil(XML->sys.machine_bits/32.0))*32; - coredynp.fp_data_width = coredynp.int_data_width; - coredynp.v_address_width = XML->sys.virtual_address_width; - coredynp.p_address_width = XML->sys.physical_address_width; - - coredynp.scheu_ty = (enum Scheduler_type)XML->sys.core[ithCore].instruction_window_scheme; - coredynp.arch_ireg_width = int(ceil(log2(XML->sys.core[ithCore].archi_Regs_IRF_size))); - coredynp.arch_freg_width = int(ceil(log2(XML->sys.core[ithCore].archi_Regs_FRF_size))); - coredynp.num_IRF_entry = XML->sys.core[ithCore].archi_Regs_IRF_size; - coredynp.num_FRF_entry = XML->sys.core[ithCore].archi_Regs_FRF_size; - coredynp.pipeline_duty_cycle = XML->sys.core[ithCore].pipeline_duty_cycle; - coredynp.total_cycles = XML->sys.core[ithCore].total_cycles; - coredynp.busy_cycles = XML->sys.core[ithCore].busy_cycles; - coredynp.idle_cycles = XML->sys.core[ithCore].idle_cycles; - - //Max power duty cycle for peak power estimation -// if (coredynp.core_ty==OOO) -// { -// coredynp.IFU_duty_cycle = 1; -// coredynp.LSU_duty_cycle = 1; -// coredynp.MemManU_I_duty_cycle =1; -// coredynp.MemManU_D_duty_cycle =1; -// coredynp.ALU_duty_cycle =1; -// coredynp.MUL_duty_cycle =1; -// coredynp.FPU_duty_cycle =1; -// coredynp.ALU_cdb_duty_cycle =1; -// coredynp.MUL_cdb_duty_cycle =1; -// coredynp.FPU_cdb_duty_cycle =1; -// } -// else -// { - coredynp.IFU_duty_cycle = XML->sys.core[ithCore].IFU_duty_cycle; - coredynp.BR_duty_cycle = XML->sys.core[ithCore].BR_duty_cycle; - coredynp.LSU_duty_cycle = XML->sys.core[ithCore].LSU_duty_cycle; - coredynp.MemManU_I_duty_cycle = XML->sys.core[ithCore].MemManU_I_duty_cycle; - coredynp.MemManU_D_duty_cycle = XML->sys.core[ithCore].MemManU_D_duty_cycle; - coredynp.ALU_duty_cycle = XML->sys.core[ithCore].ALU_duty_cycle; - coredynp.MUL_duty_cycle = XML->sys.core[ithCore].MUL_duty_cycle; - coredynp.FPU_duty_cycle = XML->sys.core[ithCore].FPU_duty_cycle; - coredynp.ALU_cdb_duty_cycle = XML->sys.core[ithCore].ALU_cdb_duty_cycle; - coredynp.MUL_cdb_duty_cycle = XML->sys.core[ithCore].MUL_cdb_duty_cycle; - coredynp.FPU_cdb_duty_cycle = XML->sys.core[ithCore].FPU_cdb_duty_cycle; -// } - - - if (!((coredynp.core_ty==OOO)||(coredynp.core_ty==Inorder))) - { - cout<<"Invalid Core Type"<sys.core[ithCore].phy_Regs_IRF_size))); - coredynp.phy_freg_width = int(ceil(log2(XML->sys.core[ithCore].phy_Regs_FRF_size))); - coredynp.num_ifreelist_entries = coredynp.num_IRF_entry = XML->sys.core[ithCore].phy_Regs_IRF_size; - coredynp.num_ffreelist_entries = coredynp.num_FRF_entry = XML->sys.core[ithCore].phy_Regs_FRF_size; - } - else if (coredynp.scheu_ty==ReservationStation) - {//ROB serves as Phy RF in RS based OOO - coredynp.phy_ireg_width = int(ceil(log2(XML->sys.core[ithCore].ROB_size))); - coredynp.phy_freg_width = int(ceil(log2(XML->sys.core[ithCore].ROB_size))); - coredynp.num_ifreelist_entries = XML->sys.core[ithCore].ROB_size; - coredynp.num_ffreelist_entries = XML->sys.core[ithCore].ROB_size; - - } +LoadStoreU ::~LoadStoreU() { + if (!exist) return; + if (LSQ) { + delete LSQ; + LSQ = 0; + } +} + +MemManU ::~MemManU() { + if (!exist) return; + if (itlb) { + delete itlb; + itlb = 0; + } + if (dtlb) { + delete dtlb; + dtlb = 0; + } +} +RegFU ::~RegFU() { + if (!exist) return; + if (IRF) { + delete IRF; + IRF = 0; + } + if (FRF) { + delete FRF; + FRF = 0; + } + if (RFWIN) { + delete RFWIN; + RFWIN = 0; + } } - coredynp.globalCheckpoint = 32;//best check pointing entries for a 4~8 issue OOO should be 16~48;See TR for reference. - coredynp.perThreadState = 8; - coredynp.instruction_length = 32; - coredynp.clockRate = XML->sys.core[ithCore].clock_rate; - coredynp.clockRate *= 1e6; - coredynp.regWindowing= (XML->sys.core[ithCore].register_windows_size>0&&coredynp.core_ty==Inorder)?true:false; - coredynp.executionTime = XML->sys.total_cycles/coredynp.clockRate; - set_pppm(coredynp.pppm_lkg_multhread, 0, coredynp.num_hthreads, coredynp.num_hthreads, 0); + +SchedulerU ::~SchedulerU() { + if (!exist) return; + if (int_inst_window) { + delete int_inst_window; + int_inst_window = 0; + } + if (fp_inst_window) { + delete int_inst_window; + int_inst_window = 0; + } + if (ROB) { + delete ROB; + ROB = 0; + } + if (instruction_selection) { + delete instruction_selection; + instruction_selection = 0; + } +} + +EXECU ::~EXECU() { + if (!exist) return; + if (int_bypass) { + delete int_bypass; + int_bypass = 0; + } + if (intTagBypass) { + delete intTagBypass; + intTagBypass = 0; + } + if (int_mul_bypass) { + delete int_mul_bypass; + int_mul_bypass = 0; + } + if (intTag_mul_Bypass) { + delete intTag_mul_Bypass; + intTag_mul_Bypass = 0; + } + if (fp_bypass) { + delete fp_bypass; + fp_bypass = 0; + } + if (fpTagBypass) { + delete fpTagBypass; + fpTagBypass = 0; + } + if (fp_u) { + delete fp_u; + fp_u = 0; + } + if (exeu) { + delete exeu; + exeu = 0; + } + if (mul) { + delete mul; + mul = 0; + } + if (rfu) { + delete rfu; + rfu = 0; + } + if (scheu) { + delete scheu; + scheu = 0; + } +} + +Core ::~Core() { + if (ifu) { + delete ifu; + ifu = 0; + } + if (lsu) { + delete lsu; + lsu = 0; + } + if (rnu) { + delete rnu; + rnu = 0; + } + if (mmu) { + delete mmu; + mmu = 0; + } + if (exu) { + delete exu; + exu = 0; + } + if (corepipe) { + delete corepipe; + corepipe = 0; + } + if (undiffCore) { + delete undiffCore; + undiffCore = 0; + } + if (l2cache) { + delete l2cache; + l2cache = 0; + } +} + +void Core::set_core_param() { + coredynp.opt_local = XML->sys.core[ithCore].opt_local; + coredynp.x86 = XML->sys.core[ithCore].x86; + coredynp.Embedded = XML->sys.Embedded; + coredynp.core_ty = (enum Core_type)XML->sys.core[ithCore].machine_type; + coredynp.rm_ty = (enum Renaming_type)XML->sys.core[ithCore].rename_scheme; + coredynp.fetchW = XML->sys.core[ithCore].fetch_width; + coredynp.decodeW = XML->sys.core[ithCore].decode_width; + coredynp.issueW = XML->sys.core[ithCore].issue_width; + coredynp.peak_issueW = XML->sys.core[ithCore].peak_issue_width; + coredynp.commitW = XML->sys.core[ithCore].commit_width; + coredynp.peak_commitW = XML->sys.core[ithCore].peak_issue_width; + coredynp.predictionW = XML->sys.core[ithCore].prediction_width; + coredynp.fp_issueW = XML->sys.core[ithCore].fp_issue_width; + coredynp.fp_decodeW = XML->sys.core[ithCore].fp_issue_width; + coredynp.num_alus = XML->sys.core[ithCore].ALU_per_core; + coredynp.num_fpus = XML->sys.core[ithCore].FPU_per_core; + coredynp.num_muls = XML->sys.core[ithCore].MUL_per_core; + + coredynp.num_hthreads = XML->sys.core[ithCore].number_hardware_threads; + coredynp.multithreaded = coredynp.num_hthreads > 1 ? true : false; + coredynp.instruction_length = XML->sys.core[ithCore].instruction_length; + coredynp.pc_width = XML->sys.virtual_address_width; + + coredynp.opcode_length = XML->sys.core[ithCore].opcode_width; + coredynp.micro_opcode_length = XML->sys.core[ithCore].micro_opcode_width; + coredynp.num_pipelines = XML->sys.core[ithCore].pipelines_per_core[0]; + coredynp.pipeline_stages = XML->sys.core[ithCore].pipeline_depth[0]; + coredynp.num_fp_pipelines = XML->sys.core[ithCore].pipelines_per_core[1]; + coredynp.fp_pipeline_stages = XML->sys.core[ithCore].pipeline_depth[1]; + coredynp.int_data_width = int(ceil(XML->sys.machine_bits / 32.0)) * 32; + coredynp.fp_data_width = coredynp.int_data_width; + coredynp.v_address_width = XML->sys.virtual_address_width; + coredynp.p_address_width = XML->sys.physical_address_width; + + coredynp.scheu_ty = + (enum Scheduler_type)XML->sys.core[ithCore].instruction_window_scheme; + coredynp.arch_ireg_width = + int(ceil(log2(XML->sys.core[ithCore].archi_Regs_IRF_size))); + coredynp.arch_freg_width = + int(ceil(log2(XML->sys.core[ithCore].archi_Regs_FRF_size))); + coredynp.num_IRF_entry = XML->sys.core[ithCore].archi_Regs_IRF_size; + coredynp.num_FRF_entry = XML->sys.core[ithCore].archi_Regs_FRF_size; + coredynp.pipeline_duty_cycle = XML->sys.core[ithCore].pipeline_duty_cycle; + coredynp.total_cycles = XML->sys.core[ithCore].total_cycles; + coredynp.busy_cycles = XML->sys.core[ithCore].busy_cycles; + coredynp.idle_cycles = XML->sys.core[ithCore].idle_cycles; + + // Max power duty cycle for peak power estimation + // if (coredynp.core_ty==OOO) + // { + // coredynp.IFU_duty_cycle = 1; + // coredynp.LSU_duty_cycle = 1; + // coredynp.MemManU_I_duty_cycle =1; + // coredynp.MemManU_D_duty_cycle =1; + // coredynp.ALU_duty_cycle =1; + // coredynp.MUL_duty_cycle =1; + // coredynp.FPU_duty_cycle =1; + // coredynp.ALU_cdb_duty_cycle =1; + // coredynp.MUL_cdb_duty_cycle =1; + // coredynp.FPU_cdb_duty_cycle =1; + // } + // else + // { + coredynp.IFU_duty_cycle = XML->sys.core[ithCore].IFU_duty_cycle; + coredynp.BR_duty_cycle = XML->sys.core[ithCore].BR_duty_cycle; + coredynp.LSU_duty_cycle = XML->sys.core[ithCore].LSU_duty_cycle; + coredynp.MemManU_I_duty_cycle = XML->sys.core[ithCore].MemManU_I_duty_cycle; + coredynp.MemManU_D_duty_cycle = XML->sys.core[ithCore].MemManU_D_duty_cycle; + coredynp.ALU_duty_cycle = XML->sys.core[ithCore].ALU_duty_cycle; + coredynp.MUL_duty_cycle = XML->sys.core[ithCore].MUL_duty_cycle; + coredynp.FPU_duty_cycle = XML->sys.core[ithCore].FPU_duty_cycle; + coredynp.ALU_cdb_duty_cycle = XML->sys.core[ithCore].ALU_cdb_duty_cycle; + coredynp.MUL_cdb_duty_cycle = XML->sys.core[ithCore].MUL_cdb_duty_cycle; + coredynp.FPU_cdb_duty_cycle = XML->sys.core[ithCore].FPU_cdb_duty_cycle; + // } + + if (!((coredynp.core_ty == OOO) || (coredynp.core_ty == Inorder))) { + cout << "Invalid Core Type" << endl; + exit(0); + } + // if (coredynp.core_ty==OOO) + // { + // cout<<"OOO processor models are being updated and will be + // available in next release"<sys.core[ithCore].phy_Regs_IRF_size))); + coredynp.phy_freg_width = + int(ceil(log2(XML->sys.core[ithCore].phy_Regs_FRF_size))); + coredynp.num_ifreelist_entries = coredynp.num_IRF_entry = + XML->sys.core[ithCore].phy_Regs_IRF_size; + coredynp.num_ffreelist_entries = coredynp.num_FRF_entry = + XML->sys.core[ithCore].phy_Regs_FRF_size; + } else if (coredynp.scheu_ty == + ReservationStation) { // ROB serves as Phy RF in RS based OOO + coredynp.phy_ireg_width = + int(ceil(log2(XML->sys.core[ithCore].ROB_size))); + coredynp.phy_freg_width = + int(ceil(log2(XML->sys.core[ithCore].ROB_size))); + coredynp.num_ifreelist_entries = XML->sys.core[ithCore].ROB_size; + coredynp.num_ffreelist_entries = XML->sys.core[ithCore].ROB_size; + } + } + coredynp.globalCheckpoint = + 32; // best check pointing entries for a 4~8 issue OOO should be + // 16~48;See TR for reference. + coredynp.perThreadState = 8; + coredynp.instruction_length = 32; + coredynp.clockRate = XML->sys.core[ithCore].clock_rate; + coredynp.clockRate *= 1e6; + coredynp.regWindowing = (XML->sys.core[ithCore].register_windows_size > 0 && + coredynp.core_ty == Inorder) + ? true + : false; + coredynp.executionTime = XML->sys.total_cycles / coredynp.clockRate; + set_pppm(coredynp.pppm_lkg_multhread, 0, coredynp.num_hthreads, + coredynp.num_hthreads, 0); } diff --git a/src/gpuwattch/core.h b/src/gpuwattch/core.h index b43a57c..67ff4b1 100644 --- a/src/gpuwattch/core.h +++ b/src/gpuwattch/core.h @@ -29,470 +29,527 @@ * ***************************************************************************/ /******************************************************************** -* 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 * + ********************************************************************/ #ifndef CORE_H_ #define CORE_H_ #include "XML_Parse.h" -#include "logic.h" -#include "cacti/parameter.h" #include "array.h" -#include "interconnect.h" #include "basic_components.h" -#include "sharedcache.h" -#include "cacti/crossbar.h" #include "cacti/arbiter.h" +#include "cacti/crossbar.h" +#include "cacti/parameter.h" +#include "interconnect.h" +#include "logic.h" #include "noc.h" +#include "sharedcache.h" -class BranchPredictor :public Component { - public: - - ParseXML *XML; - int ithCore; - InputParameter interface_ip; - CoreDynParam coredynp; - double clockRate,executionTime; - double scktRatio, chip_PR_overhead, macro_PR_overhead; - ArrayST * globalBPT; - ArrayST * localBPT; - ArrayST * L1_localBPT; - ArrayST * L2_localBPT; - ArrayST * chooser; - ArrayST * RAS; - bool exist; - - BranchPredictor(ParseXML *XML_interface, int ithCore_, InputParameter* interface_ip_,const CoreDynParam & dyn_p_, bool exsit=true); - void computeEnergy(bool is_tdp=true); - void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); - ~BranchPredictor(); +class BranchPredictor : public Component { + public: + ParseXML *XML; + int ithCore; + InputParameter interface_ip; + CoreDynParam coredynp; + double clockRate, executionTime; + double scktRatio, chip_PR_overhead, macro_PR_overhead; + ArrayST *globalBPT; + ArrayST *localBPT; + ArrayST *L1_localBPT; + ArrayST *L2_localBPT; + ArrayST *chooser; + ArrayST *RAS; + bool exist; + + BranchPredictor(ParseXML *XML_interface, int ithCore_, + InputParameter *interface_ip_, const CoreDynParam &dyn_p_, + bool exsit = true); + void computeEnergy(bool is_tdp = true); + void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); + ~BranchPredictor(); }; - -class InstFetchU :public Component { - public: - - ParseXML *XML; - int ithCore; - InputParameter interface_ip; - CoreDynParam coredynp; - double clockRate,executionTime; - double scktRatio, chip_PR_overhead, macro_PR_overhead; - enum Cache_policy cache_p; - InstCache icache; - ArrayST * IB; - ArrayST * BTB; - BranchPredictor * BPT; - inst_decoder * ID_inst; - inst_decoder * ID_operand; - inst_decoder * ID_misc; - bool exist; - - InstFetchU(ParseXML *XML_interface, int ithCore_, InputParameter* interface_ip_,const CoreDynParam & dyn_p_, bool exsit=true); - void computeEnergy(bool is_tdp=true); - void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); - ~InstFetchU(); +class InstFetchU : public Component { + public: + ParseXML *XML; + int ithCore; + InputParameter interface_ip; + CoreDynParam coredynp; + double clockRate, executionTime; + double scktRatio, chip_PR_overhead, macro_PR_overhead; + enum Cache_policy cache_p; + InstCache icache; + ArrayST *IB; + ArrayST *BTB; + BranchPredictor *BPT; + inst_decoder *ID_inst; + inst_decoder *ID_operand; + inst_decoder *ID_misc; + bool exist; + + InstFetchU(ParseXML *XML_interface, int ithCore_, + InputParameter *interface_ip_, const CoreDynParam &dyn_p_, + bool exsit = true); + void computeEnergy(bool is_tdp = true); + void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); + ~InstFetchU(); }; - -class SchedulerU :public Component { - public: - - ParseXML *XML; - int ithCore; - InputParameter interface_ip; - CoreDynParam coredynp; - double clockRate,executionTime; - double scktRatio, chip_PR_overhead, macro_PR_overhead; - double Iw_height, fp_Iw_height,ROB_height; - ArrayST * int_inst_window; - ArrayST * fp_inst_window; - ArrayST * ROB; - selection_logic * instruction_selection; - bool exist; - - SchedulerU(ParseXML *XML_interface, int ithCore_, InputParameter* interface_ip_,const CoreDynParam & dyn_p_, bool exist_=true); - void computeEnergy(bool is_tdp=true); - void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); - ~SchedulerU(); +class SchedulerU : public Component { + public: + ParseXML *XML; + int ithCore; + InputParameter interface_ip; + CoreDynParam coredynp; + double clockRate, executionTime; + double scktRatio, chip_PR_overhead, macro_PR_overhead; + double Iw_height, fp_Iw_height, ROB_height; + ArrayST *int_inst_window; + ArrayST *fp_inst_window; + ArrayST *ROB; + selection_logic *instruction_selection; + bool exist; + + SchedulerU(ParseXML *XML_interface, int ithCore_, + InputParameter *interface_ip_, const CoreDynParam &dyn_p_, + bool exist_ = true); + void computeEnergy(bool is_tdp = true); + void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); + ~SchedulerU(); }; -class RENAMINGU :public Component { - public: - - ParseXML *XML; - int ithCore; - InputParameter interface_ip; - double clockRate,executionTime; - CoreDynParam coredynp; - ArrayST * iFRAT; - ArrayST * fFRAT; - ArrayST * iRRAT; - ArrayST * fRRAT; - ArrayST * ifreeL; - ArrayST * ffreeL; - dep_resource_conflict_check * idcl; - dep_resource_conflict_check * fdcl; - ArrayST * RAHT;//register alias history table Used to store GC - bool exist; - - - RENAMINGU(ParseXML *XML_interface, int ithCore_, InputParameter* interface_ip_, const CoreDynParam & dyn_p_, bool exist_=true); - void computeEnergy(bool is_tdp=true); - void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); - ~RENAMINGU(); +class RENAMINGU : public Component { + public: + ParseXML *XML; + int ithCore; + InputParameter interface_ip; + double clockRate, executionTime; + CoreDynParam coredynp; + ArrayST *iFRAT; + ArrayST *fFRAT; + ArrayST *iRRAT; + ArrayST *fRRAT; + ArrayST *ifreeL; + ArrayST *ffreeL; + dep_resource_conflict_check *idcl; + dep_resource_conflict_check *fdcl; + ArrayST *RAHT; // register alias history table Used to store GC + bool exist; + + RENAMINGU(ParseXML *XML_interface, int ithCore_, + InputParameter *interface_ip_, const CoreDynParam &dyn_p_, + bool exist_ = true); + void computeEnergy(bool is_tdp = true); + void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); + ~RENAMINGU(); }; -class LoadStoreU :public Component { - public: - - ParseXML *XML; - int ithCore; - InputParameter interface_ip; - CoreDynParam coredynp; - enum Cache_policy cache_p; - double clockRate,executionTime; - double scktRatio, chip_PR_overhead, macro_PR_overhead; - double lsq_height; - DataCache dcache; - DataCache ccache; - DataCache tcache; - DataCache sharedmemory; - ArrayST * LSQ;//it is actually the store queue but for inorder processors it serves as both loadQ and StoreQ - ArrayST * LoadQ; - vector nocs; - bool exist; - Crossbar *xbar_shared; - Component noc; - LoadStoreU(ParseXML *XML_interface, int ithCore_, InputParameter* interface_ip_,const CoreDynParam & dyn_p_, bool exist_=true); - void computeEnergy(bool is_tdp=true); - void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); - void displayDeviceType(int device_type_, uint32_t indent);//Added by Syed Gilani - - ~LoadStoreU(); +class LoadStoreU : public Component { + public: + ParseXML *XML; + int ithCore; + InputParameter interface_ip; + CoreDynParam coredynp; + enum Cache_policy cache_p; + double clockRate, executionTime; + double scktRatio, chip_PR_overhead, macro_PR_overhead; + double lsq_height; + DataCache dcache; + DataCache ccache; + DataCache tcache; + DataCache sharedmemory; + ArrayST *LSQ; // it is actually the store queue but for inorder processors it + // serves as both loadQ and StoreQ + ArrayST *LoadQ; + vector nocs; + bool exist; + Crossbar *xbar_shared; + Component noc; + LoadStoreU(ParseXML *XML_interface, int ithCore_, + InputParameter *interface_ip_, const CoreDynParam &dyn_p_, + bool exist_ = true); + void computeEnergy(bool is_tdp = true); + void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); + void displayDeviceType(int device_type_, + uint32_t indent); // Added by Syed Gilani + + ~LoadStoreU(); }; -class MemManU :public Component { - public: - - ParseXML *XML; - int ithCore; - InputParameter interface_ip; - CoreDynParam coredynp; - double clockRate,executionTime; - double scktRatio, chip_PR_overhead, macro_PR_overhead; - ArrayST * itlb; - ArrayST * dtlb; - bool exist; - - MemManU(ParseXML *XML_interface, int ithCore_, InputParameter* interface_ip_,const CoreDynParam & dyn_p_, bool exist_=false); - void computeEnergy(bool is_tdp=true); - void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); - ~MemManU(); +class MemManU : public Component { + public: + ParseXML *XML; + int ithCore; + InputParameter interface_ip; + CoreDynParam coredynp; + double clockRate, executionTime; + double scktRatio, chip_PR_overhead, macro_PR_overhead; + ArrayST *itlb; + ArrayST *dtlb; + bool exist; + + MemManU(ParseXML *XML_interface, int ithCore_, InputParameter *interface_ip_, + const CoreDynParam &dyn_p_, bool exist_ = false); + void computeEnergy(bool is_tdp = true); + void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); + ~MemManU(); }; -class RegFU :public Component { - public: - - ParseXML *XML; - int ithCore; - InputParameter interface_ip; - CoreDynParam coredynp; - double clockRate,executionTime; - double scktRatio, chip_PR_overhead, macro_PR_overhead; - double int_regfile_height, fp_regfile_height; - ArrayST * IRF; - ArrayST * FRF; - ArrayST * RFWIN; - ArrayST * OPC;//Operand collectors - bool exist; - double exClockRate; - //OC Modelling (Syed) - Crossbar * xbar_rfu; - MCPAT_Arbiter * arbiter_rfu; - RegFU(ParseXML *XML_interface, int ithCore_, InputParameter* interface_ip_,const CoreDynParam & dyn_p_, double exClockRate, bool exist_=true); - void computeEnergy(bool is_tdp=true); - void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); - ~RegFU(); +class RegFU : public Component { + public: + ParseXML *XML; + int ithCore; + InputParameter interface_ip; + CoreDynParam coredynp; + double clockRate, executionTime; + double scktRatio, chip_PR_overhead, macro_PR_overhead; + double int_regfile_height, fp_regfile_height; + ArrayST *IRF; + ArrayST *FRF; + ArrayST *RFWIN; + ArrayST *OPC; // Operand collectors + bool exist; + double exClockRate; + // OC Modelling (Syed) + Crossbar *xbar_rfu; + MCPAT_Arbiter *arbiter_rfu; + RegFU(ParseXML *XML_interface, int ithCore_, InputParameter *interface_ip_, + const CoreDynParam &dyn_p_, double exClockRate, bool exist_ = true); + void computeEnergy(bool is_tdp = true); + void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); + ~RegFU(); }; -class EXECU :public Component { - public: - - ParseXML *XML; - int ithCore; - InputParameter interface_ip; - double clockRate,executionTime; - double scktRatio, chip_PR_overhead, macro_PR_overhead; - double lsq_height; - CoreDynParam coredynp; - RegFU * rfu; - SchedulerU * scheu; - FunctionalUnit * fp_u; - FunctionalUnit * exeu; - FunctionalUnit * mul; - interconnect * int_bypass; - interconnect * intTagBypass; - interconnect * int_mul_bypass; - interconnect * intTag_mul_Bypass; - interconnect * fp_bypass; - interconnect * fpTagBypass; - bool exist; - double rf_fu_clockRate; - Component bypass; - - - EXECU(ParseXML *XML_interface, int ithCore_, InputParameter* interface_ip_, double lsq_height_,const CoreDynParam & dyn_p_, double exClockRate, bool exist_); - void computeEnergy(bool is_tdp=true); - void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); - ~EXECU(); +class EXECU : public Component { + public: + ParseXML *XML; + int ithCore; + InputParameter interface_ip; + double clockRate, executionTime; + double scktRatio, chip_PR_overhead, macro_PR_overhead; + double lsq_height; + CoreDynParam coredynp; + RegFU *rfu; + SchedulerU *scheu; + FunctionalUnit *fp_u; + FunctionalUnit *exeu; + FunctionalUnit *mul; + interconnect *int_bypass; + interconnect *intTagBypass; + interconnect *int_mul_bypass; + interconnect *intTag_mul_Bypass; + interconnect *fp_bypass; + interconnect *fpTagBypass; + bool exist; + double rf_fu_clockRate; + Component bypass; + + EXECU(ParseXML *XML_interface, int ithCore_, InputParameter *interface_ip_, + double lsq_height_, const CoreDynParam &dyn_p_, double exClockRate, + bool exist_); + void computeEnergy(bool is_tdp = true); + void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); + ~EXECU(); }; - -class Core :public Component { - public: - - ParseXML *XML; - int ithCore; - InputParameter interface_ip; - double clockRate,executionTime; - double exClockRate; - double scktRatio, chip_PR_overhead, macro_PR_overhead; - InstFetchU * ifu; - LoadStoreU * lsu; - MemManU * mmu; - EXECU * exu; - RENAMINGU * rnu; - double IdleCoreEnergy; - double IdlePower_PerCore; - Pipeline * corepipe; - UndiffCore * undiffCore; - SharedCache * l2cache; - CoreDynParam coredynp; - double Pipeline_energy; - //full_decoder inst_decoder; - //clock_network clockNetwork; - Core(ParseXML *XML_interface, int ithCore_, InputParameter* interface_ip_); - void set_core_param(); - void computeEnergy(bool is_tdp=true); - void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); - - float get_coefficient_icache_hits(){ - //return 1.5*ifu->icache.caches->local_result.power.readOp.dynamic; - return ifu->icache.caches->local_result.power.readOp.dynamic; - } - - float get_coefficient_icache_misses(){ - float value=0; - value+=ifu->icache.caches->local_result.power.writeOp.dynamic; - value+=ifu->icache.caches->local_result.power.readOp.dynamic; - value+=ifu->icache.missb->local_result.power.searchOp.dynamic; - value+=ifu->icache.missb->local_result.power.writeOp.dynamic; - value+=ifu->icache.ifb->local_result.power.searchOp.dynamic; - value+= ifu->icache.ifb->local_result.power.writeOp.dynamic; - value+= ifu->icache.prefetchb->local_result.power.searchOp.dynamic; - value+=ifu->icache.prefetchb->local_result.power.writeOp.dynamic; - return value; - } - - float get_coefficient_tot_insts(){ - float value=0; - value+=ifu->IB->local_result.power.readOp.dynamic; - value+=ifu->IB->local_result.power.writeOp.dynamic; - value+=ifu->ID_inst->power_t.readOp.dynamic; - value+=ifu->ID_operand->power_t.readOp.dynamic; - value+=ifu->ID_misc->power_t.readOp.dynamic; - return value; - } - - float get_coefficient_fpint_insts(){ - float value=0; - value+=exu->scheu->int_inst_window->local_result.power.readOp.dynamic; - value+=2*exu->scheu->int_inst_window->local_result.power.searchOp.dynamic; - value+=exu->scheu->int_inst_window->local_result.power.writeOp.dynamic; - value+=exu->scheu->instruction_selection->power.readOp.dynamic; - return value; - } - - - float get_coefficient_dcache_readhits() - { - float value=0; - value+=lsu->dcache.caches->local_result.power.readOp.dynamic; - value+=lsu->xbar_shared->power.readOp.dynamic; - //return 0.5*value; - return value; - } - float get_coefficient_dcache_readmisses() - { - float value=0; - value+=lsu->dcache.caches->local_result.power.readOp.dynamic; - value+=(lsu->cache_p==Write_back)? 0:lsu->dcache.missb->local_result.power.searchOp.dynamic; - value+=(lsu->cache_p==Write_back)? 0:lsu->dcache.ifb->local_result.power.searchOp.dynamic; - value+=(lsu->cache_p==Write_back)? 0:lsu->dcache.prefetchb->local_result.power.searchOp.dynamic; - value+=(lsu->cache_p==Write_back)? 0:lsu->dcache.missb->local_result.power.writeOp.dynamic; - value+=(lsu->cache_p==Write_back)? 0:lsu->dcache.ifb->local_result.power.writeOp.dynamic; - value+=(lsu->cache_p==Write_back)? 0:lsu->dcache.prefetchb->local_result.power.writeOp.dynamic; - - //return 0.5*value; - return value; - } - float get_coefficient_dcache_writehits() - { - float value=0; - value+=lsu->dcache.caches->local_result.power.writeOp.dynamic; - value+=lsu->xbar_shared->power.readOp.dynamic; - return value; - } - float get_coefficient_dcache_writemisses(){ - float value=0; - value+=lsu->dcache.caches->local_result.power.writeOp.dynamic; - value+=lsu->dcache.caches->local_result.tag_array2->power.readOp.dynamic; - value+= (lsu->cache_p==Write_back)? lsu->dcache.caches->local_result.power.writeOp.dynamic:0; - value+= (lsu->cache_p==Write_back)? lsu->dcache.missb->local_result.power.searchOp.dynamic:0; - value+= (lsu->cache_p==Write_back)? lsu->dcache.ifb->local_result.power.searchOp.dynamic:0; - value+= (lsu->cache_p==Write_back)? lsu->dcache.prefetchb->local_result.power.searchOp.dynamic:0; - value+= (lsu->cache_p==Write_back)? lsu->dcache.wbb->local_result.power.searchOp.dynamic:0; - value+= (lsu->cache_p==Write_back)? lsu->dcache.missb->local_result.power.writeOp.dynamic:0; - value+= (lsu->cache_p==Write_back)? lsu->dcache.ifb->local_result.power.writeOp.dynamic:0; - value+= (lsu->cache_p==Write_back)? lsu->dcache.prefetchb->local_result.power.writeOp.dynamic:0; - value+= (lsu->cache_p==Write_back)? lsu->dcache.wbb->local_result.power.writeOp.dynamic:0; - //return 1.6*value; - return value; - } - - - - float get_coefficient_tcache_readhits() - { - float value=0; - value+=lsu->tcache.caches->local_result.power.readOp.dynamic; - value+=lsu->xbar_shared->power.readOp.dynamic; - //return 0.2*value; - return value; - } - float get_coefficient_tcache_readmisses() - { - float value=0; - value+= lsu->tcache.caches->local_result.power.readOp.dynamic; - value+=(lsu->cache_p==Write_back)? 0:lsu->tcache.missb->local_result.power.searchOp.dynamic; - value+=(lsu->cache_p==Write_back)? 0:lsu->tcache.missb->local_result.power.writeOp.dynamic; - value+=(lsu->cache_p==Write_back)? 0:lsu->tcache.ifb->local_result.power.searchOp.dynamic; - value+=(lsu->cache_p==Write_back)? 0:lsu->tcache.ifb->local_result.power.writeOp.dynamic; - value+=(lsu->cache_p==Write_back)? 0:lsu->tcache.prefetchb->local_result.power.searchOp.dynamic; - value+=(lsu->cache_p==Write_back)? 0:lsu->tcache.prefetchb->local_result.power.writeOp.dynamic; - - //return 0.2*value; - return value; - } - float get_coefficient_tcache_readmisses1(){ - - return lsu->tcache.caches->local_result.power.readOp.dynamic; - - } - float get_coefficient_tcache_readmisses2(){ - float value=0; - value+=(lsu->cache_p==Write_back)? 0:lsu->tcache.missb->local_result.power.searchOp.dynamic; - value+=(lsu->cache_p==Write_back)? 0:lsu->tcache.missb->local_result.power.writeOp.dynamic; - value+=(lsu->cache_p==Write_back)? 0:lsu->tcache.ifb->local_result.power.searchOp.dynamic; - value+=(lsu->cache_p==Write_back)? 0:lsu->tcache.ifb->local_result.power.writeOp.dynamic; - value+=(lsu->cache_p==Write_back)? 0:lsu->tcache.prefetchb->local_result.power.searchOp.dynamic; - value+=(lsu->cache_p==Write_back)? 0:lsu->tcache.prefetchb->local_result.power.writeOp.dynamic; - return value; - } - - - float get_coefficient_ccache_readhits() - { - //return 1.2*lsu->ccache.caches->local_result.power.readOp.dynamic+lsu->xbar_shared->power.readOp.dynamic; - //return 1.2*lsu->ccache.caches->local_result.power.readOp.dynamic+lsu->xbar_shared->power.readOp.dynamic; - return lsu->ccache.caches->local_result.power.readOp.dynamic+lsu->xbar_shared->power.readOp.dynamic; - } - float get_coefficient_ccache_readmisses() - { - float value=0; - value+=lsu->ccache.caches->local_result.power.readOp.dynamic; - value+=(lsu->cache_p==Write_back)? 0:lsu->ccache.missb->local_result.power.searchOp.dynamic; - value+=(lsu->cache_p==Write_back)? 0:lsu->ccache.ifb->local_result.power.searchOp.dynamic; - value+=(lsu->cache_p==Write_back)? 0:lsu->ccache.prefetchb->local_result.power.searchOp.dynamic; - value+=(lsu->cache_p==Write_back)? 0:lsu->ccache.missb->local_result.power.writeOp.dynamic; - value+=(lsu->cache_p==Write_back)? 0:lsu->ccache.ifb->local_result.power.writeOp.dynamic; - value+=(lsu->cache_p==Write_back)? 0:lsu->ccache.prefetchb->local_result.power.writeOp.dynamic; - return value; - } - - float get_coefficient_sharedmemory_readhits() - { - float value=0; - value+=lsu->sharedmemory.caches->local_result.power.readOp.dynamic; - value+=lsu->xbar_shared->power.readOp.dynamic; - //return 3*value; - return value; - } - - float get_coefficient_lsq_accesses() - { - float value=0; - //Changed by Syed -- We have removed LSQ - //value+=2*lsu->LSQ->local_result.power.searchOp.dynamic; - //value+=2*lsu->LSQ->local_result.power.readOp.dynamic; - //value+=2*lsu->LSQ->local_result.power.writeOp.dynamic; - return value; - } - - float get_coefficient_regreads_accesses(){ - float value=0; - value+=((exu->rfu->IRF->local_result.power.readOp.dynamic/32)*(4*2)/*/1.5*/); - value+=exu->rfu->xbar_rfu->power.readOp.dynamic/(32/**1.5*/); - value+=(exu->rfu->arbiter_rfu->power.readOp.dynamic/32/**1.5)*/); - value+=exu->rfu->OPC->local_result.power.readOp.dynamic/*/1.5*/; - return value; - } - - float get_coefficient_regwrites_accesses(){return ((exu->rfu->IRF->local_result.power.writeOp.dynamic/32)*(4*2)/*/1.5*/);} - - float get_coefficient_noregfileops_accesses(){return ((exu->rfu->xbar_rfu->power.readOp.dynamic/(32/**1.5*/))+ - (exu->rfu->arbiter_rfu->power.readOp.dynamic/(32/**1.5*/))+ - (exu->rfu->OPC->local_result.power.readOp.dynamic/*/(1.5)*/));} - - float get_coefficient_ialu_accesses(){ - //return 10*exu->exeu->per_access_energy*g_tp.sckt_co_eff; - return exu->exeu->per_access_energy*g_tp.sckt_co_eff; - } - - float get_coefficient_sfu_accesses(){ - return exu->mul->per_access_energy*g_tp.sckt_co_eff; - //return 2.6*exu->mul->per_access_energy*g_tp.sckt_co_eff; - } - - float get_coefficient_fpu_accesses(){ - //return 3.2*exu->fp_u->per_access_energy*g_tp.sckt_co_eff; - return exu->fp_u->per_access_energy*g_tp.sckt_co_eff; - } - - float get_coefficient_duty_cycle() - { - float value=0; - float num_units=4.0; - value=XML->sys.total_cycles * XML->sys.number_of_cores; - value*=coredynp.num_pipelines; - value/=num_units; - value*=corepipe->power.readOp.dynamic; - value*=3; - return value; - //return 1.5*value; - } - - - - void compute(); - ~Core(); +class Core : public Component { + public: + ParseXML *XML; + int ithCore; + InputParameter interface_ip; + double clockRate, executionTime; + double exClockRate; + double scktRatio, chip_PR_overhead, macro_PR_overhead; + InstFetchU *ifu; + LoadStoreU *lsu; + MemManU *mmu; + EXECU *exu; + RENAMINGU *rnu; + double IdleCoreEnergy; + double IdlePower_PerCore; + Pipeline *corepipe; + UndiffCore *undiffCore; + SharedCache *l2cache; + CoreDynParam coredynp; + double Pipeline_energy; + // full_decoder inst_decoder; + // clock_network clockNetwork; + Core(ParseXML *XML_interface, int ithCore_, InputParameter *interface_ip_); + void set_core_param(); + void computeEnergy(bool is_tdp = true); + void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); + + float get_coefficient_icache_hits() { + // return 1.5*ifu->icache.caches->local_result.power.readOp.dynamic; + return ifu->icache.caches->local_result.power.readOp.dynamic; + } + + float get_coefficient_icache_misses() { + float value = 0; + value += ifu->icache.caches->local_result.power.writeOp.dynamic; + value += ifu->icache.caches->local_result.power.readOp.dynamic; + value += ifu->icache.missb->local_result.power.searchOp.dynamic; + value += ifu->icache.missb->local_result.power.writeOp.dynamic; + value += ifu->icache.ifb->local_result.power.searchOp.dynamic; + value += ifu->icache.ifb->local_result.power.writeOp.dynamic; + value += ifu->icache.prefetchb->local_result.power.searchOp.dynamic; + value += ifu->icache.prefetchb->local_result.power.writeOp.dynamic; + return value; + } + + float get_coefficient_tot_insts() { + float value = 0; + value += ifu->IB->local_result.power.readOp.dynamic; + value += ifu->IB->local_result.power.writeOp.dynamic; + value += ifu->ID_inst->power_t.readOp.dynamic; + value += ifu->ID_operand->power_t.readOp.dynamic; + value += ifu->ID_misc->power_t.readOp.dynamic; + return value; + } + + float get_coefficient_fpint_insts() { + float value = 0; + value += exu->scheu->int_inst_window->local_result.power.readOp.dynamic; + value += + 2 * exu->scheu->int_inst_window->local_result.power.searchOp.dynamic; + value += exu->scheu->int_inst_window->local_result.power.writeOp.dynamic; + value += exu->scheu->instruction_selection->power.readOp.dynamic; + return value; + } + + float get_coefficient_dcache_readhits() { + float value = 0; + value += lsu->dcache.caches->local_result.power.readOp.dynamic; + value += lsu->xbar_shared->power.readOp.dynamic; + // return 0.5*value; + return value; + } + float get_coefficient_dcache_readmisses() { + float value = 0; + value += lsu->dcache.caches->local_result.power.readOp.dynamic; + value += (lsu->cache_p == Write_back) + ? 0 + : lsu->dcache.missb->local_result.power.searchOp.dynamic; + value += (lsu->cache_p == Write_back) + ? 0 + : lsu->dcache.ifb->local_result.power.searchOp.dynamic; + value += (lsu->cache_p == Write_back) + ? 0 + : lsu->dcache.prefetchb->local_result.power.searchOp.dynamic; + value += (lsu->cache_p == Write_back) + ? 0 + : lsu->dcache.missb->local_result.power.writeOp.dynamic; + value += (lsu->cache_p == Write_back) + ? 0 + : lsu->dcache.ifb->local_result.power.writeOp.dynamic; + value += (lsu->cache_p == Write_back) + ? 0 + : lsu->dcache.prefetchb->local_result.power.writeOp.dynamic; + + // return 0.5*value; + return value; + } + float get_coefficient_dcache_writehits() { + float value = 0; + value += lsu->dcache.caches->local_result.power.writeOp.dynamic; + value += lsu->xbar_shared->power.readOp.dynamic; + return value; + } + float get_coefficient_dcache_writemisses() { + float value = 0; + value += lsu->dcache.caches->local_result.power.writeOp.dynamic; + value += lsu->dcache.caches->local_result.tag_array2->power.readOp.dynamic; + value += (lsu->cache_p == Write_back) + ? lsu->dcache.caches->local_result.power.writeOp.dynamic + : 0; + value += (lsu->cache_p == Write_back) + ? lsu->dcache.missb->local_result.power.searchOp.dynamic + : 0; + value += (lsu->cache_p == Write_back) + ? lsu->dcache.ifb->local_result.power.searchOp.dynamic + : 0; + value += (lsu->cache_p == Write_back) + ? lsu->dcache.prefetchb->local_result.power.searchOp.dynamic + : 0; + value += (lsu->cache_p == Write_back) + ? lsu->dcache.wbb->local_result.power.searchOp.dynamic + : 0; + value += (lsu->cache_p == Write_back) + ? lsu->dcache.missb->local_result.power.writeOp.dynamic + : 0; + value += (lsu->cache_p == Write_back) + ? lsu->dcache.ifb->local_result.power.writeOp.dynamic + : 0; + value += (lsu->cache_p == Write_back) + ? lsu->dcache.prefetchb->local_result.power.writeOp.dynamic + : 0; + value += (lsu->cache_p == Write_back) + ? lsu->dcache.wbb->local_result.power.writeOp.dynamic + : 0; + // return 1.6*value; + return value; + } + + float get_coefficient_tcache_readhits() { + float value = 0; + value += lsu->tcache.caches->local_result.power.readOp.dynamic; + value += lsu->xbar_shared->power.readOp.dynamic; + // return 0.2*value; + return value; + } + float get_coefficient_tcache_readmisses() { + float value = 0; + value += lsu->tcache.caches->local_result.power.readOp.dynamic; + value += (lsu->cache_p == Write_back) + ? 0 + : lsu->tcache.missb->local_result.power.searchOp.dynamic; + value += (lsu->cache_p == Write_back) + ? 0 + : lsu->tcache.missb->local_result.power.writeOp.dynamic; + value += (lsu->cache_p == Write_back) + ? 0 + : lsu->tcache.ifb->local_result.power.searchOp.dynamic; + value += (lsu->cache_p == Write_back) + ? 0 + : lsu->tcache.ifb->local_result.power.writeOp.dynamic; + value += (lsu->cache_p == Write_back) + ? 0 + : lsu->tcache.prefetchb->local_result.power.searchOp.dynamic; + value += (lsu->cache_p == Write_back) + ? 0 + : lsu->tcache.prefetchb->local_result.power.writeOp.dynamic; + + // return 0.2*value; + return value; + } + float get_coefficient_tcache_readmisses1() { + return lsu->tcache.caches->local_result.power.readOp.dynamic; + } + float get_coefficient_tcache_readmisses2() { + float value = 0; + value += (lsu->cache_p == Write_back) + ? 0 + : lsu->tcache.missb->local_result.power.searchOp.dynamic; + value += (lsu->cache_p == Write_back) + ? 0 + : lsu->tcache.missb->local_result.power.writeOp.dynamic; + value += (lsu->cache_p == Write_back) + ? 0 + : lsu->tcache.ifb->local_result.power.searchOp.dynamic; + value += (lsu->cache_p == Write_back) + ? 0 + : lsu->tcache.ifb->local_result.power.writeOp.dynamic; + value += (lsu->cache_p == Write_back) + ? 0 + : lsu->tcache.prefetchb->local_result.power.searchOp.dynamic; + value += (lsu->cache_p == Write_back) + ? 0 + : lsu->tcache.prefetchb->local_result.power.writeOp.dynamic; + return value; + } + + float get_coefficient_ccache_readhits() { + // return 1.2*lsu->ccache.caches->local_result.power.readOp.dynamic+lsu->xbar_shared->power.readOp.dynamic; + // return 1.2*lsu->ccache.caches->local_result.power.readOp.dynamic+lsu->xbar_shared->power.readOp.dynamic; + return lsu->ccache.caches->local_result.power.readOp.dynamic + + lsu->xbar_shared->power.readOp.dynamic; + } + float get_coefficient_ccache_readmisses() { + float value = 0; + value += lsu->ccache.caches->local_result.power.readOp.dynamic; + value += (lsu->cache_p == Write_back) + ? 0 + : lsu->ccache.missb->local_result.power.searchOp.dynamic; + value += (lsu->cache_p == Write_back) + ? 0 + : lsu->ccache.ifb->local_result.power.searchOp.dynamic; + value += (lsu->cache_p == Write_back) + ? 0 + : lsu->ccache.prefetchb->local_result.power.searchOp.dynamic; + value += (lsu->cache_p == Write_back) + ? 0 + : lsu->ccache.missb->local_result.power.writeOp.dynamic; + value += (lsu->cache_p == Write_back) + ? 0 + : lsu->ccache.ifb->local_result.power.writeOp.dynamic; + value += (lsu->cache_p == Write_back) + ? 0 + : lsu->ccache.prefetchb->local_result.power.writeOp.dynamic; + return value; + } + + float get_coefficient_sharedmemory_readhits() { + float value = 0; + value += lsu->sharedmemory.caches->local_result.power.readOp.dynamic; + value += lsu->xbar_shared->power.readOp.dynamic; + // return 3*value; + return value; + } + + float get_coefficient_lsq_accesses() { + float value = 0; + // Changed by Syed -- We have removed LSQ + // value+=2*lsu->LSQ->local_result.power.searchOp.dynamic; + // value+=2*lsu->LSQ->local_result.power.readOp.dynamic; + // value+=2*lsu->LSQ->local_result.power.writeOp.dynamic; + return value; + } + + float get_coefficient_regreads_accesses() { + float value = 0; + value += ((exu->rfu->IRF->local_result.power.readOp.dynamic / 32) * + (4 * 2) /*/1.5*/); + value += exu->rfu->xbar_rfu->power.readOp.dynamic / (32 /**1.5*/); + value += (exu->rfu->arbiter_rfu->power.readOp.dynamic / 32 /**1.5)*/); + value += exu->rfu->OPC->local_result.power.readOp.dynamic /*/1.5*/; + return value; + } + + float get_coefficient_regwrites_accesses() { + return ((exu->rfu->IRF->local_result.power.writeOp.dynamic / 32) * + (4 * 2) /*/1.5*/); + } + + float get_coefficient_noregfileops_accesses() { + return ((exu->rfu->xbar_rfu->power.readOp.dynamic / (32 /**1.5*/)) + + (exu->rfu->arbiter_rfu->power.readOp.dynamic / (32 /**1.5*/)) + + (exu->rfu->OPC->local_result.power.readOp.dynamic /*/(1.5)*/)); + } + + float get_coefficient_ialu_accesses() { + // return 10*exu->exeu->per_access_energy*g_tp.sckt_co_eff; + return exu->exeu->per_access_energy * g_tp.sckt_co_eff; + } + + float get_coefficient_sfu_accesses() { + return exu->mul->per_access_energy * g_tp.sckt_co_eff; + // return 2.6*exu->mul->per_access_energy*g_tp.sckt_co_eff; + } + + float get_coefficient_fpu_accesses() { + // return 3.2*exu->fp_u->per_access_energy*g_tp.sckt_co_eff; + return exu->fp_u->per_access_energy * g_tp.sckt_co_eff; + } + + float get_coefficient_duty_cycle() { + float value = 0; + float num_units = 4.0; + value = XML->sys.total_cycles * XML->sys.number_of_cores; + value *= coredynp.num_pipelines; + value /= num_units; + value *= corepipe->power.readOp.dynamic; + value *= 3; + return value; + // return 1.5*value; + } + + void compute(); + ~Core(); }; #endif /* CORE_H_ */ diff --git a/src/gpuwattch/globalvar.h b/src/gpuwattch/globalvar.h index 9532576..e0b76c2 100644 --- a/src/gpuwattch/globalvar.h +++ b/src/gpuwattch/globalvar.h @@ -29,11 +29,10 @@ * ***************************************************************************/ - #ifndef GLOBALVAR_H_ #define GLOBALVAR_H_ -#ifdef GLOBALVAR +#ifdef GLOBALVAR #define EXTERN #else #define EXTERN extern @@ -42,7 +41,3 @@ EXTERN bool opt_for_clk; #endif /* GLOBALVAR_H_ */ - - - - diff --git a/src/gpuwattch/gpgpu_sim_wrapper.cc b/src/gpuwattch/gpgpu_sim_wrapper.cc index efb3e6b..f2989f6 100644 --- a/src/gpuwattch/gpgpu_sim_wrapper.cc +++ b/src/gpuwattch/gpgpu_sim_wrapper.cc @@ -7,755 +7,857 @@ // // Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. -// Redistributions in binary form must reproduce the above copyright notice, this -// list of conditions and the following disclaimer in the documentation and/or -// other materials provided with the distribution. -// Neither the name of The University of British Columbia nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. +// Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. Neither the name of +// The University of British Columbia nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. #include "gpgpu_sim_wrapper.h" #include #define SP_BASE_POWER 0 -#define SFU_BASE_POWER 0 +#define SFU_BASE_POWER 0 - -static const char * pwr_cmp_label[] = {"IBP,", "ICP,", "DCP,", "TCP,", "CCP,", "SHRDP,", "RFP,", "SPP,", - "SFUP,", "FPUP,", "SCHEDP,", "L2CP,", "MCP,", "NOCP,", "DRAMP,", - "PIPEP,", "IDLE_COREP,", "CONST_DYNAMICP"}; +static const char* pwr_cmp_label[] = { + "IBP,", "ICP,", "DCP,", "TCP,", "CCP,", "SHRDP,", + "RFP,", "SPP,", "SFUP,", "FPUP,", "SCHEDP,", "L2CP,", + "MCP,", "NOCP,", "DRAMP,", "PIPEP,", "IDLE_COREP,", "CONST_DYNAMICP"}; enum pwr_cmp_t { - IBP=0, - ICP, - DCP, - TCP, - CCP, - SHRDP, - RFP, - SPP, - SFUP, - FPUP, - SCHEDP, - L2CP, - MCP, - NOCP, - DRAMP, - PIPEP, - IDLE_COREP, - CONST_DYNAMICP, - NUM_COMPONENTS_MODELLED + IBP = 0, + ICP, + DCP, + TCP, + CCP, + SHRDP, + RFP, + SPP, + SFUP, + FPUP, + SCHEDP, + L2CP, + MCP, + NOCP, + DRAMP, + PIPEP, + IDLE_COREP, + CONST_DYNAMICP, + NUM_COMPONENTS_MODELLED }; - -gpgpu_sim_wrapper::gpgpu_sim_wrapper( bool power_simulation_enabled, char* xmlfile) { - kernel_sample_count=0; - total_sample_count=0; - - kernel_tot_power=0; - - num_pwr_cmps=NUM_COMPONENTS_MODELLED; - num_perf_counters=NUM_PERFORMANCE_COUNTERS; - - // Initialize per-component counter/power vectors - avg_max_min_counters init; - kernel_cmp_pwr.resize(NUM_COMPONENTS_MODELLED, init); - kernel_cmp_perf_counters.resize(NUM_PERFORMANCE_COUNTERS, init); - - kernel_power = init; // Per-kernel powers - gpu_tot_power = init; // Global powers - - sample_cmp_pwr.resize(NUM_COMPONENTS_MODELLED, 0); - - sample_perf_counters.resize(NUM_PERFORMANCE_COUNTERS, 0); - initpower_coeff.resize(NUM_PERFORMANCE_COUNTERS, 0); - effpower_coeff.resize(NUM_PERFORMANCE_COUNTERS, 0); - - const_dynamic_power=0; - proc_power=0; - - g_power_filename = NULL; - g_power_trace_filename = NULL; - g_metric_trace_filename = NULL; - g_steady_state_tracking_filename = NULL; - xml_filename= xmlfile; - g_power_simulation_enabled= power_simulation_enabled; - g_power_trace_enabled= false; - g_steady_power_levels_enabled= false; - g_power_trace_zlevel= 0; - g_power_per_cycle_dump= false; - gpu_steady_power_deviation= 0; - gpu_steady_min_period= 0; - - gpu_stat_sample_freq=0; - p=new ParseXML(); - if (g_power_simulation_enabled){ - p->parse(xml_filename); - } - proc = new Processor(p); - power_trace_file = NULL; - metric_trace_file = NULL; - steady_state_tacking_file = NULL; - has_written_avg=false; - init_inst_val=false; - +gpgpu_sim_wrapper::gpgpu_sim_wrapper(bool power_simulation_enabled, + char* xmlfile) { + kernel_sample_count = 0; + total_sample_count = 0; + + kernel_tot_power = 0; + + num_pwr_cmps = NUM_COMPONENTS_MODELLED; + num_perf_counters = NUM_PERFORMANCE_COUNTERS; + + // Initialize per-component counter/power vectors + avg_max_min_counters init; + kernel_cmp_pwr.resize(NUM_COMPONENTS_MODELLED, init); + kernel_cmp_perf_counters.resize(NUM_PERFORMANCE_COUNTERS, init); + + kernel_power = init; // Per-kernel powers + gpu_tot_power = init; // Global powers + + sample_cmp_pwr.resize(NUM_COMPONENTS_MODELLED, 0); + + sample_perf_counters.resize(NUM_PERFORMANCE_COUNTERS, 0); + initpower_coeff.resize(NUM_PERFORMANCE_COUNTERS, 0); + effpower_coeff.resize(NUM_PERFORMANCE_COUNTERS, 0); + + const_dynamic_power = 0; + proc_power = 0; + + g_power_filename = NULL; + g_power_trace_filename = NULL; + g_metric_trace_filename = NULL; + g_steady_state_tracking_filename = NULL; + xml_filename = xmlfile; + g_power_simulation_enabled = power_simulation_enabled; + g_power_trace_enabled = false; + g_steady_power_levels_enabled = false; + g_power_trace_zlevel = 0; + g_power_per_cycle_dump = false; + gpu_steady_power_deviation = 0; + gpu_steady_min_period = 0; + + gpu_stat_sample_freq = 0; + p = new ParseXML(); + if (g_power_simulation_enabled) { + p->parse(xml_filename); + } + proc = new Processor(p); + power_trace_file = NULL; + metric_trace_file = NULL; + steady_state_tacking_file = NULL; + has_written_avg = false; + init_inst_val = false; } -gpgpu_sim_wrapper::~gpgpu_sim_wrapper() { } +gpgpu_sim_wrapper::~gpgpu_sim_wrapper() {} -bool gpgpu_sim_wrapper::sanity_check(double a, double b) -{ - if (b == 0) - return (abs(a-b)<0.00001); - else - return (abs(a-b)/abs(b)<0.00001); +bool gpgpu_sim_wrapper::sanity_check(double a, double b) { + if (b == 0) + return (abs(a - b) < 0.00001); + else + return (abs(a - b) / abs(b) < 0.00001); - return false; + return false; } -void gpgpu_sim_wrapper::init_mcpat(char* xmlfile, char* powerfilename, char* power_trace_filename,char* metric_trace_filename, - char * steady_state_filename, bool power_sim_enabled,bool trace_enabled, - bool steady_state_enabled,bool power_per_cycle_dump,double steady_power_deviation, - double steady_min_period, int zlevel, double init_val,int stat_sample_freq ){ - // Write File Headers for (-metrics trace, -power trace) - - reset_counters(); - static bool mcpat_init=true; - - // initialize file name if it is not set - time_t curr_time; - time(&curr_time); - char *date = ctime(&curr_time); - char *s = date; - while (*s) { - if (*s == ' ' || *s == '\t' || *s == ':') *s = '-'; - if (*s == '\n' || *s == '\r' ) *s = 0; - s++; - } - - if(mcpat_init){ - g_power_filename = powerfilename; - g_power_trace_filename =power_trace_filename; - g_metric_trace_filename = metric_trace_filename; - g_steady_state_tracking_filename = steady_state_filename; - xml_filename=xmlfile; - g_power_simulation_enabled=power_sim_enabled; - g_power_trace_enabled=trace_enabled; - g_steady_power_levels_enabled=steady_state_enabled; - g_power_trace_zlevel=zlevel; - g_power_per_cycle_dump=power_per_cycle_dump; - gpu_steady_power_deviation=steady_power_deviation; - gpu_steady_min_period=steady_min_period; - - gpu_stat_sample_freq=stat_sample_freq; - - //p->sys.total_cycles=gpu_stat_sample_freq*4; - p->sys.total_cycles=gpu_stat_sample_freq; - power_trace_file = NULL; - metric_trace_file = NULL; - steady_state_tacking_file = NULL; - - - if (g_power_trace_enabled ){ - power_trace_file = gzopen(g_power_trace_filename, "w"); - metric_trace_file = gzopen(g_metric_trace_filename, "w"); - if ((power_trace_file == NULL) || (metric_trace_file == NULL)) { - printf("error - could not open trace files \n"); - exit(1); - } - gzsetparams(power_trace_file, g_power_trace_zlevel, Z_DEFAULT_STRATEGY); - - gzprintf(power_trace_file,"power,"); - for(unsigned i=0; isys.total_cycles=gpu_stat_sample_freq*4; + p->sys.total_cycles = gpu_stat_sample_freq; + power_trace_file = NULL; + metric_trace_file = NULL; + steady_state_tacking_file = NULL; + + if (g_power_trace_enabled) { + power_trace_file = gzopen(g_power_trace_filename, "w"); + metric_trace_file = gzopen(g_metric_trace_filename, "w"); + if ((power_trace_file == NULL) || (metric_trace_file == NULL)) { + printf("error - could not open trace files \n"); + exit(1); + } + gzsetparams(power_trace_file, g_power_trace_zlevel, Z_DEFAULT_STRATEGY); + + gzprintf(power_trace_file, "power,"); + for (unsigned i = 0; i < num_pwr_cmps; i++) { + gzprintf(power_trace_file, pwr_cmp_label[i]); + } + gzprintf(power_trace_file, "\n"); + + gzsetparams(metric_trace_file, g_power_trace_zlevel, Z_DEFAULT_STRATEGY); + for (unsigned i = 0; i < num_perf_counters; i++) { + gzprintf(metric_trace_file, perf_count_label[i]); + } + gzprintf(metric_trace_file, "\n"); + + gzclose(power_trace_file); + gzclose(metric_trace_file); + } + if (g_steady_power_levels_enabled) { + steady_state_tacking_file = gzopen(g_steady_state_tracking_filename, "w"); + if ((steady_state_tacking_file == NULL)) { + printf("error - could not open trace files \n"); + exit(1); + } + gzsetparams(steady_state_tacking_file, g_power_trace_zlevel, + Z_DEFAULT_STRATEGY); + gzprintf(steady_state_tacking_file, "start,end,power,IPC,"); + for (unsigned i = 0; i < num_perf_counters; i++) { + gzprintf(steady_state_tacking_file, perf_count_label[i]); + } + gzprintf(steady_state_tacking_file, "\n"); + + gzclose(steady_state_tacking_file); + } + mcpat_init = false; + has_written_avg = false; + powerfile.open(g_power_filename); + int flg = chmod(g_power_filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + assert(flg == 0); + } + sample_val = 0; + init_inst_val = init_val; // gpu_tot_sim_insn+gpu_sim_insn; } -void gpgpu_sim_wrapper::reset_counters(){ - - avg_max_min_counters init; - for(unsigned i=0; i init; + for (unsigned i = 0; i < num_perf_counters; ++i) { + sample_perf_counters[i] = 0; + kernel_cmp_perf_counters[i] = init; + } + for (unsigned i = 0; i < num_pwr_cmps; ++i) { + sample_cmp_pwr[i] = 0; + kernel_cmp_pwr[i] = init; + } + + // Reset per-kernel counters + kernel_sample_count = 0; + kernel_tot_power = 0; + kernel_power = init; + + return; } -void gpgpu_sim_wrapper::set_inst_power(bool clk_gated_lanes, double tot_cycles, double busy_cycles, double tot_inst, double int_inst, double fp_inst, double load_inst, double store_inst, double committed_inst) -{ - p->sys.core[0].gpgpu_clock_gated_lanes = clk_gated_lanes; - p->sys.core[0].total_cycles = tot_cycles; - p->sys.core[0].busy_cycles = busy_cycles; - p->sys.core[0].total_instructions = tot_inst * p->sys.scaling_coefficients[TOT_INST]; - p->sys.core[0].int_instructions = int_inst * p->sys.scaling_coefficients[FP_INT]; - p->sys.core[0].fp_instructions = fp_inst * p->sys.scaling_coefficients[FP_INT]; - p->sys.core[0].load_instructions = load_inst; - p->sys.core[0].store_instructions = store_inst; - p->sys.core[0].committed_instructions = committed_inst; - sample_perf_counters[FP_INT]=int_inst+fp_inst; - sample_perf_counters[TOT_INST]=tot_inst; +void gpgpu_sim_wrapper::set_inst_power(bool clk_gated_lanes, double tot_cycles, + double busy_cycles, double tot_inst, + double int_inst, double fp_inst, + double load_inst, double store_inst, + double committed_inst) { + p->sys.core[0].gpgpu_clock_gated_lanes = clk_gated_lanes; + p->sys.core[0].total_cycles = tot_cycles; + p->sys.core[0].busy_cycles = busy_cycles; + p->sys.core[0].total_instructions = + tot_inst * p->sys.scaling_coefficients[TOT_INST]; + p->sys.core[0].int_instructions = + int_inst * p->sys.scaling_coefficients[FP_INT]; + p->sys.core[0].fp_instructions = + fp_inst * p->sys.scaling_coefficients[FP_INT]; + p->sys.core[0].load_instructions = load_inst; + p->sys.core[0].store_instructions = store_inst; + p->sys.core[0].committed_instructions = committed_inst; + sample_perf_counters[FP_INT] = int_inst + fp_inst; + sample_perf_counters[TOT_INST] = tot_inst; } -void gpgpu_sim_wrapper::set_regfile_power(double reads, double writes,double ops) -{ - p->sys.core[0].int_regfile_reads = reads * p->sys.scaling_coefficients[REG_RD]; - p->sys.core[0].int_regfile_writes = writes * p->sys.scaling_coefficients[REG_WR]; - p->sys.core[0].non_rf_operands = ops *p->sys.scaling_coefficients[NON_REG_OPs]; - sample_perf_counters[REG_RD]=reads; - sample_perf_counters[REG_WR]=writes; - sample_perf_counters[NON_REG_OPs]=ops; - - - +void gpgpu_sim_wrapper::set_regfile_power(double reads, double writes, + double ops) { + p->sys.core[0].int_regfile_reads = + reads * p->sys.scaling_coefficients[REG_RD]; + p->sys.core[0].int_regfile_writes = + writes * p->sys.scaling_coefficients[REG_WR]; + p->sys.core[0].non_rf_operands = + ops * p->sys.scaling_coefficients[NON_REG_OPs]; + sample_perf_counters[REG_RD] = reads; + sample_perf_counters[REG_WR] = writes; + sample_perf_counters[NON_REG_OPs] = ops; } -void gpgpu_sim_wrapper::set_icache_power(double hits, double misses) -{ - p->sys.core[0].icache.read_accesses = hits * p->sys.scaling_coefficients[IC_H]+misses * p->sys.scaling_coefficients[IC_M]; - p->sys.core[0].icache.read_misses = misses * p->sys.scaling_coefficients[IC_M]; - sample_perf_counters[IC_H]=hits; - sample_perf_counters[IC_M]=misses; - - +void gpgpu_sim_wrapper::set_icache_power(double hits, double misses) { + p->sys.core[0].icache.read_accesses = + hits * p->sys.scaling_coefficients[IC_H] + + misses * p->sys.scaling_coefficients[IC_M]; + p->sys.core[0].icache.read_misses = + misses * p->sys.scaling_coefficients[IC_M]; + sample_perf_counters[IC_H] = hits; + sample_perf_counters[IC_M] = misses; } -void gpgpu_sim_wrapper::set_ccache_power(double hits, double misses) -{ - p->sys.core[0].ccache.read_accesses = hits * p->sys.scaling_coefficients[CC_H]+misses * p->sys.scaling_coefficients[CC_M]; - p->sys.core[0].ccache.read_misses = misses * p->sys.scaling_coefficients[CC_M]; - sample_perf_counters[CC_H]=hits; - sample_perf_counters[CC_M]=misses; - // TODO: coalescing logic is counted as part of the caches power (this is not valid for no-caches architectures) - +void gpgpu_sim_wrapper::set_ccache_power(double hits, double misses) { + p->sys.core[0].ccache.read_accesses = + hits * p->sys.scaling_coefficients[CC_H] + + misses * p->sys.scaling_coefficients[CC_M]; + p->sys.core[0].ccache.read_misses = + misses * p->sys.scaling_coefficients[CC_M]; + sample_perf_counters[CC_H] = hits; + sample_perf_counters[CC_M] = misses; + // TODO: coalescing logic is counted as part of the caches power (this is not + // valid for no-caches architectures) } -void gpgpu_sim_wrapper::set_tcache_power(double hits, double misses) -{ - p->sys.core[0].tcache.read_accesses = hits * p->sys.scaling_coefficients[TC_H]+misses * p->sys.scaling_coefficients[TC_M]; - p->sys.core[0].tcache.read_misses = misses* p->sys.scaling_coefficients[TC_M]; - sample_perf_counters[TC_H]=hits; - sample_perf_counters[TC_M]=misses; - // TODO: coalescing logic is counted as part of the caches power (this is not valid for no-caches architectures) +void gpgpu_sim_wrapper::set_tcache_power(double hits, double misses) { + p->sys.core[0].tcache.read_accesses = + hits * p->sys.scaling_coefficients[TC_H] + + misses * p->sys.scaling_coefficients[TC_M]; + p->sys.core[0].tcache.read_misses = + misses * p->sys.scaling_coefficients[TC_M]; + sample_perf_counters[TC_H] = hits; + sample_perf_counters[TC_M] = misses; + // TODO: coalescing logic is counted as part of the caches power (this is not + // valid for no-caches architectures) } -void gpgpu_sim_wrapper::set_shrd_mem_power(double accesses) -{ - p->sys.core[0].sharedmemory.read_accesses = accesses * p->sys.scaling_coefficients[SHRD_ACC]; - sample_perf_counters[SHRD_ACC]=accesses; - - +void gpgpu_sim_wrapper::set_shrd_mem_power(double accesses) { + p->sys.core[0].sharedmemory.read_accesses = + accesses * p->sys.scaling_coefficients[SHRD_ACC]; + sample_perf_counters[SHRD_ACC] = accesses; } -void gpgpu_sim_wrapper::set_l1cache_power(double read_hits, double read_misses, double write_hits, double write_misses) -{ - p->sys.core[0].dcache.read_accesses = read_hits * p->sys.scaling_coefficients[DC_RH] +read_misses * p->sys.scaling_coefficients[DC_RM]; - p->sys.core[0].dcache.read_misses = read_misses * p->sys.scaling_coefficients[DC_RM]; - p->sys.core[0].dcache.write_accesses = write_hits * p->sys.scaling_coefficients[DC_WH]+write_misses * p->sys.scaling_coefficients[DC_WM]; - p->sys.core[0].dcache.write_misses = write_misses * p->sys.scaling_coefficients[DC_WM]; - sample_perf_counters[DC_RH]=read_hits; - sample_perf_counters[DC_RM]=read_misses; - sample_perf_counters[DC_WH]=write_hits; - sample_perf_counters[DC_WM]=write_misses; - // TODO: coalescing logic is counted as part of the caches power (this is not valid for no-caches architectures) - - - +void gpgpu_sim_wrapper::set_l1cache_power(double read_hits, double read_misses, + double write_hits, + double write_misses) { + p->sys.core[0].dcache.read_accesses = + read_hits * p->sys.scaling_coefficients[DC_RH] + + read_misses * p->sys.scaling_coefficients[DC_RM]; + p->sys.core[0].dcache.read_misses = + read_misses * p->sys.scaling_coefficients[DC_RM]; + p->sys.core[0].dcache.write_accesses = + write_hits * p->sys.scaling_coefficients[DC_WH] + + write_misses * p->sys.scaling_coefficients[DC_WM]; + p->sys.core[0].dcache.write_misses = + write_misses * p->sys.scaling_coefficients[DC_WM]; + sample_perf_counters[DC_RH] = read_hits; + sample_perf_counters[DC_RM] = read_misses; + sample_perf_counters[DC_WH] = write_hits; + sample_perf_counters[DC_WM] = write_misses; + // TODO: coalescing logic is counted as part of the caches power (this is not + // valid for no-caches architectures) } -void gpgpu_sim_wrapper::set_l2cache_power(double read_hits, double read_misses, double write_hits, double write_misses) -{ - p->sys.l2.total_accesses = read_hits* p->sys.scaling_coefficients[L2_RH]+read_misses * p->sys.scaling_coefficients[L2_RM]+ write_hits * p->sys.scaling_coefficients[L2_WH]+write_misses * p->sys.scaling_coefficients[L2_WM]; - p->sys.l2.read_accesses = read_hits* p->sys.scaling_coefficients[L2_RH]+read_misses* p->sys.scaling_coefficients[L2_RM]; - p->sys.l2.write_accesses = write_hits * p->sys.scaling_coefficients[L2_WH]+write_misses * p->sys.scaling_coefficients[L2_WM]; - p->sys.l2.read_hits = read_hits * p->sys.scaling_coefficients[L2_RH]; - p->sys.l2.read_misses = read_misses * p->sys.scaling_coefficients[L2_RM]; - p->sys.l2.write_hits =write_hits * p->sys.scaling_coefficients[L2_WH]; - p->sys.l2.write_misses = write_misses * p->sys.scaling_coefficients[L2_WM]; - sample_perf_counters[L2_RH]=read_hits; - sample_perf_counters[L2_RM]=read_misses; - sample_perf_counters[L2_WH]=write_hits; - sample_perf_counters[L2_WM]=write_misses; +void gpgpu_sim_wrapper::set_l2cache_power(double read_hits, double read_misses, + double write_hits, + double write_misses) { + p->sys.l2.total_accesses = read_hits * p->sys.scaling_coefficients[L2_RH] + + read_misses * p->sys.scaling_coefficients[L2_RM] + + write_hits * p->sys.scaling_coefficients[L2_WH] + + write_misses * p->sys.scaling_coefficients[L2_WM]; + p->sys.l2.read_accesses = read_hits * p->sys.scaling_coefficients[L2_RH] + + read_misses * p->sys.scaling_coefficients[L2_RM]; + p->sys.l2.write_accesses = write_hits * p->sys.scaling_coefficients[L2_WH] + + write_misses * p->sys.scaling_coefficients[L2_WM]; + p->sys.l2.read_hits = read_hits * p->sys.scaling_coefficients[L2_RH]; + p->sys.l2.read_misses = read_misses * p->sys.scaling_coefficients[L2_RM]; + p->sys.l2.write_hits = write_hits * p->sys.scaling_coefficients[L2_WH]; + p->sys.l2.write_misses = write_misses * p->sys.scaling_coefficients[L2_WM]; + sample_perf_counters[L2_RH] = read_hits; + sample_perf_counters[L2_RM] = read_misses; + sample_perf_counters[L2_WH] = write_hits; + sample_perf_counters[L2_WM] = write_misses; } -void gpgpu_sim_wrapper::set_idle_core_power(double num_idle_core) -{ - p->sys.num_idle_cores = num_idle_core; - sample_perf_counters[IDLE_CORE_N]=num_idle_core; +void gpgpu_sim_wrapper::set_idle_core_power(double num_idle_core) { + p->sys.num_idle_cores = num_idle_core; + sample_perf_counters[IDLE_CORE_N] = num_idle_core; } -void gpgpu_sim_wrapper::set_duty_cycle_power(double duty_cycle) -{ - p->sys.core[0].pipeline_duty_cycle = duty_cycle * p->sys.scaling_coefficients[PIPE_A]; - sample_perf_counters[PIPE_A]=duty_cycle; - +void gpgpu_sim_wrapper::set_duty_cycle_power(double duty_cycle) { + p->sys.core[0].pipeline_duty_cycle = + duty_cycle * p->sys.scaling_coefficients[PIPE_A]; + sample_perf_counters[PIPE_A] = duty_cycle; } -void gpgpu_sim_wrapper::set_mem_ctrl_power(double reads, double writes, double dram_precharge) -{ - p->sys.mc.memory_accesses = reads * p->sys.scaling_coefficients[MEM_RD]+ writes * p->sys.scaling_coefficients[MEM_WR]; - p->sys.mc.memory_reads = reads *p->sys.scaling_coefficients[MEM_RD]; - p->sys.mc.memory_writes = writes*p->sys.scaling_coefficients[MEM_WR]; - p->sys.mc.dram_pre = dram_precharge*p->sys.scaling_coefficients[MEM_PRE]; - sample_perf_counters[MEM_RD]=reads; - sample_perf_counters[MEM_WR]=writes; - sample_perf_counters[MEM_PRE]=dram_precharge; - +void gpgpu_sim_wrapper::set_mem_ctrl_power(double reads, double writes, + double dram_precharge) { + p->sys.mc.memory_accesses = reads * p->sys.scaling_coefficients[MEM_RD] + + writes * p->sys.scaling_coefficients[MEM_WR]; + p->sys.mc.memory_reads = reads * p->sys.scaling_coefficients[MEM_RD]; + p->sys.mc.memory_writes = writes * p->sys.scaling_coefficients[MEM_WR]; + p->sys.mc.dram_pre = dram_precharge * p->sys.scaling_coefficients[MEM_PRE]; + sample_perf_counters[MEM_RD] = reads; + sample_perf_counters[MEM_WR] = writes; + sample_perf_counters[MEM_PRE] = dram_precharge; } -void gpgpu_sim_wrapper::set_exec_unit_power(double fpu_accesses, double ialu_accesses, double sfu_accesses) -{ - p->sys.core[0].fpu_accesses = fpu_accesses*p->sys.scaling_coefficients[FPU_ACC]; - //Integer ALU (not present in Tesla) - p->sys.core[0].ialu_accesses = ialu_accesses*p->sys.scaling_coefficients[SP_ACC]; - //Sfu accesses - p->sys.core[0].mul_accesses = sfu_accesses*p->sys.scaling_coefficients[SFU_ACC]; - - sample_perf_counters[SP_ACC]=ialu_accesses; - sample_perf_counters[SFU_ACC]=sfu_accesses; - sample_perf_counters[FPU_ACC]=fpu_accesses; - - +void gpgpu_sim_wrapper::set_exec_unit_power(double fpu_accesses, + double ialu_accesses, + double sfu_accesses) { + p->sys.core[0].fpu_accesses = + fpu_accesses * p->sys.scaling_coefficients[FPU_ACC]; + // Integer ALU (not present in Tesla) + p->sys.core[0].ialu_accesses = + ialu_accesses * p->sys.scaling_coefficients[SP_ACC]; + // Sfu accesses + p->sys.core[0].mul_accesses = + sfu_accesses * p->sys.scaling_coefficients[SFU_ACC]; + + sample_perf_counters[SP_ACC] = ialu_accesses; + sample_perf_counters[SFU_ACC] = sfu_accesses; + sample_perf_counters[FPU_ACC] = fpu_accesses; } -void gpgpu_sim_wrapper::set_active_lanes_power(double sp_avg_active_lane, double sfu_avg_active_lane) -{ - p->sys.core[0].sp_average_active_lanes = sp_avg_active_lane; - p->sys.core[0].sfu_average_active_lanes = sfu_avg_active_lane; +void gpgpu_sim_wrapper::set_active_lanes_power(double sp_avg_active_lane, + double sfu_avg_active_lane) { + p->sys.core[0].sp_average_active_lanes = sp_avg_active_lane; + p->sys.core[0].sfu_average_active_lanes = sfu_avg_active_lane; } -void gpgpu_sim_wrapper::set_NoC_power(double noc_tot_reads, double noc_tot_writes ) -{ - p->sys.NoC[0].total_accesses = noc_tot_reads * p->sys.scaling_coefficients[NOC_A] + noc_tot_writes * p->sys.scaling_coefficients[NOC_A]; - sample_perf_counters[NOC_A]=noc_tot_reads+noc_tot_writes; +void gpgpu_sim_wrapper::set_NoC_power(double noc_tot_reads, + double noc_tot_writes) { + p->sys.NoC[0].total_accesses = + noc_tot_reads * p->sys.scaling_coefficients[NOC_A] + + noc_tot_writes * p->sys.scaling_coefficients[NOC_A]; + sample_perf_counters[NOC_A] = noc_tot_reads + noc_tot_writes; } +void gpgpu_sim_wrapper::power_metrics_calculations() { + total_sample_count++; + kernel_sample_count++; + + // Current sample power + double sample_power = + proc->rt_power.readOp.dynamic + sample_cmp_pwr[CONST_DYNAMICP]; + + // Average power + // Previous + new + constant dynamic power (e.g., dynamic clocking power) + kernel_tot_power += sample_power; + kernel_power.avg = kernel_tot_power / kernel_sample_count; + for (unsigned ind = 0; ind < num_pwr_cmps; ++ind) { + kernel_cmp_pwr[ind].avg += (double)sample_cmp_pwr[ind]; + } + + for (unsigned ind = 0; ind < num_perf_counters; ++ind) { + kernel_cmp_perf_counters[ind].avg += (double)sample_perf_counters[ind]; + } + + // Max Power + if (sample_power > kernel_power.max) { + kernel_power.max = sample_power; + for (unsigned ind = 0; ind < num_pwr_cmps; ++ind) { + kernel_cmp_pwr[ind].max = (double)sample_cmp_pwr[ind]; + } + for (unsigned ind = 0; ind < num_perf_counters; ++ind) { + kernel_cmp_perf_counters[ind].max = sample_perf_counters[ind]; + } + } -void gpgpu_sim_wrapper::power_metrics_calculations() -{ - total_sample_count++; - kernel_sample_count++; - - // Current sample power - double sample_power = proc->rt_power.readOp.dynamic + sample_cmp_pwr[CONST_DYNAMICP]; - - // Average power - // Previous + new + constant dynamic power (e.g., dynamic clocking power) - kernel_tot_power += sample_power; - kernel_power.avg = kernel_tot_power / kernel_sample_count; - for(unsigned ind=0; ind kernel_power.max){ - kernel_power.max = sample_power; - for(unsigned ind=0; ind gpu_tot_power.max) ? sample_power : gpu_tot_power.max; - gpu_tot_power.min = ((sample_power < gpu_tot_power.min) || (gpu_tot_power.min == 0)) ? sample_power : gpu_tot_power.min; - + // Min Power + if (sample_power < kernel_power.min || (kernel_power.min == 0)) { + kernel_power.min = sample_power; + for (unsigned ind = 0; ind < num_pwr_cmps; ++ind) { + kernel_cmp_pwr[ind].min = (double)sample_cmp_pwr[ind]; + } + for (unsigned ind = 0; ind < num_perf_counters; ++ind) { + kernel_cmp_perf_counters[ind].min = sample_perf_counters[ind]; + } + } + + gpu_tot_power.avg = (gpu_tot_power.avg + sample_power); + gpu_tot_power.max = + (sample_power > gpu_tot_power.max) ? sample_power : gpu_tot_power.max; + gpu_tot_power.min = + ((sample_power < gpu_tot_power.min) || (gpu_tot_power.min == 0)) + ? sample_power + : gpu_tot_power.min; } +void gpgpu_sim_wrapper::print_trace_files() { + open_files(); -void gpgpu_sim_wrapper::print_trace_files() -{ - open_files(); - - for(unsigned i=0; icores[0]->get_coefficient_fpint_insts(); - effpower_coeff[FP_INT]=initpower_coeff[FP_INT] * p->sys.scaling_coefficients[FP_INT]; - - initpower_coeff[TOT_INST]=proc->cores[0]->get_coefficient_tot_insts(); - effpower_coeff[TOT_INST]=initpower_coeff[TOT_INST] * p->sys.scaling_coefficients[TOT_INST]; - - initpower_coeff[REG_RD]=proc->cores[0]->get_coefficient_regreads_accesses()*(proc->cores[0]->exu->rf_fu_clockRate/proc->cores[0]->exu->clockRate); - initpower_coeff[REG_WR]=proc->cores[0]->get_coefficient_regwrites_accesses()*(proc->cores[0]->exu->rf_fu_clockRate/proc->cores[0]->exu->clockRate); - initpower_coeff[NON_REG_OPs]=proc->cores[0]->get_coefficient_noregfileops_accesses()*(proc->cores[0]->exu->rf_fu_clockRate/proc->cores[0]->exu->clockRate); - effpower_coeff[REG_RD]=initpower_coeff[REG_RD]*p->sys.scaling_coefficients[REG_RD]; - effpower_coeff[REG_WR]=initpower_coeff[REG_WR]*p->sys.scaling_coefficients[REG_WR]; - effpower_coeff[NON_REG_OPs]=initpower_coeff[NON_REG_OPs]*p->sys.scaling_coefficients[NON_REG_OPs]; - - initpower_coeff[IC_H]=proc->cores[0]->get_coefficient_icache_hits(); - initpower_coeff[IC_M]=proc->cores[0]->get_coefficient_icache_misses(); - effpower_coeff[IC_H]=initpower_coeff[IC_H]*p->sys.scaling_coefficients[IC_H]; - effpower_coeff[IC_M]=initpower_coeff[IC_M]*p->sys.scaling_coefficients[IC_M]; - - initpower_coeff[CC_H]=(proc->cores[0]->get_coefficient_ccache_readhits()+proc->get_coefficient_readcoalescing()); - initpower_coeff[CC_M]=(proc->cores[0]->get_coefficient_ccache_readmisses()+proc->get_coefficient_readcoalescing()); - effpower_coeff[CC_H]=initpower_coeff[CC_H]*p->sys.scaling_coefficients[CC_H]; - effpower_coeff[CC_M]=initpower_coeff[CC_M]*p->sys.scaling_coefficients[CC_M]; - - initpower_coeff[TC_H]=(proc->cores[0]->get_coefficient_tcache_readhits()+proc->get_coefficient_readcoalescing()); - initpower_coeff[TC_M]=(proc->cores[0]->get_coefficient_tcache_readmisses()+proc->get_coefficient_readcoalescing()); - effpower_coeff[TC_H]=initpower_coeff[TC_H]*p->sys.scaling_coefficients[TC_H]; - effpower_coeff[TC_M]=initpower_coeff[TC_M]*p->sys.scaling_coefficients[TC_M]; - - initpower_coeff[SHRD_ACC]=proc->cores[0]->get_coefficient_sharedmemory_readhits(); - effpower_coeff[SHRD_ACC]=initpower_coeff[SHRD_ACC]*p->sys.scaling_coefficients[SHRD_ACC]; - - initpower_coeff[DC_RH]=(proc->cores[0]->get_coefficient_dcache_readhits() + proc->get_coefficient_readcoalescing()); - initpower_coeff[DC_RM]=(proc->cores[0]->get_coefficient_dcache_readmisses() + proc->get_coefficient_readcoalescing()); - initpower_coeff[DC_WH]=(proc->cores[0]->get_coefficient_dcache_writehits() + proc->get_coefficient_writecoalescing()); - initpower_coeff[DC_WM]=(proc->cores[0]->get_coefficient_dcache_writemisses() + proc->get_coefficient_writecoalescing()); - effpower_coeff[DC_RH]=initpower_coeff[DC_RH]*p->sys.scaling_coefficients[DC_RH]; - effpower_coeff[DC_RM]=initpower_coeff[DC_RM]*p->sys.scaling_coefficients[DC_RM]; - effpower_coeff[DC_WH]=initpower_coeff[DC_WH]*p->sys.scaling_coefficients[DC_WH]; - effpower_coeff[DC_WM]=initpower_coeff[DC_WM]*p->sys.scaling_coefficients[DC_WM]; - - initpower_coeff[L2_RH]=proc->get_coefficient_l2_read_hits(); - initpower_coeff[L2_RM]=proc->get_coefficient_l2_read_misses(); - initpower_coeff[L2_WH]=proc->get_coefficient_l2_write_hits(); - initpower_coeff[L2_WM]=proc->get_coefficient_l2_write_misses(); - effpower_coeff[L2_RH]=initpower_coeff[L2_RH]*p->sys.scaling_coefficients[L2_RH]; - effpower_coeff[L2_RM]=initpower_coeff[L2_RM]*p->sys.scaling_coefficients[L2_RM]; - effpower_coeff[L2_WH]=initpower_coeff[L2_WH]*p->sys.scaling_coefficients[L2_WH]; - effpower_coeff[L2_WM]=initpower_coeff[L2_WM]*p->sys.scaling_coefficients[L2_WM]; - - initpower_coeff[IDLE_CORE_N]=p->sys.idle_core_power * proc->cores[0]->executionTime; - effpower_coeff[IDLE_CORE_N]=initpower_coeff[IDLE_CORE_N]*p->sys.scaling_coefficients[IDLE_CORE_N]; - - initpower_coeff[PIPE_A]=proc->cores[0]->get_coefficient_duty_cycle(); - effpower_coeff[PIPE_A]=initpower_coeff[PIPE_A]*p->sys.scaling_coefficients[PIPE_A]; - - initpower_coeff[MEM_RD]=proc->get_coefficient_mem_reads(); - initpower_coeff[MEM_WR]=proc->get_coefficient_mem_writes(); - initpower_coeff[MEM_PRE]=proc->get_coefficient_mem_pre(); - effpower_coeff[MEM_RD]=initpower_coeff[MEM_RD]*p->sys.scaling_coefficients[MEM_RD]; - effpower_coeff[MEM_WR]=initpower_coeff[MEM_WR]*p->sys.scaling_coefficients[MEM_WR]; - effpower_coeff[MEM_PRE]=initpower_coeff[MEM_PRE]*p->sys.scaling_coefficients[MEM_PRE]; - - initpower_coeff[SP_ACC]=proc->cores[0]->get_coefficient_ialu_accesses()*(proc->cores[0]->exu->rf_fu_clockRate/proc->cores[0]->exu->clockRate);; - initpower_coeff[SFU_ACC]=proc->cores[0]->get_coefficient_sfu_accesses(); - initpower_coeff[FPU_ACC]=proc->cores[0]->get_coefficient_fpu_accesses(); - - effpower_coeff[SP_ACC]=initpower_coeff[SP_ACC]*p->sys.scaling_coefficients[SP_ACC]; - effpower_coeff[SFU_ACC]=initpower_coeff[SFU_ACC]*p->sys.scaling_coefficients[SFU_ACC]; - effpower_coeff[FPU_ACC]=initpower_coeff[FPU_ACC]*p->sys.scaling_coefficients[FPU_ACC]; - - initpower_coeff[NOC_A]=proc->get_coefficient_noc_accesses(); - effpower_coeff[NOC_A]=initpower_coeff[NOC_A]*p->sys.scaling_coefficients[NOC_A]; - - const_dynamic_power=proc->get_const_dynamic_power()/(proc->cores[0]->executionTime); - - for(unsigned i=0; icores[0]->executionTime); - effpower_coeff[i]/=(proc->cores[0]->executionTime); - } +void gpgpu_sim_wrapper::update_coefficients() { + initpower_coeff[FP_INT] = proc->cores[0]->get_coefficient_fpint_insts(); + effpower_coeff[FP_INT] = + initpower_coeff[FP_INT] * p->sys.scaling_coefficients[FP_INT]; + + initpower_coeff[TOT_INST] = proc->cores[0]->get_coefficient_tot_insts(); + effpower_coeff[TOT_INST] = + initpower_coeff[TOT_INST] * p->sys.scaling_coefficients[TOT_INST]; + + initpower_coeff[REG_RD] = + proc->cores[0]->get_coefficient_regreads_accesses() * + (proc->cores[0]->exu->rf_fu_clockRate / proc->cores[0]->exu->clockRate); + initpower_coeff[REG_WR] = + proc->cores[0]->get_coefficient_regwrites_accesses() * + (proc->cores[0]->exu->rf_fu_clockRate / proc->cores[0]->exu->clockRate); + initpower_coeff[NON_REG_OPs] = + proc->cores[0]->get_coefficient_noregfileops_accesses() * + (proc->cores[0]->exu->rf_fu_clockRate / proc->cores[0]->exu->clockRate); + effpower_coeff[REG_RD] = + initpower_coeff[REG_RD] * p->sys.scaling_coefficients[REG_RD]; + effpower_coeff[REG_WR] = + initpower_coeff[REG_WR] * p->sys.scaling_coefficients[REG_WR]; + effpower_coeff[NON_REG_OPs] = + initpower_coeff[NON_REG_OPs] * p->sys.scaling_coefficients[NON_REG_OPs]; + + initpower_coeff[IC_H] = proc->cores[0]->get_coefficient_icache_hits(); + initpower_coeff[IC_M] = proc->cores[0]->get_coefficient_icache_misses(); + effpower_coeff[IC_H] = + initpower_coeff[IC_H] * p->sys.scaling_coefficients[IC_H]; + effpower_coeff[IC_M] = + initpower_coeff[IC_M] * p->sys.scaling_coefficients[IC_M]; + + initpower_coeff[CC_H] = (proc->cores[0]->get_coefficient_ccache_readhits() + + proc->get_coefficient_readcoalescing()); + initpower_coeff[CC_M] = (proc->cores[0]->get_coefficient_ccache_readmisses() + + proc->get_coefficient_readcoalescing()); + effpower_coeff[CC_H] = + initpower_coeff[CC_H] * p->sys.scaling_coefficients[CC_H]; + effpower_coeff[CC_M] = + initpower_coeff[CC_M] * p->sys.scaling_coefficients[CC_M]; + + initpower_coeff[TC_H] = (proc->cores[0]->get_coefficient_tcache_readhits() + + proc->get_coefficient_readcoalescing()); + initpower_coeff[TC_M] = (proc->cores[0]->get_coefficient_tcache_readmisses() + + proc->get_coefficient_readcoalescing()); + effpower_coeff[TC_H] = + initpower_coeff[TC_H] * p->sys.scaling_coefficients[TC_H]; + effpower_coeff[TC_M] = + initpower_coeff[TC_M] * p->sys.scaling_coefficients[TC_M]; + + initpower_coeff[SHRD_ACC] = + proc->cores[0]->get_coefficient_sharedmemory_readhits(); + effpower_coeff[SHRD_ACC] = + initpower_coeff[SHRD_ACC] * p->sys.scaling_coefficients[SHRD_ACC]; + + initpower_coeff[DC_RH] = (proc->cores[0]->get_coefficient_dcache_readhits() + + proc->get_coefficient_readcoalescing()); + initpower_coeff[DC_RM] = + (proc->cores[0]->get_coefficient_dcache_readmisses() + + proc->get_coefficient_readcoalescing()); + initpower_coeff[DC_WH] = (proc->cores[0]->get_coefficient_dcache_writehits() + + proc->get_coefficient_writecoalescing()); + initpower_coeff[DC_WM] = + (proc->cores[0]->get_coefficient_dcache_writemisses() + + proc->get_coefficient_writecoalescing()); + effpower_coeff[DC_RH] = + initpower_coeff[DC_RH] * p->sys.scaling_coefficients[DC_RH]; + effpower_coeff[DC_RM] = + initpower_coeff[DC_RM] * p->sys.scaling_coefficients[DC_RM]; + effpower_coeff[DC_WH] = + initpower_coeff[DC_WH] * p->sys.scaling_coefficients[DC_WH]; + effpower_coeff[DC_WM] = + initpower_coeff[DC_WM] * p->sys.scaling_coefficients[DC_WM]; + + initpower_coeff[L2_RH] = proc->get_coefficient_l2_read_hits(); + initpower_coeff[L2_RM] = proc->get_coefficient_l2_read_misses(); + initpower_coeff[L2_WH] = proc->get_coefficient_l2_write_hits(); + initpower_coeff[L2_WM] = proc->get_coefficient_l2_write_misses(); + effpower_coeff[L2_RH] = + initpower_coeff[L2_RH] * p->sys.scaling_coefficients[L2_RH]; + effpower_coeff[L2_RM] = + initpower_coeff[L2_RM] * p->sys.scaling_coefficients[L2_RM]; + effpower_coeff[L2_WH] = + initpower_coeff[L2_WH] * p->sys.scaling_coefficients[L2_WH]; + effpower_coeff[L2_WM] = + initpower_coeff[L2_WM] * p->sys.scaling_coefficients[L2_WM]; + + initpower_coeff[IDLE_CORE_N] = + p->sys.idle_core_power * proc->cores[0]->executionTime; + effpower_coeff[IDLE_CORE_N] = + initpower_coeff[IDLE_CORE_N] * p->sys.scaling_coefficients[IDLE_CORE_N]; + + initpower_coeff[PIPE_A] = proc->cores[0]->get_coefficient_duty_cycle(); + effpower_coeff[PIPE_A] = + initpower_coeff[PIPE_A] * p->sys.scaling_coefficients[PIPE_A]; + + initpower_coeff[MEM_RD] = proc->get_coefficient_mem_reads(); + initpower_coeff[MEM_WR] = proc->get_coefficient_mem_writes(); + initpower_coeff[MEM_PRE] = proc->get_coefficient_mem_pre(); + effpower_coeff[MEM_RD] = + initpower_coeff[MEM_RD] * p->sys.scaling_coefficients[MEM_RD]; + effpower_coeff[MEM_WR] = + initpower_coeff[MEM_WR] * p->sys.scaling_coefficients[MEM_WR]; + effpower_coeff[MEM_PRE] = + initpower_coeff[MEM_PRE] * p->sys.scaling_coefficients[MEM_PRE]; + + initpower_coeff[SP_ACC] = + proc->cores[0]->get_coefficient_ialu_accesses() * + (proc->cores[0]->exu->rf_fu_clockRate / proc->cores[0]->exu->clockRate); + ; + initpower_coeff[SFU_ACC] = proc->cores[0]->get_coefficient_sfu_accesses(); + initpower_coeff[FPU_ACC] = proc->cores[0]->get_coefficient_fpu_accesses(); + + effpower_coeff[SP_ACC] = + initpower_coeff[SP_ACC] * p->sys.scaling_coefficients[SP_ACC]; + effpower_coeff[SFU_ACC] = + initpower_coeff[SFU_ACC] * p->sys.scaling_coefficients[SFU_ACC]; + effpower_coeff[FPU_ACC] = + initpower_coeff[FPU_ACC] * p->sys.scaling_coefficients[FPU_ACC]; + + initpower_coeff[NOC_A] = proc->get_coefficient_noc_accesses(); + effpower_coeff[NOC_A] = + initpower_coeff[NOC_A] * p->sys.scaling_coefficients[NOC_A]; + + const_dynamic_power = + proc->get_const_dynamic_power() / (proc->cores[0]->executionTime); + + for (unsigned i = 0; i < num_perf_counters; i++) { + initpower_coeff[i] /= (proc->cores[0]->executionTime); + effpower_coeff[i] /= (proc->cores[0]->executionTime); + } } -void gpgpu_sim_wrapper::update_components_power() -{ - - update_coefficients(); - - proc_power=proc->rt_power.readOp.dynamic; - - sample_cmp_pwr[IBP]=(proc->cores[0]->ifu->IB->rt_power.readOp.dynamic - +proc->cores[0]->ifu->IB->rt_power.writeOp.dynamic - +proc->cores[0]->ifu->ID_misc->rt_power.readOp.dynamic - +proc->cores[0]->ifu->ID_operand->rt_power.readOp.dynamic - +proc->cores[0]->ifu->ID_inst->rt_power.readOp.dynamic)/(proc->cores[0]->executionTime); - - sample_cmp_pwr[ICP]=proc->cores[0]->ifu->icache.rt_power.readOp.dynamic/(proc->cores[0]->executionTime); - - sample_cmp_pwr[DCP]=proc->cores[0]->lsu->dcache.rt_power.readOp.dynamic/(proc->cores[0]->executionTime); - - sample_cmp_pwr[TCP]=proc->cores[0]->lsu->tcache.rt_power.readOp.dynamic/(proc->cores[0]->executionTime); - - sample_cmp_pwr[CCP]=proc->cores[0]->lsu->ccache.rt_power.readOp.dynamic/(proc->cores[0]->executionTime); - - sample_cmp_pwr[SHRDP]=proc->cores[0]->lsu->sharedmemory.rt_power.readOp.dynamic/(proc->cores[0]->executionTime); - - sample_cmp_pwr[RFP]=(proc->cores[0]->exu->rfu->rt_power.readOp.dynamic/(proc->cores[0]->executionTime)) - *(proc->cores[0]->exu->rf_fu_clockRate/proc->cores[0]->exu->clockRate); - - sample_cmp_pwr[SPP]=(proc->cores[0]->exu->exeu->rt_power.readOp.dynamic/(proc->cores[0]->executionTime)) - *(proc->cores[0]->exu->rf_fu_clockRate/proc->cores[0]->exu->clockRate); - - sample_cmp_pwr[SFUP]=(proc->cores[0]->exu->mul->rt_power.readOp.dynamic/(proc->cores[0]->executionTime)); - - sample_cmp_pwr[FPUP]=(proc->cores[0]->exu->fp_u->rt_power.readOp.dynamic/(proc->cores[0]->executionTime)); - - sample_cmp_pwr[SCHEDP]=proc->cores[0]->exu->scheu->rt_power.readOp.dynamic/(proc->cores[0]->executionTime); - - sample_cmp_pwr[L2CP]=(proc->XML->sys.number_of_L2s>0)? proc->l2array[0]->rt_power.readOp.dynamic/(proc->cores[0]->executionTime):0; - - sample_cmp_pwr[MCP]=(proc->mc->rt_power.readOp.dynamic-proc->mc->dram->rt_power.readOp.dynamic)/(proc->cores[0]->executionTime); - - sample_cmp_pwr[NOCP]=proc->nocs[0]->rt_power.readOp.dynamic/(proc->cores[0]->executionTime); - - sample_cmp_pwr[DRAMP]=proc->mc->dram->rt_power.readOp.dynamic/(proc->cores[0]->executionTime); - - sample_cmp_pwr[PIPEP]=proc->cores[0]->Pipeline_energy/(proc->cores[0]->executionTime); - - sample_cmp_pwr[IDLE_COREP]=proc->cores[0]->IdleCoreEnergy/(proc->cores[0]->executionTime); +void gpgpu_sim_wrapper::update_components_power() { + update_coefficients(); + + proc_power = proc->rt_power.readOp.dynamic; + + sample_cmp_pwr[IBP] = + (proc->cores[0]->ifu->IB->rt_power.readOp.dynamic + + proc->cores[0]->ifu->IB->rt_power.writeOp.dynamic + + proc->cores[0]->ifu->ID_misc->rt_power.readOp.dynamic + + proc->cores[0]->ifu->ID_operand->rt_power.readOp.dynamic + + proc->cores[0]->ifu->ID_inst->rt_power.readOp.dynamic) / + (proc->cores[0]->executionTime); + + sample_cmp_pwr[ICP] = proc->cores[0]->ifu->icache.rt_power.readOp.dynamic / + (proc->cores[0]->executionTime); + + sample_cmp_pwr[DCP] = proc->cores[0]->lsu->dcache.rt_power.readOp.dynamic / + (proc->cores[0]->executionTime); + + sample_cmp_pwr[TCP] = proc->cores[0]->lsu->tcache.rt_power.readOp.dynamic / + (proc->cores[0]->executionTime); + + sample_cmp_pwr[CCP] = proc->cores[0]->lsu->ccache.rt_power.readOp.dynamic / + (proc->cores[0]->executionTime); + + sample_cmp_pwr[SHRDP] = + proc->cores[0]->lsu->sharedmemory.rt_power.readOp.dynamic / + (proc->cores[0]->executionTime); + + sample_cmp_pwr[RFP] = + (proc->cores[0]->exu->rfu->rt_power.readOp.dynamic / + (proc->cores[0]->executionTime)) * + (proc->cores[0]->exu->rf_fu_clockRate / proc->cores[0]->exu->clockRate); + + sample_cmp_pwr[SPP] = + (proc->cores[0]->exu->exeu->rt_power.readOp.dynamic / + (proc->cores[0]->executionTime)) * + (proc->cores[0]->exu->rf_fu_clockRate / proc->cores[0]->exu->clockRate); + + sample_cmp_pwr[SFUP] = (proc->cores[0]->exu->mul->rt_power.readOp.dynamic / + (proc->cores[0]->executionTime)); + + sample_cmp_pwr[FPUP] = (proc->cores[0]->exu->fp_u->rt_power.readOp.dynamic / + (proc->cores[0]->executionTime)); + + sample_cmp_pwr[SCHEDP] = proc->cores[0]->exu->scheu->rt_power.readOp.dynamic / + (proc->cores[0]->executionTime); + + sample_cmp_pwr[L2CP] = (proc->XML->sys.number_of_L2s > 0) + ? proc->l2array[0]->rt_power.readOp.dynamic / + (proc->cores[0]->executionTime) + : 0; + + sample_cmp_pwr[MCP] = (proc->mc->rt_power.readOp.dynamic - + proc->mc->dram->rt_power.readOp.dynamic) / + (proc->cores[0]->executionTime); + + sample_cmp_pwr[NOCP] = + proc->nocs[0]->rt_power.readOp.dynamic / (proc->cores[0]->executionTime); + + sample_cmp_pwr[DRAMP] = + proc->mc->dram->rt_power.readOp.dynamic / (proc->cores[0]->executionTime); + + sample_cmp_pwr[PIPEP] = + proc->cores[0]->Pipeline_energy / (proc->cores[0]->executionTime); + + sample_cmp_pwr[IDLE_COREP] = + proc->cores[0]->IdleCoreEnergy / (proc->cores[0]->executionTime); + + // This constant dynamic power (e.g., clock power) part is estimated via + // regression model. + sample_cmp_pwr[CONST_DYNAMICP] = 0; + double cnst_dyn = + proc->get_const_dynamic_power() / (proc->cores[0]->executionTime); + // If the regression scaling term is greater than the recorded constant + // dynamic power then use the difference (other portion already added to + // dynamic power). Else, all the constant dynamic power is accounted for, add + // nothing. + if (p->sys.scaling_coefficients[CONST_DYNAMICN] > cnst_dyn) + sample_cmp_pwr[CONST_DYNAMICP] = + (p->sys.scaling_coefficients[CONST_DYNAMICN] - cnst_dyn); + + proc_power += sample_cmp_pwr[CONST_DYNAMICP]; + + double sum_pwr_cmp = 0; + for (unsigned i = 0; i < num_pwr_cmps; i++) { + sum_pwr_cmp += sample_cmp_pwr[i]; + } + bool check = false; + check = sanity_check(sum_pwr_cmp, proc_power); + assert("Total Power does not equal the sum of the components\n" && (check)); +} - // This constant dynamic power (e.g., clock power) part is estimated via regression model. - sample_cmp_pwr[CONST_DYNAMICP]=0; - double cnst_dyn = proc->get_const_dynamic_power()/(proc->cores[0]->executionTime); - // If the regression scaling term is greater than the recorded constant dynamic power - // then use the difference (other portion already added to dynamic power). Else, - // all the constant dynamic power is accounted for, add nothing. - if(p->sys.scaling_coefficients[CONST_DYNAMICN] > cnst_dyn) - sample_cmp_pwr[CONST_DYNAMICP] = (p->sys.scaling_coefficients[CONST_DYNAMICN]-cnst_dyn); +void gpgpu_sim_wrapper::compute() { proc->compute(); } +void gpgpu_sim_wrapper::print_power_kernel_stats( + double gpu_sim_cycle, double gpu_tot_sim_cycle, double init_value, + const std::string& kernel_info_string, bool print_trace) { + detect_print_steady_state(1, init_value); + if (g_power_simulation_enabled) { + powerfile << kernel_info_string << std::endl; + + sanity_check((kernel_power.avg * kernel_sample_count), kernel_tot_power); + powerfile << "Kernel Average Power Data:" << std::endl; + powerfile << "kernel_avg_power = " << kernel_power.avg << std::endl; + + for (unsigned i = 0; i < num_pwr_cmps; ++i) { + powerfile << "gpu_avg_" << pwr_cmp_label[i] << " = " + << kernel_cmp_pwr[i].avg / kernel_sample_count << std::endl; + } + for (unsigned i = 0; i < num_perf_counters; ++i) { + powerfile << "gpu_avg_" << perf_count_label[i] << " = " + << kernel_cmp_perf_counters[i].avg / kernel_sample_count + << std::endl; + } - proc_power+=sample_cmp_pwr[CONST_DYNAMICP]; + powerfile << std::endl << "Kernel Maximum Power Data:" << std::endl; + powerfile << "kernel_max_power = " << kernel_power.max << std::endl; + for (unsigned i = 0; i < num_pwr_cmps; ++i) { + powerfile << "gpu_max_" << pwr_cmp_label[i] << " = " + << kernel_cmp_pwr[i].max << std::endl; + } + for (unsigned i = 0; i < num_perf_counters; ++i) { + powerfile << "gpu_max_" << perf_count_label[i] << " = " + << kernel_cmp_perf_counters[i].max << std::endl; + } - double sum_pwr_cmp=0; - for(unsigned i=0; i gpu_steady_min_period)){ // If steady state occurred for some time, print to file - has_written_avg=true; - gzprintf(steady_state_tacking_file,"%u,%d,%f,%f,",sample_start,total_sample_count,temp_avg,temp_ipc); - for(unsigned i=0; irt_power.readOp.dynamic; + init_inst_val = init_val; + samples.push_back(proc->rt_power.readOp.dynamic); + assert(samples_counter.size() == 0); + assert(pwr_counter.size() == 0); + + for (unsigned i = 0; i < (num_perf_counters); ++i) { + samples_counter.push_back(sample_perf_counters[i]); + } -void gpgpu_sim_wrapper::detect_print_steady_state(int position, double init_val) -{ - // Calculating Average - if(g_power_simulation_enabled && g_steady_power_levels_enabled){ - steady_state_tacking_file = gzopen(g_steady_state_tracking_filename,"a"); - if(position==0){ - if(samples.size() == 0){ - // First sample - sample_start = total_sample_count; - sample_val = proc->rt_power.readOp.dynamic; - init_inst_val=init_val; - samples.push_back(proc->rt_power.readOp.dynamic); - assert(samples_counter.size() == 0); - assert(pwr_counter.size() == 0); - - for(unsigned i=0; i<(num_perf_counters); ++i){ - samples_counter.push_back(sample_perf_counters[i]); - } - - for(unsigned i=0; i<(num_pwr_cmps); ++i){ - pwr_counter.push_back(sample_cmp_pwr[i]); - } - assert(pwr_counter.size() == (double)num_pwr_cmps); - assert(samples_counter.size() == (double)num_perf_counters); - }else{ - // Get current average - double temp_avg = sample_val / (double)samples.size() ; - - if( abs(proc->rt_power.readOp.dynamic-temp_avg) < gpu_steady_power_deviation){ // Value is within threshold - sample_val += proc->rt_power.readOp.dynamic; - samples.push_back(proc->rt_power.readOp.dynamic); - for(unsigned i=0; i<(num_perf_counters); ++i){ - samples_counter.at(i) += sample_perf_counters[i]; - } - - for(unsigned i=0; i<(num_pwr_cmps); ++i){ - pwr_counter.at(i) += sample_cmp_pwr[i]; - } - - }else{ // Value exceeds threshold, not considered steady state - print_steady_state(position, init_val); - } - } - }else{ - print_steady_state(position, init_val); - } - gzclose(steady_state_tacking_file); + for (unsigned i = 0; i < (num_pwr_cmps); ++i) { + pwr_counter.push_back(sample_cmp_pwr[i]); + } + assert(pwr_counter.size() == (double)num_pwr_cmps); + assert(samples_counter.size() == (double)num_perf_counters); + } else { + // Get current average + double temp_avg = sample_val / (double)samples.size(); + + if (abs(proc->rt_power.readOp.dynamic - temp_avg) < + gpu_steady_power_deviation) { // Value is within threshold + sample_val += proc->rt_power.readOp.dynamic; + samples.push_back(proc->rt_power.readOp.dynamic); + for (unsigned i = 0; i < (num_perf_counters); ++i) { + samples_counter.at(i) += sample_perf_counters[i]; + } + + for (unsigned i = 0; i < (num_pwr_cmps); ++i) { + pwr_counter.at(i) += sample_cmp_pwr[i]; + } + + } else { // Value exceeds threshold, not considered steady state + print_steady_state(position, init_val); + } + } + } else { + print_steady_state(position, init_val); } + gzclose(steady_state_tacking_file); + } } -void gpgpu_sim_wrapper::open_files() -{ - if(g_power_simulation_enabled){ - if (g_power_trace_enabled ){ - power_trace_file = gzopen(g_power_trace_filename, "a"); - metric_trace_file = gzopen(g_metric_trace_filename, "a"); - } +void gpgpu_sim_wrapper::open_files() { + if (g_power_simulation_enabled) { + if (g_power_trace_enabled) { + power_trace_file = gzopen(g_power_trace_filename, "a"); + metric_trace_file = gzopen(g_metric_trace_filename, "a"); } + } } -void gpgpu_sim_wrapper::close_files() -{ - if(g_power_simulation_enabled){ - if(g_power_trace_enabled){ - gzclose(power_trace_file); - gzclose(metric_trace_file); - } - } - +void gpgpu_sim_wrapper::close_files() { + if (g_power_simulation_enabled) { + if (g_power_trace_enabled) { + gzclose(power_trace_file); + gzclose(metric_trace_file); + } + } } diff --git a/src/gpuwattch/gpgpu_sim_wrapper.h b/src/gpuwattch/gpgpu_sim_wrapper.h index 9d06092..00e4f07 100644 --- a/src/gpuwattch/gpgpu_sim_wrapper.h +++ b/src/gpuwattch/gpgpu_sim_wrapper.h @@ -7,141 +7,162 @@ // // Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. -// Redistributions in binary form must reproduce the above copyright notice, this -// list of conditions and the following disclaimer in the documentation and/or -// other materials provided with the distribution. -// Neither the name of The University of British Columbia nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. +// Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. Neither the name of +// The University of British Columbia nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. #ifndef GPGPU_SIM_WRAPPER_H_ #define GPGPU_SIM_WRAPPER_H_ -#include "processor.h" +#include #include #include -#include -#include -#include -#include -#include #include - +#include +#include +#include +#include +#include "processor.h" using namespace std; template -struct avg_max_min_counters{ - T avg; - T max; - T min; - - avg_max_min_counters(){avg=0; max=0; min=0;} +struct avg_max_min_counters { + T avg; + T max; + T min; + + avg_max_min_counters() { + avg = 0; + max = 0; + min = 0; + } }; class gpgpu_sim_wrapper { -public: - gpgpu_sim_wrapper(bool power_simulation_enabled, char* xmlfile); - ~gpgpu_sim_wrapper(); - - void init_mcpat(char* xmlfile, char* powerfile, char* power_trace_file,char* metric_trace_file, - char * steady_state_file,bool power_sim_enabled,bool trace_enabled,bool steady_state_enabled, - bool power_per_cycle_dump,double steady_power_deviation,double steady_min_period,int zlevel, - double init_val,int stat_sample_freq); - void detect_print_steady_state(int position, double init_val); - void close_files(); - void open_files(); - void compute(); - void dump(); - void print_trace_files(); - void update_components_power(); - void update_coefficients(); - void reset_counters(); - void print_power_kernel_stats(double gpu_sim_cycle, double gpu_tot_sim_cycle, double init_value, const std::string & kernel_info_string, bool print_trace); - void power_metrics_calculations(); - void set_inst_power(bool clk_gated_lanes, double tot_cycles, double busy_cycles, double tot_inst, double int_inst, double fp_inst, double load_inst, double store_inst, double committed_inst); - void set_regfile_power(double reads, double writes, double ops); - void set_icache_power(double accesses, double misses); - void set_ccache_power(double accesses, double misses); - void set_tcache_power(double accesses, double misses); - void set_shrd_mem_power(double accesses); - void set_l1cache_power(double read_accesses, double read_misses, double write_accesses, double write_misses); - void set_l2cache_power(double read_accesses, double read_misses, double write_accesses, double write_misses); - void set_idle_core_power(double num_idle_core); - void set_duty_cycle_power(double duty_cycle); - void set_mem_ctrl_power(double reads, double writes, double dram_precharge); - void set_exec_unit_power(double fpu_accesses, double ialu_accesses, double sfu_accesses); - void set_active_lanes_power(double sp_avg_active_lane, double sfu_avg_active_lane); - void set_NoC_power(double noc_tot_reads, double noc_tot_write); - bool sanity_check(double a, double b); - -private: - - void print_steady_state(int position, double init_val); - - Processor* proc; - ParseXML * p; - // power parameters - double const_dynamic_power; - double proc_power; - - unsigned num_perf_counters; // # of performance counters - unsigned num_pwr_cmps; // # of components modelled - int kernel_sample_count; // # of samples per kernel - int total_sample_count; // # of samples per benchmark - - std::vector< avg_max_min_counters > kernel_cmp_pwr; // Per-kernel component power avg/max/min values - std::vector< avg_max_min_counters > kernel_cmp_perf_counters; // Per-kernel component avg/max/min performance counters - - double kernel_tot_power; // Total per-kernel power - avg_max_min_counters kernel_power; // Per-kernel power avg/max/min values - avg_max_min_counters gpu_tot_power; // Global GPU power avg/max/min values (across kernels) - - bool has_written_avg; - - std::vector sample_cmp_pwr; // Current sample component powers - std::vector sample_perf_counters; // Current sample component perf. counts - std::vector initpower_coeff; - std::vector effpower_coeff; - - // For calculating steady-state average - unsigned sample_start; - double sample_val; - double init_inst_val; - std::vector samples; - std::vector samples_counter; - std::vector pwr_counter; - - char *xml_filename; - char *g_power_filename; - char *g_power_trace_filename; - char *g_metric_trace_filename; - char * g_steady_state_tracking_filename; - bool g_power_simulation_enabled; - bool g_steady_power_levels_enabled; - bool g_power_trace_enabled; - bool g_power_per_cycle_dump; - double gpu_steady_power_deviation; - double gpu_steady_min_period; - int g_power_trace_zlevel; - double gpu_stat_sample_frequency; - int gpu_stat_sample_freq; - - std::ofstream powerfile; - gzFile power_trace_file; - gzFile metric_trace_file; - gzFile steady_state_tacking_file; + public: + gpgpu_sim_wrapper(bool power_simulation_enabled, char* xmlfile); + ~gpgpu_sim_wrapper(); + + void init_mcpat(char* xmlfile, char* powerfile, char* power_trace_file, + char* metric_trace_file, char* steady_state_file, + bool power_sim_enabled, bool trace_enabled, + bool steady_state_enabled, bool power_per_cycle_dump, + double steady_power_deviation, double steady_min_period, + int zlevel, double init_val, int stat_sample_freq); + void detect_print_steady_state(int position, double init_val); + void close_files(); + void open_files(); + void compute(); + void dump(); + void print_trace_files(); + void update_components_power(); + void update_coefficients(); + void reset_counters(); + void print_power_kernel_stats(double gpu_sim_cycle, double gpu_tot_sim_cycle, + double init_value, + const std::string& kernel_info_string, + bool print_trace); + void power_metrics_calculations(); + void set_inst_power(bool clk_gated_lanes, double tot_cycles, + double busy_cycles, double tot_inst, double int_inst, + double fp_inst, double load_inst, double store_inst, + double committed_inst); + void set_regfile_power(double reads, double writes, double ops); + void set_icache_power(double accesses, double misses); + void set_ccache_power(double accesses, double misses); + void set_tcache_power(double accesses, double misses); + void set_shrd_mem_power(double accesses); + void set_l1cache_power(double read_accesses, double read_misses, + double write_accesses, double write_misses); + void set_l2cache_power(double read_accesses, double read_misses, + double write_accesses, double write_misses); + void set_idle_core_power(double num_idle_core); + void set_duty_cycle_power(double duty_cycle); + void set_mem_ctrl_power(double reads, double writes, double dram_precharge); + void set_exec_unit_power(double fpu_accesses, double ialu_accesses, + double sfu_accesses); + void set_active_lanes_power(double sp_avg_active_lane, + double sfu_avg_active_lane); + void set_NoC_power(double noc_tot_reads, double noc_tot_write); + bool sanity_check(double a, double b); + + private: + void print_steady_state(int position, double init_val); + + Processor* proc; + ParseXML* p; + // power parameters + double const_dynamic_power; + double proc_power; + + unsigned num_perf_counters; // # of performance counters + unsigned num_pwr_cmps; // # of components modelled + int kernel_sample_count; // # of samples per kernel + int total_sample_count; // # of samples per benchmark + + std::vector > + kernel_cmp_pwr; // Per-kernel component power avg/max/min values + std::vector > + kernel_cmp_perf_counters; // Per-kernel component avg/max/min performance + // counters + + double kernel_tot_power; // Total per-kernel power + avg_max_min_counters + kernel_power; // Per-kernel power avg/max/min values + avg_max_min_counters + gpu_tot_power; // Global GPU power avg/max/min values (across kernels) + + bool has_written_avg; + + std::vector sample_cmp_pwr; // Current sample component powers + std::vector + sample_perf_counters; // Current sample component perf. counts + std::vector initpower_coeff; + std::vector effpower_coeff; + + // For calculating steady-state average + unsigned sample_start; + double sample_val; + double init_inst_val; + std::vector samples; + std::vector samples_counter; + std::vector pwr_counter; + + char* xml_filename; + char* g_power_filename; + char* g_power_trace_filename; + char* g_metric_trace_filename; + char* g_steady_state_tracking_filename; + bool g_power_simulation_enabled; + bool g_steady_power_levels_enabled; + bool g_power_trace_enabled; + bool g_power_per_cycle_dump; + double gpu_steady_power_deviation; + double gpu_steady_min_period; + int g_power_trace_zlevel; + double gpu_stat_sample_frequency; + int gpu_stat_sample_freq; + + std::ofstream powerfile; + gzFile power_trace_file; + gzFile metric_trace_file; + gzFile steady_state_tacking_file; }; #endif /* GPGPU_SIM_WRAPPER_H_ */ diff --git a/src/gpuwattch/interconnect.cc b/src/gpuwattch/interconnect.cc index f109da7..caf66b3 100644 --- a/src/gpuwattch/interconnect.cc +++ b/src/gpuwattch/interconnect.cc @@ -29,63 +29,51 @@ * ***************************************************************************/ - #include "interconnect.h" -#include "wire.h" #include #include #include "globalvar.h" +#include "wire.h" -interconnect::interconnect( - string name_, - enum Device_ty device_ty_, - double base_w, double base_h, - int data_w, double len,const InputParameter *configure_interface, - int start_wiring_level_, - bool pipelinable_ , - double route_over_perc_ , - bool opt_local_, - enum Core_type core_ty_, - enum Wire_type wire_model, - double width_s, double space_s, - TechnologyParameter::DeviceType *dt -) - :name(name_), - device_ty(device_ty_), - in_rise_time(0), - out_rise_time(0), - base_width(base_w), - base_height(base_h), - data_width(data_w), - wt(wire_model), - width_scaling(width_s), - space_scaling(space_s), - start_wiring_level(start_wiring_level_), - length(len), - //interconnect_latency(1e-12), - //interconnect_throughput(1e-12), - opt_local(opt_local_), - core_ty(core_ty_), - pipelinable(pipelinable_), - route_over_perc(route_over_perc_), - deviceType(dt) -{ - +interconnect::interconnect(string name_, enum Device_ty device_ty_, + double base_w, double base_h, int data_w, double len, + const InputParameter *configure_interface, + int start_wiring_level_, bool pipelinable_, + double route_over_perc_, bool opt_local_, + enum Core_type core_ty_, enum Wire_type wire_model, + double width_s, double space_s, + TechnologyParameter::DeviceType *dt) + : name(name_), + device_ty(device_ty_), + in_rise_time(0), + out_rise_time(0), + base_width(base_w), + base_height(base_h), + data_width(data_w), + wt(wire_model), + width_scaling(width_s), + space_scaling(space_s), + start_wiring_level(start_wiring_level_), + length(len), + // interconnect_latency(1e-12), + // interconnect_throughput(1e-12), + opt_local(opt_local_), + core_ty(core_ty_), + pipelinable(pipelinable_), + route_over_perc(route_over_perc_), + deviceType(dt) { wt = Global; - l_ip=*configure_interface; + l_ip = *configure_interface; local_result = init_interface(&l_ip); - - max_unpipelined_link_delay = 0; //TODO + max_unpipelined_link_delay = 0; // TODO min_w_nmos = g_tp.min_w_nmos_; min_w_pmos = deviceType->n_to_p_eff_curr_drv_ratio * min_w_nmos; - - - latency = l_ip.latency; - throughput = l_ip.throughput; - latency_overflow=false; - throughput_overflow=false; + latency = l_ip.latency; + throughput = l_ip.throughput; + latency_overflow = false; + throughput_overflow = false; /* * TODO: Add wiring option from semi-global to global automatically @@ -96,66 +84,62 @@ interconnect::interconnect( * not have fat wires. */ if (pipelinable == false) - //Non-pipelinable wires, such as bypass logic, care latency + // Non-pipelinable wires, such as bypass logic, care latency { - compute(); - if (opt_for_clk && opt_local) - { - while (delay > latency && width_scaling<3.0) - { - width_scaling *= 2; - space_scaling *= 2; - Wire winit(width_scaling, space_scaling); - compute(); - } - if (delay > latency) - { - latency_overflow=true; - } - } - } - else //Pipelinable wires, such as bus, does not care latency but throughput + compute(); + if (opt_for_clk && opt_local) { + while (delay > latency && width_scaling < 3.0) { + width_scaling *= 2; + space_scaling *= 2; + Wire winit(width_scaling, space_scaling); + compute(); + } + if (delay > latency) { + latency_overflow = true; + } + } + } else // Pipelinable wires, such as bus, does not care latency but + // throughput { - /* - * TODO: Add pipe regs power, area, and timing; - * Pipelinable wires optimize latency first. - */ - compute(); - if (opt_for_clk && opt_local) - { - while (delay > throughput && width_scaling<3.0) - { - width_scaling *= 2; - space_scaling *= 2; - Wire winit(width_scaling, space_scaling); - compute(); - } - if (delay > throughput) - // insert pipeline stages - { - num_pipe_stages = (int)ceil(delay/throughput); - assert(num_pipe_stages>0); - delay = delay/num_pipe_stages + num_pipe_stages*0.05*delay; - } - } + /* + * TODO: Add pipe regs power, area, and timing; + * Pipelinable wires optimize latency first. + */ + compute(); + if (opt_for_clk && opt_local) { + while (delay > throughput && width_scaling < 3.0) { + width_scaling *= 2; + space_scaling *= 2; + Wire winit(width_scaling, space_scaling); + compute(); + } + if (delay > throughput) + // insert pipeline stages + { + num_pipe_stages = (int)ceil(delay / throughput); + assert(num_pipe_stages > 0); + delay = delay / num_pipe_stages + num_pipe_stages * 0.05 * delay; + } + } } power_bit = power; power.readOp.dynamic *= data_width; power.readOp.leakage *= data_width; power.readOp.gate_leakage *= data_width; - area.set_area(area.get_area()*data_width); + area.set_area(area.get_area() * data_width); no_device_under_wire_area.h *= data_width; - if (latency_overflow==true) - cout<< "Warning: "<< name <<" wire structure cannot satisfy latency constraint." << endl; - + if (latency_overflow == true) + cout << "Warning: " << name + << " wire structure cannot satisfy latency constraint." << endl; assert(power.readOp.dynamic > 0); assert(power.readOp.leakage > 0); assert(power.readOp.gate_leakage > 0); - double long_channel_device_reduction = longer_channel_device_reduction(device_ty,core_ty); + double long_channel_device_reduction = + longer_channel_device_reduction(device_ty, core_ty); double sckRation = g_tp.sckt_co_eff; power.readOp.dynamic *= sckRation; @@ -163,20 +147,17 @@ interconnect::interconnect( power.searchOp.dynamic *= sckRation; power.readOp.longer_channel_leakage = - power.readOp.leakage*long_channel_device_reduction; + power.readOp.leakage * long_channel_device_reduction; - if (pipelinable)//Only global wires has the option to choose whether routing over or not - area.set_area(area.get_area()*route_over_perc + no_device_under_wire_area.get_area()*(1-route_over_perc)); + if (pipelinable) // Only global wires has the option to choose whether + // routing over or not + area.set_area(area.get_area() * route_over_perc + + no_device_under_wire_area.get_area() * (1 - route_over_perc)); Wire wreset(); } - - -void -interconnect::compute() -{ - +void interconnect::compute() { Wire *wtemp1 = 0; wtemp1 = new Wire(wt, length, 1, width_scaling, space_scaling); delay = wtemp1->delay; @@ -185,18 +166,15 @@ interconnect::compute() power.readOp.gate_leakage = wtemp1->power.readOp.gate_leakage; area.set_area(wtemp1->area.get_area()); - no_device_under_wire_area.h = (wtemp1->wire_width + wtemp1->wire_spacing); + no_device_under_wire_area.h = (wtemp1->wire_width + wtemp1->wire_spacing); no_device_under_wire_area.w = length; - if (wtemp1) - delete wtemp1; - + if (wtemp1) delete wtemp1; } -void interconnect::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 interconnect::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 compute(); @@ -209,13 +187,14 @@ void interconnect::leakage_feedback(double temperature) assert(power.readOp.leakage > 0); assert(power.readOp.gate_leakage > 0); - double long_channel_device_reduction = longer_channel_device_reduction(device_ty,core_ty); + double long_channel_device_reduction = + longer_channel_device_reduction(device_ty, core_ty); double sckRation = g_tp.sckt_co_eff; power.readOp.dynamic *= sckRation; power.writeOp.dynamic *= sckRation; power.searchOp.dynamic *= sckRation; - power.readOp.longer_channel_leakage = power.readOp.leakage*long_channel_device_reduction; + power.readOp.longer_channel_leakage = + power.readOp.leakage * long_channel_device_reduction; } - diff --git a/src/gpuwattch/interconnect.h b/src/gpuwattch/interconnect.h index 9471c7a..b725c1d 100644 --- a/src/gpuwattch/interconnect.h +++ b/src/gpuwattch/interconnect.h @@ -29,83 +29,72 @@ * ***************************************************************************/ - #ifndef __INTERCONNECT_H__ #define __INTERCONNECT_H__ -#include "cacti/basic_circuit.h" +#include "assert.h" #include "basic_components.h" +#include "cacti/basic_circuit.h" +#include "cacti/cacti_interface.h" #include "cacti/component.h" #include "cacti/parameter.h" -#include "assert.h" #include "cacti/subarray.h" -#include "cacti/cacti_interface.h" #include "cacti/wire.h" // leakge power includes entire htree in a bank (when uca_tree == false) // leakge power includes only part to one bank when uca_tree == true -class interconnect : public Component -{ - public: - interconnect( - string name_, - enum Device_ty device_ty_, - double base_w =0, double base_h =0, int data_w =0, double len =0, - const InputParameter *configure_interface = NULL, int start_wiring_level_ =0, - bool pipelinable_ = false, - double route_over_perc_ =0.5, - bool opt_local_=true, - enum Core_type core_ty_=Inorder, - enum Wire_type wire_model=Global, - double width_s=1.0, double space_s=1.0, - TechnologyParameter::DeviceType *dt = &(g_tp.peri_global) - ); +class interconnect : public Component { + public: + interconnect(string name_, enum Device_ty device_ty_, double base_w = 0, + double base_h = 0, int data_w = 0, double len = 0, + const InputParameter *configure_interface = NULL, + int start_wiring_level_ = 0, bool pipelinable_ = false, + double route_over_perc_ = 0.5, bool opt_local_ = true, + enum Core_type core_ty_ = Inorder, + enum Wire_type wire_model = Global, double width_s = 1.0, + double space_s = 1.0, + TechnologyParameter::DeviceType *dt = &(g_tp.peri_global)); - ~interconnect() {}; + ~interconnect(){}; - void compute(); - string name; - enum Device_ty device_ty; - double in_rise_time, out_rise_time; - InputParameter l_ip; - uca_org_t local_result; - Area no_device_under_wire_area; - void set_in_rise_time(double rt) - { - in_rise_time = rt; - } - - void leakage_feedback(double temperature); - double max_unpipelined_link_delay; - powerDef power_bit; + void compute(); + string name; + enum Device_ty device_ty; + double in_rise_time, out_rise_time; + InputParameter l_ip; + uca_org_t local_result; + Area no_device_under_wire_area; + void set_in_rise_time(double rt) { in_rise_time = rt; } - double wire_bw; - double init_wire_bw; // bus width at root - double base_width; - double base_height; - int data_width; - enum Wire_type wt; - double width_scaling, space_scaling; - int start_wiring_level; - double length; - double min_w_nmos; - double min_w_pmos; - double latency, throughput; - bool latency_overflow; - bool throughput_overflow; - double interconnect_latency; - double interconnect_throughput; - bool opt_local; - enum Core_type core_ty; - bool pipelinable; - double route_over_perc; - int num_pipe_stages; + void leakage_feedback(double temperature); + double max_unpipelined_link_delay; + powerDef power_bit; - private: - TechnologyParameter::DeviceType *deviceType; + double wire_bw; + double init_wire_bw; // bus width at root + double base_width; + double base_height; + int data_width; + enum Wire_type wt; + double width_scaling, space_scaling; + int start_wiring_level; + double length; + double min_w_nmos; + double min_w_pmos; + double latency, throughput; + bool latency_overflow; + bool throughput_overflow; + double interconnect_latency; + double interconnect_throughput; + bool opt_local; + enum Core_type core_ty; + bool pipelinable; + double route_over_perc; + int num_pipe_stages; + private: + TechnologyParameter::DeviceType *deviceType; }; #endif - diff --git a/src/gpuwattch/iocontrollers.cc b/src/gpuwattch/iocontrollers.cc index 7575cc9..f5e2502 100644 --- a/src/gpuwattch/iocontrollers.cc +++ b/src/gpuwattch/iocontrollers.cc @@ -28,20 +28,19 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.” * ***************************************************************************/ -#include "io.h" -#include "parameter.h" -#include "const.h" -#include "logic.h" -#include "cacti/basic_circuit.h" -#include +#include "iocontrollers.h" +#include #include -#include "XML_Parse.h" -#include #include -#include -#include "iocontrollers.h" +#include +#include +#include "XML_Parse.h" #include "basic_components.h" - +#include "cacti/basic_circuit.h" +#include "const.h" +#include "io.h" +#include "logic.h" +#include "parameter.h" /* SUN Niagara 2 I/O power analysis: @@ -52,390 +51,453 @@ PCIe bits: (8 + 8)*2 = 32 Debug I/Os: 168 Other I/Os: 711- 32-32 - 384 - 168 = 95 -According to "Implementation of an 8-Core, 64-Thread, Power-Efficient SPARC Server on a Chip" -90% of I/Os are SerDers (the calucaltion is 384+64/(711-168)=83% about the same as the 90% reported in the paper) +According to "Implementation of an 8-Core, 64-Thread, Power-Efficient SPARC +Server on a Chip" 90% of I/Os are SerDers (the calucaltion is +384+64/(711-168)=83% about the same as the 90% reported in the paper) --> around 80Pins are common I/Os. Common I/Os consumes 71mW/Gb/s according to Cadence ChipEstimate @65nm -Niagara 2 I/O clock is 1/4 of core clock. --> 87pin (<--((711-168)*17%)) * 71mW/Gb/s *0.25*1.4Ghz = 2.17W +Niagara 2 I/O clock is 1/4 of core clock. --> 87pin (<--((711-168)*17%)) * +71mW/Gb/s *0.25*1.4Ghz = 2.17W -Total dynamic power of FBDIMM, NIC, PCIe = 84*0.132 + 84*0.049*0.132 = 11.14 - 2.17 = 8.98 -Further, if assuming I/O logic power is about 50% of I/Os then Total energy of FBDIMM, NIC, PCIe = 11.14 - 2.17*1.5 = 7.89 +Total dynamic power of FBDIMM, NIC, PCIe = 84*0.132 + 84*0.049*0.132 = 11.14 +- 2.17 = 8.98 Further, if assuming I/O logic power is about 50% of I/Os then +Total energy of FBDIMM, NIC, PCIe = 11.14 - 2.17*1.5 = 7.89 */ /* - * A bug in Cadence ChipEstimator: After update the clock rate in the clock tab, a user - * need to re-select the IP clock (the same clk) and then click Estimate. if not reselect - * the new clock rate may not be propogate into the IPs. + * A bug in Cadence ChipEstimator: After update the clock rate in the clock tab, + * a user need to re-select the IP clock (the same clk) and then click Estimate. + * if not reselect the new clock rate may not be propogate into the IPs. * */ -NIUController::NIUController(ParseXML *XML_interface,InputParameter* interface_ip_) -:XML(XML_interface), - interface_ip(*interface_ip_) - { - local_result = init_interface(&interface_ip); - - double frontend_area,mac_area, SerDer_area; - double frontend_dyn, mac_dyn, SerDer_dyn; - double frontend_gates, mac_gates; - double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio(); - double NMOS_sizing, PMOS_sizing; - - set_niu_param(); - - if (niup.type == 0) //high performance NIU - { - //Area estimation based on average of die photo from Niagara 2 and Cadence ChipEstimate using 65nm. - mac_area = (1.53 + 0.3)/2 * (interface_ip.F_sz_um/0.065)* (interface_ip.F_sz_um/0.065); - //Area estimation based on average of die photo from Niagara 2, ISSCC "An 800mW 10Gb Ethernet Transceiver in 0.13μm CMOS" - //and"A 1.2-V-Only 900-mW 10 Gb Ethernet Transceiver and XAUI Interface With Robust VCO Tuning Technique" Frontend is PCS - frontend_area = (9.8 + (6 + 18)*65/130*65/130)/3 * (interface_ip.F_sz_um/0.065)* (interface_ip.F_sz_um/0.065); - //Area estimation based on average of die photo from Niagara 2 and Cadence ChipEstimate hard IP @65nm. - //SerDer is very hard to scale - SerDer_area = (1.39 + 0.36) * (interface_ip.F_sz_um/0.065);//* (interface_ip.F_sz_um/0.065); - //total area - area.set_area((mac_area + frontend_area + SerDer_area)*1e6); - //Power - //Cadence ChipEstimate using 65nm (mac, front_end are all energy. E=P*T = P/F = 1.37/1Ghz = 1.37e-9); - mac_dyn = 2.19e-9*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0);//niup.clockRate; //2.19W@1GHz fully active according to Cadence ChipEstimate @65nm - //Cadence ChipEstimate using 65nm soft IP; - frontend_dyn = 0.27e-9*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0);//niup.clockRate; - //according to "A 100mW 9.6Gb/s Transceiver in 90nm CMOS..." ISSCC 2006 - //SerDer_dyn is power not energy, scaling from 10mw/Gb/s @90nm - SerDer_dyn = 0.01*10*sqrt(interface_ip.F_sz_um/0.09)*g_tp.peri_global.Vdd/1.2*g_tp.peri_global.Vdd/1.2; - SerDer_dyn /= niup.clockRate;//covert to energy per clock cycle of whole NIU - - //Cadence ChipEstimate using 65nm - mac_gates = 111700; - frontend_gates = 320000; - NMOS_sizing = 5*g_tp.min_w_nmos_; - PMOS_sizing = 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r; - - - } - else - {//Low power implementations are mostly from Cadence ChipEstimator; Ignore the multiple IP effect - // ---When there are multiple IP (same kind or not) selected, Cadence ChipEstimator results are not - // a simple summation of all IPs. Ignore this effect - mac_area = 0.24 * (interface_ip.F_sz_um/0.065)* (interface_ip.F_sz_um/0.065); - frontend_area = 0.1 * (interface_ip.F_sz_um/0.065)* (interface_ip.F_sz_um/0.065);//Frontend is the PCS layer - SerDer_area = 0.35 * (interface_ip.F_sz_um/0.065)* (interface_ip.F_sz_um/0.065); - //Compare 130um implementation in "A 1.2-V-Only 900-mW 10 Gb Ethernet Transceiver and XAUI Interface With Robust VCO Tuning Technique" - //and the ChipEstimator XAUI PHY hard IP, confirm that even PHY can scale perfectly with the technology - //total area - area.set_area((mac_area + frontend_area + SerDer_area)*1e6); - //Power - //Cadence ChipEstimate using 65nm (mac, front_end are all energy. E=P*T = P/F = 1.37/1Ghz = 1.37e-9); - mac_dyn = 1.257e-9*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0);//niup.clockRate; //2.19W@1GHz fully active according to Cadence ChipEstimate @65nm - //Cadence ChipEstimate using 65nm soft IP; - frontend_dyn = 0.6e-9*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0);//niup.clockRate; - //SerDer_dyn is power not energy, scaling from 216mw/10Gb/s @130nm - SerDer_dyn = 0.0216*10*(interface_ip.F_sz_um/0.13)*g_tp.peri_global.Vdd/1.2*g_tp.peri_global.Vdd/1.2; - SerDer_dyn /= niup.clockRate;//covert to energy per clock cycle of whole NIU - - mac_gates = 111700; - frontend_gates = 52000; - - NMOS_sizing = g_tp.min_w_nmos_; - PMOS_sizing = g_tp.min_w_nmos_*pmos_to_nmos_sizing_r; - - } - - power_t.readOp.dynamic = mac_dyn + frontend_dyn + SerDer_dyn; - power_t.readOp.leakage = (mac_gates + frontend_gates + frontend_gates)*cmos_Isub_leakage(NMOS_sizing, PMOS_sizing, 2, nand)*g_tp.peri_global.Vdd;//unit W - double long_channel_device_reduction = longer_channel_device_reduction(Uncore_device); - power_t.readOp.longer_channel_leakage = power_t.readOp.leakage * long_channel_device_reduction; - power_t.readOp.gate_leakage = (mac_gates + frontend_gates + frontend_gates)*cmos_Ig_leakage(NMOS_sizing, PMOS_sizing, 2, nand)*g_tp.peri_global.Vdd;//unit W - } - -void NIUController::computeEnergy(bool is_tdp) -{ - if (is_tdp) - { - - - power = power_t; - power.readOp.dynamic *= niup.duty_cycle; - - } - else - { - rt_power = power_t; - rt_power.readOp.dynamic *= niup.perc_load; - } +NIUController::NIUController(ParseXML* XML_interface, + InputParameter* interface_ip_) + : XML(XML_interface), interface_ip(*interface_ip_) { + local_result = init_interface(&interface_ip); + + double frontend_area, mac_area, SerDer_area; + double frontend_dyn, mac_dyn, SerDer_dyn; + double frontend_gates, mac_gates; + double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio(); + double NMOS_sizing, PMOS_sizing; + + set_niu_param(); + + if (niup.type == 0) // high performance NIU + { + // Area estimation based on average of die photo from Niagara 2 and Cadence + // ChipEstimate using 65nm. + mac_area = (1.53 + 0.3) / 2 * (interface_ip.F_sz_um / 0.065) * + (interface_ip.F_sz_um / 0.065); + // Area estimation based on average of die photo from Niagara 2, ISSCC "An + // 800mW 10Gb Ethernet Transceiver in 0.13μm CMOS" and"A 1.2-V-Only 900-mW + // 10 Gb Ethernet Transceiver and XAUI Interface With Robust VCO Tuning + // Technique" Frontend is PCS + frontend_area = (9.8 + (6 + 18) * 65 / 130 * 65 / 130) / 3 * + (interface_ip.F_sz_um / 0.065) * + (interface_ip.F_sz_um / 0.065); + // Area estimation based on average of die photo from Niagara 2 and Cadence + // ChipEstimate hard IP @65nm. SerDer is very hard to scale + SerDer_area = (1.39 + 0.36) * (interface_ip.F_sz_um / + 0.065); //* (interface_ip.F_sz_um/0.065); + // total area + area.set_area((mac_area + frontend_area + SerDer_area) * 1e6); + // Power + // Cadence ChipEstimate using 65nm (mac, front_end are all energy. E=P*T = + // P/F = 1.37/1Ghz = 1.37e-9); + mac_dyn = 2.19e-9 * g_tp.peri_global.Vdd / 1.1 * g_tp.peri_global.Vdd / + 1.1 * + (interface_ip.F_sz_nm / + 65.0); // niup.clockRate; //2.19W@1GHz fully active according to + // Cadence ChipEstimate @65nm + // Cadence ChipEstimate using 65nm soft IP; + frontend_dyn = 0.27e-9 * g_tp.peri_global.Vdd / 1.1 * g_tp.peri_global.Vdd / + 1.1 * (interface_ip.F_sz_nm / 65.0); // niup.clockRate; + // according to "A 100mW 9.6Gb/s Transceiver in 90nm CMOS..." ISSCC 2006 + // SerDer_dyn is power not energy, scaling from 10mw/Gb/s @90nm + SerDer_dyn = 0.01 * 10 * sqrt(interface_ip.F_sz_um / 0.09) * + g_tp.peri_global.Vdd / 1.2 * g_tp.peri_global.Vdd / 1.2; + SerDer_dyn /= + niup.clockRate; // covert to energy per clock cycle of whole NIU + + // Cadence ChipEstimate using 65nm + mac_gates = 111700; + frontend_gates = 320000; + NMOS_sizing = 5 * g_tp.min_w_nmos_; + PMOS_sizing = 5 * g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r; + + } else { // Low power implementations are mostly from Cadence ChipEstimator; + // Ignore the multiple IP effect + // ---When there are multiple IP (same kind or not) selected, Cadence + // ChipEstimator results are not a simple summation of all IPs. Ignore this + // effect + mac_area = + 0.24 * (interface_ip.F_sz_um / 0.065) * (interface_ip.F_sz_um / 0.065); + frontend_area = + 0.1 * (interface_ip.F_sz_um / 0.065) * + (interface_ip.F_sz_um / 0.065); // Frontend is the PCS layer + SerDer_area = + 0.35 * (interface_ip.F_sz_um / 0.065) * (interface_ip.F_sz_um / 0.065); + // Compare 130um implementation in "A 1.2-V-Only 900-mW 10 Gb Ethernet + // Transceiver and XAUI Interface With Robust VCO Tuning Technique" and the + // ChipEstimator XAUI PHY hard IP, confirm that even PHY can scale perfectly + // with the technology total area + area.set_area((mac_area + frontend_area + SerDer_area) * 1e6); + // Power + // Cadence ChipEstimate using 65nm (mac, front_end are all energy. E=P*T = + // P/F = 1.37/1Ghz = 1.37e-9); + mac_dyn = 1.257e-9 * g_tp.peri_global.Vdd / 1.1 * g_tp.peri_global.Vdd / + 1.1 * + (interface_ip.F_sz_nm / + 65.0); // niup.clockRate; //2.19W@1GHz fully active according to + // Cadence ChipEstimate @65nm + // Cadence ChipEstimate using 65nm soft IP; + frontend_dyn = 0.6e-9 * g_tp.peri_global.Vdd / 1.1 * g_tp.peri_global.Vdd / + 1.1 * (interface_ip.F_sz_nm / 65.0); // niup.clockRate; + // SerDer_dyn is power not energy, scaling from 216mw/10Gb/s @130nm + SerDer_dyn = 0.0216 * 10 * (interface_ip.F_sz_um / 0.13) * + g_tp.peri_global.Vdd / 1.2 * g_tp.peri_global.Vdd / 1.2; + SerDer_dyn /= + niup.clockRate; // covert to energy per clock cycle of whole NIU + + mac_gates = 111700; + frontend_gates = 52000; + + NMOS_sizing = g_tp.min_w_nmos_; + PMOS_sizing = g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r; + } + + power_t.readOp.dynamic = mac_dyn + frontend_dyn + SerDer_dyn; + power_t.readOp.leakage = + (mac_gates + frontend_gates + frontend_gates) * + cmos_Isub_leakage(NMOS_sizing, PMOS_sizing, 2, nand) * + g_tp.peri_global.Vdd; // unit W + double long_channel_device_reduction = + longer_channel_device_reduction(Uncore_device); + power_t.readOp.longer_channel_leakage = + power_t.readOp.leakage * long_channel_device_reduction; + power_t.readOp.gate_leakage = + (mac_gates + frontend_gates + frontend_gates) * + cmos_Ig_leakage(NMOS_sizing, PMOS_sizing, 2, nand) * + g_tp.peri_global.Vdd; // unit W } -void NIUController::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 << "NIU:" << endl; - cout << indent_str<< "Area = " << area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str << "Peak Dynamic = " << power.readOp.dynamic*niup.clockRate << " W" << endl; - cout << indent_str<< "Subthreshold Leakage = " - << (long_channel? power.readOp.longer_channel_leakage:power.readOp.leakage) <<" W" << endl; - //cout << indent_str<< "Subthreshold Leakage = " << power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str<< "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl; - cout << indent_str << "Runtime Dynamic = " << rt_power.readOp.dynamic*niup.clockRate << " W" << endl; - cout<sys.longer_channel_device; + + if (is_tdp) { + cout << "NIU:" << endl; + cout << indent_str << "Area = " << area.get_area() * 1e-6 << " mm^2" + << endl; + cout << indent_str + << "Peak Dynamic = " << power.readOp.dynamic * niup.clockRate << " W" + << endl; + cout << indent_str << "Subthreshold Leakage = " + << (long_channel ? power.readOp.longer_channel_leakage + : power.readOp.leakage) + << " W" << endl; + // cout << indent_str<< "Subthreshold Leakage = " << + // power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str << "Gate Leakage = " << power.readOp.gate_leakage << " W" + << endl; + cout << indent_str + << "Runtime Dynamic = " << rt_power.readOp.dynamic * niup.clockRate + << " W" << endl; + cout << endl; + } else { + } } -void NIUController::set_niu_param() -{ - niup.clockRate = XML->sys.niu.clockrate; - niup.clockRate *= 1e6; - niup.num_units = XML->sys.niu.number_units; - niup.duty_cycle = XML->sys.niu.duty_cycle; - niup.perc_load = XML->sys.niu.total_load_perc; - niup.type = XML->sys.niu.type; -// niup.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); +void NIUController::set_niu_param() { + niup.clockRate = XML->sys.niu.clockrate; + niup.clockRate *= 1e6; + niup.num_units = XML->sys.niu.number_units; + niup.duty_cycle = XML->sys.niu.duty_cycle; + niup.perc_load = XML->sys.niu.total_load_perc; + niup.type = XML->sys.niu.type; + // niup.executionTime = + // XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); } -PCIeController::PCIeController(ParseXML *XML_interface,InputParameter* interface_ip_) -:XML(XML_interface), - interface_ip(*interface_ip_) - { - local_result = init_interface(&interface_ip); - double ctrl_area, SerDer_area; - double ctrl_dyn, SerDer_dyn; - double ctrl_gates, SerDer_gates; - double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio(); - double NMOS_sizing, PMOS_sizing; - - /* Assuming PCIe is bit-slice based architecture - * This is the reason for /8 in both area and power calculation - * to get per lane numbers - */ - - set_pcie_param(); - if (pciep.type == 0) //high performance NIU - { - //Area estimation based on average of die photo from Niagara 2 and Cadence ChipEstimate @ 65nm. - ctrl_area = (5.2 + 0.5)/2 * (interface_ip.F_sz_um/0.065)* (interface_ip.F_sz_um/0.065); - //Area estimation based on average of die photo from Niagara 2, and Cadence ChipEstimate @ 65nm. - //Area estimation based on average of die photo from Niagara 2 and Cadence ChipEstimate hard IP @65nm. - //SerDer is very hard to scale - SerDer_area = (3.03 + 0.36) * (interface_ip.F_sz_um/0.065);//* (interface_ip.F_sz_um/0.065); - //total area - //Power - //Cadence ChipEstimate using 65nm the controller includes everything: the PHY, the data link and transaction layer - ctrl_dyn = 3.75e-9/8*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0); - // //Cadence ChipEstimate using 65nm soft IP; - // frontend_dyn = 0.27e-9/8*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0); - //SerDer_dyn is power not energy, scaling from 10mw/Gb/s @90nm - SerDer_dyn = 0.01*4*(interface_ip.F_sz_um/0.09)*g_tp.peri_global.Vdd/1.2*g_tp.peri_global.Vdd/1.2;//PCIe 2.0 max per lane speed is 4Gb/s - SerDer_dyn /= pciep.clockRate;//covert to energy per clock cycle - - //power_t.readOp.dynamic = (ctrl_dyn)*pciep.num_channels; - //Cadence ChipEstimate using 65nm - ctrl_gates = 900000/8*pciep.num_channels; - // frontend_gates = 120000/8; - // SerDer_gates = 200000/8; - NMOS_sizing = 5*g_tp.min_w_nmos_; - PMOS_sizing = 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r; - } - else - { - ctrl_area = 0.412 * (interface_ip.F_sz_um/0.065)* (interface_ip.F_sz_um/0.065); - //Area estimation based on average of die photo from Niagara 2, and Cadence ChipEstimate @ 65nm. - SerDer_area = 0.36 * (interface_ip.F_sz_um/0.065)* (interface_ip.F_sz_um/0.065); - //total area - //Power - //Cadence ChipEstimate using 65nm the controller includes everything: the PHY, the data link and transaction layer - ctrl_dyn = 2.21e-9/8*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0); - // //Cadence ChipEstimate using 65nm soft IP; - // frontend_dyn = 0.27e-9/8*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0); - //SerDer_dyn is power not energy, scaling from 10mw/Gb/s @90nm - SerDer_dyn = 0.01*4*(interface_ip.F_sz_um/0.09)*g_tp.peri_global.Vdd/1.2*g_tp.peri_global.Vdd/1.2;//PCIe 2.0 max per lane speed is 4Gb/s - SerDer_dyn /= pciep.clockRate;//covert to energy per clock cycle - - //Cadence ChipEstimate using 65nm - ctrl_gates = 200000/8*pciep.num_channels; - // frontend_gates = 120000/8; - SerDer_gates = 200000/8*pciep.num_channels; - NMOS_sizing = g_tp.min_w_nmos_; - PMOS_sizing = g_tp.min_w_nmos_*pmos_to_nmos_sizing_r; - - } - area.set_area(((ctrl_area + (pciep.withPHY? SerDer_area:0))/8*pciep.num_channels)*1e6); - power_t.readOp.dynamic = (ctrl_dyn + (pciep.withPHY? SerDer_dyn:0))*pciep.num_channels; - power_t.readOp.leakage = (ctrl_gates + (pciep.withPHY? SerDer_gates:0))*cmos_Isub_leakage(NMOS_sizing, PMOS_sizing, 2, nand)*g_tp.peri_global.Vdd;//unit W - double long_channel_device_reduction = longer_channel_device_reduction(Uncore_device); - power_t.readOp.longer_channel_leakage = power_t.readOp.leakage * long_channel_device_reduction; - power_t.readOp.gate_leakage = (ctrl_gates + (pciep.withPHY? SerDer_gates:0))*cmos_Ig_leakage(NMOS_sizing, PMOS_sizing, 2, nand)*g_tp.peri_global.Vdd;//unit W - } - -void PCIeController::computeEnergy(bool is_tdp) -{ - if (is_tdp) - { - - - power = power_t; - power.readOp.dynamic *= pciep.duty_cycle; - - } - else - { - rt_power = power_t; - rt_power.readOp.dynamic *= pciep.perc_load; - } +PCIeController::PCIeController(ParseXML* XML_interface, + InputParameter* interface_ip_) + : XML(XML_interface), interface_ip(*interface_ip_) { + local_result = init_interface(&interface_ip); + double ctrl_area, SerDer_area; + double ctrl_dyn, SerDer_dyn; + double ctrl_gates, SerDer_gates; + double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio(); + double NMOS_sizing, PMOS_sizing; + + /* Assuming PCIe is bit-slice based architecture + * This is the reason for /8 in both area and power calculation + * to get per lane numbers + */ + + set_pcie_param(); + if (pciep.type == 0) // high performance NIU + { + // Area estimation based on average of die photo from Niagara 2 and Cadence + // ChipEstimate @ 65nm. + ctrl_area = (5.2 + 0.5) / 2 * (interface_ip.F_sz_um / 0.065) * + (interface_ip.F_sz_um / 0.065); + // Area estimation based on average of die photo from Niagara 2, and Cadence + // ChipEstimate @ 65nm. Area estimation based on average of die photo from + // Niagara 2 and Cadence ChipEstimate hard IP @65nm. SerDer is very hard to + // scale + SerDer_area = (3.03 + 0.36) * (interface_ip.F_sz_um / + 0.065); //* (interface_ip.F_sz_um/0.065); + // total area + // Power + // Cadence ChipEstimate using 65nm the controller includes everything: the + // PHY, the data link and transaction layer + ctrl_dyn = 3.75e-9 / 8 * g_tp.peri_global.Vdd / 1.1 * g_tp.peri_global.Vdd / + 1.1 * (interface_ip.F_sz_nm / 65.0); + // //Cadence ChipEstimate using 65nm soft IP; + // frontend_dyn = + // 0.27e-9/8*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0); + // SerDer_dyn is power not energy, scaling from 10mw/Gb/s @90nm + SerDer_dyn = 0.01 * 4 * (interface_ip.F_sz_um / 0.09) * + g_tp.peri_global.Vdd / 1.2 * g_tp.peri_global.Vdd / + 1.2; // PCIe 2.0 max per lane speed is 4Gb/s + SerDer_dyn /= pciep.clockRate; // covert to energy per clock cycle + + // power_t.readOp.dynamic = (ctrl_dyn)*pciep.num_channels; + // Cadence ChipEstimate using 65nm + ctrl_gates = 900000 / 8 * pciep.num_channels; + // frontend_gates = 120000/8; + // SerDer_gates = 200000/8; + NMOS_sizing = 5 * g_tp.min_w_nmos_; + PMOS_sizing = 5 * g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r; + } else { + ctrl_area = + 0.412 * (interface_ip.F_sz_um / 0.065) * (interface_ip.F_sz_um / 0.065); + // Area estimation based on average of die photo from Niagara 2, and Cadence + // ChipEstimate @ 65nm. + SerDer_area = + 0.36 * (interface_ip.F_sz_um / 0.065) * (interface_ip.F_sz_um / 0.065); + // total area + // Power + // Cadence ChipEstimate using 65nm the controller includes everything: the + // PHY, the data link and transaction layer + ctrl_dyn = 2.21e-9 / 8 * g_tp.peri_global.Vdd / 1.1 * g_tp.peri_global.Vdd / + 1.1 * (interface_ip.F_sz_nm / 65.0); + // //Cadence ChipEstimate using 65nm soft IP; + // frontend_dyn = + // 0.27e-9/8*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0); + // SerDer_dyn is power not energy, scaling from 10mw/Gb/s @90nm + SerDer_dyn = 0.01 * 4 * (interface_ip.F_sz_um / 0.09) * + g_tp.peri_global.Vdd / 1.2 * g_tp.peri_global.Vdd / + 1.2; // PCIe 2.0 max per lane speed is 4Gb/s + SerDer_dyn /= pciep.clockRate; // covert to energy per clock cycle + + // Cadence ChipEstimate using 65nm + ctrl_gates = 200000 / 8 * pciep.num_channels; + // frontend_gates = 120000/8; + SerDer_gates = 200000 / 8 * pciep.num_channels; + NMOS_sizing = g_tp.min_w_nmos_; + PMOS_sizing = g_tp.min_w_nmos_ * pmos_to_nmos_sizing_r; + } + area.set_area(((ctrl_area + (pciep.withPHY ? SerDer_area : 0)) / 8 * + pciep.num_channels) * + 1e6); + power_t.readOp.dynamic = + (ctrl_dyn + (pciep.withPHY ? SerDer_dyn : 0)) * pciep.num_channels; + power_t.readOp.leakage = + (ctrl_gates + (pciep.withPHY ? SerDer_gates : 0)) * + cmos_Isub_leakage(NMOS_sizing, PMOS_sizing, 2, nand) * + g_tp.peri_global.Vdd; // unit W + double long_channel_device_reduction = + longer_channel_device_reduction(Uncore_device); + power_t.readOp.longer_channel_leakage = + power_t.readOp.leakage * long_channel_device_reduction; + power_t.readOp.gate_leakage = + (ctrl_gates + (pciep.withPHY ? SerDer_gates : 0)) * + cmos_Ig_leakage(NMOS_sizing, PMOS_sizing, 2, nand) * + g_tp.peri_global.Vdd; // unit W } -void PCIeController::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 << "PCIe:" << endl; - cout << indent_str<< "Area = " << area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str << "Peak Dynamic = " << power.readOp.dynamic*pciep.clockRate << " W" << endl; - cout << indent_str<< "Subthreshold Leakage = " - << (long_channel? power.readOp.longer_channel_leakage:power.readOp.leakage) <<" W" << endl; - //cout << indent_str<< "Subthreshold Leakage = " << power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str<< "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl; - cout << indent_str << "Runtime Dynamic = " << rt_power.readOp.dynamic*pciep.clockRate << " W" << endl; - cout<sys.pcie.clockrate; - pciep.clockRate *= 1e6; - pciep.num_units = XML->sys.pcie.number_units; - pciep.num_channels = XML->sys.pcie.num_channels; - pciep.duty_cycle = XML->sys.pcie.duty_cycle; - pciep.perc_load = XML->sys.pcie.total_load_perc; - pciep.type = XML->sys.pcie.type; - pciep.withPHY = XML->sys.pcie.withPHY; -// pciep.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); +void PCIeController::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 << "PCIe:" << endl; + cout << indent_str << "Area = " << area.get_area() * 1e-6 << " mm^2" + << endl; + cout << indent_str + << "Peak Dynamic = " << power.readOp.dynamic * pciep.clockRate << " W" + << endl; + cout << indent_str << "Subthreshold Leakage = " + << (long_channel ? power.readOp.longer_channel_leakage + : power.readOp.leakage) + << " W" << endl; + // cout << indent_str<< "Subthreshold Leakage = " << + // power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str << "Gate Leakage = " << power.readOp.gate_leakage << " W" + << endl; + cout << indent_str + << "Runtime Dynamic = " << rt_power.readOp.dynamic * pciep.clockRate + << " W" << endl; + cout << endl; + } else { + } +} +void PCIeController::set_pcie_param() { + pciep.clockRate = XML->sys.pcie.clockrate; + pciep.clockRate *= 1e6; + pciep.num_units = XML->sys.pcie.number_units; + pciep.num_channels = XML->sys.pcie.num_channels; + pciep.duty_cycle = XML->sys.pcie.duty_cycle; + pciep.perc_load = XML->sys.pcie.total_load_perc; + pciep.type = XML->sys.pcie.type; + pciep.withPHY = XML->sys.pcie.withPHY; + // pciep.executionTime = + // XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); } -FlashController::FlashController(ParseXML *XML_interface,InputParameter* interface_ip_) -:XML(XML_interface), - interface_ip(*interface_ip_) - { - local_result = init_interface(&interface_ip); - double ctrl_area, SerDer_area; - double ctrl_dyn, SerDer_dyn; - double ctrl_gates, SerDer_gates; - double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio(); - double NMOS_sizing, PMOS_sizing; - - /* Assuming PCIe is bit-slice based architecture - * This is the reason for /8 in both area and power calculation - * to get per lane numbers - */ - - set_fc_param(); - if (fcp.type == 0) //high performance NIU - { - cout<<"Current McPAT does not support high performance flash contorller since even low power designs are enough for maintain throughput"<sys.longer_channel_device; - - if (is_tdp) - { - cout << "Flash Controller:" << endl; - cout << indent_str<< "Area = " << area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str << "Peak Dynamic = " << power.readOp.dynamic << " W" << endl;//no multiply of clock since this is power already - cout << indent_str<< "Subthreshold Leakage = " - << (long_channel? power.readOp.longer_channel_leakage:power.readOp.leakage) <<" W" << endl; - //cout << indent_str<< "Subthreshold Leakage = " << power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str<< "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl; - cout << indent_str << "Runtime Dynamic = " << rt_power.readOp.dynamic << " W" << endl; - cout<sys.flashc.mc_clock; -// fcp.clockRate *= 1e6; - fcp.peakDataTransferRate = XML->sys.flashc.peak_transfer_rate; - fcp.num_channels = ceil(fcp.peakDataTransferRate/200); - fcp.num_mcs = XML->sys.flashc.number_mcs; - fcp.duty_cycle = XML->sys.flashc.duty_cycle; - fcp.perc_load = XML->sys.flashc.total_load_perc; - fcp.type = XML->sys.flashc.type; - fcp.withPHY = XML->sys.flashc.withPHY; -// flashcp.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); +void FlashController::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 << "Flash Controller:" << endl; + cout << indent_str << "Area = " << area.get_area() * 1e-6 << " mm^2" + << endl; + cout << indent_str << "Peak Dynamic = " << power.readOp.dynamic << " W" + << endl; // no multiply of clock since this is power already + cout << indent_str << "Subthreshold Leakage = " + << (long_channel ? power.readOp.longer_channel_leakage + : power.readOp.leakage) + << " W" << endl; + // cout << indent_str<< "Subthreshold Leakage = " << + // power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str << "Gate Leakage = " << power.readOp.gate_leakage << " W" + << endl; + cout << indent_str << "Runtime Dynamic = " << rt_power.readOp.dynamic + << " W" << endl; + cout << endl; + } else { + } +} +void FlashController::set_fc_param() { + // fcp.clockRate = XML->sys.flashc.mc_clock; + // fcp.clockRate *= 1e6; + fcp.peakDataTransferRate = XML->sys.flashc.peak_transfer_rate; + fcp.num_channels = ceil(fcp.peakDataTransferRate / 200); + fcp.num_mcs = XML->sys.flashc.number_mcs; + fcp.duty_cycle = XML->sys.flashc.duty_cycle; + fcp.perc_load = XML->sys.flashc.total_load_perc; + fcp.type = XML->sys.flashc.type; + fcp.withPHY = XML->sys.flashc.withPHY; + // flashcp.executionTime = + // XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); } diff --git a/src/gpuwattch/iocontrollers.h b/src/gpuwattch/iocontrollers.h index 68ddbcb..9d6c48a 100644 --- a/src/gpuwattch/iocontrollers.h +++ b/src/gpuwattch/iocontrollers.h @@ -31,7 +31,6 @@ #ifndef IOCONTROLLERS_H_ #define IOCONTROLLERS_H_ - #endif /* IOCONTROLLERS_H_ */ #include "XML_Parse.h" @@ -43,44 +42,43 @@ #include "basic_components.h" class NIUController : public Component { - public: - ParseXML *XML; - InputParameter interface_ip; - NIUParam niup; - powerDef power_t; - uca_org_t local_result; - NIUController(ParseXML *XML_interface,InputParameter* interface_ip_); - void set_niu_param(); - void computeEnergy(bool is_tdp=true); - void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); - ~NIUController(){}; + public: + ParseXML *XML; + InputParameter interface_ip; + NIUParam niup; + powerDef power_t; + uca_org_t local_result; + NIUController(ParseXML *XML_interface, InputParameter *interface_ip_); + void set_niu_param(); + void computeEnergy(bool is_tdp = true); + void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); + ~NIUController(){}; }; class PCIeController : public Component { - public: - ParseXML *XML; - InputParameter interface_ip; - PCIeParam pciep; - powerDef power_t; - uca_org_t local_result; - PCIeController(ParseXML *XML_interface,InputParameter* interface_ip_); - void set_pcie_param(); - void computeEnergy(bool is_tdp=true); - void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); - ~PCIeController(){}; + public: + ParseXML *XML; + InputParameter interface_ip; + PCIeParam pciep; + powerDef power_t; + uca_org_t local_result; + PCIeController(ParseXML *XML_interface, InputParameter *interface_ip_); + void set_pcie_param(); + void computeEnergy(bool is_tdp = true); + void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); + ~PCIeController(){}; }; class FlashController : public Component { - public: - ParseXML *XML; - InputParameter interface_ip; - MCParam fcp; - powerDef power_t; - uca_org_t local_result; - FlashController(ParseXML *XML_interface,InputParameter* interface_ip_); - void set_fc_param(); - void computeEnergy(bool is_tdp=true); - void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); - ~FlashController(){}; + public: + ParseXML *XML; + InputParameter interface_ip; + MCParam fcp; + powerDef power_t; + uca_org_t local_result; + FlashController(ParseXML *XML_interface, InputParameter *interface_ip_); + void set_fc_param(); + void computeEnergy(bool is_tdp = true); + void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); + ~FlashController(){}; }; - 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; - - 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 +// 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; +} + +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 - - - 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 - - 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; + // 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; + + // 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); + + 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); - - 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; + 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); + + 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); - - 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); - +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); + + 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); - - 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); + 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); } -//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); + + // 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; + ; + + /* 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) -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;; - - /* 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) ); + 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) - - { - 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(); +void Pipeline::compute() { + compute_stage_vector(); + DFFCell pipe_reg(false, WNANDn, WNANDp, load_per_pipeline_stage, &l_ip); + pipe_reg.compute_DFF_cell(); + + 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); } -void Pipeline::compute() -{ - compute_stage_vector(); - DFFCell pipe_reg(false, WNANDn,WNANDp, load_per_pipeline_stage, &l_ip); - pipe_reg.compute_DFF_cell(); - - 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); -} +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; + + } 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 + */ + + /* 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; + } -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; + /* 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 (!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; - - } - 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 */ - - /* 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; - - 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: "<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 - - } - 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"<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 *=(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2); - - - //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: "<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"<sys.Embedded) - area.set_area(area.get_area()*macro_layout_overhead); +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: "<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 + + } 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 *= (g_tp.peri_global.Vdd * g_tp.peri_global.Vdd / 1.2 / 1.2); + + // 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: "<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); } -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; - - } - 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 "<sys.core[ithCore].ialu_accesses; - rtp_stats = stats_t; - //cout<<"ALU: --accesses "<sys.core[ithCore].mul_accesses; - rtp_stats = stats_t; - //cout<<"MUL: --accesses "<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::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; + + } 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 "<sys.core[ithCore].ialu_accesses; + rtp_stats = stats_t; + // cout<<"ALU: --accesses "<sys.core[ithCore].mul_accesses; + rtp_stats = stats_t; + // cout<<"MUL: --accesses "<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: "<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: + // "<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"<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"<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); - - - -// 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< 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); + + // 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<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 <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; + } } -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; - - 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; - - 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); - - 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); - - PredecBlkDrv * predec_blk_drv1 = new PredecBlkDrv(0, predec_blk1, false); - PredecBlkDrv * predec_blk_drv2 = new PredecBlkDrv(0, predec_blk2, false); - - pre_dec = new Predec(predec_blk_drv1, predec_blk_drv2); - - 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); - - inst_decoder_delay_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; - -} +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; + + 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; + + 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); + + 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); + + PredecBlkDrv *predec_blk_drv1 = new PredecBlkDrv(0, predec_blk1, false); + PredecBlkDrv *predec_blk_drv2 = new PredecBlkDrv(0, predec_blk2, false); + + pre_dec = new Predec(predec_blk_drv1, predec_blk_drv2); + + 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); + + inst_decoder_delay_power(); -void inst_decoder::inst_decoder_delay_power() -{ + double sckRation = g_tp.sckt_co_eff; + power.readOp.dynamic *= sckRation; + power.writeOp.dynamic *= sckRation; + power.searchOp.dynamic *= sckRation; - double pppm_t[4] = {1,1,1,1}; - double squencer_passes = x86?2:1; + 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; +} - 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::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; } -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; } diff --git a/src/gpuwattch/logic.h b/src/gpuwattch/logic.h index 406b249..1e7a23d 100644 --- a/src/gpuwattch/logic.h +++ b/src/gpuwattch/logic.h @@ -29,212 +29,210 @@ * ***************************************************************************/ /******************************************************************** -* 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 * + ********************************************************************/ #ifndef LOGIC_H_ #define LOGIC_H_ -#include "cacti/const.h" -#include "cacti/component.h" +#include +#include +#include +#include +#include "XML_Parse.h" +#include "arch_const.h" #include "basic_components.h" #include "cacti/basic_circuit.h" #include "cacti/cacti_interface.h" +#include "cacti/component.h" +#include "cacti/const.h" #include "cacti/decoder.h" #include "cacti/parameter.h" #include "xmlParser.h" -#include "XML_Parse.h" -#include "arch_const.h" -#include -#include -#include -#include - using namespace std; -class selection_logic : public Component{ -public: - selection_logic(bool _is_default, int win_entries_, - int issue_width_, const InputParameter *configure_interface, - enum Device_ty device_ty_=Core_device, - enum Core_type core_ty_=Inorder);//, const ParseXML *_XML_interface); - bool is_default; - InputParameter l_ip; - uca_org_t local_result; - const ParseXML *XML_interface; - int win_entries; - int issue_width; - int num_threads; - enum Device_ty device_ty; - enum Core_type core_ty; - - void selection_power(); - void leakage_feedback(double temperature); // TODO +class selection_logic : public Component { + public: + selection_logic( + bool _is_default, int win_entries_, int issue_width_, + const InputParameter *configure_interface, + enum Device_ty device_ty_ = Core_device, + enum Core_type core_ty_ = Inorder); //, const ParseXML *_XML_interface); + bool is_default; + InputParameter l_ip; + uca_org_t local_result; + const ParseXML *XML_interface; + int win_entries; + int issue_width; + int num_threads; + enum Device_ty device_ty; + enum Core_type core_ty; + + void selection_power(); + void leakage_feedback(double temperature); // TODO }; -class dep_resource_conflict_check : public Component{ -public: - dep_resource_conflict_check(const InputParameter *configure_interface, const CoreDynParam & dyn_p_, int compare_bits_, bool _is_default=true); - InputParameter l_ip; - uca_org_t local_result; - double WNORn, WNORp, Wevalinvp, Wevalinvn, Wcompn, Wcompp, Wcomppreequ; - CoreDynParam coredynp; - int compare_bits; - bool is_default; - statsDef tdp_stats; - statsDef rtp_stats; - statsDef stats_t; - powerDef power_t; - - void conflict_check_power(); - double compare_cap(); - ~dep_resource_conflict_check(){ - local_result.cleanup(); - } - - void leakage_feedback(double temperature); +class dep_resource_conflict_check : public Component { + public: + dep_resource_conflict_check(const InputParameter *configure_interface, + const CoreDynParam &dyn_p_, int compare_bits_, + bool _is_default = true); + InputParameter l_ip; + uca_org_t local_result; + double WNORn, WNORp, Wevalinvp, Wevalinvn, Wcompn, Wcompp, Wcomppreequ; + CoreDynParam coredynp; + int compare_bits; + bool is_default; + statsDef tdp_stats; + statsDef rtp_stats; + statsDef stats_t; + powerDef power_t; + + void conflict_check_power(); + double compare_cap(); + ~dep_resource_conflict_check() { local_result.cleanup(); } + + void leakage_feedback(double temperature); }; -class inst_decoder: public Component{ -public: - inst_decoder(bool _is_default, const InputParameter *configure_interface, - int opcode_length_, - int num_decoders_, - bool x86_, - enum Device_ty device_ty_=Core_device, - enum Core_type core_ty_=Inorder); - inst_decoder(); - bool is_default; - int opcode_length; - int num_decoders; - bool x86; - int num_decoder_segments; - int num_decoded_signals; - InputParameter l_ip; - uca_org_t local_result; - enum Device_ty device_ty; - enum Core_type core_ty; - - Decoder * final_dec; - Predec * pre_dec; - - statsDef tdp_stats; - statsDef rtp_stats; - statsDef stats_t; - powerDef power_t; - void inst_decoder_delay_power(); - ~inst_decoder(); - void leakage_feedback(double temperature); +class inst_decoder : public Component { + public: + inst_decoder(bool _is_default, const InputParameter *configure_interface, + int opcode_length_, int num_decoders_, bool x86_, + enum Device_ty device_ty_ = Core_device, + enum Core_type core_ty_ = Inorder); + inst_decoder(); + bool is_default; + int opcode_length; + int num_decoders; + bool x86; + int num_decoder_segments; + int num_decoded_signals; + InputParameter l_ip; + uca_org_t local_result; + enum Device_ty device_ty; + enum Core_type core_ty; + + Decoder *final_dec; + Predec *pre_dec; + + statsDef tdp_stats; + statsDef rtp_stats; + statsDef stats_t; + powerDef power_t; + void inst_decoder_delay_power(); + ~inst_decoder(); + void leakage_feedback(double temperature); }; class DFFCell : public Component { -public: - DFFCell(bool _is_dram, double _WdecNANDn, double _WdecNANDp,double _cell_load, - const InputParameter *configure_interface); - InputParameter l_ip; - bool is_dram; - double cell_load; - double WdecNANDn; - double WdecNANDp; - double clock_cap; - int model; - int n_switch; - int n_keep_1; - int n_keep_0; - int n_clock; - powerDef e_switch; - powerDef e_keep_1; - powerDef e_keep_0; - powerDef e_clock; - - double fpfp_node_cap(unsigned int fan_in, unsigned int fan_out); - void compute_DFF_cell(void); - }; - -class Pipeline : public Component{ -public: - Pipeline(const InputParameter *configure_interface, const CoreDynParam & dyn_p_, enum Device_ty device_ty_=Core_device, bool _is_core_pipeline=true, bool _is_default=true); - InputParameter l_ip; - uca_org_t local_result; - CoreDynParam coredynp; - enum Device_ty device_ty; - bool is_core_pipeline, is_default; - double num_piperegs; -// int pipeline_stages; -// int tot_stage_vector, per_stage_vector; - bool process_ind; - double WNANDn ; - double WNANDp; - double load_per_pipeline_stage; -// int Hthread, num_thread, fetchWidth, decodeWidth, issueWidth, commitWidth, instruction_length; -// int PC_width, opcode_length, num_arch_reg_tag, data_width,num_phsical_reg_tag, address_width; -// bool thread_clock_gated; -// bool in_order, multithreaded; - void compute_stage_vector(); - void compute(); - ~Pipeline(){ - local_result.cleanup(); - }; + public: + DFFCell(bool _is_dram, double _WdecNANDn, double _WdecNANDp, + double _cell_load, const InputParameter *configure_interface); + InputParameter l_ip; + bool is_dram; + double cell_load; + double WdecNANDn; + double WdecNANDp; + double clock_cap; + int model; + int n_switch; + int n_keep_1; + int n_keep_0; + int n_clock; + powerDef e_switch; + powerDef e_keep_1; + powerDef e_keep_0; + powerDef e_clock; + + double fpfp_node_cap(unsigned int fan_in, unsigned int fan_out); + void compute_DFF_cell(void); +}; +class Pipeline : public Component { + public: + Pipeline(const InputParameter *configure_interface, + const CoreDynParam &dyn_p_, enum Device_ty device_ty_ = Core_device, + bool _is_core_pipeline = true, bool _is_default = true); + InputParameter l_ip; + uca_org_t local_result; + CoreDynParam coredynp; + enum Device_ty device_ty; + bool is_core_pipeline, is_default; + double num_piperegs; + // int pipeline_stages; + // int tot_stage_vector, per_stage_vector; + bool process_ind; + double WNANDn; + double WNANDp; + double load_per_pipeline_stage; + // int Hthread, num_thread, fetchWidth, decodeWidth, issueWidth, + // commitWidth, instruction_length; int PC_width, opcode_length, + // num_arch_reg_tag, data_width,num_phsical_reg_tag, address_width; bool + // thread_clock_gated; bool in_order, multithreaded; + void compute_stage_vector(); + void compute(); + ~Pipeline() { local_result.cleanup(); }; }; -//class core_pipeline :public pipeline{ -//public: -// int Hthread, num_thread, fetchWidth, decodeWidth, issueWidth, commitWidth, instruction_length; -// int PC_width, opcode_length, num_arch_reg_tag, data_width,num_phsical_reg_tag, address_width; -// bool thread_clock_gated; -// bool in_order, multithreaded; -// core_pipeline(bool _is_default, const InputParameter *configure_interface); -// virtual void compute_stage_vector(); +// class core_pipeline :public pipeline{ +// public: +// int Hthread, num_thread, fetchWidth, decodeWidth, issueWidth, +// commitWidth, instruction_length; int PC_width, opcode_length, +// num_arch_reg_tag, data_width,num_phsical_reg_tag, address_width; bool +// thread_clock_gated; bool in_order, multithreaded; core_pipeline(bool +//_is_default, const InputParameter *configure_interface); virtual void +// compute_stage_vector(); // //}; -class FunctionalUnit :public Component{ -public: - ParseXML *XML; - int ithCore; - InputParameter interface_ip; - CoreDynParam coredynp; - double FU_height; - double clockRate,executionTime; - double num_fu; - double energy, base_energy,per_access_energy, leakage, gate_leakage; - bool is_default; - enum FU_type fu_type; - statsDef tdp_stats; - statsDef rtp_stats; - statsDef stats_t; - powerDef power_t; - - FunctionalUnit(ParseXML *XML_interface, int ithCore_, InputParameter* interface_ip_,const CoreDynParam & dyn_p_, enum FU_type fu_type, double exClockRate); - void computeEnergy(bool is_tdp=true); - void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); - void leakage_feedback(double temperature); - +class FunctionalUnit : public Component { + public: + ParseXML *XML; + int ithCore; + InputParameter interface_ip; + CoreDynParam coredynp; + double FU_height; + double clockRate, executionTime; + double num_fu; + double energy, base_energy, per_access_energy, leakage, gate_leakage; + bool is_default; + enum FU_type fu_type; + statsDef tdp_stats; + statsDef rtp_stats; + statsDef stats_t; + powerDef power_t; + + FunctionalUnit(ParseXML *XML_interface, int ithCore_, + InputParameter *interface_ip_, const CoreDynParam &dyn_p_, + enum FU_type fu_type, double exClockRate); + void computeEnergy(bool is_tdp = true); + void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); + void leakage_feedback(double temperature); }; -class UndiffCore :public Component{ -public: - UndiffCore(ParseXML* XML_interface, int ithCore_, InputParameter* interface_ip_, const CoreDynParam & dyn_p_, bool exist_=true, bool embedded_=false); - ParseXML *XML; - int ithCore; - InputParameter interface_ip; - CoreDynParam coredynp; - double clockRate,executionTime; - double scktRatio, chip_PR_overhead, macro_PR_overhead; - enum Core_type core_ty; - bool opt_performance, embedded; - double pipeline_stage,num_hthreads,issue_width; - bool is_default; - - void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); - ~UndiffCore(){}; - bool exist; - - +class UndiffCore : public Component { + public: + UndiffCore(ParseXML *XML_interface, int ithCore_, + InputParameter *interface_ip_, const CoreDynParam &dyn_p_, + bool exist_ = true, bool embedded_ = false); + ParseXML *XML; + int ithCore; + InputParameter interface_ip; + CoreDynParam coredynp; + double clockRate, executionTime; + double scktRatio, chip_PR_overhead, macro_PR_overhead; + enum Core_type core_ty; + bool opt_performance, embedded; + double pipeline_stage, num_hthreads, issue_width; + bool is_default; + + void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); + ~UndiffCore(){}; + bool exist; }; #endif /* LOGIC_H_ */ diff --git a/src/gpuwattch/main.cc b/src/gpuwattch/main.cc index c370e32..03d3e7c 100644 --- a/src/gpuwattch/main.cc +++ b/src/gpuwattch/main.cc @@ -28,74 +28,68 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.” * ***************************************************************************/ -#include "io.h" #include -#include "xmlParser.h" #include "XML_Parse.h" -#include "processor.h" #include "globalvar.h" +#include "io.h" +#include "processor.h" #include "version.h" - +#include "xmlParser.h" using namespace std; -void print_usage(char * argv0); - -int main(int argc,char *argv[]) -{ - char * fb ; - bool infile_specified = false; - int plevel = 2; - opt_for_clk =true; - //cout.precision(10); - if (argc <= 1 || argv[1] == string("-h") || argv[1] == string("--help")) - { - print_usage(argv[0]); - } +void print_usage(char *argv0); - for (int32_t i = 0; i < argc; i++) - { - if (argv[i] == string("-infile")) - { - infile_specified = true; - i++; - fb = argv[ i]; - } +int main(int argc, char *argv[]) { + char *fb; + bool infile_specified = false; + int plevel = 2; + opt_for_clk = true; + // cout.precision(10); + if (argc <= 1 || argv[1] == string("-h") || argv[1] == string("--help")) { + print_usage(argv[0]); + } - if (argv[i] == string("-print_level")) - { - i++; - plevel = atoi(argv[i]); - } + for (int32_t i = 0; i < argc; i++) { + if (argv[i] == string("-infile")) { + infile_specified = true; + i++; + fb = argv[i]; + } - if (argv[i] == string("-opt_for_clk")) - { - i++; - opt_for_clk = (bool)atoi(argv[i]); - } - } - if (infile_specified == false) - { - print_usage(argv[0]); - } + if (argv[i] == string("-print_level")) { + i++; + plevel = atoi(argv[i]); + } + if (argv[i] == string("-opt_for_clk")) { + i++; + opt_for_clk = (bool)atoi(argv[i]); + } + } + if (infile_specified == false) { + print_usage(argv[0]); + } - cout<<"McPAT (version "<< VER_MAJOR <<"."<< VER_MINOR - << " of " << VER_UPDATE << ") is computing the target processor...\n "<parse(fb); - Processor proc(p1); - proc.displayEnergy(2, plevel); - delete p1; - return 0; + // parse XML-based interface + ParseXML *p1 = new ParseXML(); + p1->parse(fb); + Processor proc(p1); + proc.displayEnergy(2, plevel); + delete p1; + return 0; } -void print_usage(char * argv0) -{ - cerr << "How to use McPAT:" << endl; - cerr << " mcpat -infile -print_level < level of details 0~5 > -opt_for_clk < 0 (optimize for ED^2P only)/1 (optimzed for target clock rate)>"<< endl; - //cerr << " Note:default print level is at processor level, please increase it to see the details" << endl; - exit(1); +void print_usage(char *argv0) { + cerr << "How to use McPAT:" << endl; + cerr << " mcpat -infile -print_level < level of details " + "0~5 > -opt_for_clk < 0 (optimize for ED^2P only)/1 (optimzed for " + "target clock rate)>" + << endl; + // cerr << " Note:default print level is at processor level, please + // increase it to see the details" << endl; + exit(1); } diff --git a/src/gpuwattch/memoryctrl.cc b/src/gpuwattch/memoryctrl.cc index f13c695..2abb1d9 100644 --- a/src/gpuwattch/memoryctrl.cc +++ b/src/gpuwattch/memoryctrl.cc @@ -29,12 +29,12 @@ * ***************************************************************************/ /******************************************************************** -* 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 * + ********************************************************************/ // clang-format off #include "io.h" #include "parameter.h" @@ -51,944 +51,1213 @@ #include "basic_components.h" // clang-format on /* overview of MC models: - * McPAT memory controllers are modeled according to large number of industrial data points. - * The Basic memory controller architecture is base on the Synopsis designs - * (DesignWare DDR2/DDR3-Lite memory controllers and DDR2/DDR3-Lite protocol controllers) - * as in Cadence ChipEstimator Tool + * McPAT memory controllers are modeled according to large number of industrial + * data points. The Basic memory controller architecture is base on the Synopsis + * designs (DesignWare DDR2/DDR3-Lite memory controllers and DDR2/DDR3-Lite + * protocol controllers) as in Cadence ChipEstimator Tool * - * An MC has 3 parts as shown in this design. McPAT models both high performance MC - * based on Niagara processor designs and curving and low power MC based on data points in - * Cadence ChipEstimator Tool. + * An MC has 3 parts as shown in this design. McPAT models both high performance + * MC based on Niagara processor designs and curving and low power MC based on + * data points in Cadence ChipEstimator Tool. * - * The frontend is modeled analytically, the backend is modeled empirically according to - * DDR2/DDR3-Lite protocol controllers in Cadence ChipEstimator Tool - * The PHY is modeled based on - * "A 100mW 9.6Gb/s Transceiver in 90nm CMOS for next-generation memory interfaces ," ISSCC 2006, - * and A 14mW 6.25Gb/s Transceiver in 90nm CMOS for Serial Chip-to-Chip Communication," ISSCC 2007 + * The frontend is modeled analytically, the backend is modeled empirically + * according to DDR2/DDR3-Lite protocol controllers in Cadence ChipEstimator + * Tool The PHY is modeled based on "A 100mW 9.6Gb/s Transceiver in 90nm CMOS + * for next-generation memory interfaces ," ISSCC 2006, and A 14mW 6.25Gb/s + * Transceiver in 90nm CMOS for Serial Chip-to-Chip Communication," ISSCC 2007 * - * In Cadence ChipEstimator Tool there are two types of memory controllers: the full memory controllers - * that includes the frontend as the DesignWare DDR2/DDR3-Lite memory controllers and the backend only - * memory controllers as the DDR2/DDR3-Lite protocol controllers (except DesignWare DDR2/DDR3-Lite memory - * controllers, all memory controller IP in Cadence ChipEstimator Tool are backend memory controllers such as - * DDRC 1600A and DDRC 800A). Thus,to some extend the area and power difference between DesignWare - * DDR2/DDR3-Lite memory controllers and DDR2/DDR3-Lite protocol controllers can be an estimation to the - * frontend power and area, which is very close the analitically modeled results of the frontend for Niagara2@65nm + * In Cadence ChipEstimator Tool there are two types of memory controllers: the + * full memory controllers that includes the frontend as the DesignWare + * DDR2/DDR3-Lite memory controllers and the backend only memory controllers as + * the DDR2/DDR3-Lite protocol controllers (except DesignWare DDR2/DDR3-Lite + * memory controllers, all memory controller IP in Cadence ChipEstimator Tool + * are backend memory controllers such as DDRC 1600A and DDRC 800A). Thus,to + * some extend the area and power difference between DesignWare DDR2/DDR3-Lite + * memory controllers and DDR2/DDR3-Lite protocol controllers can be an + * estimation to the frontend power and area, which is very close the + * analitically modeled results of the frontend for Niagara2@65nm * */ -MCBackend::MCBackend(InputParameter* interface_ip_, const MCParam & mcp_, enum MemoryCtrl_type mc_type_) -:l_ip(*interface_ip_), - mc_type(mc_type_), - mcp(mcp_) -{ - +MCBackend::MCBackend(InputParameter* interface_ip_, const MCParam& mcp_, + enum MemoryCtrl_type mc_type_) + : l_ip(*interface_ip_), mc_type(mc_type_), mcp(mcp_) { local_result = init_interface(&l_ip); compute(); - } - -void MCBackend::compute() -{ - //double max_row_addr_width = 20.0;//Current address 12~18bits - double C_MCB, mc_power, backend_dyn, backend_gates;//, refresh_period,refresh_freq;//Equivalent per bit Cap for backend, +void MCBackend::compute() { + // double max_row_addr_width = 20.0;//Current address 12~18bits + double C_MCB, mc_power, backend_dyn, + backend_gates; //, refresh_period,refresh_freq;//Equivalent per bit Cap + // for backend, double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio(); double NMOS_sizing, PMOS_sizing; - if (mc_type == MC) - { - if (mcp.type == 0) - { - //area = (2.2927*log(peakDataTransferRate)-14.504)*memDataWidth/144.0*(l_ip.F_sz_um/0.09); - area.set_area((2.7927*log(mcp.peakDataTransferRate*2)-19.862)/2.0*mcp.dataBusWidth/128.0*(l_ip.F_sz_um/0.09)*mcp.num_channels*1e6);//um^2 - //assuming the approximately same scaling factor as seen in processors. - //C_MCB=0.2/1.3/1.3/266/64/0.09*g_ip.F_sz_um;//based on AMD Geode processor which has a very basic mc on chip. - //C_MCB = 1.6/200/1e6/144/1.2/1.2*g_ip.F_sz_um/0.19;//Based on Niagara power numbers.The base power (W) is divided by device frequency and vdd and scale to target process. - //mc_power = 0.0291*2;//29.1mW@200MHz @130nm From Power Analysis of SystemLevel OnChip Communication Architectures by Lahiri et - mc_power = 4.32*0.1;//4.32W@1GhzMHz @65nm Cadence ChipEstimator 10% for backend - C_MCB = mc_power/1e9/72/1.1/1.1*l_ip.F_sz_um/0.065; - power_t.readOp.dynamic = C_MCB*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(mcp.dataBusWidth/*+mcp.addressBusWidth*/);//per access energy in memory controller - power_t.readOp.leakage = area.get_area()/2 *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(g_tp.min_w_nmos_, g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd;//unit W - power_t.readOp.gate_leakage = area.get_area()/2 *(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(g_tp.min_w_nmos_, g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd;//unit W - - } - else - { NMOS_sizing = g_tp.min_w_nmos_; - PMOS_sizing = g_tp.min_w_nmos_*pmos_to_nmos_sizing_r; - area.set_area(0.15*mcp.dataBusWidth/72.0*(l_ip.F_sz_um/0.065)* (l_ip.F_sz_um/0.065)*mcp.num_channels*1e6);//um^2 - backend_dyn = 0.9e-9/800e6*mcp.clockRate/12800*mcp.peakDataTransferRate*mcp.dataBusWidth/72.0*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(l_ip.F_sz_nm/65.0);//Average on DDR2/3 protocol controller and DDRC 1600/800A in Cadence ChipEstimate - //Scaling to technology and DIMM feature. The base IP support DDR3-1600(PC3 12800) - backend_gates = 50000*mcp.dataBusWidth/64.0;//5000 is from Cadence ChipEstimator - - power_t.readOp.dynamic = backend_dyn; - power_t.readOp.leakage = (backend_gates)*cmos_Isub_leakage(NMOS_sizing, PMOS_sizing, 2, nand)*g_tp.peri_global.Vdd;//unit W - power_t.readOp.gate_leakage = (backend_gates)*cmos_Ig_leakage(NMOS_sizing, PMOS_sizing, 2, nand)*g_tp.peri_global.Vdd;//unit W - - } - } - else - {//skip old model - cout<<"Unknown memory controllers"<sys.physical_address_width + mcp.opcodeW)/8.0)); - interface_ip.cache_sz = data*XML->sys.mc.req_window_size_per_channel; - interface_ip.line_sz = data; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.access_mode = 0; - interface_ip.throughput = 1.0/mcp.clockRate; - interface_ip.latency = 1.0/mcp.clockRate; - interface_ip.is_cache = true; - interface_ip.pure_cam = false; - interface_ip.pure_ram = false; + // memory request reorder buffer + tag = mcp.addressBusWidth + EXTRA_TAG_BITS + mcp.opcodeW; + data = int(ceil((XML->sys.physical_address_width + mcp.opcodeW) / 8.0)); + interface_ip.cache_sz = data * XML->sys.mc.req_window_size_per_channel; + interface_ip.line_sz = data; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.access_mode = 0; + interface_ip.throughput = 1.0 / mcp.clockRate; + interface_ip.latency = 1.0 / mcp.clockRate; + interface_ip.is_cache = true; + interface_ip.pure_cam = false; + interface_ip.pure_ram = false; interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = XML->sys.mc.memory_channels_per_mc; - interface_ip.num_wr_ports = interface_ip.num_rd_ports; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = XML->sys.mc.memory_channels_per_mc; - frontendBuffer = new ArrayST(&interface_ip, "MC ReorderBuffer", Uncore_device); - frontendBuffer->area.set_area(frontendBuffer->area.get_area()+ frontendBuffer->local_result.area*XML->sys.mc.memory_channels_per_mc); - area.set_area(area.get_area()+ frontendBuffer->local_result.area*XML->sys.mc.memory_channels_per_mc); - - //selection and arbitration logic - MC_arb = new selection_logic(is_default, XML->sys.mc.req_window_size_per_channel,1,&interface_ip, Uncore_device); - - //read buffers. - data = (int)ceil(mcp.dataBusWidth/8.0);//Support key words first operation //8 means converting bit to Byte - interface_ip.cache_sz = data*XML->sys.mc.IO_buffer_size_per_channel;//*llcBlockSize; - interface_ip.line_sz = data; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 1; - interface_ip.throughput = 1.0/mcp.clockRate; - interface_ip.latency = 2.0/mcp.clockRate; - interface_ip.is_cache = false; - interface_ip.pure_cam = false; - interface_ip.pure_ram = true; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = XML->sys.mc.memory_channels_per_mc; + interface_ip.num_wr_ports = interface_ip.num_rd_ports; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = XML->sys.mc.memory_channels_per_mc; + frontendBuffer = + new ArrayST(&interface_ip, "MC ReorderBuffer", Uncore_device); + frontendBuffer->area.set_area(frontendBuffer->area.get_area() + + frontendBuffer->local_result.area * + XML->sys.mc.memory_channels_per_mc); + area.set_area(area.get_area() + frontendBuffer->local_result.area * + XML->sys.mc.memory_channels_per_mc); + + // selection and arbitration logic + MC_arb = + new selection_logic(is_default, XML->sys.mc.req_window_size_per_channel, + 1, &interface_ip, Uncore_device); + + // read buffers. + data = + (int)ceil(mcp.dataBusWidth / 8.0); // Support key words first operation + // //8 means converting bit to Byte + interface_ip.cache_sz = + data * XML->sys.mc.IO_buffer_size_per_channel; //*llcBlockSize; + interface_ip.line_sz = data; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 1; + interface_ip.throughput = 1.0 / mcp.clockRate; + interface_ip.latency = 2.0 / mcp.clockRate; + interface_ip.is_cache = false; + interface_ip.pure_cam = false; + interface_ip.pure_ram = true; interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0;//XML->sys.mc.memory_channels_per_mc*2>2?2:XML->sys.mc.memory_channels_per_mc*2; - interface_ip.num_rd_ports = XML->sys.mc.memory_channels_per_mc; - interface_ip.num_wr_ports = interface_ip.num_rd_ports; - interface_ip.num_se_rd_ports = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = + 0; // XML->sys.mc.memory_channels_per_mc*2>2?2:XML->sys.mc.memory_channels_per_mc*2; + interface_ip.num_rd_ports = XML->sys.mc.memory_channels_per_mc; + interface_ip.num_wr_ports = interface_ip.num_rd_ports; + interface_ip.num_se_rd_ports = 0; readBuffer = new ArrayST(&interface_ip, "MC ReadBuffer", Uncore_device); - readBuffer->area.set_area(readBuffer->area.get_area()+ readBuffer->local_result.area*XML->sys.mc.memory_channels_per_mc); - area.set_area(area.get_area()+ readBuffer->local_result.area*XML->sys.mc.memory_channels_per_mc); - - //write buffer - data = (int)ceil(mcp.dataBusWidth/8.0);//Support key words first operation //8 means converting bit to Byte - interface_ip.cache_sz = data*XML->sys.mc.IO_buffer_size_per_channel;//*llcBlockSize; - interface_ip.line_sz = data; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 0; - interface_ip.throughput = 1.0/mcp.clockRate; - interface_ip.latency = 2.0/mcp.clockRate; + readBuffer->area.set_area(readBuffer->area.get_area() + + readBuffer->local_result.area * + XML->sys.mc.memory_channels_per_mc); + area.set_area(area.get_area() + readBuffer->local_result.area * + XML->sys.mc.memory_channels_per_mc); + + // write buffer + data = + (int)ceil(mcp.dataBusWidth / 8.0); // Support key words first operation + // //8 means converting bit to Byte + interface_ip.cache_sz = + data * XML->sys.mc.IO_buffer_size_per_channel; //*llcBlockSize; + interface_ip.line_sz = data; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 0; + interface_ip.throughput = 1.0 / mcp.clockRate; + interface_ip.latency = 2.0 / mcp.clockRate; interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = XML->sys.mc.memory_channels_per_mc; - interface_ip.num_wr_ports = interface_ip.num_rd_ports; - interface_ip.num_se_rd_ports = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = XML->sys.mc.memory_channels_per_mc; + interface_ip.num_wr_ports = interface_ip.num_rd_ports; + interface_ip.num_se_rd_ports = 0; writeBuffer = new ArrayST(&interface_ip, "MC writeBuffer", Uncore_device); - writeBuffer->area.set_area(writeBuffer->area.get_area()+ writeBuffer->local_result.area*XML->sys.mc.memory_channels_per_mc); - area.set_area(area.get_area()+ writeBuffer->local_result.area*XML->sys.mc.memory_channels_per_mc); - - //SRAM structures for memory coalescing --Syed Gilani - //Pending Request Table (base addresses, offset addresses, threads IDs), Thread Masks + writeBuffer->area.set_area(writeBuffer->area.get_area() + + writeBuffer->local_result.area * + XML->sys.mc.memory_channels_per_mc); + area.set_area(area.get_area() + writeBuffer->local_result.area * + XML->sys.mc.memory_channels_per_mc); + + // SRAM structures for memory coalescing --Syed Gilani + // Pending Request Table (base addresses, offset addresses, threads IDs), + // Thread Masks //***PRT - //We assume 24 bits of base address and 8 bits of offset address. - //THese values are used for coalesing memory requests to the same base address block. - //TIDs are assumed to be 8 bits - /*Contents of each PRT entry - * - * Warp ID (6 bits) | Memory address (32 bits) per thread | Request Size (2-bits) per thread | - * line size= 6+ 32*16 + 2*16 ~ 64 bytes - * - * - */ - data = 64;//Support key words first operation //8 means converting bit to Byte - interface_ip.cache_sz = data*XML->sys.mc.PRT_entries;//PRT table; - interface_ip.line_sz = data; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 0; - interface_ip.throughput = 1.0/XML->sys.target_core_clockrate; - interface_ip.latency = 2.0/XML->sys.target_core_clockrate; + // We assume 24 bits of base address and 8 bits of offset address. + // THese values are used for coalesing memory requests to the same base + // address block. TIDs are assumed to be 8 bits + /*Contents of each PRT entry + * + * Warp ID (6 bits) | Memory address (32 bits) per thread | Request Size + * (2-bits) per thread | line size= 6+ 32*16 + 2*16 ~ 64 bytes + * + * + */ + data = + 64; // Support key words first operation //8 means converting bit to Byte + interface_ip.cache_sz = data * XML->sys.mc.PRT_entries; // PRT table; + interface_ip.line_sz = data; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 0; + interface_ip.throughput = 1.0 / XML->sys.target_core_clockrate; + interface_ip.latency = 2.0 / XML->sys.target_core_clockrate; interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = 1; - interface_ip.num_wr_ports = 1; - interface_ip.num_se_rd_ports = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = 1; + interface_ip.num_wr_ports = 1; + interface_ip.num_se_rd_ports = 0; PRT = new ArrayST(&interface_ip, "MC PRT", Uncore_device); - PRT->area.set_area(PRT->area.get_area()+ PRT->local_result.area*XML->sys.mc.memory_channels_per_mc); - area.set_area(area.get_area()+ PRT->local_result.area*XML->sys.mc.memory_channels_per_mc); - - - //***ThreadMasks storage (coalesced threads whose memory requests are satisfied by each memory access) - /* contents of the thread masks Array - * 16-bit bit masks for up to 16 memory requests of a warp | Number of pending memory requests (5 bits) - * - * 16*PRT_entry thread Mask, each entry has 16 mask bits. - * - */ - data = 2; - interface_ip.cache_sz = data*XML->sys.mc.PRT_entries*16;//PRT table; - interface_ip.line_sz = data; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 0; - interface_ip.throughput = 1.0/XML->sys.target_core_clockrate; - interface_ip.latency = 2.0/XML->sys.target_core_clockrate; + PRT->area.set_area(PRT->area.get_area() + + PRT->local_result.area * + XML->sys.mc.memory_channels_per_mc); + area.set_area(area.get_area() + + PRT->local_result.area * XML->sys.mc.memory_channels_per_mc); + + //***ThreadMasks storage (coalesced threads whose memory requests are + // satisfied by each memory access) + /* contents of the thread masks Array + * 16-bit bit masks for up to 16 memory requests of a warp | Number of + * pending memory requests (5 bits) + * + * 16*PRT_entry thread Mask, each entry has 16 mask bits. + * + */ + data = 2; + interface_ip.cache_sz = data * XML->sys.mc.PRT_entries * 16; // PRT table; + interface_ip.line_sz = data; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 0; + interface_ip.throughput = 1.0 / XML->sys.target_core_clockrate; + interface_ip.latency = 2.0 / XML->sys.target_core_clockrate; interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = 1; - interface_ip.num_wr_ports = 1; - interface_ip.num_se_rd_ports = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = 1; + interface_ip.num_wr_ports = 1; + interface_ip.num_se_rd_ports = 0; threadMasks = new ArrayST(&interface_ip, "MC ThreadMasks", Uncore_device); - threadMasks->area.set_area(threadMasks->area.get_area()+ threadMasks->local_result.area*XML->sys.mc.memory_channels_per_mc); - area.set_area(area.get_area()+ threadMasks->local_result.area*XML->sys.mc.memory_channels_per_mc); + threadMasks->area.set_area(threadMasks->area.get_area() + + threadMasks->local_result.area * + XML->sys.mc.memory_channels_per_mc); + area.set_area(area.get_area() + threadMasks->local_result.area * + XML->sys.mc.memory_channels_per_mc); //***Numer of pending requests per PRT entry - /* - * 1-byte data, PRT entries deep - */ - data = 1; - interface_ip.cache_sz = data*XML->sys.mc.PRT_entries;//PRT table; - interface_ip.line_sz = data; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 0; - interface_ip.throughput = 1.0/XML->sys.target_core_clockrate; - interface_ip.latency = 2.0/XML->sys.target_core_clockrate; + /* + * 1-byte data, PRT entries deep + */ + data = 1; + interface_ip.cache_sz = data * XML->sys.mc.PRT_entries; // PRT table; + interface_ip.line_sz = data; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.access_mode = 0; + interface_ip.throughput = 1.0 / XML->sys.target_core_clockrate; + interface_ip.latency = 2.0 / XML->sys.target_core_clockrate; interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 0; - interface_ip.num_rd_ports = 1; - interface_ip.num_wr_ports = 1; - interface_ip.num_se_rd_ports = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 0; + interface_ip.num_rd_ports = 1; + interface_ip.num_wr_ports = 1; + interface_ip.num_se_rd_ports = 0; PRC = new ArrayST(&interface_ip, "MC PendingRequestCount", Uncore_device); - PRC->area.set_area(PRC->area.get_area()+ PRC->local_result.area*XML->sys.mc.memory_channels_per_mc); - area.set_area(area.get_area()+ PRC->local_result.area*XML->sys.mc.memory_channels_per_mc); - + PRC->area.set_area(PRC->area.get_area() + + PRC->local_result.area * + XML->sys.mc.memory_channels_per_mc); + area.set_area(area.get_area() + + PRC->local_result.area * XML->sys.mc.memory_channels_per_mc); } +void DRAM::computeEnergy(bool is_tdp) { + if (is_tdp) { + power.reset(); + return; /// not supporting TDP calculation for DRAM + } + rt_power.reset(); + dramp.executionTime = + XML->sys.total_cycles / (XML->sys.target_core_clockrate * 1e6); -void DRAM::computeEnergy(bool is_tdp) -{ - if (is_tdp){ - power.reset(); - return; /// not supporting TDP calculation for DRAM - } - rt_power.reset(); - dramp.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); - - power_t.reset(); - power_t.readOp.dynamic+=XML->sys.mc.memory_reads*dramp.rd_coeff; - power_t.readOp.dynamic+=XML->sys.mc.memory_writes*dramp.wr_coeff; - power_t.readOp.dynamic+=XML->sys.mc.dram_pre*dramp.pre_coeff; + power_t.reset(); + power_t.readOp.dynamic += XML->sys.mc.memory_reads * dramp.rd_coeff; + power_t.readOp.dynamic += XML->sys.mc.memory_writes * dramp.wr_coeff; + power_t.readOp.dynamic += XML->sys.mc.dram_pre * dramp.pre_coeff; - rt_power = rt_power + power_t ; + rt_power = rt_power + power_t; } +void MCFrontEnd::computeEnergy(bool is_tdp) { + if (is_tdp) { + power.reset(); + // init stats for Peak + frontendBuffer->stats_t.readAc.access = + frontendBuffer->l_ip.num_search_ports; + frontendBuffer->stats_t.writeAc.access = frontendBuffer->l_ip.num_wr_ports; + frontendBuffer->tdp_stats = frontendBuffer->stats_t; + + readBuffer->stats_t.readAc.access = + readBuffer->l_ip.num_rd_ports * mcp.frontend_duty_cycle; + readBuffer->stats_t.writeAc.access = + readBuffer->l_ip.num_wr_ports * mcp.frontend_duty_cycle; + readBuffer->tdp_stats = readBuffer->stats_t; + + writeBuffer->stats_t.readAc.access = + writeBuffer->l_ip.num_rd_ports * mcp.frontend_duty_cycle; + writeBuffer->stats_t.writeAc.access = + writeBuffer->l_ip.num_wr_ports * mcp.frontend_duty_cycle; + writeBuffer->tdp_stats = writeBuffer->stats_t; + + PRT->stats_t.readAc.access = + PRT->l_ip.num_rd_ports * mcp.frontend_duty_cycle; + PRT->stats_t.writeAc.access = + PRT->l_ip.num_wr_ports * mcp.frontend_duty_cycle; + PRT->tdp_stats = PRT->stats_t; + + threadMasks->stats_t.readAc.access = + threadMasks->l_ip.num_rd_ports * mcp.frontend_duty_cycle; + threadMasks->stats_t.writeAc.access = + threadMasks->l_ip.num_wr_ports * mcp.frontend_duty_cycle; + threadMasks->tdp_stats = threadMasks->stats_t; + + PRC->stats_t.readAc.access = + threadMasks->l_ip.num_rd_ports * mcp.frontend_duty_cycle; + PRC->stats_t.writeAc.access = + threadMasks->l_ip.num_wr_ports * mcp.frontend_duty_cycle; + PRC->tdp_stats = threadMasks->stats_t; + + } else { + rt_power.reset(); // Jingwen + // init stats for runtime power (RTP) + frontendBuffer->stats_t.readAc.access = + XML->sys.mc.memory_reads * mcp.llcBlockSize * 8.0 / mcp.dataBusWidth * + mcp.dataBusWidth / 72; + // For each channel, each memory word need to check the address data to + // achieve best scheduling results. and this need to be done on all physical + // DIMMs in each logical memory DIMM *mcp.dataBusWidth/72 + frontendBuffer->stats_t.writeAc.access = + XML->sys.mc.memory_writes * mcp.llcBlockSize * 8.0 / mcp.dataBusWidth * + mcp.dataBusWidth / 72; + frontendBuffer->rtp_stats = frontendBuffer->stats_t; + + readBuffer->stats_t.readAc.access = + XML->sys.mc.memory_reads * mcp.llcBlockSize * 8.0 / + mcp.dataBusWidth; // support key word first + readBuffer->stats_t.writeAc.access = + XML->sys.mc.memory_reads * mcp.llcBlockSize * 8.0 / + mcp.dataBusWidth; // support key word first + readBuffer->rtp_stats = readBuffer->stats_t; + + writeBuffer->stats_t.readAc.access = + XML->sys.mc.memory_writes * mcp.llcBlockSize * 8.0 / mcp.dataBusWidth; + writeBuffer->stats_t.writeAc.access = + XML->sys.mc.memory_writes * mcp.llcBlockSize * 8.0 / mcp.dataBusWidth; + writeBuffer->rtp_stats = writeBuffer->stats_t; + + // Pending request table + // Co-alesce all misses in caches and add an entry for them in PRT + // TODO: Change 0 to ithCore and move to LSU (Syed) + // TODO: Do these accesses represent coalesced accesses? + PRT->stats_t.readAc.access = XML->sys.core[0].dcache.read_accesses + + XML->sys.core[0].ccache.read_accesses + + XML->sys.core[0].tcache.read_accesses; + PRT->stats_t.writeAc.access = XML->sys.core[0].dcache.write_accesses + + XML->sys.core[0].ccache.write_accesses + + XML->sys.core[0].tcache.write_accesses; + PRT->rtp_stats = PRT->stats_t; + + threadMasks->stats_t.readAc.access = XML->sys.core[0].dcache.read_accesses + + XML->sys.core[0].ccache.read_accesses + + XML->sys.core[0].tcache.read_accesses; + threadMasks->stats_t.writeAc.access = + XML->sys.core[0].dcache.write_accesses + + XML->sys.core[0].ccache.write_accesses + + XML->sys.core[0].tcache.write_accesses; + threadMasks->rtp_stats = threadMasks->stats_t; + + PRC->stats_t.readAc.access = XML->sys.core[0].dcache.read_accesses + + XML->sys.core[0].ccache.read_accesses + + XML->sys.core[0].tcache.read_accesses; + PRC->stats_t.writeAc.access = XML->sys.core[0].dcache.write_accesses + + XML->sys.core[0].ccache.write_accesses + + XML->sys.core[0].tcache.write_accesses; + PRC->rtp_stats = threadMasks->stats_t; + } -void MCFrontEnd::computeEnergy(bool is_tdp) -{ - if (is_tdp) - { - power.reset(); - //init stats for Peak - frontendBuffer->stats_t.readAc.access = frontendBuffer->l_ip.num_search_ports; - frontendBuffer->stats_t.writeAc.access = frontendBuffer->l_ip.num_wr_ports; - frontendBuffer->tdp_stats = frontendBuffer->stats_t; - - readBuffer->stats_t.readAc.access = readBuffer->l_ip.num_rd_ports*mcp.frontend_duty_cycle; - readBuffer->stats_t.writeAc.access = readBuffer->l_ip.num_wr_ports*mcp.frontend_duty_cycle; - readBuffer->tdp_stats = readBuffer->stats_t; - - writeBuffer->stats_t.readAc.access = writeBuffer->l_ip.num_rd_ports*mcp.frontend_duty_cycle; - writeBuffer->stats_t.writeAc.access = writeBuffer->l_ip.num_wr_ports*mcp.frontend_duty_cycle; - writeBuffer->tdp_stats = writeBuffer->stats_t; - - PRT->stats_t.readAc.access = PRT->l_ip.num_rd_ports*mcp.frontend_duty_cycle; - PRT->stats_t.writeAc.access = PRT->l_ip.num_wr_ports*mcp.frontend_duty_cycle; - PRT->tdp_stats = PRT->stats_t; - - threadMasks->stats_t.readAc.access = threadMasks->l_ip.num_rd_ports*mcp.frontend_duty_cycle; - threadMasks->stats_t.writeAc.access = threadMasks->l_ip.num_wr_ports*mcp.frontend_duty_cycle; - threadMasks->tdp_stats = threadMasks->stats_t; - - PRC->stats_t.readAc.access = threadMasks->l_ip.num_rd_ports*mcp.frontend_duty_cycle; - PRC->stats_t.writeAc.access = threadMasks->l_ip.num_wr_ports*mcp.frontend_duty_cycle; - PRC->tdp_stats = threadMasks->stats_t; - - } - else - { - rt_power.reset(); //Jingwen - //init stats for runtime power (RTP) - frontendBuffer->stats_t.readAc.access = XML->sys.mc.memory_reads *mcp.llcBlockSize*8.0/mcp.dataBusWidth*mcp.dataBusWidth/72; - //For each channel, each memory word need to check the address data to achieve best scheduling results. - //and this need to be done on all physical DIMMs in each logical memory DIMM *mcp.dataBusWidth/72 - frontendBuffer->stats_t.writeAc.access = XML->sys.mc.memory_writes*mcp.llcBlockSize*8.0/mcp.dataBusWidth*mcp.dataBusWidth/72; - frontendBuffer->rtp_stats = frontendBuffer->stats_t; - - readBuffer->stats_t.readAc.access = XML->sys.mc.memory_reads*mcp.llcBlockSize*8.0/mcp.dataBusWidth;//support key word first - readBuffer->stats_t.writeAc.access = XML->sys.mc.memory_reads*mcp.llcBlockSize*8.0/mcp.dataBusWidth;//support key word first - readBuffer->rtp_stats = readBuffer->stats_t; - - writeBuffer->stats_t.readAc.access = XML->sys.mc.memory_writes*mcp.llcBlockSize*8.0/mcp.dataBusWidth; - writeBuffer->stats_t.writeAc.access = XML->sys.mc.memory_writes*mcp.llcBlockSize*8.0/mcp.dataBusWidth; - writeBuffer->rtp_stats = writeBuffer->stats_t; - - //Pending request table - //Co-alesce all misses in caches and add an entry for them in PRT - //TODO: Change 0 to ithCore and move to LSU (Syed) - //TODO: Do these accesses represent coalesced accesses? - PRT->stats_t.readAc.access = XML->sys.core[0].dcache.read_accesses + XML->sys.core[0].ccache.read_accesses + - XML->sys.core[0].tcache.read_accesses; - PRT->stats_t.writeAc.access = XML->sys.core[0].dcache.write_accesses + XML->sys.core[0].ccache.write_accesses + - XML->sys.core[0].tcache.write_accesses; - PRT->rtp_stats = PRT->stats_t; - - threadMasks->stats_t.readAc.access = XML->sys.core[0].dcache.read_accesses + XML->sys.core[0].ccache.read_accesses + - XML->sys.core[0].tcache.read_accesses; - threadMasks->stats_t.writeAc.access = XML->sys.core[0].dcache.write_accesses + XML->sys.core[0].ccache.write_accesses + - XML->sys.core[0].tcache.write_accesses; - threadMasks->rtp_stats = threadMasks->stats_t; - - PRC->stats_t.readAc.access = XML->sys.core[0].dcache.read_accesses + XML->sys.core[0].ccache.read_accesses + - XML->sys.core[0].tcache.read_accesses; - PRC->stats_t.writeAc.access = XML->sys.core[0].dcache.write_accesses + XML->sys.core[0].ccache.write_accesses + - XML->sys.core[0].tcache.write_accesses; - PRC->rtp_stats = threadMasks->stats_t; - - } - - frontendBuffer->power_t.reset(); - readBuffer->power_t.reset(); - writeBuffer->power_t.reset(); - threadMasks->power_t.reset(); - PRT->power_t.reset(); - PRC->power_t.reset(); - -// frontendBuffer->power_t.readOp.dynamic += (frontendBuffer->stats_t.readAc.access* -// (frontendBuffer->local_result.power.searchOp.dynamic+frontendBuffer->local_result.power.readOp.dynamic)+ -// frontendBuffer->stats_t.writeAc.access*frontendBuffer->local_result.power.writeOp.dynamic); - - frontendBuffer->power_t.readOp.dynamic += (frontendBuffer->stats_t.readAc.access + - frontendBuffer->stats_t.writeAc.access)*frontendBuffer->local_result.power.searchOp.dynamic+ - frontendBuffer->stats_t.readAc.access * frontendBuffer->local_result.power.readOp.dynamic+ - frontendBuffer->stats_t.writeAc.access*frontendBuffer->local_result.power.writeOp.dynamic; - - readBuffer->power_t.readOp.dynamic += (readBuffer->stats_t.readAc.access* - readBuffer->local_result.power.readOp.dynamic+ - readBuffer->stats_t.writeAc.access*readBuffer->local_result.power.writeOp.dynamic); - writeBuffer->power_t.readOp.dynamic += (writeBuffer->stats_t.readAc.access* - writeBuffer->local_result.power.readOp.dynamic+ - writeBuffer->stats_t.writeAc.access*writeBuffer->local_result.power.writeOp.dynamic); - - PRT->power_t.readOp.dynamic += (PRT->stats_t.readAc.access* - PRT->local_result.power.readOp.dynamic+ - PRT->stats_t.writeAc.access*PRT->local_result.power.writeOp.dynamic); - - threadMasks->power_t.readOp.dynamic += (threadMasks->stats_t.readAc.access* - threadMasks->local_result.power.readOp.dynamic+ - threadMasks->stats_t.writeAc.access*threadMasks->local_result.power.writeOp.dynamic); - - PRC->power_t.readOp.dynamic += (PRC->stats_t.readAc.access* - PRC->local_result.power.readOp.dynamic+ - PRC->stats_t.writeAc.access*PRC->local_result.power.writeOp.dynamic); - - //Add coalescing logic power (Estimated from Verilog HDL description and Synopsys PowerCompiler)--Syed - #define COALESCE_SCALE 1 - double perAccessCoalescingEnergy=coalesce_scale * ((0.443e-3)*(0.5e-9)*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd)/(1*1); - threadMasks->power_t.readOp.dynamic += (threadMasks->stats_t.readAc.access+threadMasks->stats_t.writeAc.access)*perAccessCoalescingEnergy; - - //printf("***PRT: %10.30f, threadMasks: %10.30f, PRC: %10.30f\n",PRT->power_t.readOp.dynamic,threadMasks->power_t.readOp.dynamic,PRC->power_t.readOp.dynamic); - //printf("***Accesses: read:%lf write:%lf\n",threadMasks->stats_t.readAc.access, threadMasks->stats_t.writeAc.access); - if (is_tdp) - { - power = power + frontendBuffer->power_t + readBuffer->power_t + writeBuffer->power_t + PRT->power_t + threadMasks->power_t + - PRC->power_t + - (frontendBuffer->local_result.power + - readBuffer->local_result.power + - writeBuffer->local_result.power+PRT->local_result.power+ - threadMasks->local_result.power+PRC->local_result.power)*pppm_lkg; - - - } - else - { - rt_power = rt_power + frontendBuffer->power_t + readBuffer->power_t + writeBuffer->power_t + PRT->power_t + threadMasks->power_t + - PRC->power_t+ - (frontendBuffer->local_result.power + - readBuffer->local_result.power + - writeBuffer->local_result.power + PRT->local_result.power + threadMasks->local_result.power+ - PRC->local_result.power)*pppm_lkg; - rt_power.readOp.dynamic = rt_power.readOp.dynamic + power.readOp.dynamic*0.1*mcp.clockRate*mcp.num_mcs*mcp.executionTime; - } + frontendBuffer->power_t.reset(); + readBuffer->power_t.reset(); + writeBuffer->power_t.reset(); + threadMasks->power_t.reset(); + PRT->power_t.reset(); + PRC->power_t.reset(); + + // frontendBuffer->power_t.readOp.dynamic += + //(frontendBuffer->stats_t.readAc.access* + // (frontendBuffer->local_result.power.searchOp.dynamic+frontendBuffer->local_result.power.readOp.dynamic)+ + // frontendBuffer->stats_t.writeAc.access*frontendBuffer->local_result.power.writeOp.dynamic); + + frontendBuffer->power_t.readOp.dynamic += + (frontendBuffer->stats_t.readAc.access + + frontendBuffer->stats_t.writeAc.access) * + frontendBuffer->local_result.power.searchOp.dynamic + + frontendBuffer->stats_t.readAc.access * + frontendBuffer->local_result.power.readOp.dynamic + + frontendBuffer->stats_t.writeAc.access * + frontendBuffer->local_result.power.writeOp.dynamic; + + readBuffer->power_t.readOp.dynamic += + (readBuffer->stats_t.readAc.access * + readBuffer->local_result.power.readOp.dynamic + + readBuffer->stats_t.writeAc.access * + readBuffer->local_result.power.writeOp.dynamic); + writeBuffer->power_t.readOp.dynamic += + (writeBuffer->stats_t.readAc.access * + writeBuffer->local_result.power.readOp.dynamic + + writeBuffer->stats_t.writeAc.access * + writeBuffer->local_result.power.writeOp.dynamic); + + PRT->power_t.readOp.dynamic += + (PRT->stats_t.readAc.access * PRT->local_result.power.readOp.dynamic + + PRT->stats_t.writeAc.access * PRT->local_result.power.writeOp.dynamic); + + threadMasks->power_t.readOp.dynamic += + (threadMasks->stats_t.readAc.access * + threadMasks->local_result.power.readOp.dynamic + + threadMasks->stats_t.writeAc.access * + threadMasks->local_result.power.writeOp.dynamic); + + PRC->power_t.readOp.dynamic += + (PRC->stats_t.readAc.access * PRC->local_result.power.readOp.dynamic + + PRC->stats_t.writeAc.access * PRC->local_result.power.writeOp.dynamic); + + // Add coalescing logic power (Estimated from Verilog HDL description and + // Synopsys PowerCompiler)--Syed +#define COALESCE_SCALE 1 + double perAccessCoalescingEnergy = + coalesce_scale * + ((0.443e-3) * (0.5e-9) * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd) / + (1 * 1); + threadMasks->power_t.readOp.dynamic += (threadMasks->stats_t.readAc.access + + threadMasks->stats_t.writeAc.access) * + perAccessCoalescingEnergy; + + // printf("***PRT: %10.30f, threadMasks: %10.30f, PRC: + // %10.30f\n",PRT->power_t.readOp.dynamic,threadMasks->power_t.readOp.dynamic,PRC->power_t.readOp.dynamic); + // printf("***Accesses: read:%lf + // write:%lf\n",threadMasks->stats_t.readAc.access, + // threadMasks->stats_t.writeAc.access); + if (is_tdp) { + power = + power + frontendBuffer->power_t + readBuffer->power_t + + writeBuffer->power_t + PRT->power_t + threadMasks->power_t + + PRC->power_t + + (frontendBuffer->local_result.power + readBuffer->local_result.power + + writeBuffer->local_result.power + PRT->local_result.power + + threadMasks->local_result.power + PRC->local_result.power) * + pppm_lkg; + + } else { + rt_power = + rt_power + frontendBuffer->power_t + readBuffer->power_t + + writeBuffer->power_t + PRT->power_t + threadMasks->power_t + + PRC->power_t + + (frontendBuffer->local_result.power + readBuffer->local_result.power + + writeBuffer->local_result.power + PRT->local_result.power + + threadMasks->local_result.power + PRC->local_result.power) * + pppm_lkg; + rt_power.readOp.dynamic = + rt_power.readOp.dynamic + power.readOp.dynamic * 0.1 * mcp.clockRate * + mcp.num_mcs * mcp.executionTime; + } } -void MCFrontEnd::displayEnergy(uint32_t indent,int plevel,bool is_tdp) -{ - string indent_str(indent, ' '); - string indent_str_next(indent+2, ' '); - - if (is_tdp) - { - cout << indent_str << "Front End ROB:" << endl; - cout << indent_str_next << "Area = " << frontendBuffer->area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << frontendBuffer->power.readOp.dynamic*mcp.clockRate << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " << frontendBuffer->power.readOp.leakage <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << frontendBuffer->power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << frontendBuffer->rt_power.readOp.dynamic/mcp.executionTime << " W" << endl; - - cout <area.get_area()); + area.set_area(area.get_area() + frontend->area.get_area()); transecEngine = new MCBackend(&interface_ip, mcp, mc_type); - area.set_area(area.get_area()+ transecEngine->area.get_area()); - if (mcp.type==0 || (mcp.type==1&&mcp.withPHY)) - { - PHY = new MCPHY(&interface_ip, mcp, mc_type); - area.set_area(area.get_area()+ PHY->area.get_area()); + area.set_area(area.get_area() + transecEngine->area.get_area()); + if (mcp.type == 0 || (mcp.type == 1 && mcp.withPHY)) { + PHY = new MCPHY(&interface_ip, mcp, mc_type); + area.set_area(area.get_area() + PHY->area.get_area()); } - //+++++++++Transaction engine +++++++++++++++++ ////TODO needs better numbers, Run the RTL code from OpenSparc. -// transecEngine.initialize(&interface_ip); -// transecEngine.peakDataTransferRate = XML->sys.mem.peak_transfer_rate; -// transecEngine.memDataWidth = dataBusWidth; -// transecEngine.memRank = XML->sys.mem.number_ranks; -// //transecEngine.memAccesses=XML->sys.mc.memory_accesses; -// //transecEngine.llcBlocksize=llcBlockSize; -// transecEngine.compute(); -// transecEngine.area.set_area(XML->sys.mc.memory_channels_per_mc*transecEngine.area.get_area()) ; -// area.set_area(area.get_area()+ transecEngine.area.get_area()); -// ///cout<<"area="<sys.mem.peak_transfer_rate; -// PHY.memDataWidth = dataBusWidth; -// //PHY.memAccesses=PHY.peakDataTransferRate;//this is the max power -// //PHY.llcBlocksize=llcBlockSize; -// PHY.compute(); -// PHY.area.set_area(XML->sys.mc.memory_channels_per_mc*PHY.area.get_area()) ; -// area.set_area(area.get_area()+ PHY.area.get_area()); - ///cout<<"area="<sys.core[0].opcode_width + dataBusWidth; -// pipeLogic = new pipeline(is_default, &interface_ip); -// //pipeLogic.init_pipeline(is_default, &interface_ip); -// pipeLogic->compute_pipeline(); -// area.set_area(area.get_area()+ pipeLogic->area.get_area()*1e-6); -// area.set_area((area.get_area()+mc_area*1e-6)*1.1);//placement and routing overhead -// -// -//// //clock -//// clockNetwork.init_wire_external(is_default, &interface_ip); -//// clockNetwork.clk_area =area*1.1;//10% of placement overhead. rule of thumb -//// clockNetwork.end_wiring_level =5;//toplevel metal -//// clockNetwork.start_wiring_level =5;//toplevel metal -//// clockNetwork.num_regs = pipeLogic.tot_stage_vector; -//// clockNetwork.optimize_wire(); - - + //+++++++++Transaction engine +++++++++++++++++ ////TODO needs better numbers, + // Run the RTL code from OpenSparc. + // transecEngine.initialize(&interface_ip); + // transecEngine.peakDataTransferRate = XML->sys.mem.peak_transfer_rate; + // transecEngine.memDataWidth = dataBusWidth; + // transecEngine.memRank = XML->sys.mem.number_ranks; + // //transecEngine.memAccesses=XML->sys.mc.memory_accesses; + // //transecEngine.llcBlocksize=llcBlockSize; + // transecEngine.compute(); + // transecEngine.area.set_area(XML->sys.mc.memory_channels_per_mc*transecEngine.area.get_area()) + // ; area.set_area(area.get_area()+ transecEngine.area.get_area()); + // ///cout<<"area="<sys.mem.peak_transfer_rate; + // PHY.memDataWidth = dataBusWidth; + // //PHY.memAccesses=PHY.peakDataTransferRate;//this is the max power + // //PHY.llcBlocksize=llcBlockSize; + // PHY.compute(); + // PHY.area.set_area(XML->sys.mc.memory_channels_per_mc*PHY.area.get_area()) + // ; area.set_area(area.get_area()+ PHY.area.get_area()); + /// cout<<"area="<sys.core[0].opcode_width + dataBusWidth; pipeLogic = new + // pipeline(is_default, &interface_ip); + // //pipeLogic.init_pipeline(is_default, &interface_ip); + // pipeLogic->compute_pipeline(); + // area.set_area(area.get_area()+ pipeLogic->area.get_area()*1e-6); + // area.set_area((area.get_area()+mc_area*1e-6)*1.1);//placement and routing + // overhead + // + // + //// //clock + //// clockNetwork.init_wire_external(is_default, &interface_ip); + //// clockNetwork.clk_area =area*1.1;//10% of placement overhead. + /// rule of thumb / clockNetwork.end_wiring_level =5;//toplevel metal / + /// clockNetwork.start_wiring_level =5;//toplevel metal / + /// clockNetwork.num_regs = pipeLogic.tot_stage_vector; / + /// clockNetwork.optimize_wire(); } -void MemoryController::computeEnergy(bool is_tdp) -{ - - rt_power.reset(); //Jingwen +void MemoryController::computeEnergy(bool is_tdp) { + rt_power.reset(); // Jingwen frontend->rt_power.reset(); transecEngine->rt_power.reset(); dram->rt_power.reset(); - mcp.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); //Jingwen - frontend->mcp.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); //Jingwen - transecEngine->mcp.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); //Jingwen - + mcp.executionTime = XML->sys.total_cycles / + (XML->sys.target_core_clockrate * 1e6); // Jingwen + frontend->mcp.executionTime = + XML->sys.total_cycles / + (XML->sys.target_core_clockrate * 1e6); // Jingwen + transecEngine->mcp.executionTime = + XML->sys.total_cycles / + (XML->sys.target_core_clockrate * 1e6); // Jingwen + /*Jingwen: give stats for backend and phy */ - transecEngine->mcp.reads =XML->sys.mc.memory_reads; - transecEngine->mcp.writes =XML->sys.mc.memory_writes; - - //set_mc_param(); - - frontend->computeEnergy(is_tdp); - transecEngine->computeEnergy(is_tdp); - dram->computeEnergy(is_tdp); - if (mcp.type==0 || (mcp.type==1&&mcp.withPHY)) - { - if(!is_tdp) - PHY->rt_power.reset();//Jingwen - PHY->mcp.reads =XML->sys.mc.memory_reads; - PHY->mcp.writes =XML->sys.mc.memory_writes; - PHY->mcp.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); //Jingwen - PHY->computeEnergy(is_tdp); - } - if (is_tdp) - { - power = power + frontend->power + transecEngine->power; - if (mcp.type==0 || (mcp.type==1&&mcp.withPHY)) - { - power = power + PHY->power; - } - } - else - { - rt_power = rt_power + frontend->rt_power + transecEngine->rt_power+dram->rt_power; - if (mcp.type==0 || (mcp.type==1&&mcp.withPHY)) - { - rt_power = rt_power + PHY->rt_power; - } - } + transecEngine->mcp.reads = XML->sys.mc.memory_reads; + transecEngine->mcp.writes = XML->sys.mc.memory_writes; + + // set_mc_param(); + + frontend->computeEnergy(is_tdp); + transecEngine->computeEnergy(is_tdp); + dram->computeEnergy(is_tdp); + if (mcp.type == 0 || (mcp.type == 1 && mcp.withPHY)) { + if (!is_tdp) PHY->rt_power.reset(); // Jingwen + PHY->mcp.reads = XML->sys.mc.memory_reads; + PHY->mcp.writes = XML->sys.mc.memory_writes; + PHY->mcp.executionTime = XML->sys.total_cycles / + (XML->sys.target_core_clockrate * 1e6); // Jingwen + PHY->computeEnergy(is_tdp); + } + if (is_tdp) { + power = power + frontend->power + transecEngine->power; + if (mcp.type == 0 || (mcp.type == 1 && mcp.withPHY)) { + power = power + PHY->power; + } + } else { + rt_power = rt_power + frontend->rt_power + transecEngine->rt_power + + dram->rt_power; + if (mcp.type == 0 || (mcp.type == 1 && mcp.withPHY)) { + rt_power = rt_power + PHY->rt_power; + } + } } -void MemoryController::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 << "Memory Controller:" << endl; - cout << indent_str<< "Area = " << area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str << "Peak Dynamic = " << power.readOp.dynamic*mcp.clockRate << " W" << endl; - cout << indent_str<< "Subthreshold Leakage = " - << (long_channel? power.readOp.longer_channel_leakage:power.readOp.leakage) <<" W" << endl; - //cout << indent_str<< "Subthreshold Leakage = " << power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str<< "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl; - cout << indent_str << "Runtime Dynamic = " << rt_power.readOp.dynamic/mcp.executionTime << " W" << endl; - cout<2){ - frontend->displayEnergy(indent+4,is_tdp); - //} - cout << indent_str << "Transaction Engine:" << endl; - cout << indent_str_next << "Area = " << transecEngine->area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << transecEngine->power.readOp.dynamic*mcp.clockRate << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? transecEngine->power.readOp.longer_channel_leakage:transecEngine->power.readOp.leakage) <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << transecEngine->power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << transecEngine->rt_power.readOp.dynamic/mcp.executionTime << " W" << endl; - cout <sys.longer_channel_device; + + if (is_tdp) { + cout << "Memory Controller:" << endl; + cout << indent_str << "Area = " << area.get_area() * 1e-6 << " mm^2" + << endl; + cout << indent_str + << "Peak Dynamic = " << power.readOp.dynamic * mcp.clockRate << " W" + << endl; + cout << indent_str << "Subthreshold Leakage = " + << (long_channel ? power.readOp.longer_channel_leakage + : power.readOp.leakage) + << " W" << endl; + // cout << indent_str<< "Subthreshold Leakage = " << + // power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str << "Gate Leakage = " << power.readOp.gate_leakage << " W" + << endl; + cout << indent_str + << "Runtime Dynamic = " << rt_power.readOp.dynamic / mcp.executionTime + << " W" << endl; + cout << endl; + cout << indent_str << "Front End Engine:" << endl; + cout << indent_str_next << "Area = " << frontend->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << frontend->power.readOp.dynamic * mcp.clockRate + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? frontend->power.readOp.longer_channel_leakage + : frontend->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << frontend->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << frontend->rt_power.readOp.dynamic / mcp.executionTime << " W" + << endl; + cout << endl; + // if (plevel >2){ + frontend->displayEnergy(indent + 4, is_tdp); + //} + cout << indent_str << "Transaction Engine:" << endl; + cout << indent_str_next + << "Area = " << transecEngine->area.get_area() * 1e-6 << " mm^2" + << endl; + cout << indent_str_next << "Peak Dynamic = " + << transecEngine->power.readOp.dynamic * mcp.clockRate << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? transecEngine->power.readOp.longer_channel_leakage + : transecEngine->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << transecEngine->power.readOp.gate_leakage + << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " + << transecEngine->rt_power.readOp.dynamic / mcp.executionTime << " W" + << endl; + cout << endl; + if (mcp.type == 0 || (mcp.type == 1 && mcp.withPHY)) { + cout << indent_str << "PHY:" << endl; + cout << indent_str_next << "Area = " << PHY->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next + << "Peak Dynamic = " << PHY->power.readOp.dynamic * mcp.clockRate + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? PHY->power.readOp.longer_channel_leakage + : PHY->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << PHY->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << PHY->rt_power.readOp.dynamic / mcp.executionTime << " W" << endl; + cout << endl; + } + } else { + cout << "Memory Controller:" << endl; + cout << indent_str_next << "Area = " << area.get_area() * 1e-6 << " mm^2" + << endl; + cout << indent_str_next + << "Peak Dynamic = " << power.readOp.dynamic * mcp.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 << endl; + } } -void DRAM::set_dram_param() -{ - dramp.cmd_coeff = XML->sys.mc.dram_rd_coeff; - dramp.act_coeff = XML->sys.mc.dram_act_coeff; - dramp.nop_coeff = XML->sys.mc.dram_nop_coeff; - dramp.activity_coeff = XML->sys.mc.dram_activity_coeff; - dramp.pre_coeff = XML->sys.mc.dram_pre_coeff; - dramp.rd_coeff = XML->sys.mc.dram_rd_coeff; - dramp.wr_coeff = XML->sys.mc.dram_wr_coeff; - dramp.req_coeff = XML->sys.mc.dram_req_coeff; - dramp.const_coeff = XML->sys.mc.dram_const_coeff; +void DRAM::set_dram_param() { + dramp.cmd_coeff = XML->sys.mc.dram_rd_coeff; + dramp.act_coeff = XML->sys.mc.dram_act_coeff; + dramp.nop_coeff = XML->sys.mc.dram_nop_coeff; + dramp.activity_coeff = XML->sys.mc.dram_activity_coeff; + dramp.pre_coeff = XML->sys.mc.dram_pre_coeff; + dramp.rd_coeff = XML->sys.mc.dram_rd_coeff; + dramp.wr_coeff = XML->sys.mc.dram_wr_coeff; + dramp.req_coeff = XML->sys.mc.dram_req_coeff; + dramp.const_coeff = XML->sys.mc.dram_const_coeff; } -void MemoryController::set_mc_param() -{ - - if (mc_type==MC) - { - mcp.clockRate =XML->sys.mc.mc_clock*2;//DDR double pumped - mcp.clockRate *= 1e6; - mcp.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); - - mcp.llcBlockSize =int(ceil(XML->sys.mc.llc_line_length/8.0))+XML->sys.mc.llc_line_length;//ecc overhead - mcp.dataBusWidth =int(ceil(XML->sys.mc.databus_width/8.0)) + XML->sys.mc.databus_width; - mcp.addressBusWidth =int(ceil(XML->sys.mc.addressbus_width));//XML->sys.physical_address_width; - mcp.opcodeW =16; - mcp.num_mcs = XML->sys.mc.number_mcs; - mcp.num_channels = XML->sys.mc.memory_channels_per_mc; - mcp.reads = XML->sys.mc.memory_reads; - mcp.writes = XML->sys.mc.memory_writes; - //+++++++++Transaction engine +++++++++++++++++ ////TODO needs better numbers, Run the RTL code from OpenSparc. - mcp.peakDataTransferRate = XML->sys.mc.peak_transfer_rate; - mcp.memRank = XML->sys.mc.number_ranks; - //++++++++++++++PHY ++++++++++++++++++++++++++ //TODO needs better numbers - //PHY.memAccesses=PHY.peakDataTransferRate;//this is the max power - //PHY.llcBlocksize=llcBlockSize; - mcp.frontend_duty_cycle = 0.5;//for max power, the actual off-chip links is bidirectional but time shared - mcp.LVDS = XML->sys.mc.LVDS; - mcp.type = XML->sys.mc.type; - mcp.withPHY = XML->sys.mc.withPHY; - } -// else if (mc_type==FLASHC) -// { -// mcp.clockRate =XML->sys.flashc.mc_clock*2;//DDR double pumped -// mcp.clockRate *= 1e6; -// mcp.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); -// -// mcp.llcBlockSize =int(ceil(XML->sys.flashc.llc_line_length/8.0))+XML->sys.flashc.llc_line_length;//ecc overhead -// mcp.dataBusWidth =int(ceil(XML->sys.flashc.databus_width/8.0)) + XML->sys.flashc.databus_width; -// mcp.addressBusWidth =int(ceil(XML->sys.flashc.addressbus_width));//XML->sys.physical_address_width; -// mcp.opcodeW =16; -// mcp.num_mcs = XML->sys.flashc.number_mcs; -// mcp.num_channels = XML->sys.flashc.memory_channels_per_mc; -// mcp.reads = XML->sys.flashc.memory_reads; -// mcp.writes = XML->sys.flashc.memory_writes; -// //+++++++++Transaction engine +++++++++++++++++ ////TODO needs better numbers, Run the RTL code from OpenSparc. -// mcp.peakDataTransferRate = XML->sys.flashc.peak_transfer_rate; -// mcp.memRank = XML->sys.flashc.number_ranks; -// //++++++++++++++PHY ++++++++++++++++++++++++++ //TODO needs better numbers -// //PHY.memAccesses=PHY.peakDataTransferRate;//this is the max power -// //PHY.llcBlocksize=llcBlockSize; -// mcp.frontend_duty_cycle = 0.5;//for max power, the actual off-chip links is bidirectional but time shared -// mcp.LVDS = XML->sys.flashc.LVDS; -// mcp.type = XML->sys.flashc.type; -// } - else - { - cout<<"Unknown memory controller type: neither DRAM controller nor Flash controller" <sys.mc.mc_clock * 2; // DDR double pumped + mcp.clockRate *= 1e6; + mcp.executionTime = + XML->sys.total_cycles / (XML->sys.target_core_clockrate * 1e6); + + mcp.llcBlockSize = int(ceil(XML->sys.mc.llc_line_length / 8.0)) + + XML->sys.mc.llc_line_length; // ecc overhead + mcp.dataBusWidth = + int(ceil(XML->sys.mc.databus_width / 8.0)) + XML->sys.mc.databus_width; + mcp.addressBusWidth = int(ceil( + XML->sys.mc.addressbus_width)); // XML->sys.physical_address_width; + mcp.opcodeW = 16; + mcp.num_mcs = XML->sys.mc.number_mcs; + mcp.num_channels = XML->sys.mc.memory_channels_per_mc; + mcp.reads = XML->sys.mc.memory_reads; + mcp.writes = XML->sys.mc.memory_writes; + //+++++++++Transaction engine +++++++++++++++++ ////TODO needs better + // numbers, Run the RTL code from OpenSparc. + mcp.peakDataTransferRate = XML->sys.mc.peak_transfer_rate; + mcp.memRank = XML->sys.mc.number_ranks; + //++++++++++++++PHY ++++++++++++++++++++++++++ //TODO needs better numbers + // PHY.memAccesses=PHY.peakDataTransferRate;//this is the max power + // PHY.llcBlocksize=llcBlockSize; + mcp.frontend_duty_cycle = 0.5; // for max power, the actual off-chip links + // is bidirectional but time shared + mcp.LVDS = XML->sys.mc.LVDS; + mcp.type = XML->sys.mc.type; + mcp.withPHY = XML->sys.mc.withPHY; + } + // else if (mc_type==FLASHC) + // { + // mcp.clockRate =XML->sys.flashc.mc_clock*2;//DDR double + // pumped mcp.clockRate *= 1e6; mcp.executionTime = + // XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); + // + // mcp.llcBlockSize + //=int(ceil(XML->sys.flashc.llc_line_length/8.0))+XML->sys.flashc.llc_line_length;//ecc + // overhead mcp.dataBusWidth + // =int(ceil(XML->sys.flashc.databus_width/8.0)) + + // XML->sys.flashc.databus_width; mcp.addressBusWidth + //=int(ceil(XML->sys.flashc.addressbus_width));//XML->sys.physical_address_width; + // mcp.opcodeW =16; + // mcp.num_mcs = XML->sys.flashc.number_mcs; + // mcp.num_channels = XML->sys.flashc.memory_channels_per_mc; + // mcp.reads = XML->sys.flashc.memory_reads; + // mcp.writes = XML->sys.flashc.memory_writes; + // //+++++++++Transaction engine +++++++++++++++++ ////TODO needs + // better numbers, Run the RTL code from OpenSparc. + // mcp.peakDataTransferRate = + // XML->sys.flashc.peak_transfer_rate; mcp.memRank = + // XML->sys.flashc.number_ranks; + // //++++++++++++++PHY ++++++++++++++++++++++++++ //TODO needs + // better numbers + // //PHY.memAccesses=PHY.peakDataTransferRate;//this is the max + // power + // //PHY.llcBlocksize=llcBlockSize; + // mcp.frontend_duty_cycle = 0.5;//for max power, the actual + // off-chip links is bidirectional but time shared mcp.LVDS = + // XML->sys.flashc.LVDS; mcp.type = XML->sys.flashc.type; + // } + else { + cout << "Unknown memory controller type: neither DRAM controller nor Flash " + "controller" + << endl; + exit(0); + } } -MCFrontEnd ::~MCFrontEnd(){ - - if(MC_arb) {delete MC_arb; MC_arb = 0;} - if(frontendBuffer) {delete frontendBuffer; frontendBuffer = 0;} - if(readBuffer) {delete readBuffer; readBuffer = 0;} - if(writeBuffer) {delete writeBuffer; writeBuffer = 0;} +MCFrontEnd ::~MCFrontEnd() { + if (MC_arb) { + delete MC_arb; + MC_arb = 0; + } + if (frontendBuffer) { + delete frontendBuffer; + frontendBuffer = 0; + } + if (readBuffer) { + delete readBuffer; + readBuffer = 0; + } + if (writeBuffer) { + delete writeBuffer; + writeBuffer = 0; + } } -MemoryController ::~MemoryController(){ - - if(frontend) {delete frontend; frontend = 0;} - if(transecEngine) {delete transecEngine; transecEngine = 0;} - if(PHY) {delete PHY; PHY = 0;} - if(pipeLogic) {delete pipeLogic; pipeLogic = 0;} +MemoryController ::~MemoryController() { + if (frontend) { + delete frontend; + frontend = 0; + } + if (transecEngine) { + delete transecEngine; + transecEngine = 0; + } + if (PHY) { + delete PHY; + PHY = 0; + } + if (pipeLogic) { + delete pipeLogic; + pipeLogic = 0; + } } - diff --git a/src/gpuwattch/memoryctrl.h b/src/gpuwattch/memoryctrl.h index e725e85..4ac55fc 100644 --- a/src/gpuwattch/memoryctrl.h +++ b/src/gpuwattch/memoryctrl.h @@ -29,12 +29,12 @@ * ***************************************************************************/ /******************************************************************** -* 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 * + ********************************************************************/ #ifndef MEMORYCTRL_H_ #define MEMORYCTRL_H_ @@ -48,95 +48,100 @@ #include "basic_components.h" class MCBackend : public Component { - public: - InputParameter l_ip; - uca_org_t local_result; - enum MemoryCtrl_type mc_type; - MCParam mcp; - statsDef tdp_stats; - statsDef rtp_stats; - statsDef stats_t; - powerDef power_t; - MCBackend(InputParameter* interface_ip_, const MCParam & mcp_, enum MemoryCtrl_type mc_type_); - void compute(); - void computeEnergy(bool is_tdp=true); - void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); - ~MCBackend(){}; + public: + InputParameter l_ip; + uca_org_t local_result; + enum MemoryCtrl_type mc_type; + MCParam mcp; + statsDef tdp_stats; + statsDef rtp_stats; + statsDef stats_t; + powerDef power_t; + MCBackend(InputParameter *interface_ip_, const MCParam &mcp_, + enum MemoryCtrl_type mc_type_); + void compute(); + void computeEnergy(bool is_tdp = true); + void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); + ~MCBackend(){}; }; class MCPHY : public Component { - public: - InputParameter l_ip; - uca_org_t local_result; - enum MemoryCtrl_type mc_type; - MCParam mcp; - statsDef tdp_stats; - statsDef rtp_stats; - statsDef stats_t; - powerDef power_t; - MCPHY(InputParameter* interface_ip_, const MCParam & mcp_, enum MemoryCtrl_type mc_type_); - void compute(); - void computeEnergy(bool is_tdp=true); - void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); - ~MCPHY(){}; + public: + InputParameter l_ip; + uca_org_t local_result; + enum MemoryCtrl_type mc_type; + MCParam mcp; + statsDef tdp_stats; + statsDef rtp_stats; + statsDef stats_t; + powerDef power_t; + MCPHY(InputParameter *interface_ip_, const MCParam &mcp_, + enum MemoryCtrl_type mc_type_); + void compute(); + void computeEnergy(bool is_tdp = true); + void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); + ~MCPHY(){}; }; class MCFrontEnd : public Component { - public: - ParseXML *XML; - InputParameter interface_ip; - enum MemoryCtrl_type mc_type; - MCParam mcp; - selection_logic * MC_arb; - ArrayST * frontendBuffer; - ArrayST * readBuffer; - ArrayST * writeBuffer; + public: + ParseXML *XML; + InputParameter interface_ip; + enum MemoryCtrl_type mc_type; + MCParam mcp; + selection_logic *MC_arb; + ArrayST *frontendBuffer; + ArrayST *readBuffer; + ArrayST *writeBuffer; - ArrayST * PRT; - ArrayST * threadMasks; - ArrayST * PRC; - double coalesce_scale; + ArrayST *PRT; + ArrayST *threadMasks; + ArrayST *PRC; + double coalesce_scale; - MCFrontEnd(ParseXML *XML_interface,InputParameter* interface_ip_, const MCParam & mcp_, enum MemoryCtrl_type mc_type_); - void computeEnergy(bool is_tdp=true); - void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); - ~MCFrontEnd(); + MCFrontEnd(ParseXML *XML_interface, InputParameter *interface_ip_, + const MCParam &mcp_, enum MemoryCtrl_type mc_type_); + void computeEnergy(bool is_tdp = true); + void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); + ~MCFrontEnd(); }; class DRAM : public Component { - public: - ParseXML *XML; - InputParameter interface_ip; - enum Dram_type dram_type; - DRAMParam dramp; - powerDef power_t; - DRAM(ParseXML *XML_interface,InputParameter* interface_ip_, enum Dram_type dram_type_); - void set_dram_param(); - void computeEnergy(bool is_tdp=true); - void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); - ~DRAM(); + public: + ParseXML *XML; + InputParameter interface_ip; + enum Dram_type dram_type; + DRAMParam dramp; + powerDef power_t; + DRAM(ParseXML *XML_interface, InputParameter *interface_ip_, + enum Dram_type dram_type_); + void set_dram_param(); + void computeEnergy(bool is_tdp = true); + void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); + ~DRAM(); }; class MemoryController : public Component { - public: - ParseXML *XML; - InputParameter interface_ip; - enum MemoryCtrl_type mc_type; - MCParam mcp; - DRAM * dram; - MCFrontEnd * frontend; - MCBackend * transecEngine; - MCPHY * PHY; - Pipeline * pipeLogic; + public: + ParseXML *XML; + InputParameter interface_ip; + enum MemoryCtrl_type mc_type; + MCParam mcp; + DRAM *dram; + MCFrontEnd *frontend; + MCBackend *transecEngine; + MCPHY *PHY; + Pipeline *pipeLogic; - //Add coalescing logic related modules with each memory controller --Syed Gilani - + // Add coalescing logic related modules with each memory controller --Syed + // Gilani - //clock_network clockNetwork; - MemoryController(ParseXML *XML_interface,InputParameter* interface_ip_, enum MemoryCtrl_type mc_type_,enum Dram_type dram_type_); - void set_mc_param(); - void computeEnergy(bool is_tdp=true); - void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); - ~MemoryController(); + // clock_network clockNetwork; + MemoryController(ParseXML *XML_interface, InputParameter *interface_ip_, + enum MemoryCtrl_type mc_type_, enum Dram_type dram_type_); + void set_mc_param(); + void computeEnergy(bool is_tdp = true); + void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); + ~MemoryController(); }; #endif /* MEMORYCTRL_H_ */ diff --git a/src/gpuwattch/noc.cc b/src/gpuwattch/noc.cc index 08fa2ef..9453ccb 100644 --- a/src/gpuwattch/noc.cc +++ b/src/gpuwattch/noc.cc @@ -29,348 +29,425 @@ * ***************************************************************************/ /******************************************************************** -* 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 "io.h" -#include "parameter.h" -#include "const.h" -#include "cacti/basic_circuit.h" -#include +#include "noc.h" +#include #include -#include "XML_Parse.h" -#include #include -#include -#include "noc.h" - - - -NoC::NoC(ParseXML *XML_interface, int ithNoC_, InputParameter* interface_ip_, double M_traffic_pattern_, double link_len_) -:XML(XML_interface), -ithNoC(ithNoC_), -interface_ip(*interface_ip_), -router(0), -link_bus(0), -link_bus_exist(false), -router_exist(false), -M_traffic_pattern(M_traffic_pattern_) -{ - /* - * initialize, compute and optimize individual components. - */ - - if (XML->sys.Embedded) - { - interface_ip.wt =Global_30; - interface_ip.wire_is_mat_type = 0; - interface_ip.wire_os_mat_type = 1; - } - else - { - interface_ip.wt =Global; - interface_ip.wire_is_mat_type = 2; - interface_ip.wire_os_mat_type = 2; - } - set_noc_param(); - local_result=init_interface(&interface_ip); - scktRatio = g_tp.sckt_co_eff; - - if (nocdynp.type) - {/* - * if NOC compute router, router links must be computed separately - * and called from external - * since total chip area must be known first - */ - init_router(); - } - else - { - init_link_bus(link_len_); //if bus compute bus - } +#include +#include +#include "XML_Parse.h" +#include "cacti/basic_circuit.h" +#include "const.h" +#include "io.h" +#include "parameter.h" - // //clock power - // clockNetwork.init_wire_external(is_default, &interface_ip); - // clockNetwork.clk_area =area*1.1;//10% of placement overhead. rule of thumb - // clockNetwork.end_wiring_level =5;//toplevel metal - // clockNetwork.start_wiring_level =5;//toplevel metal - // clockNetwork.num_regs = corepipe.tot_stage_vector; - // clockNetwork.optimize_wire(); +NoC::NoC(ParseXML* XML_interface, int ithNoC_, InputParameter* interface_ip_, + double M_traffic_pattern_, double link_len_) + : XML(XML_interface), + ithNoC(ithNoC_), + interface_ip(*interface_ip_), + router(0), + link_bus(0), + link_bus_exist(false), + router_exist(false), + M_traffic_pattern(M_traffic_pattern_) { + /* + * initialize, compute and optimize individual components. + */ + + if (XML->sys.Embedded) { + interface_ip.wt = Global_30; + interface_ip.wire_is_mat_type = 0; + interface_ip.wire_os_mat_type = 1; + } else { + interface_ip.wt = Global; + interface_ip.wire_is_mat_type = 2; + interface_ip.wire_os_mat_type = 2; + } + set_noc_param(); + local_result = init_interface(&interface_ip); + scktRatio = g_tp.sckt_co_eff; + + if (nocdynp.type) { /* + * if NOC compute router, router links must be computed + * separately and called from external since total chip + * area must be known first + */ + init_router(); + } else { + init_link_bus(link_len_); // if bus compute bus + } + + // //clock power + // clockNetwork.init_wire_external(is_default, &interface_ip); + // clockNetwork.clk_area =area*1.1;//10% of placement overhead. + // rule of thumb clockNetwork.end_wiring_level =5;//toplevel metal + // clockNetwork.start_wiring_level =5;//toplevel metal + // clockNetwork.num_regs = corepipe.tot_stage_vector; + // clockNetwork.optimize_wire(); } -void NoC::init_router() -{ - router = new MCPAT_Router(nocdynp.flit_size, - nocdynp.virtual_channel_per_port*nocdynp.input_buffer_entries_per_vc, - nocdynp.virtual_channel_per_port, &(g_tp.peri_global), - nocdynp.input_ports,nocdynp.output_ports, M_traffic_pattern); - //router->print_router(); - area.set_area(area.get_area()+ router->area.get_area()*nocdynp.total_nodes); - - double long_channel_device_reduction = longer_channel_device_reduction(Uncore_device); - router->power.readOp.longer_channel_leakage = router->power.readOp.leakage * long_channel_device_reduction; - router->buffer.power.readOp.longer_channel_leakage = router->buffer.power.readOp.leakage * long_channel_device_reduction; - router->crossbar.power.readOp.longer_channel_leakage = router->crossbar.power.readOp.leakage * long_channel_device_reduction; - router->arbiter.power.readOp.longer_channel_leakage = router->arbiter.power.readOp.leakage * long_channel_device_reduction; - router_exist = true; +void NoC::init_router() { + router = new MCPAT_Router( + nocdynp.flit_size, + nocdynp.virtual_channel_per_port * nocdynp.input_buffer_entries_per_vc, + nocdynp.virtual_channel_per_port, &(g_tp.peri_global), + nocdynp.input_ports, nocdynp.output_ports, M_traffic_pattern); + // router->print_router(); + area.set_area(area.get_area() + + router->area.get_area() * nocdynp.total_nodes); + + double long_channel_device_reduction = + longer_channel_device_reduction(Uncore_device); + router->power.readOp.longer_channel_leakage = + router->power.readOp.leakage * long_channel_device_reduction; + router->buffer.power.readOp.longer_channel_leakage = + router->buffer.power.readOp.leakage * long_channel_device_reduction; + router->crossbar.power.readOp.longer_channel_leakage = + router->crossbar.power.readOp.leakage * long_channel_device_reduction; + router->arbiter.power.readOp.longer_channel_leakage = + router->arbiter.power.readOp.leakage * long_channel_device_reduction; + router_exist = true; } -void NoC ::init_link_bus(double link_len_) -{ - - -// if (nocdynp.min_ports==1 ) - if (nocdynp.type) - link_name = "Links"; - else - link_name = "Bus"; +void NoC ::init_link_bus(double link_len_) { + // if (nocdynp.min_ports==1 ) + if (nocdynp.type) + link_name = "Links"; + else + link_name = "Bus"; - link_len=link_len_; - assert(link_len>0); + link_len = link_len_; + assert(link_len > 0); - interface_ip.throughput = nocdynp.link_throughput/nocdynp.clockRate; - interface_ip.latency = nocdynp.link_latency/nocdynp.clockRate; + interface_ip.throughput = nocdynp.link_throughput / nocdynp.clockRate; + interface_ip.latency = nocdynp.link_latency / nocdynp.clockRate; - link_len /= (nocdynp.horizontal_nodes + nocdynp.vertical_nodes)/2; + link_len /= (nocdynp.horizontal_nodes + nocdynp.vertical_nodes) / 2; - if (nocdynp.total_nodes >1) link_len /=2; //All links are shared by neighbors - link_bus = new interconnect(name, Uncore_device, 1, 1, nocdynp.flit_size, - link_len, &interface_ip, 3, true/*pipelinable*/, nocdynp.route_over_perc); + if (nocdynp.total_nodes > 1) + link_len /= 2; // All links are shared by neighbors + link_bus = new interconnect(name, Uncore_device, 1, 1, nocdynp.flit_size, + link_len, &interface_ip, 3, true /*pipelinable*/, + nocdynp.route_over_perc); - link_bus_tot_per_Router.area.set_area(link_bus_tot_per_Router.area.get_area()+ link_bus->area.get_area() - * nocdynp.global_linked_ports); + link_bus_tot_per_Router.area.set_area( + link_bus_tot_per_Router.area.get_area() + + link_bus->area.get_area() * nocdynp.global_linked_ports); - area.set_area(area.get_area()+ link_bus_tot_per_Router.area.get_area()* nocdynp.total_nodes); - link_bus_exist = true; + area.set_area(area.get_area() + + link_bus_tot_per_Router.area.get_area() * nocdynp.total_nodes); + link_bus_exist = true; } -void NoC::computeEnergy(bool is_tdp) -{ - //power_point_product_masks - double pppm_t[4] = {1,1,1,1}; - double M=nocdynp.duty_cycle; - // nocdynp.executionTime=XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6);//Syed - //cout<<"NOC Total Cycles: "<sys.total_cycles<sys.target_core_clockrate<power = router->power*pppm_t; - set_pppm(pppm_t, nocdynp.total_nodes, nocdynp.total_nodes, nocdynp.total_nodes, nocdynp.total_nodes); - power = power + router->power*pppm_t; - } - if (link_bus_exist) - { - if (nocdynp.type) - set_pppm(pppm_t, 1*M_traffic_pattern*M*(nocdynp.min_ports -1), nocdynp.global_linked_ports, - nocdynp.global_linked_ports, nocdynp.global_linked_ports); - //reset traffic pattern; local port do not have router links - else - set_pppm(pppm_t, 1*M_traffic_pattern*M*(nocdynp.min_ports), nocdynp.global_linked_ports, - nocdynp.global_linked_ports, nocdynp.global_linked_ports);//reset traffic pattern - - link_bus_tot_per_Router.power = link_bus->power*pppm_t; - - set_pppm(pppm_t, nocdynp.total_nodes, - nocdynp.total_nodes, - nocdynp.total_nodes, - nocdynp.total_nodes); - power = power + link_bus_tot_per_Router.power*pppm_t; - - } - } - else - { - rt_power.reset(); - router->buffer.rt_power.reset(); - router->crossbar.rt_power.reset(); - router->arbiter.rt_power.reset(); - router->rt_power.reset(); - //link_bus->rt_power.reset(); - - //init stats for runtime power (RTP) - stats_t.readAc.access = XML->sys.NoC[ithNoC].total_accesses; - //cout<<"NOC(computeEnergy) read accesses: "<< stats_t.readAc.access<buffer.rt_power.readOp.dynamic = (router->buffer.power.readOp.dynamic + router->buffer.power.writeOp.dynamic)*rtp_stats.readAc.access ; - router->crossbar.rt_power.readOp.dynamic = router->crossbar.power.readOp.dynamic*rtp_stats.readAc.access ; - router->arbiter.rt_power.readOp.dynamic = router->arbiter.power.readOp.dynamic*rtp_stats.readAc.access ; - - router->rt_power = router->rt_power + (router->buffer.rt_power + router->crossbar.rt_power + router->arbiter.rt_power)*pppm_t + - router->power*pppm_lkg;//TDP power must be calculated first! - rt_power = rt_power + router->rt_power; - } - if (link_bus_exist) - { - link_bus->rt_power.reset(); - set_pppm(pppm_t, rtp_stats.readAc.access, 1 , 1, rtp_stats.readAc.access); - link_bus->rt_power = link_bus->power * pppm_t; - rt_power = rt_power + link_bus->rt_power; - } - - } +void NoC::computeEnergy(bool is_tdp) { + // power_point_product_masks + double pppm_t[4] = {1, 1, 1, 1}; + double M = nocdynp.duty_cycle; + // nocdynp.executionTime=XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6);//Syed + // cout<<"NOC Total Cycles: "<sys.total_cycles<sys.target_core_clockrate<power = router->power * pppm_t; + set_pppm(pppm_t, nocdynp.total_nodes, nocdynp.total_nodes, + nocdynp.total_nodes, nocdynp.total_nodes); + power = power + router->power * pppm_t; + } + if (link_bus_exist) { + if (nocdynp.type) + set_pppm(pppm_t, 1 * M_traffic_pattern * M * (nocdynp.min_ports - 1), + nocdynp.global_linked_ports, nocdynp.global_linked_ports, + nocdynp.global_linked_ports); + // reset traffic pattern; local port do not have router links + else + set_pppm(pppm_t, 1 * M_traffic_pattern * M * (nocdynp.min_ports), + nocdynp.global_linked_ports, nocdynp.global_linked_ports, + nocdynp.global_linked_ports); // reset traffic pattern + + link_bus_tot_per_Router.power = link_bus->power * pppm_t; + + set_pppm(pppm_t, nocdynp.total_nodes, nocdynp.total_nodes, + nocdynp.total_nodes, nocdynp.total_nodes); + power = power + link_bus_tot_per_Router.power * pppm_t; + } + } else { + rt_power.reset(); + router->buffer.rt_power.reset(); + router->crossbar.rt_power.reset(); + router->arbiter.rt_power.reset(); + router->rt_power.reset(); + // link_bus->rt_power.reset(); + + // init stats for runtime power (RTP) + stats_t.readAc.access = XML->sys.NoC[ithNoC].total_accesses; + // cout<<"NOC(computeEnergy) read accesses: "<< stats_t.readAc.access<buffer.rt_power.readOp.dynamic = + (router->buffer.power.readOp.dynamic + + router->buffer.power.writeOp.dynamic) * + rtp_stats.readAc.access; + router->crossbar.rt_power.readOp.dynamic = + router->crossbar.power.readOp.dynamic * rtp_stats.readAc.access; + router->arbiter.rt_power.readOp.dynamic = + router->arbiter.power.readOp.dynamic * rtp_stats.readAc.access; + + router->rt_power = + router->rt_power + + (router->buffer.rt_power + router->crossbar.rt_power + + router->arbiter.rt_power) * + pppm_t + + router->power * pppm_lkg; // TDP power must be calculated first! + rt_power = rt_power + router->rt_power; + } + if (link_bus_exist) { + link_bus->rt_power.reset(); + set_pppm(pppm_t, rtp_stats.readAc.access, 1, 1, rtp_stats.readAc.access); + link_bus->rt_power = link_bus->power * pppm_t; + rt_power = rt_power + link_bus->rt_power; + } + } } - -void NoC::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; - - double M =M_traffic_pattern*nocdynp.duty_cycle; - /*only router as a whole has been applied the M_traffic_pattern(0.6 by default) factor in router.cc; - * When power of crossbars, arbiters, etc need to be displayed, the M_traffic_pattern factor need to - * be applied together with McPAT's extra traffic pattern. - * */ - if (is_tdp) - { - cout << name << endl; - cout << indent_str << "Area = " << area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str<< "Peak Dynamic = " << power.readOp.dynamic*nocdynp.clockRate << " W" << endl; - cout << indent_str << "Subthreshold Leakage = " - << (long_channel? power.readOp.longer_channel_leakage:power.readOp.leakage) <<" W" << endl; - cout << indent_str << "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl; - cout << indent_str<< "Runtime Dynamic = " << rt_power.readOp.dynamic/nocdynp.executionTime << " W" << endl; - //cout << indent_str<< "Execution Time = " << nocdynp.executionTime << " s" << endl; - cout<2){ - cout << indent_str<< indent_str << "Virtual Channel Buffer:" << endl; - cout << indent_str<< indent_str_next << "Area = " << router->buffer.area.get_area()*1e-6*nocdynp.input_ports<< " mm^2" << endl; - cout << indent_str<< indent_str_next << "Peak Dynamic = " <<(router->buffer.power.readOp.dynamic + router->buffer.power.writeOp.dynamic) - *nocdynp.min_ports*M*nocdynp.clockRate << " W" << endl; - cout << indent_str<< indent_str_next << "Subthreshold Leakage = " - << (long_channel? router->buffer.power.readOp.longer_channel_leakage*nocdynp.input_ports:router->buffer.power.readOp.leakage*nocdynp.input_ports) <<" W" << endl; - cout << indent_str<< indent_str_next << "Gate Leakage = " << router->buffer.power.readOp.gate_leakage*nocdynp.input_ports << " W" << endl; - cout << indent_str<< indent_str_next << "Runtime Dynamic = " << router->buffer.rt_power.readOp.dynamic/nocdynp.executionTime << " W" << endl; - cout <sys.longer_channel_device; + + double M = M_traffic_pattern * nocdynp.duty_cycle; + /*only router as a whole has been applied the M_traffic_pattern(0.6 by + * default) factor in router.cc; When power of crossbars, arbiters, etc need + * to be displayed, the M_traffic_pattern factor need to be applied together + * with McPAT's extra traffic pattern. + * */ + if (is_tdp) { + cout << name << endl; + cout << indent_str << "Area = " << area.get_area() * 1e-6 << " mm^2" + << endl; + cout << indent_str + << "Peak Dynamic = " << power.readOp.dynamic * nocdynp.clockRate + << " W" << endl; + cout << indent_str << "Subthreshold Leakage = " + << (long_channel ? power.readOp.longer_channel_leakage + : power.readOp.leakage) + << " W" << endl; + cout << indent_str << "Gate Leakage = " << power.readOp.gate_leakage << " W" + << endl; + cout << indent_str << "Runtime Dynamic = " + << rt_power.readOp.dynamic / nocdynp.executionTime << " W" << endl; + // cout << indent_str<< "Execution Time = " << nocdynp.executionTime << " s" + // << endl; + cout << endl; + + if (router_exist) { + cout << indent_str << "Router: " << endl; + cout << indent_str_next << "Area = " << router->area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " + << router->power.readOp.dynamic * nocdynp.clockRate << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? router->power.readOp.longer_channel_leakage + : router->power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << router->power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next << "Runtime Dynamic = " + << router->rt_power.readOp.dynamic / nocdynp.executionTime << " W" + << endl; + cout << endl; + if (plevel > 2) { + cout << indent_str << indent_str << "Virtual Channel Buffer:" << endl; + cout << indent_str << indent_str_next << "Area = " + << router->buffer.area.get_area() * 1e-6 * nocdynp.input_ports + << " mm^2" << endl; + cout << indent_str << indent_str_next << "Peak Dynamic = " + << (router->buffer.power.readOp.dynamic + + router->buffer.power.writeOp.dynamic) * + nocdynp.min_ports * M * nocdynp.clockRate + << " W" << endl; + cout << indent_str << indent_str_next << "Subthreshold Leakage = " + << (long_channel + ? router->buffer.power.readOp.longer_channel_leakage * + nocdynp.input_ports + : router->buffer.power.readOp.leakage * + nocdynp.input_ports) + << " W" << endl; + cout << indent_str << indent_str_next << "Gate Leakage = " + << router->buffer.power.readOp.gate_leakage * nocdynp.input_ports + << " W" << endl; + cout << indent_str << indent_str_next << "Runtime Dynamic = " + << router->buffer.rt_power.readOp.dynamic / nocdynp.executionTime + << " W" << endl; + cout << endl; + cout << indent_str << indent_str << "Crossbar:" << endl; + cout << indent_str << indent_str_next + << "Area = " << router->crossbar.area.get_area() * 1e-6 << " mm^2" + << endl; + cout << indent_str << indent_str_next << "Peak Dynamic = " + << router->crossbar.power.readOp.dynamic * nocdynp.clockRate * + nocdynp.min_ports * M + << " W" << endl; + cout << indent_str << indent_str_next << "Subthreshold Leakage = " + << (long_channel + ? router->crossbar.power.readOp.longer_channel_leakage + : router->crossbar.power.readOp.leakage) + << " W" << endl; + cout << indent_str << indent_str_next + << "Gate Leakage = " << router->crossbar.power.readOp.gate_leakage + << " W" << endl; + cout << indent_str << indent_str_next << "Runtime Dynamic = " + << router->crossbar.rt_power.readOp.dynamic / nocdynp.executionTime + << " W" << endl; + cout << endl; + cout << indent_str << indent_str << "Arbiter:" << endl; + cout << indent_str << indent_str_next << "Peak Dynamic = " + << router->arbiter.power.readOp.dynamic * nocdynp.clockRate * + nocdynp.min_ports * M + << " W" << endl; + cout << indent_str << indent_str_next << "Subthreshold Leakage = " + << (long_channel + ? router->arbiter.power.readOp.longer_channel_leakage + : router->arbiter.power.readOp.leakage) + << " W" << endl; + cout << indent_str << indent_str_next + << "Gate Leakage = " << router->arbiter.power.readOp.gate_leakage + << " W" << endl; + cout << indent_str << indent_str_next << "Runtime Dynamic = " + << router->arbiter.rt_power.readOp.dynamic / nocdynp.executionTime + << " W" << endl; + cout << endl; + } + } + if (link_bus_exist) { + cout << indent_str << (nocdynp.type ? "Per Router " : "") << link_name + << ": " << endl; + cout << indent_str_next + << "Area = " << link_bus_tot_per_Router.area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " + << link_bus_tot_per_Router.power.readOp.dynamic * nocdynp.clockRate + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel + ? link_bus_tot_per_Router.power.readOp.longer_channel_leakage + : link_bus_tot_per_Router.power.readOp.leakage) + << " W" << endl; + cout << indent_str_next << "Gate Leakage = " + << link_bus_tot_per_Router.power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next << "Runtime Dynamic = " + << link_bus->rt_power.readOp.dynamic / nocdynp.executionTime << " W" + << endl; + cout << endl; + } + } else { + // cout << indent_str_next << "Instruction Fetch Unit Peak Dynamic + //= + //" + //<< ifu->rt_power.readOp.dynamic*clockRate << " W" << endl; + //cout + //<< indent_str_next << "Instruction Fetch Unit Subthreshold Leakage = " + // << ifu->rt_power.readOp.leakage <<" W" << endl; cout << + // indent_str_next << "Instruction Fetch Unit Gate Leakage = " << + // ifu->rt_power.readOp.gate_leakage << " W" << endl; cout << + // indent_str_next + //<< "Load Store Unit Peak Dynamic = " << + // lsu->rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout + // << indent_str_next << "Load Store Unit Subthreshold Leakage = " << + // lsu->rt_power.readOp.leakage << " W" << endl; cout << + // indent_str_next + // << "Load Store Unit Gate Leakage = " << + // lsu->rt_power.readOp.gate_leakage + //<< " W" << endl; cout << indent_str_next << "Memory Management + //Unit Peak Dynamic = " << mmu->rt_power.readOp.dynamic*clockRate << " W" + // << + // endl; cout << indent_str_next << "Memory Management Unit + // Subthreshold Leakage = " << mmu->rt_power.readOp.leakage << " W" << + // endl; cout + // << indent_str_next << "Memory Management Unit Gate Leakage = " << + // mmu->rt_power.readOp.gate_leakage << " W" << endl; cout << + // indent_str_next << "Execution Unit Peak Dynamic = " << + // exu->rt_power.readOp.dynamic*clockRate << " W" << endl; + // cout + // << indent_str_next << "Execution Unit Subthreshold Leakage = " << + // exu->rt_power.readOp.leakage << " W" << endl; cout << + // indent_str_next + // << "Execution Unit Gate Leakage = " << + // exu->rt_power.readOp.gate_leakage + //<< " W" << endl; + } } -void NoC::set_noc_param() -{ - - nocdynp.type = XML->sys.NoC[ithNoC].type; - nocdynp.clockRate =XML->sys.NoC[ithNoC].clockrate; - nocdynp.clockRate *= 1e6; - nocdynp.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); - - nocdynp.flit_size = XML->sys.NoC[ithNoC].flit_bits; - if (nocdynp.type) - { - nocdynp.input_ports = XML->sys.NoC[ithNoC].input_ports; - nocdynp.output_ports = XML->sys.NoC[ithNoC].output_ports;//later minus 1 - nocdynp.min_ports = min(nocdynp.input_ports,nocdynp.output_ports); - nocdynp.global_linked_ports = (nocdynp.input_ports-1) + (nocdynp.output_ports-1); - /* - * Except local i/o ports, all ports needs links( global_linked_ports); - * However only min_ports can be fully active simultaneously - * since the fewer number of ports (input or output ) is the bottleneck. - */ - } - else - { - nocdynp.input_ports = 1; - nocdynp.output_ports = 1; - nocdynp.min_ports = min(nocdynp.input_ports,nocdynp.output_ports); - nocdynp.global_linked_ports = 1; - } - - nocdynp.virtual_channel_per_port = XML->sys.NoC[ithNoC].virtual_channel_per_port; - nocdynp.input_buffer_entries_per_vc = XML->sys.NoC[ithNoC].input_buffer_entries_per_vc; - - nocdynp.horizontal_nodes = XML->sys.NoC[ithNoC].horizontal_nodes; - nocdynp.vertical_nodes = XML->sys.NoC[ithNoC].vertical_nodes; - nocdynp.total_nodes = nocdynp.horizontal_nodes*nocdynp.vertical_nodes; - nocdynp.duty_cycle = XML->sys.NoC[ithNoC].duty_cycle; - nocdynp.has_global_link = XML->sys.NoC[ithNoC].has_global_link; - nocdynp.link_throughput = XML->sys.NoC[ithNoC].link_throughput; - nocdynp.link_latency = XML->sys.NoC[ithNoC].link_latency; - nocdynp.chip_coverage = XML->sys.NoC[ithNoC].chip_coverage; - nocdynp.route_over_perc = XML->sys.NoC[ithNoC].route_over_perc; - - assert (nocdynp.chip_coverage <=1); - assert (nocdynp.route_over_perc <=1); - - if (nocdynp.type) - name = "NOC"; - else - name = "BUSES"; - +void NoC::set_noc_param() { + nocdynp.type = XML->sys.NoC[ithNoC].type; + nocdynp.clockRate = XML->sys.NoC[ithNoC].clockrate; + nocdynp.clockRate *= 1e6; + nocdynp.executionTime = + XML->sys.total_cycles / (XML->sys.target_core_clockrate * 1e6); + + nocdynp.flit_size = XML->sys.NoC[ithNoC].flit_bits; + if (nocdynp.type) { + nocdynp.input_ports = XML->sys.NoC[ithNoC].input_ports; + nocdynp.output_ports = XML->sys.NoC[ithNoC].output_ports; // later minus 1 + nocdynp.min_ports = min(nocdynp.input_ports, nocdynp.output_ports); + nocdynp.global_linked_ports = + (nocdynp.input_ports - 1) + (nocdynp.output_ports - 1); + /* + * Except local i/o ports, all ports needs links( global_linked_ports); + * However only min_ports can be fully active simultaneously + * since the fewer number of ports (input or output ) is the bottleneck. + */ + } else { + nocdynp.input_ports = 1; + nocdynp.output_ports = 1; + nocdynp.min_ports = min(nocdynp.input_ports, nocdynp.output_ports); + nocdynp.global_linked_ports = 1; + } + + nocdynp.virtual_channel_per_port = + XML->sys.NoC[ithNoC].virtual_channel_per_port; + nocdynp.input_buffer_entries_per_vc = + XML->sys.NoC[ithNoC].input_buffer_entries_per_vc; + + nocdynp.horizontal_nodes = XML->sys.NoC[ithNoC].horizontal_nodes; + nocdynp.vertical_nodes = XML->sys.NoC[ithNoC].vertical_nodes; + nocdynp.total_nodes = nocdynp.horizontal_nodes * nocdynp.vertical_nodes; + nocdynp.duty_cycle = XML->sys.NoC[ithNoC].duty_cycle; + nocdynp.has_global_link = XML->sys.NoC[ithNoC].has_global_link; + nocdynp.link_throughput = XML->sys.NoC[ithNoC].link_throughput; + nocdynp.link_latency = XML->sys.NoC[ithNoC].link_latency; + nocdynp.chip_coverage = XML->sys.NoC[ithNoC].chip_coverage; + nocdynp.route_over_perc = XML->sys.NoC[ithNoC].route_over_perc; + + assert(nocdynp.chip_coverage <= 1); + assert(nocdynp.route_over_perc <= 1); + + if (nocdynp.type) + name = "NOC"; + else + name = "BUSES"; } - -NoC ::~NoC(){ - - if(router) {delete router; router = 0;} - if(link_bus) {delete link_bus; link_bus = 0;} +NoC ::~NoC() { + if (router) { + delete router; + router = 0; + } + if (link_bus) { + delete link_bus; + link_bus = 0; + } } diff --git a/src/gpuwattch/noc.h b/src/gpuwattch/noc.h index f3f6e84..3dc3ac2 100644 --- a/src/gpuwattch/noc.h +++ b/src/gpuwattch/noc.h @@ -29,54 +29,55 @@ * ***************************************************************************/ /******************************************************************** -* 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 * + ********************************************************************/ #ifndef NOC_H_ #define NOC_H_ #include "XML_Parse.h" -#include "logic.h" -#include "cacti/parameter.h" #include "array.h" -#include "interconnect.h" #include "basic_components.h" +#include "cacti/parameter.h" #include "cacti/router.h" +#include "interconnect.h" +#include "logic.h" -class NoC :public Component { - public: - - ParseXML *XML; - int ithNoC; - InputParameter interface_ip; - double link_len; - double executionTime; - double scktRatio, chip_PR_overhead, macro_PR_overhead; - MCPAT_Router * router; - interconnect * link_bus; - NoCParam nocdynp; - uca_org_t local_result; - statsDef tdp_stats; - statsDef rtp_stats; - statsDef stats_t; - powerDef power_t; - Component link_bus_tot_per_Router; - bool link_bus_exist; - bool router_exist; - string name, link_name; - double M_traffic_pattern; - NoC(ParseXML *XML_interface, int ithNoC_, InputParameter* interface_ip_, double M_traffic_pattern_ = 0.6,double link_len_=0); - void set_noc_param(); - void computeEnergy(bool is_tdp=true); - void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); - void init_link_bus(double link_len_); - void init_router(); - void computeEnergy_link_bus(bool is_tdp=true); - void displayEnergy_link_bus(uint32_t indent = 0,int plevel = 100, bool is_tdp=true); - ~NoC(); +class NoC : public Component { + public: + ParseXML *XML; + int ithNoC; + InputParameter interface_ip; + double link_len; + double executionTime; + double scktRatio, chip_PR_overhead, macro_PR_overhead; + MCPAT_Router *router; + interconnect *link_bus; + NoCParam nocdynp; + uca_org_t local_result; + statsDef tdp_stats; + statsDef rtp_stats; + statsDef stats_t; + powerDef power_t; + Component link_bus_tot_per_Router; + bool link_bus_exist; + bool router_exist; + string name, link_name; + double M_traffic_pattern; + NoC(ParseXML *XML_interface, int ithNoC_, InputParameter *interface_ip_, + double M_traffic_pattern_ = 0.6, double link_len_ = 0); + void set_noc_param(); + void computeEnergy(bool is_tdp = true); + void displayEnergy(uint32_t indent = 0, int plevel = 100, bool is_tdp = true); + void init_link_bus(double link_len_); + void init_router(); + void computeEnergy_link_bus(bool is_tdp = true); + void displayEnergy_link_bus(uint32_t indent = 0, int plevel = 100, + bool is_tdp = true); + ~NoC(); }; #endif /* NOC_H_ */ diff --git a/src/gpuwattch/processor.cc b/src/gpuwattch/processor.cc index 5dda9fc..fc6db46 100644 --- a/src/gpuwattch/processor.cc +++ b/src/gpuwattch/processor.cc @@ -29,1034 +29,1177 @@ * ***************************************************************************/ /******************************************************************** -* 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 -#include + * 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 "processor.h" +#include #include -#include #include +#include #include -#include #include -#include "parameter.h" +#include +#include "XML_Parse.h" #include "array.h" -#include "const.h" #include "cacti/basic_circuit.h" -#include "XML_Parse.h" -#include "processor.h" +#include "const.h" +#include "parameter.h" #include "version.h" - Processor::Processor(ParseXML *XML_interface) -:XML(XML_interface),//TODO: using one global copy may have problems. - mc(0), - niu(0), - pcie(0), - flashcontroller(0) -{ + : XML(XML_interface), // TODO: using one global copy may have problems. + mc(0), + niu(0), + pcie(0), + flashcontroller(0) { /* - * placement and routing overhead is 10%, core scales worse than cache 40% is accumulated from 90 to 22nm - * There is no point to have heterogeneous memory controller on chip, - * thus McPAT only support homogeneous memory controllers. + * placement and routing overhead is 10%, core scales worse than cache 40% is + * accumulated from 90 to 22nm There is no point to have heterogeneous memory + * controller on chip, thus McPAT only support homogeneous memory controllers. */ rt_power.reset(); int i; - double pppm_t[4] = {1,1,1,1}; - l2_power=0; - idle_core_power=0; + double pppm_t[4] = {1, 1, 1, 1}; + l2_power = 0; + idle_core_power = 0; set_proc_param(); if (procdynp.homoCore) - numCore = procdynp.numCore==0? 0:1; + numCore = procdynp.numCore == 0 ? 0 : 1; else - numCore = procdynp.numCore; + numCore = procdynp.numCore; if (procdynp.homoL2) - numL2 = procdynp.numL2==0? 0:1; + numL2 = procdynp.numL2 == 0 ? 0 : 1; else - numL2 = procdynp.numL2; + numL2 = procdynp.numL2; - if (XML->sys.Private_L2 && numCore != numL2) - { - cout<<"Number of private L2 does not match number of cores"<sys.Private_L2 && numCore != numL2) { + cout << "Number of private L2 does not match number of cores" << endl; + exit(0); } if (procdynp.homoL3) - numL3 = procdynp.numL3==0? 0:1; + numL3 = procdynp.numL3 == 0 ? 0 : 1; else - numL3 = procdynp.numL3; + numL3 = procdynp.numL3; if (procdynp.homoNOC) - numNOC = procdynp.numNOC==0? 0:1; + numNOC = procdynp.numNOC == 0 ? 0 : 1; else - numNOC = procdynp.numNOC; + numNOC = procdynp.numNOC; -// if (!procdynp.homoNOC) -// { -// cout<<"Current McPAT does not support heterogeneous NOC"<computeEnergy(); - cores[i]->computeEnergy(false); - if (procdynp.homoCore){ - core.area.set_area(core.area.get_area() + cores[i]->area.get_area()*procdynp.numCore); - set_pppm(pppm_t,cores[i]->clockRate*procdynp.numCore, procdynp.numCore,procdynp.numCore,procdynp.numCore); - //set the exClockRate - exClockRate=cores[0]->clockRate*2;//TODO; get from XML file - //cout<<"****EX clock rate:"<power*pppm_t; - set_pppm(pppm_t,1/cores[i]->executionTime, procdynp.numCore,procdynp.numCore,procdynp.numCore); - core.rt_power = core.rt_power + cores[i]->rt_power*pppm_t; - area.set_area(area.get_area() + core.area.get_area());//placement and routing overhead is 10%, core scales worse than cache 40% is accumulated from 90 to 22nm - power = power + core.power; - rt_power = rt_power + core.rt_power; - } - else{ - core.area.set_area(core.area.get_area() + cores[i]->area.get_area()); - area.set_area(area.get_area() + cores[i]->area.get_area());//placement and routing overhead is 10%, core scales worse than cache 40% is accumulated from 90 to 22nm - - set_pppm(pppm_t,cores[i]->clockRate, 1, 1, 1); - //set the exClockRate - exClockRate=cores[0]->clockRate;//TODO; get from XML file - //cout<<"****EX clock rate:"<power*pppm_t; - power = power + cores[i]->power*pppm_t; - - set_pppm(pppm_t,1/cores[i]->executionTime, 1, 1, 1); - core.rt_power = core.rt_power + cores[i]->rt_power*pppm_t; - rt_power = rt_power + cores[i]->rt_power*pppm_t; - } + numL2Dir = procdynp.numL2Dir; + + for (i = 0; i < numCore; i++) { + cores.push_back(new Core(XML, i, &interface_ip)); + cores[i]->computeEnergy(); + cores[i]->computeEnergy(false); + if (procdynp.homoCore) { + core.area.set_area(core.area.get_area() + + cores[i]->area.get_area() * procdynp.numCore); + set_pppm(pppm_t, cores[i]->clockRate * procdynp.numCore, procdynp.numCore, + procdynp.numCore, procdynp.numCore); + // set the exClockRate + exClockRate = cores[0]->clockRate * 2; // TODO; get from XML file + // cout<<"****EX clock rate:"<power * pppm_t; + set_pppm(pppm_t, 1 / cores[i]->executionTime, procdynp.numCore, + procdynp.numCore, procdynp.numCore); + core.rt_power = core.rt_power + cores[i]->rt_power * pppm_t; + area.set_area( + area.get_area() + + core.area.get_area()); // placement and routing overhead is + // 10%, core scales worse than cache + // 40% is accumulated from 90 to 22nm + power = power + core.power; + rt_power = rt_power + core.rt_power; + } else { + core.area.set_area(core.area.get_area() + cores[i]->area.get_area()); + area.set_area( + area.get_area() + + cores[i]->area.get_area()); // placement and routing overhead is 10%, + // core scales worse than cache 40% is + // accumulated from 90 to 22nm + + set_pppm(pppm_t, cores[i]->clockRate, 1, 1, 1); + // set the exClockRate + exClockRate = cores[0]->clockRate; // TODO; get from XML file + // cout<<"****EX clock rate:"<power * pppm_t; + power = power + cores[i]->power * pppm_t; + + set_pppm(pppm_t, 1 / cores[i]->executionTime, 1, 1, 1); + core.rt_power = core.rt_power + cores[i]->rt_power * pppm_t; + rt_power = rt_power + cores[i]->rt_power * pppm_t; + } } - if (!XML->sys.Private_L2) - { - - if (numL2 >0) - for (i = 0;i < numL2; i++) - { - l2array.push_back(new SharedCache(XML,i, &interface_ip)); - - l2array[i]->computeEnergy(); - l2array[i]->computeEnergy(false); - if (procdynp.homoL2){ - l2.area.set_area(l2.area.get_area() + l2array[i]->area.get_area()*procdynp.numL2); - set_pppm(pppm_t,l2array[i]->cachep.clockRate*procdynp.numL2, procdynp.numL2,procdynp.numL2,procdynp.numL2); - l2.power = l2.power + l2array[i]->power*pppm_t; - set_pppm(pppm_t,1/l2array[i]->cachep.executionTime, procdynp.numL2,procdynp.numL2,procdynp.numL2); - l2.rt_power = l2.rt_power + l2array[i]->rt_power*pppm_t; - area.set_area(area.get_area() + l2.area.get_area());//placement and routing overhead is 10%, l2 scales worse than cache 40% is accumulated from 90 to 22nm - power = power + l2.power; - rt_power = rt_power + l2.rt_power; - } - else{ - l2.area.set_area(l2.area.get_area() + l2array[i]->area.get_area()); - area.set_area(area.get_area() + l2array[i]->area.get_area());//placement and routing overhead is 10%, l2 scales worse than cache 40% is accumulated from 90 to 22nm - - set_pppm(pppm_t,l2array[i]->cachep.clockRate, 1, 1, 1); - l2.power = l2.power + l2array[i]->power*pppm_t; - power = power + l2array[i]->power*pppm_t;; - set_pppm(pppm_t,1/l2array[i]->cachep.executionTime, 1, 1, 1); - l2.rt_power = l2.rt_power + l2array[i]->rt_power*pppm_t; - rt_power = rt_power + l2array[i]->rt_power*pppm_t; - } - } + if (!XML->sys.Private_L2) { + if (numL2 > 0) + for (i = 0; i < numL2; i++) { + l2array.push_back(new SharedCache(XML, i, &interface_ip)); + + l2array[i]->computeEnergy(); + l2array[i]->computeEnergy(false); + if (procdynp.homoL2) { + l2.area.set_area(l2.area.get_area() + + l2array[i]->area.get_area() * procdynp.numL2); + set_pppm(pppm_t, l2array[i]->cachep.clockRate * procdynp.numL2, + procdynp.numL2, procdynp.numL2, procdynp.numL2); + l2.power = l2.power + l2array[i]->power * pppm_t; + set_pppm(pppm_t, 1 / l2array[i]->cachep.executionTime, procdynp.numL2, + procdynp.numL2, procdynp.numL2); + l2.rt_power = l2.rt_power + l2array[i]->rt_power * pppm_t; + area.set_area( + area.get_area() + + l2.area.get_area()); // placement and routing overhead is 10%, l2 + // scales worse than cache 40% is + // accumulated from 90 to 22nm + power = power + l2.power; + rt_power = rt_power + l2.rt_power; + } else { + l2.area.set_area(l2.area.get_area() + l2array[i]->area.get_area()); + area.set_area( + area.get_area() + + l2array[i] + ->area.get_area()); // placement and routing overhead is 10%, + // l2 scales worse than cache 40% is + // accumulated from 90 to 22nm + + set_pppm(pppm_t, l2array[i]->cachep.clockRate, 1, 1, 1); + l2.power = l2.power + l2array[i]->power * pppm_t; + power = power + l2array[i]->power * pppm_t; + ; + set_pppm(pppm_t, 1 / l2array[i]->cachep.executionTime, 1, 1, 1); + l2.rt_power = l2.rt_power + l2array[i]->rt_power * pppm_t; + rt_power = rt_power + l2array[i]->rt_power * pppm_t; + } + } } - if (numL3 >0) - for (i = 0;i < numL3; i++) - { - l3array.push_back(new SharedCache(XML,i, &interface_ip, L3)); - l3array[i]->computeEnergy(); - l3array[i]->computeEnergy(false); - if (procdynp.homoL3){ - l3.area.set_area(l3.area.get_area() + l3array[i]->area.get_area()*procdynp.numL3); - set_pppm(pppm_t,l3array[i]->cachep.clockRate*procdynp.numL3, procdynp.numL3,procdynp.numL3,procdynp.numL3); - l3.power = l3.power + l3array[i]->power*pppm_t; - set_pppm(pppm_t,1/l3array[i]->cachep.executionTime, procdynp.numL3,procdynp.numL3,procdynp.numL3); - l3.rt_power = l3.rt_power + l3array[i]->rt_power*pppm_t; - area.set_area(area.get_area() + l3.area.get_area());//placement and routing overhead is 10%, l3 scales worse than cache 40% is accumulated from 90 to 22nm - power = power + l3.power; - rt_power = rt_power + l3.rt_power; - - } - else{ - l3.area.set_area(l3.area.get_area() + l3array[i]->area.get_area()); - area.set_area(area.get_area() + l3array[i]->area.get_area());//placement and routing overhead is 10%, l3 scales worse than cache 40% is accumulated from 90 to 22nm - set_pppm(pppm_t,l3array[i]->cachep.clockRate, 1, 1, 1); - l3.power = l3.power + l3array[i]->power*pppm_t; - power = power + l3array[i]->power*pppm_t; - set_pppm(pppm_t,1/l3array[i]->cachep.executionTime, 1, 1, 1); - l3.rt_power = l3.rt_power + l3array[i]->rt_power*pppm_t; - rt_power = rt_power + l3array[i]->rt_power*pppm_t; - - } - } - if (numL1Dir >0) - for (i = 0;i < numL1Dir; i++) - { - l1dirarray.push_back(new SharedCache(XML,i, &interface_ip, L1Directory)); - l1dirarray[i]->computeEnergy(); - l1dirarray[i]->computeEnergy(false); - if (procdynp.homoL1Dir){ - l1dir.area.set_area(l1dir.area.get_area() + l1dirarray[i]->area.get_area()*procdynp.numL1Dir); - set_pppm(pppm_t,l1dirarray[i]->cachep.clockRate*procdynp.numL1Dir, procdynp.numL1Dir,procdynp.numL1Dir,procdynp.numL1Dir); - l1dir.power = l1dir.power + l1dirarray[i]->power*pppm_t; - set_pppm(pppm_t,1/l1dirarray[i]->cachep.executionTime, procdynp.numL1Dir,procdynp.numL1Dir,procdynp.numL1Dir); - l1dir.rt_power = l1dir.rt_power + l1dirarray[i]->rt_power*pppm_t; - area.set_area(area.get_area() + l1dir.area.get_area());//placement and routing overhead is 10%, l1dir scales worse than cache 40% is accumulated from 90 to 22nm - power = power + l1dir.power; - rt_power = rt_power + l1dir.rt_power; - - } - else{ - l1dir.area.set_area(l1dir.area.get_area() + l1dirarray[i]->area.get_area()); - area.set_area(area.get_area() + l1dirarray[i]->area.get_area()); - set_pppm(pppm_t,l1dirarray[i]->cachep.clockRate, 1, 1, 1); - l1dir.power = l1dir.power + l1dirarray[i]->power*pppm_t; - power = power + l1dirarray[i]->power; - set_pppm(pppm_t,1/l1dirarray[i]->cachep.executionTime, 1, 1, 1); - l1dir.rt_power = l1dir.rt_power + l1dirarray[i]->rt_power*pppm_t; - rt_power = rt_power + l1dirarray[i]->rt_power; - } - } - - if (numL2Dir >0) - for (i = 0;i < numL2Dir; i++) - { - l2dirarray.push_back(new SharedCache(XML,i, &interface_ip, L2Directory)); - l2dirarray[i]->computeEnergy(); - l2dirarray[i]->computeEnergy(false); - if (procdynp.homoL2Dir){ - l2dir.area.set_area(l2dir.area.get_area() + l2dirarray[i]->area.get_area()*procdynp.numL2Dir); - set_pppm(pppm_t,l2dirarray[i]->cachep.clockRate*procdynp.numL2Dir, procdynp.numL2Dir,procdynp.numL2Dir,procdynp.numL2Dir); - l2dir.power = l2dir.power + l2dirarray[i]->power*pppm_t; - set_pppm(pppm_t,1/l2dirarray[i]->cachep.executionTime, procdynp.numL2Dir,procdynp.numL2Dir,procdynp.numL2Dir); - l2dir.rt_power = l2dir.rt_power + l2dirarray[i]->rt_power*pppm_t; - area.set_area(area.get_area() + l2dir.area.get_area());//placement and routing overhead is 10%, l2dir scales worse than cache 40% is accumulated from 90 to 22nm - power = power + l2dir.power; - rt_power = rt_power + l2dir.rt_power; - - } - else{ - l2dir.area.set_area(l2dir.area.get_area() + l2dirarray[i]->area.get_area()); - area.set_area(area.get_area() + l2dirarray[i]->area.get_area()); - set_pppm(pppm_t,l2dirarray[i]->cachep.clockRate, 1, 1, 1); - l2dir.power = l2dir.power + l2dirarray[i]->power*pppm_t; - power = power + l2dirarray[i]->power*pppm_t; - set_pppm(pppm_t,1/l2dirarray[i]->cachep.executionTime, 1, 1, 1); - l2dir.rt_power = l2dir.rt_power + l2dirarray[i]->rt_power*pppm_t; - rt_power = rt_power + l2dirarray[i]->rt_power*pppm_t; - } - } - - if (XML->sys.mc.number_mcs >0 && XML->sys.mc.memory_channels_per_mc>0) - { - if(XML->sys.architecture==1) // 1 for fermi - mc = new MemoryController(XML, &interface_ip, MC,GDDR5); - else if (XML->sys.architecture==2) // 2 for quadro - mc = new MemoryController(XML, &interface_ip, MC,GDDR3); - else { - printf("Architecture %d not defined!\n", XML->sys.architecture); - printf("use 1 for fermi and 2 for quadro!\n"); - exit(1); - } - mc->computeEnergy(); - mc->computeEnergy(false); - mcs.area.set_area(mcs.area.get_area()+mc->area.get_area()*XML->sys.mc.number_mcs); - area.set_area(area.get_area()+mc->area.get_area()*XML->sys.mc.number_mcs); - set_pppm(pppm_t,XML->sys.mc.number_mcs*mc->mcp.clockRate, XML->sys.mc.number_mcs,XML->sys.mc.number_mcs,XML->sys.mc.number_mcs); - mcs.power = mc->power*pppm_t; - power = power + mcs.power; - set_pppm(pppm_t,1/mc->mcp.executionTime, XML->sys.mc.number_mcs,XML->sys.mc.number_mcs,XML->sys.mc.number_mcs); - mcs.rt_power = mc->rt_power*pppm_t; - rt_power = rt_power + mcs.rt_power; - + if (numL3 > 0) + for (i = 0; i < numL3; i++) { + l3array.push_back(new SharedCache(XML, i, &interface_ip, L3)); + l3array[i]->computeEnergy(); + l3array[i]->computeEnergy(false); + if (procdynp.homoL3) { + l3.area.set_area(l3.area.get_area() + + l3array[i]->area.get_area() * procdynp.numL3); + set_pppm(pppm_t, l3array[i]->cachep.clockRate * procdynp.numL3, + procdynp.numL3, procdynp.numL3, procdynp.numL3); + l3.power = l3.power + l3array[i]->power * pppm_t; + set_pppm(pppm_t, 1 / l3array[i]->cachep.executionTime, procdynp.numL3, + procdynp.numL3, procdynp.numL3); + l3.rt_power = l3.rt_power + l3array[i]->rt_power * pppm_t; + area.set_area( + area.get_area() + + l3.area.get_area()); // placement and routing overhead is + // 10%, l3 scales worse than cache + // 40% is accumulated from 90 to 22nm + power = power + l3.power; + rt_power = rt_power + l3.rt_power; + + } else { + l3.area.set_area(l3.area.get_area() + l3array[i]->area.get_area()); + area.set_area( + area.get_area() + + l3array[i]->area.get_area()); // placement and routing overhead is + // 10%, l3 scales worse than cache + // 40% is accumulated from 90 to 22nm + set_pppm(pppm_t, l3array[i]->cachep.clockRate, 1, 1, 1); + l3.power = l3.power + l3array[i]->power * pppm_t; + power = power + l3array[i]->power * pppm_t; + set_pppm(pppm_t, 1 / l3array[i]->cachep.executionTime, 1, 1, 1); + l3.rt_power = l3.rt_power + l3array[i]->rt_power * pppm_t; + rt_power = rt_power + l3array[i]->rt_power * pppm_t; + } + } + if (numL1Dir > 0) + for (i = 0; i < numL1Dir; i++) { + l1dirarray.push_back(new SharedCache(XML, i, &interface_ip, L1Directory)); + l1dirarray[i]->computeEnergy(); + l1dirarray[i]->computeEnergy(false); + if (procdynp.homoL1Dir) { + l1dir.area.set_area(l1dir.area.get_area() + + l1dirarray[i]->area.get_area() * procdynp.numL1Dir); + set_pppm(pppm_t, l1dirarray[i]->cachep.clockRate * procdynp.numL1Dir, + procdynp.numL1Dir, procdynp.numL1Dir, procdynp.numL1Dir); + l1dir.power = l1dir.power + l1dirarray[i]->power * pppm_t; + set_pppm(pppm_t, 1 / l1dirarray[i]->cachep.executionTime, + procdynp.numL1Dir, procdynp.numL1Dir, procdynp.numL1Dir); + l1dir.rt_power = l1dir.rt_power + l1dirarray[i]->rt_power * pppm_t; + area.set_area( + area.get_area() + + l1dir.area.get_area()); // placement and routing overhead is 10%, + // l1dir scales worse than cache 40% is + // accumulated from 90 to 22nm + power = power + l1dir.power; + rt_power = rt_power + l1dir.rt_power; + + } else { + l1dir.area.set_area(l1dir.area.get_area() + + l1dirarray[i]->area.get_area()); + area.set_area(area.get_area() + l1dirarray[i]->area.get_area()); + set_pppm(pppm_t, l1dirarray[i]->cachep.clockRate, 1, 1, 1); + l1dir.power = l1dir.power + l1dirarray[i]->power * pppm_t; + power = power + l1dirarray[i]->power; + set_pppm(pppm_t, 1 / l1dirarray[i]->cachep.executionTime, 1, 1, 1); + l1dir.rt_power = l1dir.rt_power + l1dirarray[i]->rt_power * pppm_t; + rt_power = rt_power + l1dirarray[i]->rt_power; + } + } + + if (numL2Dir > 0) + for (i = 0; i < numL2Dir; i++) { + l2dirarray.push_back(new SharedCache(XML, i, &interface_ip, L2Directory)); + l2dirarray[i]->computeEnergy(); + l2dirarray[i]->computeEnergy(false); + if (procdynp.homoL2Dir) { + l2dir.area.set_area(l2dir.area.get_area() + + l2dirarray[i]->area.get_area() * procdynp.numL2Dir); + set_pppm(pppm_t, l2dirarray[i]->cachep.clockRate * procdynp.numL2Dir, + procdynp.numL2Dir, procdynp.numL2Dir, procdynp.numL2Dir); + l2dir.power = l2dir.power + l2dirarray[i]->power * pppm_t; + set_pppm(pppm_t, 1 / l2dirarray[i]->cachep.executionTime, + procdynp.numL2Dir, procdynp.numL2Dir, procdynp.numL2Dir); + l2dir.rt_power = l2dir.rt_power + l2dirarray[i]->rt_power * pppm_t; + area.set_area( + area.get_area() + + l2dir.area.get_area()); // placement and routing overhead is 10%, + // l2dir scales worse than cache 40% is + // accumulated from 90 to 22nm + power = power + l2dir.power; + rt_power = rt_power + l2dir.rt_power; + + } else { + l2dir.area.set_area(l2dir.area.get_area() + + l2dirarray[i]->area.get_area()); + area.set_area(area.get_area() + l2dirarray[i]->area.get_area()); + set_pppm(pppm_t, l2dirarray[i]->cachep.clockRate, 1, 1, 1); + l2dir.power = l2dir.power + l2dirarray[i]->power * pppm_t; + power = power + l2dirarray[i]->power * pppm_t; + set_pppm(pppm_t, 1 / l2dirarray[i]->cachep.executionTime, 1, 1, 1); + l2dir.rt_power = l2dir.rt_power + l2dirarray[i]->rt_power * pppm_t; + rt_power = rt_power + l2dirarray[i]->rt_power * pppm_t; + } + } + + if (XML->sys.mc.number_mcs > 0 && XML->sys.mc.memory_channels_per_mc > 0) { + if (XML->sys.architecture == 1) // 1 for fermi + mc = new MemoryController(XML, &interface_ip, MC, GDDR5); + else if (XML->sys.architecture == 2) // 2 for quadro + mc = new MemoryController(XML, &interface_ip, MC, GDDR3); + else { + printf("Architecture %d not defined!\n", XML->sys.architecture); + printf("use 1 for fermi and 2 for quadro!\n"); + exit(1); + } + mc->computeEnergy(); + mc->computeEnergy(false); + mcs.area.set_area(mcs.area.get_area() + + mc->area.get_area() * XML->sys.mc.number_mcs); + area.set_area(area.get_area() + + mc->area.get_area() * XML->sys.mc.number_mcs); + set_pppm(pppm_t, XML->sys.mc.number_mcs * mc->mcp.clockRate, + XML->sys.mc.number_mcs, XML->sys.mc.number_mcs, + XML->sys.mc.number_mcs); + mcs.power = mc->power * pppm_t; + power = power + mcs.power; + set_pppm(pppm_t, 1 / mc->mcp.executionTime, XML->sys.mc.number_mcs, + XML->sys.mc.number_mcs, XML->sys.mc.number_mcs); + mcs.rt_power = mc->rt_power * pppm_t; + rt_power = rt_power + mcs.rt_power; } - if (XML->sys.flashc.number_mcs >0 )//flash controller + if (XML->sys.flashc.number_mcs > 0) // flash controller { - flashcontroller = new FlashController(XML, &interface_ip); - flashcontroller->computeEnergy(); - flashcontroller->computeEnergy(false); - double number_fcs = flashcontroller->fcp.num_mcs; - flashcontrollers.area.set_area(flashcontrollers.area.get_area()+flashcontroller->area.get_area()*number_fcs); - area.set_area(area.get_area()+flashcontrollers.area.get_area()); - set_pppm(pppm_t,number_fcs, number_fcs ,number_fcs, number_fcs ); - flashcontrollers.power = flashcontroller->power*pppm_t; - power = power + flashcontrollers.power; - set_pppm(pppm_t,number_fcs , number_fcs ,number_fcs ,number_fcs ); - flashcontrollers.rt_power = flashcontroller->rt_power*pppm_t; - rt_power = rt_power + flashcontrollers.rt_power; - + flashcontroller = new FlashController(XML, &interface_ip); + flashcontroller->computeEnergy(); + flashcontroller->computeEnergy(false); + double number_fcs = flashcontroller->fcp.num_mcs; + flashcontrollers.area.set_area(flashcontrollers.area.get_area() + + flashcontroller->area.get_area() * + number_fcs); + area.set_area(area.get_area() + flashcontrollers.area.get_area()); + set_pppm(pppm_t, number_fcs, number_fcs, number_fcs, number_fcs); + flashcontrollers.power = flashcontroller->power * pppm_t; + power = power + flashcontrollers.power; + set_pppm(pppm_t, number_fcs, number_fcs, number_fcs, number_fcs); + flashcontrollers.rt_power = flashcontroller->rt_power * pppm_t; + rt_power = rt_power + flashcontrollers.rt_power; } - if (XML->sys.niu.number_units >0) - { - niu = new NIUController(XML, &interface_ip); - niu->computeEnergy(); - niu->computeEnergy(false); - nius.area.set_area(nius.area.get_area()+niu->area.get_area()*XML->sys.niu.number_units); - area.set_area(area.get_area()+niu->area.get_area()*XML->sys.niu.number_units); - set_pppm(pppm_t,XML->sys.niu.number_units*niu->niup.clockRate, XML->sys.niu.number_units,XML->sys.niu.number_units,XML->sys.niu.number_units); - nius.power = niu->power*pppm_t; - power = power + nius.power; - set_pppm(pppm_t,XML->sys.niu.number_units*niu->niup.clockRate, XML->sys.niu.number_units,XML->sys.niu.number_units,XML->sys.niu.number_units); - nius.rt_power = niu->rt_power*pppm_t; - rt_power = rt_power + nius.rt_power; - + if (XML->sys.niu.number_units > 0) { + niu = new NIUController(XML, &interface_ip); + niu->computeEnergy(); + niu->computeEnergy(false); + nius.area.set_area(nius.area.get_area() + + niu->area.get_area() * XML->sys.niu.number_units); + area.set_area(area.get_area() + + niu->area.get_area() * XML->sys.niu.number_units); + set_pppm(pppm_t, XML->sys.niu.number_units * niu->niup.clockRate, + XML->sys.niu.number_units, XML->sys.niu.number_units, + XML->sys.niu.number_units); + nius.power = niu->power * pppm_t; + power = power + nius.power; + set_pppm(pppm_t, XML->sys.niu.number_units * niu->niup.clockRate, + XML->sys.niu.number_units, XML->sys.niu.number_units, + XML->sys.niu.number_units); + nius.rt_power = niu->rt_power * pppm_t; + rt_power = rt_power + nius.rt_power; } - if (XML->sys.pcie.number_units >0 && XML->sys.pcie.num_channels >0) - { - pcie = new PCIeController(XML, &interface_ip); - pcie->computeEnergy(); - pcie->computeEnergy(false); - pcies.area.set_area(pcies.area.get_area()+pcie->area.get_area()*XML->sys.pcie.number_units); - area.set_area(area.get_area()+pcie->area.get_area()*XML->sys.pcie.number_units); - set_pppm(pppm_t,XML->sys.pcie.number_units*pcie->pciep.clockRate, XML->sys.pcie.number_units,XML->sys.pcie.number_units,XML->sys.pcie.number_units); - pcies.power = pcie->power*pppm_t; - power = power + pcies.power; - set_pppm(pppm_t,XML->sys.pcie.number_units*pcie->pciep.clockRate, XML->sys.pcie.number_units,XML->sys.pcie.number_units,XML->sys.pcie.number_units); - pcies.rt_power = pcie->rt_power*pppm_t; - rt_power = rt_power + pcies.rt_power; - + if (XML->sys.pcie.number_units > 0 && XML->sys.pcie.num_channels > 0) { + pcie = new PCIeController(XML, &interface_ip); + pcie->computeEnergy(); + pcie->computeEnergy(false); + pcies.area.set_area(pcies.area.get_area() + + pcie->area.get_area() * XML->sys.pcie.number_units); + area.set_area(area.get_area() + + pcie->area.get_area() * XML->sys.pcie.number_units); + set_pppm(pppm_t, XML->sys.pcie.number_units * pcie->pciep.clockRate, + XML->sys.pcie.number_units, XML->sys.pcie.number_units, + XML->sys.pcie.number_units); + pcies.power = pcie->power * pppm_t; + power = power + pcies.power; + set_pppm(pppm_t, XML->sys.pcie.number_units * pcie->pciep.clockRate, + XML->sys.pcie.number_units, XML->sys.pcie.number_units, + XML->sys.pcie.number_units); + pcies.rt_power = pcie->rt_power * pppm_t; + rt_power = rt_power + pcies.rt_power; } - if (numNOC >0) - { - for (i = 0;i < numNOC; i++) - { - if (XML->sys.NoC[i].type) - {//First add up area of routers if NoC is used - nocs.push_back(new NoC(XML,i, &interface_ip, 1)); - - if (procdynp.homoNOC) - { - noc.area.set_area(noc.area.get_area() + nocs[i]->area.get_area()*procdynp.numNOC); - area.set_area(area.get_area() + noc.area.get_area()); - } - else - { - noc.area.set_area(noc.area.get_area() + nocs[i]->area.get_area()); - area.set_area(area.get_area() + nocs[i]->area.get_area()); - } - } - else - {//Bus based interconnect - nocs.push_back(new NoC(XML,i, &interface_ip, 1, sqrt(area.get_area()*XML->sys.NoC[i].chip_coverage))); - if (procdynp.homoNOC){ - noc.area.set_area(noc.area.get_area() + nocs[i]->area.get_area()*procdynp.numNOC); - area.set_area(area.get_area() + noc.area.get_area()); - } - else - { - noc.area.set_area(noc.area.get_area() + nocs[i]->area.get_area()); - area.set_area(area.get_area() + nocs[i]->area.get_area()); - } - } - } - - /* - * Compute global links associated with each NOC, if any. This must be done at the end (even after the NOC router part) since the total chip - * area must be obtain to decide the link routing - */ - for (i = 0;i < numNOC; i++) - { - if (nocs[i]->nocdynp.has_global_link && XML->sys.NoC[i].type) - { - nocs[i]->init_link_bus(sqrt(area.get_area()*XML->sys.NoC[i].chip_coverage));//compute global links - if (procdynp.homoNOC) - { - noc.area.set_area(noc.area.get_area() + nocs[i]->link_bus_tot_per_Router.area.get_area() - * nocs[i]->nocdynp.total_nodes - * procdynp.numNOC); - area.set_area(area.get_area() + nocs[i]->link_bus_tot_per_Router.area.get_area() - * nocs[i]->nocdynp.total_nodes - * procdynp.numNOC); - } - else - { - noc.area.set_area(noc.area.get_area() + nocs[i]->link_bus_tot_per_Router.area.get_area() - * nocs[i]->nocdynp.total_nodes); - area.set_area(area.get_area() + nocs[i]->link_bus_tot_per_Router.area.get_area() - * nocs[i]->nocdynp.total_nodes); - } - } - } - //Compute energy of NoC (w or w/o links) or buses - for (i = 0;i < numNOC; i++) - { - //cout<<"******************COMPUTE NOC ENERGY********************"<computeEnergy(); - nocs[i]->computeEnergy(false); - if (procdynp.homoNOC){ - - set_pppm(pppm_t,procdynp.numNOC*nocs[i]->nocdynp.clockRate, procdynp.numNOC,procdynp.numNOC,procdynp.numNOC); - noc.power = noc.power + nocs[i]->power*pppm_t; - set_pppm(pppm_t,1/nocs[i]->nocdynp.executionTime, procdynp.numNOC,procdynp.numNOC,procdynp.numNOC); - noc.rt_power = noc.rt_power + nocs[i]->rt_power*pppm_t; - power = power + noc.power; - rt_power = rt_power + noc.rt_power; - } - else - { - set_pppm(pppm_t,nocs[i]->nocdynp.clockRate, 1, 1, 1); - noc.power = noc.power + nocs[i]->power*pppm_t; - power = power + nocs[i]->power*pppm_t; - set_pppm(pppm_t,1/nocs[i]->nocdynp.executionTime, 1, 1, 1); - noc.rt_power = noc.rt_power + nocs[i]->rt_power*pppm_t; - rt_power = rt_power + nocs[i]->rt_power*pppm_t; - - - } - } + if (numNOC > 0) { + for (i = 0; i < numNOC; i++) { + if (XML->sys.NoC[i].type) { // First add up area of routers if NoC is + // used + nocs.push_back(new NoC(XML, i, &interface_ip, 1)); + + if (procdynp.homoNOC) { + noc.area.set_area(noc.area.get_area() + + nocs[i]->area.get_area() * procdynp.numNOC); + area.set_area(area.get_area() + noc.area.get_area()); + } else { + noc.area.set_area(noc.area.get_area() + nocs[i]->area.get_area()); + area.set_area(area.get_area() + nocs[i]->area.get_area()); + } + } else { // Bus based interconnect + nocs.push_back( + new NoC(XML, i, &interface_ip, 1, + sqrt(area.get_area() * XML->sys.NoC[i].chip_coverage))); + if (procdynp.homoNOC) { + noc.area.set_area(noc.area.get_area() + + nocs[i]->area.get_area() * procdynp.numNOC); + area.set_area(area.get_area() + noc.area.get_area()); + } else { + noc.area.set_area(noc.area.get_area() + nocs[i]->area.get_area()); + area.set_area(area.get_area() + nocs[i]->area.get_area()); + } + } + } + + /* + * Compute global links associated with each NOC, if any. This must be done + * at the end (even after the NOC router part) since the total chip area + * must be obtain to decide the link routing + */ + for (i = 0; i < numNOC; i++) { + if (nocs[i]->nocdynp.has_global_link && XML->sys.NoC[i].type) { + nocs[i]->init_link_bus( + sqrt(area.get_area() * + XML->sys.NoC[i].chip_coverage)); // compute global links + if (procdynp.homoNOC) { + noc.area.set_area(noc.area.get_area() + + nocs[i]->link_bus_tot_per_Router.area.get_area() * + nocs[i]->nocdynp.total_nodes * procdynp.numNOC); + area.set_area(area.get_area() + + nocs[i]->link_bus_tot_per_Router.area.get_area() * + nocs[i]->nocdynp.total_nodes * procdynp.numNOC); + } else { + noc.area.set_area(noc.area.get_area() + + nocs[i]->link_bus_tot_per_Router.area.get_area() * + nocs[i]->nocdynp.total_nodes); + area.set_area(area.get_area() + + nocs[i]->link_bus_tot_per_Router.area.get_area() * + nocs[i]->nocdynp.total_nodes); + } + } + } + // Compute energy of NoC (w or w/o links) or buses + for (i = 0; i < numNOC; i++) { + // cout<<"******************COMPUTE NOC ENERGY********************"<computeEnergy(); + nocs[i]->computeEnergy(false); + if (procdynp.homoNOC) { + set_pppm(pppm_t, procdynp.numNOC * nocs[i]->nocdynp.clockRate, + procdynp.numNOC, procdynp.numNOC, procdynp.numNOC); + noc.power = noc.power + nocs[i]->power * pppm_t; + set_pppm(pppm_t, 1 / nocs[i]->nocdynp.executionTime, procdynp.numNOC, + procdynp.numNOC, procdynp.numNOC); + noc.rt_power = noc.rt_power + nocs[i]->rt_power * pppm_t; + power = power + noc.power; + rt_power = rt_power + noc.rt_power; + } else { + set_pppm(pppm_t, nocs[i]->nocdynp.clockRate, 1, 1, 1); + noc.power = noc.power + nocs[i]->power * pppm_t; + power = power + nocs[i]->power * pppm_t; + set_pppm(pppm_t, 1 / nocs[i]->nocdynp.executionTime, 1, 1, 1); + noc.rt_power = noc.rt_power + nocs[i]->rt_power * pppm_t; + rt_power = rt_power + nocs[i]->rt_power * pppm_t; + } + } } -// //clock power -// globalClock.init_wire_external(is_default, &interface_ip); -// globalClock.clk_area =area*1e6; //change it from mm^2 to um^2 -// globalClock.end_wiring_level =5;//toplevel metal -// globalClock.start_wiring_level =5;//toplevel metal -// globalClock.l_ip.with_clock_grid=false;//global clock does not drive local final nodes -// globalClock.optimize_wire(); + // //clock power + // globalClock.init_wire_external(is_default, &interface_ip); + // globalClock.clk_area =area*1e6; //change it from mm^2 to um^2 + // globalClock.end_wiring_level =5;//toplevel metal + // globalClock.start_wiring_level =5;//toplevel metal + // globalClock.l_ip.with_clock_grid=false;//global clock does not drive local + // final nodes globalClock.optimize_wire(); } -void Processor::compute () -{ +void Processor::compute() { int i; - double pppm_t[4] = {1,1,1,1}; + double pppm_t[4] = {1, 1, 1, 1}; rt_power.reset(); - //power.reset(); - //core.power.reset(); + // power.reset(); + // core.power.reset(); core.rt_power.reset(); - for (i = 0;i < numCore; i++) - { - cores[i]->executionTime = XML->sys.total_cycles /(XML->sys.core[i].clock_rate*1e6); - cores[i]->rt_power.reset(); - cores[i]->compute(); - //cores[i]->computeEnergy(false); - if (procdynp.homoCore){ - set_pppm(pppm_t,1/cores[i]->executionTime, procdynp.numCore,procdynp.numCore,procdynp.numCore); - core.rt_power = core.rt_power + cores[i]->rt_power*pppm_t; - rt_power = rt_power + core.rt_power; - } - else{ - set_pppm(pppm_t,1/cores[i]->executionTime, 1, 1, 1); - core.rt_power = core.rt_power + cores[i]->rt_power*pppm_t; - rt_power = rt_power + cores[i]->rt_power*pppm_t; - } + for (i = 0; i < numCore; i++) { + cores[i]->executionTime = + XML->sys.total_cycles / (XML->sys.core[i].clock_rate * 1e6); + cores[i]->rt_power.reset(); + cores[i]->compute(); + // cores[i]->computeEnergy(false); + if (procdynp.homoCore) { + set_pppm(pppm_t, 1 / cores[i]->executionTime, procdynp.numCore, + procdynp.numCore, procdynp.numCore); + core.rt_power = core.rt_power + cores[i]->rt_power * pppm_t; + rt_power = rt_power + core.rt_power; + } else { + set_pppm(pppm_t, 1 / cores[i]->executionTime, 1, 1, 1); + core.rt_power = core.rt_power + cores[i]->rt_power * pppm_t; + rt_power = rt_power + cores[i]->rt_power * pppm_t; + } } - if (!XML->sys.Private_L2) - { - if (numL2 >0) - l2.rt_power.reset(); - for (i = 0;i < numL2; i++) - { + if (!XML->sys.Private_L2) { + if (numL2 > 0) l2.rt_power.reset(); + for (i = 0; i < numL2; i++) { l2array[i]->rt_power.reset(); - l2array[i]->cachep.executionTime=XML->sys.total_cycles /(XML->sys.core[0].clock_rate*1e6); - l2array[i]->computeEnergy(false); - if (procdynp.homoL2){ - set_pppm(pppm_t,1/l2array[i]->cachep.executionTime, procdynp.numL2,procdynp.numL2,procdynp.numL2); - l2.rt_power = l2.rt_power + l2array[i]->rt_power*pppm_t; - rt_power = rt_power + l2.rt_power; - } - else{ - set_pppm(pppm_t,1/l2array[i]->cachep.executionTime, 1, 1, 1); - l2.rt_power = l2.rt_power + l2array[i]->rt_power*pppm_t; - rt_power = rt_power + l2array[i]->rt_power*pppm_t; - } - } + l2array[i]->cachep.executionTime = + XML->sys.total_cycles / (XML->sys.core[0].clock_rate * 1e6); + l2array[i]->computeEnergy(false); + if (procdynp.homoL2) { + set_pppm(pppm_t, 1 / l2array[i]->cachep.executionTime, procdynp.numL2, + procdynp.numL2, procdynp.numL2); + l2.rt_power = l2.rt_power + l2array[i]->rt_power * pppm_t; + rt_power = rt_power + l2.rt_power; + } else { + set_pppm(pppm_t, 1 / l2array[i]->cachep.executionTime, 1, 1, 1); + l2.rt_power = l2.rt_power + l2array[i]->rt_power * pppm_t; + rt_power = rt_power + l2array[i]->rt_power * pppm_t; + } + } } l3.rt_power.reset(); - if (numL3 >0) - for (i = 0;i < numL3; i++) - { - l3array[i]->rt_power.reset(); - l3array[i]->computeEnergy(false); - if (procdynp.homoL3){ - set_pppm(pppm_t,1/l3array[i]->cachep.executionTime, procdynp.numL3,procdynp.numL3,procdynp.numL3); - l3.rt_power = l3.rt_power + l3array[i]->rt_power*pppm_t; - rt_power = rt_power + l3.rt_power; - - } - else{ - set_pppm(pppm_t,1/l3array[i]->cachep.executionTime, 1, 1, 1); - l3.rt_power = l3.rt_power + l3array[i]->rt_power*pppm_t; - rt_power = rt_power + l3array[i]->rt_power*pppm_t; - - } - } + if (numL3 > 0) + for (i = 0; i < numL3; i++) { + l3array[i]->rt_power.reset(); + l3array[i]->computeEnergy(false); + if (procdynp.homoL3) { + set_pppm(pppm_t, 1 / l3array[i]->cachep.executionTime, procdynp.numL3, + procdynp.numL3, procdynp.numL3); + l3.rt_power = l3.rt_power + l3array[i]->rt_power * pppm_t; + rt_power = rt_power + l3.rt_power; + + } else { + set_pppm(pppm_t, 1 / l3array[i]->cachep.executionTime, 1, 1, 1); + l3.rt_power = l3.rt_power + l3array[i]->rt_power * pppm_t; + rt_power = rt_power + l3array[i]->rt_power * pppm_t; + } + } l1dir.rt_power.reset(); - if (numL1Dir >0) - for (i = 0;i < numL1Dir; i++) - { - l1dirarray[i]->rt_power.reset(); - l1dirarray[i]->computeEnergy(false); - if (procdynp.homoL1Dir){ - set_pppm(pppm_t,1/l1dirarray[i]->cachep.executionTime, procdynp.numL1Dir,procdynp.numL1Dir,procdynp.numL1Dir); - l1dir.rt_power = l1dir.rt_power + l1dirarray[i]->rt_power*pppm_t; - rt_power = rt_power + l1dir.rt_power; - - } - else{ - set_pppm(pppm_t,1/l1dirarray[i]->cachep.executionTime, 1, 1, 1); - l1dir.rt_power = l1dir.rt_power + l1dirarray[i]->rt_power*pppm_t; - rt_power = rt_power + l1dirarray[i]->rt_power; - } - } - + if (numL1Dir > 0) + for (i = 0; i < numL1Dir; i++) { + l1dirarray[i]->rt_power.reset(); + l1dirarray[i]->computeEnergy(false); + if (procdynp.homoL1Dir) { + set_pppm(pppm_t, 1 / l1dirarray[i]->cachep.executionTime, + procdynp.numL1Dir, procdynp.numL1Dir, procdynp.numL1Dir); + l1dir.rt_power = l1dir.rt_power + l1dirarray[i]->rt_power * pppm_t; + rt_power = rt_power + l1dir.rt_power; + + } else { + set_pppm(pppm_t, 1 / l1dirarray[i]->cachep.executionTime, 1, 1, 1); + l1dir.rt_power = l1dir.rt_power + l1dirarray[i]->rt_power * pppm_t; + rt_power = rt_power + l1dirarray[i]->rt_power; + } + } l2dir.rt_power.reset(); - if (numL2Dir >0) - for (i = 0;i < numL2Dir; i++) - { - l2dirarray[i]->rt_power.reset(); - l2dirarray[i]->computeEnergy(false); - if (procdynp.homoL2Dir){ - set_pppm(pppm_t,1/l2dirarray[i]->cachep.executionTime, procdynp.numL2Dir,procdynp.numL2Dir,procdynp.numL2Dir); - l2dir.rt_power = l2dir.rt_power + l2dirarray[i]->rt_power*pppm_t; - rt_power = rt_power + l2dir.rt_power; - - } - else{ - set_pppm(pppm_t,1/l2dirarray[i]->cachep.executionTime, 1, 1, 1); - l2dir.rt_power = l2dir.rt_power + l2dirarray[i]->rt_power*pppm_t; - rt_power = rt_power + l2dirarray[i]->rt_power*pppm_t; - } - } - + if (numL2Dir > 0) + for (i = 0; i < numL2Dir; i++) { + l2dirarray[i]->rt_power.reset(); + l2dirarray[i]->computeEnergy(false); + if (procdynp.homoL2Dir) { + set_pppm(pppm_t, 1 / l2dirarray[i]->cachep.executionTime, + procdynp.numL2Dir, procdynp.numL2Dir, procdynp.numL2Dir); + l2dir.rt_power = l2dir.rt_power + l2dirarray[i]->rt_power * pppm_t; + rt_power = rt_power + l2dir.rt_power; + + } else { + set_pppm(pppm_t, 1 / l2dirarray[i]->cachep.executionTime, 1, 1, 1); + l2dir.rt_power = l2dir.rt_power + l2dirarray[i]->rt_power * pppm_t; + rt_power = rt_power + l2dirarray[i]->rt_power * pppm_t; + } + } mcs.rt_power.reset(); - if (XML->sys.mc.number_mcs >0 && XML->sys.mc.memory_channels_per_mc>0) - { - mc->rt_power.reset(); - mc->mcp.executionTime = XML->sys.total_cycles /(XML->sys.core[0].clock_rate*1e6); //Jingwen - mc->computeEnergy(false); - set_pppm(pppm_t,1/mc->mcp.executionTime, XML->sys.mc.number_mcs,XML->sys.mc.number_mcs,XML->sys.mc.number_mcs); - mcs.rt_power = mc->rt_power*pppm_t; - rt_power = rt_power + mcs.rt_power; - + if (XML->sys.mc.number_mcs > 0 && XML->sys.mc.memory_channels_per_mc > 0) { + mc->rt_power.reset(); + mc->mcp.executionTime = + XML->sys.total_cycles / (XML->sys.core[0].clock_rate * 1e6); // Jingwen + mc->computeEnergy(false); + set_pppm(pppm_t, 1 / mc->mcp.executionTime, XML->sys.mc.number_mcs, + XML->sys.mc.number_mcs, XML->sys.mc.number_mcs); + mcs.rt_power = mc->rt_power * pppm_t; + rt_power = rt_power + mcs.rt_power; } - - -/* - if (XML->sys.flashc.number_mcs >0 )//flash controller - { - flashcontrollers.rt_power.reset(); - flashcontroller->computeEnergy(false); - double number_fcs = flashcontroller->fcp.num_mcs; - set_pppm(pppm_t,number_fcs , number_fcs ,number_fcs ,number_fcs ); - flashcontrollers.rt_power = flashcontroller->rt_power*pppm_t; - rt_power = rt_power + flashcontrollers.rt_power; - - } - - if (XML->sys.niu.number_units >0) - { - niu->computeEnergy(false); - nius.rt_power.reset(); - set_pppm(pppm_t,XML->sys.niu.number_units*niu->niup.clockRate, XML->sys.niu.number_units,XML->sys.niu.number_units,XML->sys.niu.number_units); - nius.rt_power = niu->rt_power*pppm_t; - rt_power = rt_power + nius.rt_power; - - } - - if (XML->sys.pcie.number_units >0 && XML->sys.pcie.num_channels >0) - { - pcie->computeEnergy(false); - pcies.rt_power.reset(); - set_pppm(pppm_t,XML->sys.pcie.number_units*pcie->pciep.clockRate, XML->sys.pcie.number_units,XML->sys.pcie.number_units,XML->sys.pcie.number_units); - pcies.rt_power = pcie->rt_power*pppm_t; - rt_power = rt_power + pcies.rt_power; + /* + if (XML->sys.flashc.number_mcs >0 )//flash controller + { + flashcontrollers.rt_power.reset(); + flashcontroller->computeEnergy(false); + double number_fcs = flashcontroller->fcp.num_mcs; + set_pppm(pppm_t,number_fcs , number_fcs ,number_fcs ,number_fcs ); + flashcontrollers.rt_power = flashcontroller->rt_power*pppm_t; + rt_power = rt_power + flashcontrollers.rt_power; + + } + + if (XML->sys.niu.number_units >0) + { + niu->computeEnergy(false); + nius.rt_power.reset(); + set_pppm(pppm_t,XML->sys.niu.number_units*niu->niup.clockRate, + XML->sys.niu.number_units,XML->sys.niu.number_units,XML->sys.niu.number_units); + nius.rt_power = niu->rt_power*pppm_t; + rt_power = rt_power + nius.rt_power; + + } + + if (XML->sys.pcie.number_units >0 && XML->sys.pcie.num_channels >0) + { + pcie->computeEnergy(false); + pcies.rt_power.reset(); + set_pppm(pppm_t,XML->sys.pcie.number_units*pcie->pciep.clockRate, + XML->sys.pcie.number_units,XML->sys.pcie.number_units,XML->sys.pcie.number_units); + pcies.rt_power = pcie->rt_power*pppm_t; + rt_power = rt_power + pcies.rt_power; + + } + + + // * Compute global links associated with each NOC, if any. This + must be done at the end (even after the NOC router part) since the total + chip + // * area must be obtain to decide the link routing + */ + // Compute energy of NoC (w or w/o links) or buses + noc.rt_power.reset(); + for (i = 0; i < numNOC; i++) { + nocs[i]->nocdynp.executionTime = + XML->sys.total_cycles / (XML->sys.core[0].clock_rate * 1e6); + nocs[i]->computeEnergy(false); + if (procdynp.homoNOC) { + set_pppm(pppm_t, 1 / nocs[i]->nocdynp.executionTime, procdynp.numNOC, + procdynp.numNOC, procdynp.numNOC); + noc.rt_power = noc.rt_power + nocs[i]->rt_power * pppm_t; + rt_power = rt_power + noc.rt_power; + } else { + set_pppm(pppm_t, 1 / nocs[i]->nocdynp.executionTime, 1, 1, 1); + noc.rt_power = noc.rt_power + nocs[i]->rt_power * pppm_t; + rt_power = rt_power + nocs[i]->rt_power * pppm_t; + } } - - // * Compute global links associated with each NOC, if any. This must be done at the end (even after the NOC router part) since the total chip - // * area must be obtain to decide the link routing - */ - //Compute energy of NoC (w or w/o links) or buses - noc.rt_power.reset(); - for (i = 0;i < numNOC; i++) - { - nocs[i]->nocdynp.executionTime=XML->sys.total_cycles /(XML->sys.core[0].clock_rate*1e6); - nocs[i]->computeEnergy(false); - if (procdynp.homoNOC){ - set_pppm(pppm_t,1/nocs[i]->nocdynp.executionTime, procdynp.numNOC,procdynp.numNOC,procdynp.numNOC); - noc.rt_power = noc.rt_power + nocs[i]->rt_power*pppm_t; - rt_power = rt_power + noc.rt_power; - } - else - { - set_pppm(pppm_t,1/nocs[i]->nocdynp.executionTime, 1, 1, 1); - noc.rt_power = noc.rt_power + nocs[i]->rt_power*pppm_t; - rt_power = rt_power + nocs[i]->rt_power*pppm_t; - } - } - - -// //clock power -// globalClock.init_wire_external(is_default, &interface_ip); -// globalClock.clk_area =area*1e6; //change it from mm^2 to um^2 -// globalClock.end_wiring_level =5;//toplevel metal -// globalClock.start_wiring_level =5;//toplevel metal -// globalClock.l_ip.with_clock_grid=false;//global clock does not drive local final nodes -// globalClock.optimize_wire(); - + // //clock power + // globalClock.init_wire_external(is_default, &interface_ip); + // globalClock.clk_area =area*1e6; //change it from mm^2 to um^2 + // globalClock.end_wiring_level =5;//toplevel metal + // globalClock.start_wiring_level =5;//toplevel metal + // globalClock.l_ip.with_clock_grid=false;//global clock does not drive local + // final nodes globalClock.optimize_wire(); } -void Processor::displayDeviceType(int device_type_, uint32_t indent) -{ - string indent_str(indent, ' '); - - switch ( device_type_ ) { - - case 0 : - cout <sys.longer_channel_device; - string indent_str(indent, ' '); - string indent_str_next(indent+2, ' '); - bool is_tdp=is_tdp_parm; - if (is_tdp_parm) - { - - - if (plevel<5) - { - cout<<"\nMcPAT (version "<< VER_MAJOR <<"."<< VER_MINOR - << " of " << VER_UPDATE << ") results (current print level is "<< plevel - <<", please increase print level to see the details in components): "<sys.core_tech_node<<" nm"<sys.core[0].clock_rate<0){ - cout <sys.number_of_cores << " cores "<sys.device_type,indent); - cout << indent_str_next << "Area = " << core.area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << core.power.readOp.dynamic << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? core.power.readOp.longer_channel_leakage:core.power.readOp.leakage) <<" W" << endl; - //cout << indent_str_next << "Subthreshold Leakage = " << core.power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << core.power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << core.rt_power.readOp.dynamic << " W" << endl; - cout <sys.Private_L2) - { - if (numL2 >0){ - cout <sys.L2[0].device_type,indent); - cout << indent_str_next << "Area = " << l2.area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << l2.power.readOp.dynamic << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? l2.power.readOp.longer_channel_leakage:l2.power.readOp.leakage) <<" W" << endl; - //cout << indent_str_next << "Subthreshold Leakage = " << l2.power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << l2.power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << l2.rt_power.readOp.dynamic << " W" << endl; - cout <0){ - cout <sys.L3[0].device_type, indent); - cout << indent_str_next << "Area = " << l3.area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << l3.power.readOp.dynamic << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? l3.power.readOp.longer_channel_leakage:l3.power.readOp.leakage) <<" W" << endl; - //cout << indent_str_next << "Subthreshold Leakage = " << l3.power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << l3.power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << l3.rt_power.readOp.dynamic << " W" << endl; - cout <0){ - cout <sys.L1Directory[0].device_type, indent); - cout << indent_str_next << "Area = " << l1dir.area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << l1dir.power.readOp.dynamic << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? l1dir.power.readOp.longer_channel_leakage:l1dir.power.readOp.leakage) <<" W" << endl; - //cout << indent_str_next << "Subthreshold Leakage = " << l1dir.power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << l1dir.power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << l1dir.rt_power.readOp.dynamic << " W" << endl; - cout <0){ - cout <sys.L1Directory[0].device_type, indent); - cout << indent_str_next << "Area = " << l2dir.area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << l2dir.power.readOp.dynamic << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? l2dir.power.readOp.longer_channel_leakage:l2dir.power.readOp.leakage) <<" W" << endl; - //cout << indent_str_next << "Subthreshold Leakage = " << l2dir.power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << l2dir.power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << l2dir.rt_power.readOp.dynamic << " W" << endl; - cout <0){ - cout <sys.device_type, indent); - cout << indent_str_next << "Area = " << noc.area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << noc.power.readOp.dynamic << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? noc.power.readOp.longer_channel_leakage:noc.power.readOp.leakage) <<" W" << endl; - //cout << indent_str_next << "Subthreshold Leakage = " << noc.power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << noc.power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << noc.rt_power.readOp.dynamic << " W" << endl; - cout <sys.mc.number_mcs >0 && XML->sys.mc.memory_channels_per_mc>0) - { - cout <sys.mc.number_mcs << " Memory Controllers "<sys.device_type, indent); - cout << indent_str_next << "Area = " << mcs.area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << mcs.power.readOp.dynamic << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? mcs.power.readOp.longer_channel_leakage:mcs.power.readOp.leakage) <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << mcs.power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << mcs.rt_power.readOp.dynamic << " W" << endl; - cout <sys.flashc.number_mcs >0) - { - cout <fcp.num_mcs << " Flash/SSD Controllers "<sys.device_type, indent); - cout << indent_str_next << "Area = " << flashcontrollers.area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << flashcontrollers.power.readOp.dynamic << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? flashcontrollers.power.readOp.longer_channel_leakage:flashcontrollers.power.readOp.leakage) <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << flashcontrollers.power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << flashcontrollers.rt_power.readOp.dynamic << " W" << endl; - cout <sys.niu.number_units >0 ) - { - cout <niup.num_units << " Network Interface Units "<sys.device_type, indent); - cout << indent_str_next << "Area = " << nius.area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << nius.power.readOp.dynamic << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? nius.power.readOp.longer_channel_leakage:nius.power.readOp.leakage) <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << nius.power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << nius.rt_power.readOp.dynamic << " W" << endl; - cout <sys.pcie.number_units >0 && XML->sys.pcie.num_channels>0) - { - cout <pciep.num_units << " PCIe Controllers "<sys.device_type, indent); - cout << indent_str_next << "Area = " << pcies.area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str_next << "Peak Dynamic = " << pcies.power.readOp.dynamic << " W" << endl; - cout << indent_str_next << "Subthreshold Leakage = " - << (long_channel? pcies.power.readOp.longer_channel_leakage:pcies.power.readOp.leakage) <<" W" << endl; - cout << indent_str_next << "Gate Leakage = " << pcies.power.readOp.gate_leakage << " W" << endl; - cout << indent_str_next << "Runtime Dynamic = " << pcies.rt_power.readOp.dynamic << " W" << endl; - cout <1) - { - for (i = 0;i < numCore; i++) - { - cores[i]->displayEnergy(indent+4,plevel,is_tdp); - cout <<"*****************************************************************************************"<sys.Private_L2) - { - for (i = 0;i < numL2; i++) - { - l2array[i]->displayEnergy(indent+4,is_tdp); - cout <<"*****************************************************************************************"<displayEnergy(indent+4,is_tdp); - cout <<"*****************************************************************************************"<displayEnergy(indent+4,is_tdp); - cout <<"*****************************************************************************************"<displayEnergy(indent+4,is_tdp); - cout <<"*****************************************************************************************"<sys.mc.number_mcs >0 && XML->sys.mc.memory_channels_per_mc>0) - { - mc->displayEnergy(indent+4,is_tdp); - cout <<"*****************************************************************************************"<sys.flashc.number_mcs >0 && XML->sys.flashc.memory_channels_per_mc>0) - { - flashcontroller->displayEnergy(indent+4,is_tdp); - cout <<"*****************************************************************************************"<sys.niu.number_units >0 ) - { - niu->displayEnergy(indent+4,is_tdp); - cout <<"*****************************************************************************************"<sys.pcie.number_units >0 && XML->sys.pcie.num_channels>0) - { - pcie->displayEnergy(indent+4,is_tdp); - cout <<"*****************************************************************************************"<displayEnergy(indent+4,plevel,is_tdp); - cout <<"*****************************************************************************************"<sys.longer_channel_device; + string indent_str(indent, ' '); + string indent_str_next(indent + 2, ' '); + bool is_tdp = is_tdp_parm; + if (is_tdp_parm) { + if (plevel < 5) { + cout + << "\nMcPAT (version " << VER_MAJOR << "." << VER_MINOR << " of " + << VER_UPDATE << ") results (current print level is " << plevel + << ", please increase print level to see the details in components): " + << endl; + } else { + cout << "\nMcPAT (version " << VER_MAJOR << "." << VER_MINOR << " of " + << VER_UPDATE << ") results (current print level is 5)" << endl; + } + cout << "******************************************************************" + "***********************" + << endl; + cout << indent_str << "Technology " << XML->sys.core_tech_node << " nm" + << endl; + // cout <sys.interconnect_projection_type<sys.interconnect_projection_type, indent); + cout << indent_str << "Core clock Rate(MHz) " << XML->sys.core[0].clock_rate + << endl; + cout << endl; + cout << "******************************************************************" + "***********************" + << endl; + cout << "Processor: " << endl; + cout << indent_str << "Area = " << area.get_area() * 1e-6 << " mm^2" + << endl; + cout << indent_str << "Peak Power = " + << power.readOp.dynamic + + (long_channel ? power.readOp.longer_channel_leakage + : power.readOp.leakage) + + power.readOp.gate_leakage + << " W" << endl; + cout << indent_str << "Total Leakage = " + << (long_channel ? power.readOp.longer_channel_leakage + : power.readOp.leakage) + + power.readOp.gate_leakage + << " W" << endl; + cout << indent_str << "Peak Dynamic = " << power.readOp.dynamic << " W" + << endl; + cout << indent_str << "Subthreshold Leakage = " + << (long_channel ? power.readOp.longer_channel_leakage + : power.readOp.leakage) + << " W" << endl; + // cout << indent_str << "Subthreshold Leakage = " << + // power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str << "Gate Leakage = " << power.readOp.gate_leakage << " W" + << endl; + cout << indent_str << "Runtime Dynamic = " << rt_power.readOp.dynamic + << " W" << endl; + cout << endl; + if (numCore > 0) { + cout << indent_str << "Total Cores: " << XML->sys.number_of_cores + << " cores " << endl; + displayDeviceType(XML->sys.device_type, indent); + cout << indent_str_next << "Area = " << core.area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << core.power.readOp.dynamic + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? core.power.readOp.longer_channel_leakage + : core.power.readOp.leakage) + << " W" << endl; + // cout << indent_str_next << "Subthreshold Leakage = " << + // core.power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str_next + << "Gate Leakage = " << core.power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next + << "Runtime Dynamic = " << core.rt_power.readOp.dynamic << " W" + << endl; + cout << endl; + } + if (!XML->sys.Private_L2) { + if (numL2 > 0) { + cout << indent_str << "Total L2s: " << endl; + displayDeviceType(XML->sys.L2[0].device_type, indent); + cout << indent_str_next << "Area = " << l2.area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << l2.power.readOp.dynamic + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? l2.power.readOp.longer_channel_leakage + : l2.power.readOp.leakage) + << " W" << endl; + // cout << indent_str_next << "Subthreshold Leakage = " << + // l2.power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str_next + << "Gate Leakage = " << l2.power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next + << "Runtime Dynamic = " << l2.rt_power.readOp.dynamic << " W" + << endl; + cout << endl; + } + } + if (numL3 > 0) { + cout << indent_str << "Total L3s: " << endl; + displayDeviceType(XML->sys.L3[0].device_type, indent); + cout << indent_str_next << "Area = " << l3.area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << l3.power.readOp.dynamic + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? l3.power.readOp.longer_channel_leakage + : l3.power.readOp.leakage) + << " W" << endl; + // cout << indent_str_next << "Subthreshold Leakage = " << + // l3.power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str_next + << "Gate Leakage = " << l3.power.readOp.gate_leakage << " W" << endl; + cout << indent_str_next + << "Runtime Dynamic = " << l3.rt_power.readOp.dynamic << " W" + << endl; + cout << endl; + } + if (numL1Dir > 0) { + cout << indent_str << "Total First Level Directory: " << endl; + displayDeviceType(XML->sys.L1Directory[0].device_type, indent); + cout << indent_str_next << "Area = " << l1dir.area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << l1dir.power.readOp.dynamic + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? l1dir.power.readOp.longer_channel_leakage + : l1dir.power.readOp.leakage) + << " W" << endl; + // cout << indent_str_next << "Subthreshold Leakage = " << + // l1dir.power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str_next + << "Gate Leakage = " << l1dir.power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next + << "Runtime Dynamic = " << l1dir.rt_power.readOp.dynamic << " W" + << endl; + cout << endl; + } + if (numL2Dir > 0) { + cout << indent_str << "Total First Level Directory: " << endl; + displayDeviceType(XML->sys.L1Directory[0].device_type, indent); + cout << indent_str_next << "Area = " << l2dir.area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << l2dir.power.readOp.dynamic + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? l2dir.power.readOp.longer_channel_leakage + : l2dir.power.readOp.leakage) + << " W" << endl; + // cout << indent_str_next << "Subthreshold Leakage = " << + // l2dir.power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str_next + << "Gate Leakage = " << l2dir.power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next + << "Runtime Dynamic = " << l2dir.rt_power.readOp.dynamic << " W" + << endl; + cout << endl; + } + if (numNOC > 0) { + cout << indent_str << "Total NoCs (Network/Bus): " << endl; + displayDeviceType(XML->sys.device_type, indent); + cout << indent_str_next << "Area = " << noc.area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << noc.power.readOp.dynamic + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? noc.power.readOp.longer_channel_leakage + : noc.power.readOp.leakage) + << " W" << endl; + // cout << indent_str_next << "Subthreshold Leakage = " << + // noc.power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str_next + << "Gate Leakage = " << noc.power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next + << "Runtime Dynamic = " << noc.rt_power.readOp.dynamic << " W" + << endl; + cout << endl; + } + if (XML->sys.mc.number_mcs > 0 && XML->sys.mc.memory_channels_per_mc > 0) { + cout << indent_str << "Total MCs: " << XML->sys.mc.number_mcs + << " Memory Controllers " << endl; + displayDeviceType(XML->sys.device_type, indent); + cout << indent_str_next << "Area = " << mcs.area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << mcs.power.readOp.dynamic + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? mcs.power.readOp.longer_channel_leakage + : mcs.power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << mcs.power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next + << "Runtime Dynamic = " << mcs.rt_power.readOp.dynamic << " W" + << endl; + cout << endl; + } + if (XML->sys.flashc.number_mcs > 0) { + cout << indent_str + << "Total Flash/SSD Controllers: " << flashcontroller->fcp.num_mcs + << " Flash/SSD Controllers " << endl; + displayDeviceType(XML->sys.device_type, indent); + cout << indent_str_next + << "Area = " << flashcontrollers.area.get_area() * 1e-6 << " mm^2" + << endl; + cout << indent_str_next + << "Peak Dynamic = " << flashcontrollers.power.readOp.dynamic << " W" + << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel + ? flashcontrollers.power.readOp.longer_channel_leakage + : flashcontrollers.power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << flashcontrollers.power.readOp.gate_leakage + << " W" << endl; + cout << indent_str_next + << "Runtime Dynamic = " << flashcontrollers.rt_power.readOp.dynamic + << " W" << endl; + cout << endl; + } + if (XML->sys.niu.number_units > 0) { + cout << indent_str << "Total NIUs: " << niu->niup.num_units + << " Network Interface Units " << endl; + displayDeviceType(XML->sys.device_type, indent); + cout << indent_str_next << "Area = " << nius.area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << nius.power.readOp.dynamic + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? nius.power.readOp.longer_channel_leakage + : nius.power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << nius.power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next + << "Runtime Dynamic = " << nius.rt_power.readOp.dynamic << " W" + << endl; + cout << endl; + } + if (XML->sys.pcie.number_units > 0 && XML->sys.pcie.num_channels > 0) { + cout << indent_str << "Total PCIes: " << pcie->pciep.num_units + << " PCIe Controllers " << endl; + displayDeviceType(XML->sys.device_type, indent); + cout << indent_str_next << "Area = " << pcies.area.get_area() * 1e-6 + << " mm^2" << endl; + cout << indent_str_next << "Peak Dynamic = " << pcies.power.readOp.dynamic + << " W" << endl; + cout << indent_str_next << "Subthreshold Leakage = " + << (long_channel ? pcies.power.readOp.longer_channel_leakage + : pcies.power.readOp.leakage) + << " W" << endl; + cout << indent_str_next + << "Gate Leakage = " << pcies.power.readOp.gate_leakage << " W" + << endl; + cout << indent_str_next + << "Runtime Dynamic = " << pcies.rt_power.readOp.dynamic << " W" + << endl; + cout << endl; + } + cout << "******************************************************************" + "***********************" + << endl; + if (plevel > 1) { + for (i = 0; i < numCore; i++) { + cores[i]->displayEnergy(indent + 4, plevel, is_tdp); + cout << "**************************************************************" + "***************************" + << endl; + } + if (!XML->sys.Private_L2) { + for (i = 0; i < numL2; i++) { + l2array[i]->displayEnergy(indent + 4, is_tdp); + cout << "************************************************************" + "*****************************" + << endl; + } + } + for (i = 0; i < numL3; i++) { + l3array[i]->displayEnergy(indent + 4, is_tdp); + cout << "**************************************************************" + "***************************" + << endl; + } + for (i = 0; i < numL1Dir; i++) { + l1dirarray[i]->displayEnergy(indent + 4, is_tdp); + cout << "**************************************************************" + "***************************" + << endl; + } + for (i = 0; i < numL2Dir; i++) { + l2dirarray[i]->displayEnergy(indent + 4, is_tdp); + cout << "**************************************************************" + "***************************" + << endl; + } + if (XML->sys.mc.number_mcs > 0 && + XML->sys.mc.memory_channels_per_mc > 0) { + mc->displayEnergy(indent + 4, is_tdp); + cout << "**************************************************************" + "***************************" + << endl; + } + if (XML->sys.flashc.number_mcs > 0 && + XML->sys.flashc.memory_channels_per_mc > 0) { + flashcontroller->displayEnergy(indent + 4, is_tdp); + cout << "**************************************************************" + "***************************" + << endl; + } + if (XML->sys.niu.number_units > 0) { + niu->displayEnergy(indent + 4, is_tdp); + cout << "**************************************************************" + "***************************" + << endl; + } + if (XML->sys.pcie.number_units > 0 && XML->sys.pcie.num_channels > 0) { + pcie->displayEnergy(indent + 4, is_tdp); + cout << "**************************************************************" + "***************************" + << endl; + } + + for (i = 0; i < numNOC; i++) { + nocs[i]->displayEnergy(indent + 4, plevel, is_tdp); + cout << "**************************************************************" + "***************************" + << endl; + } + } + } else { + } } -void Processor::set_proc_param() -{ - bool debug = false; - - procdynp.homoCore = bool(debug?1:XML->sys.homogeneous_cores); - procdynp.homoL2 = bool(debug?1:XML->sys.homogeneous_L2s); - procdynp.homoL3 = bool(debug?1:XML->sys.homogeneous_L3s); - procdynp.homoNOC = bool(debug?1:XML->sys.homogeneous_NoCs); - procdynp.homoL1Dir = bool(debug?1:XML->sys.homogeneous_L1Directories); - procdynp.homoL2Dir = bool(debug?1:XML->sys.homogeneous_L2Directories); - - procdynp.numCore = XML->sys.number_of_cores; - procdynp.numL2 = XML->sys.number_of_L2s; - procdynp.numL3 = XML->sys.number_of_L3s; - procdynp.numNOC = XML->sys.number_of_NoCs; - procdynp.numL1Dir = XML->sys.number_of_L1Directories; - procdynp.numL2Dir = XML->sys.number_of_L2Directories; - procdynp.numMC = XML->sys.mc.number_mcs; - procdynp.numMCChannel = XML->sys.mc.memory_channels_per_mc; - -// if (procdynp.numCore<1) -// { -// cout<<" The target processor should at least have one core on chip." <2) - // { - // cout <<"number of NOCs must be 1 (only global NOCs) or 2 (both global and local NOCs)"<sys.device_type; - interface_ip.data_arr_peri_global_tech_type = debug?0:XML->sys.device_type; - interface_ip.tag_arr_ram_cell_tech_type = debug?0:XML->sys.device_type; - interface_ip.tag_arr_peri_global_tech_type = debug?0:XML->sys.device_type; - - interface_ip.ic_proj_type = debug?0:XML->sys.interconnect_projection_type; - interface_ip.delay_wt = 100;//Fixed number, make sure timing can be satisfied. - interface_ip.area_wt = 0;//Fixed number, This is used to exhaustive search for individual components. - interface_ip.dynamic_power_wt = 100;//Fixed number, This is used to exhaustive search for individual components. - interface_ip.leakage_power_wt = 0; - interface_ip.cycle_time_wt = 0; - - interface_ip.delay_dev = 10000;//Fixed number, make sure timing can be satisfied. - interface_ip.area_dev = 10000;//Fixed number, This is used to exhaustive search for individual components. - interface_ip.dynamic_power_dev = 10000;//Fixed number, This is used to exhaustive search for individual components. - interface_ip.leakage_power_dev = 10000; - interface_ip.cycle_time_dev = 10000; - - interface_ip.ed = 2; - interface_ip.burst_len = 1;//parameters are fixed for processor section, since memory is processed separately - interface_ip.int_prefetch_w = 1; - interface_ip.page_sz_bits = 0; - interface_ip.temp = debug?360: XML->sys.temperature; - interface_ip.F_sz_nm = debug?90:XML->sys.core_tech_node;//XML->sys.core_tech_node; - interface_ip.F_sz_um = interface_ip.F_sz_nm / 1000; - - //***********This section of code does not have real meaning, they are just to ensure all data will have initial value to prevent errors. - //They will be overridden during each components initialization - interface_ip.cache_sz =64; - interface_ip.line_sz = 1; - interface_ip.assoc = 1; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.specific_tag = 1; - interface_ip.tag_w = 64; - interface_ip.access_mode = 2; - - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - - interface_ip.is_main_mem = false; - interface_ip.rpters_in_htree = true ; - interface_ip.ver_htree_wires_over_array = 0; - interface_ip.broadcast_addr_din_over_ver_htrees = 0; - - interface_ip.num_rw_ports = 1; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = 1; - interface_ip.nuca = 0; - interface_ip.nuca_bank_count = 0; - interface_ip.is_cache =true; - interface_ip.pure_ram =false; - interface_ip.pure_cam =false; - interface_ip.force_cache_config =false; - if (XML->sys.Embedded) - { - interface_ip.wt =Global_30; - interface_ip.wire_is_mat_type = 0; - interface_ip.wire_os_mat_type = 0; - } - else - { - interface_ip.wt =Global; - interface_ip.wire_is_mat_type = 2; - interface_ip.wire_os_mat_type = 2; - } - interface_ip.force_wiretype = false; - interface_ip.print_detail = 1; - interface_ip.add_ecc_b_ =true; +void Processor::set_proc_param() { + bool debug = false; + + procdynp.homoCore = bool(debug ? 1 : XML->sys.homogeneous_cores); + procdynp.homoL2 = bool(debug ? 1 : XML->sys.homogeneous_L2s); + procdynp.homoL3 = bool(debug ? 1 : XML->sys.homogeneous_L3s); + procdynp.homoNOC = bool(debug ? 1 : XML->sys.homogeneous_NoCs); + procdynp.homoL1Dir = bool(debug ? 1 : XML->sys.homogeneous_L1Directories); + procdynp.homoL2Dir = bool(debug ? 1 : XML->sys.homogeneous_L2Directories); + + procdynp.numCore = XML->sys.number_of_cores; + procdynp.numL2 = XML->sys.number_of_L2s; + procdynp.numL3 = XML->sys.number_of_L3s; + procdynp.numNOC = XML->sys.number_of_NoCs; + procdynp.numL1Dir = XML->sys.number_of_L1Directories; + procdynp.numL2Dir = XML->sys.number_of_L2Directories; + procdynp.numMC = XML->sys.mc.number_mcs; + procdynp.numMCChannel = XML->sys.mc.memory_channels_per_mc; + + // if (procdynp.numCore<1) + // { + // cout<<" The target processor should at least have one core on + // chip." + //<2) + // { + // cout <<"number of NOCs must be 1 (only global NOCs) or 2 (both global + // and local NOCs)"<sys.device_type; + interface_ip.data_arr_peri_global_tech_type = + debug ? 0 : XML->sys.device_type; + interface_ip.tag_arr_ram_cell_tech_type = debug ? 0 : XML->sys.device_type; + interface_ip.tag_arr_peri_global_tech_type = debug ? 0 : XML->sys.device_type; + + interface_ip.ic_proj_type = debug ? 0 : XML->sys.interconnect_projection_type; + interface_ip.delay_wt = + 100; // Fixed number, make sure timing can be satisfied. + interface_ip.area_wt = 0; // Fixed number, This is used to exhaustive search + // for individual components. + interface_ip.dynamic_power_wt = + 100; // Fixed number, This is used to exhaustive search for individual + // components. + interface_ip.leakage_power_wt = 0; + interface_ip.cycle_time_wt = 0; + + interface_ip.delay_dev = + 10000; // Fixed number, make sure timing can be satisfied. + interface_ip.area_dev = 10000; // Fixed number, This is used to exhaustive + // search for individual components. + interface_ip.dynamic_power_dev = + 10000; // Fixed number, This is used to exhaustive search for individual + // components. + interface_ip.leakage_power_dev = 10000; + interface_ip.cycle_time_dev = 10000; + + interface_ip.ed = 2; + interface_ip.burst_len = 1; // parameters are fixed for processor section, + // since memory is processed separately + interface_ip.int_prefetch_w = 1; + interface_ip.page_sz_bits = 0; + interface_ip.temp = debug ? 360 : XML->sys.temperature; + interface_ip.F_sz_nm = + debug ? 90 : XML->sys.core_tech_node; // XML->sys.core_tech_node; + interface_ip.F_sz_um = interface_ip.F_sz_nm / 1000; + + //***********This section of code does not have real meaning, they are just to + // ensure all data will have initial value to prevent errors. They will be + // overridden during each components initialization + interface_ip.cache_sz = 64; + interface_ip.line_sz = 1; + interface_ip.assoc = 1; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8; + interface_ip.specific_tag = 1; + interface_ip.tag_w = 64; + interface_ip.access_mode = 2; + + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + + interface_ip.is_main_mem = false; + interface_ip.rpters_in_htree = true; + interface_ip.ver_htree_wires_over_array = 0; + interface_ip.broadcast_addr_din_over_ver_htrees = 0; + + interface_ip.num_rw_ports = 1; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = 1; + interface_ip.nuca = 0; + interface_ip.nuca_bank_count = 0; + interface_ip.is_cache = true; + interface_ip.pure_ram = false; + interface_ip.pure_cam = false; + interface_ip.force_cache_config = false; + if (XML->sys.Embedded) { + interface_ip.wt = Global_30; + interface_ip.wire_is_mat_type = 0; + interface_ip.wire_os_mat_type = 0; + } else { + interface_ip.wt = Global; + interface_ip.wire_is_mat_type = 2; + interface_ip.wire_os_mat_type = 2; + } + interface_ip.force_wiretype = false; + interface_ip.print_detail = 1; + interface_ip.add_ecc_b_ = true; } - -Processor::~Processor(){ - while (!cores.empty()) - { - delete cores.back(); - cores.pop_back(); - } - while (!l2array.empty()) - { - delete l2array.back(); - l2array.pop_back(); - } - while (!l3array.empty()) - { - delete l3array.back(); - l3array.pop_back(); - } - while (!nocs.empty()) - { - delete nocs.back(); - nocs.pop_back(); - } - if (!mc) - { - delete mc; - } - if (!niu) - { - delete niu; - } - if (!pcie) - { - delete pcie; - } - if (!flashcontroller) - { - delete flashcontroller; - } +Processor::~Processor() { + while (!cores.empty()) { + delete cores.back(); + cores.pop_back(); + } + while (!l2array.empty()) { + delete l2array.back(); + l2array.pop_back(); + } + while (!l3array.empty()) { + delete l3array.back(); + l3array.pop_back(); + } + while (!nocs.empty()) { + delete nocs.back(); + nocs.pop_back(); + } + if (!mc) { + delete mc; + } + if (!niu) { + delete niu; + } + if (!pcie) { + delete pcie; + } + if (!flashcontroller) { + delete flashcontroller; + } }; - - diff --git a/src/gpuwattch/processor.h b/src/gpuwattch/processor.h index 7202460..888ba31 100644 --- a/src/gpuwattch/processor.h +++ b/src/gpuwattch/processor.h @@ -29,262 +29,296 @@ * ***************************************************************************/ /******************************************************************** -* 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 * + ********************************************************************/ #ifndef PROCESSOR_H_ #define PROCESSOR_H_ +#include +#include "../gpgpu-sim/visualizer.h" #include "XML_Parse.h" +#include "array.h" +#include "basic_components.h" +#include "cacti/arbiter.h" #include "cacti/area.h" #include "cacti/decoder.h" #include "cacti/parameter.h" -#include "array.h" -#include "cacti/arbiter.h" -#include -#include "basic_components.h" +#include "cacti/router.h" #include "core.h" +#include "iocontrollers.h" #include "memoryctrl.h" -#include "cacti/router.h" -#include "sharedcache.h" #include "noc.h" -#include "iocontrollers.h" -#include "../gpgpu-sim/visualizer.h" - -class Processor : public Component -{ - public: - ParseXML *XML; - vector cores; - vector l2array; - vector l3array; - vector l1dirarray; - vector l2dirarray; - vector nocs; - MemoryController * mc; - NIUController * niu; - PCIeController * pcie; - FlashController * flashcontroller; - InputParameter interface_ip; - double exClockRate; - ProcParam procdynp; - //for debugging nonlinear model - double dyn_power_before_scaling; - - //wire globalInterconnect; - //clock_network globalClock; - Component core, l2, l3, l1dir, l2dir, noc, mcs, cc, nius, pcies,flashcontrollers; - int numCore, numL2, numL3, numNOC, numL1Dir, numL2Dir; - Processor(ParseXML *XML_interface); - void compute(); - void set_proc_param(); - void visualizer_print( gzFile visualizer_file ); - void displayEnergy(uint32_t indent = 0,int plevel = 100, bool is_tdp_parm=true); - void displayDeviceType(int device_type_, uint32_t indent = 0); - void displayInterconnectType(int interconnect_type_, uint32_t indent = 0); - double l2_power; - double idle_core_power; - - double get_const_dynamic_power() - { - - double constpart=0; - constpart+=(mc->frontend->power.readOp.dynamic*0.1*mc->frontend->mcp.clockRate*mc->frontend->mcp.num_mcs*mc->frontend->mcp.executionTime); - constpart+=(mc->transecEngine->power.readOp.dynamic*0.1*mc->transecEngine->mcp.clockRate*mc->transecEngine->mcp.num_mcs*mc->transecEngine->mcp.executionTime); - constpart+=(mc->PHY->power.readOp.dynamic*0.1*mc->PHY->mcp.clockRate*mc->PHY->mcp.num_mcs*mc->PHY->mcp.executionTime); - constpart+=(cores[0]->exu->exeu->base_energy/cores[0]->exu->exeu->clockRate)*(cores[0]->exu->rf_fu_clockRate/cores[0]->exu->clockRate); - constpart+=(cores[0]->exu->mul->base_energy/cores[0]->exu->mul->clockRate); - constpart+=(cores[0]->exu->fp_u->base_energy/cores[0]->exu->fp_u->clockRate); - return constpart; - } -#define COALESCE_SCALE 1 - double get_coefficient_readcoalescing() - { - double value=0; - double perAccessCoalescingEnergy=COALESCE_SCALE * ((0.443e-3)*(0.5e-9)*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd)/(1*1); - value+=mc->frontend->PRT->local_result.power.readOp.dynamic; - value+=mc->frontend->threadMasks->local_result.power.readOp.dynamic; - value+=mc->frontend->PRC->local_result.power.readOp.dynamic; - value+=perAccessCoalescingEnergy; - return value; +#include "sharedcache.h" +class Processor : public Component { + public: + ParseXML *XML; + vector cores; + vector l2array; + vector l3array; + vector l1dirarray; + vector l2dirarray; + vector nocs; + MemoryController *mc; + NIUController *niu; + PCIeController *pcie; + FlashController *flashcontroller; + InputParameter interface_ip; + double exClockRate; + ProcParam procdynp; + // for debugging nonlinear model + double dyn_power_before_scaling; + + // wire globalInterconnect; + // clock_network globalClock; + Component core, l2, l3, l1dir, l2dir, noc, mcs, cc, nius, pcies, + flashcontrollers; + int numCore, numL2, numL3, numNOC, numL1Dir, numL2Dir; + Processor(ParseXML *XML_interface); + void compute(); + void set_proc_param(); + void visualizer_print(gzFile visualizer_file); + void displayEnergy(uint32_t indent = 0, int plevel = 100, + bool is_tdp_parm = true); + void displayDeviceType(int device_type_, uint32_t indent = 0); + void displayInterconnectType(int interconnect_type_, uint32_t indent = 0); + double l2_power; + double idle_core_power; + + double get_const_dynamic_power() { + double constpart = 0; + constpart += (mc->frontend->power.readOp.dynamic * 0.1 * + mc->frontend->mcp.clockRate * mc->frontend->mcp.num_mcs * + mc->frontend->mcp.executionTime); + constpart += + (mc->transecEngine->power.readOp.dynamic * 0.1 * + mc->transecEngine->mcp.clockRate * mc->transecEngine->mcp.num_mcs * + mc->transecEngine->mcp.executionTime); + constpart += (mc->PHY->power.readOp.dynamic * 0.1 * mc->PHY->mcp.clockRate * + mc->PHY->mcp.num_mcs * mc->PHY->mcp.executionTime); + constpart += + (cores[0]->exu->exeu->base_energy / cores[0]->exu->exeu->clockRate) * + (cores[0]->exu->rf_fu_clockRate / cores[0]->exu->clockRate); + constpart += + (cores[0]->exu->mul->base_energy / cores[0]->exu->mul->clockRate); + constpart += + (cores[0]->exu->fp_u->base_energy / cores[0]->exu->fp_u->clockRate); + return constpart; + } +#define COALESCE_SCALE 1 + double get_coefficient_readcoalescing() { + double value = 0; + double perAccessCoalescingEnergy = + COALESCE_SCALE * + ((0.443e-3) * (0.5e-9) * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd) / + (1 * 1); + value += mc->frontend->PRT->local_result.power.readOp.dynamic; + value += mc->frontend->threadMasks->local_result.power.readOp.dynamic; + value += mc->frontend->PRC->local_result.power.readOp.dynamic; + value += perAccessCoalescingEnergy; + return value; + } + double get_coefficient_writecoalescing() { + double value = 0; + double perAccessCoalescingEnergy = + COALESCE_SCALE * + ((0.443e-3) * (0.5e-9) * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd) / + (1 * 1); + value += (mc->frontend->PRT->local_result.power.writeOp.dynamic); + value += mc->frontend->threadMasks->local_result.power.writeOp.dynamic; + value += mc->frontend->PRC->local_result.power.writeOp.dynamic; + value += perAccessCoalescingEnergy; + return value; + } + + double get_coefficient_noc_accesses() { + double read_coef = 0; + // the 32/4 is applied to the NoC access counters (32/4*L2 cache access) + read_coef += nocs[0]->router->buffer.power.readOp.dynamic; + read_coef += nocs[0]->router->buffer.power.writeOp.dynamic; + read_coef += nocs[0]->router->crossbar.power.readOp.dynamic; + read_coef += nocs[0]->router->arbiter.power.readOp.dynamic; + return read_coef; + } + + double get_coefficient_l2_read_hits() { + double read_coef = 0; + if (XML->sys.number_of_L2s > 0) + read_coef = + l2array[0]->unicache.caches->local_result.power.readOp.dynamic; + return read_coef; + } + + double get_coefficient_l2_read_misses() { + double read_coef = 0; + if (XML->sys.number_of_L2s > 0) + read_coef = + l2array[0] + ->unicache.caches->local_result.tag_array2->power.readOp.dynamic; + return read_coef; + } + + double get_coefficient_l2_write_hits() { + double read_coef = 0; + if (XML->sys.number_of_L2s > 0) + read_coef = + l2array[0]->unicache.caches->local_result.power.writeOp.dynamic; + return read_coef; + } + double get_coefficient_l2_write_misses() { + double read_coef = 0; + if (XML->sys.number_of_L2s > 0) { + read_coef = l2array[0] + ->unicache.caches->local_result.tag_array2->power.writeOp + .dynamic; //*(32/4); // removed by Jingwen, the scaling + // of 32/4 is not used in the mcpat + read_coef += + l2array[0]->unicache.caches->local_result.power.writeOp.dynamic; + read_coef += + l2array[0]->unicache.missb->local_result.power.searchOp.dynamic; + read_coef += + l2array[0]->unicache.missb->local_result.power.writeOp.dynamic; + read_coef += + l2array[0]->unicache.ifb->local_result.power.searchOp.dynamic; + read_coef += l2array[0]->unicache.ifb->local_result.power.writeOp.dynamic; + read_coef += + l2array[0]->unicache.prefetchb->local_result.power.searchOp.dynamic; + read_coef += + l2array[0]->unicache.prefetchb->local_result.power.writeOp.dynamic; + read_coef += + l2array[0]->unicache.wbb->local_result.power.searchOp.dynamic; + read_coef += l2array[0]->unicache.wbb->local_result.power.writeOp.dynamic; } - double get_coefficient_writecoalescing() - { - double value=0; - double perAccessCoalescingEnergy=COALESCE_SCALE *((0.443e-3)*(0.5e-9)*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd)/(1*1); - value+=(mc->frontend->PRT->local_result.power.writeOp.dynamic); - value+=mc->frontend->threadMasks->local_result.power.writeOp.dynamic; - value+=mc->frontend->PRC->local_result.power.writeOp.dynamic; - value+=perAccessCoalescingEnergy; - return value; - } - - - double get_coefficient_noc_accesses() { - double read_coef=0; - // the 32/4 is applied to the NoC access counters (32/4*L2 cache access) - read_coef+= nocs[0]->router->buffer.power.readOp.dynamic; - read_coef+= nocs[0]->router->buffer.power.writeOp.dynamic; - read_coef+= nocs[0]->router->crossbar.power.readOp.dynamic; - read_coef+= nocs[0]->router->arbiter.power.readOp.dynamic; - return read_coef; - } - - double get_coefficient_l2_read_hits(){ - double read_coef=0; - if(XML->sys.number_of_L2s>0) - read_coef = l2array[0]->unicache.caches->local_result.power.readOp.dynamic; - return read_coef; - } - - double get_coefficient_l2_read_misses(){ - double read_coef=0; - if(XML->sys.number_of_L2s>0) - read_coef = l2array[0]->unicache.caches->local_result.tag_array2->power.readOp.dynamic; - return read_coef; - - } - - double get_coefficient_l2_write_hits(){ - double read_coef=0; - if(XML->sys.number_of_L2s>0) - read_coef = l2array[0]->unicache.caches->local_result.power.writeOp.dynamic; - return read_coef; - - } - double get_coefficient_l2_write_misses(){ - double read_coef=0; - if(XML->sys.number_of_L2s>0){ - read_coef = l2array[0]->unicache.caches->local_result.tag_array2->power.writeOp.dynamic;//*(32/4); // removed by Jingwen, the scaling of 32/4 is not used in the mcpat - read_coef +=l2array[0]->unicache.caches->local_result.power.writeOp.dynamic; - read_coef += l2array[0]->unicache.missb->local_result.power.searchOp.dynamic; - read_coef += l2array[0]->unicache.missb->local_result.power.writeOp.dynamic; - read_coef += l2array[0]->unicache.ifb->local_result.power.searchOp.dynamic; - read_coef += l2array[0]->unicache.ifb->local_result.power.writeOp.dynamic; - read_coef += l2array[0]->unicache.prefetchb->local_result.power.searchOp.dynamic; - read_coef += l2array[0]->unicache.prefetchb->local_result.power.writeOp.dynamic; - read_coef += l2array[0]->unicache.wbb->local_result.power.searchOp.dynamic; - read_coef += l2array[0]->unicache.wbb->local_result.power.writeOp.dynamic; - } - - return read_coef; - - } - - - double get_coefficient_mem_reads() - { - double value=0; - value+= (mc->frontend->mcp.llcBlockSize*8.0/mc->frontend->mcp.dataBusWidth*mc->frontend->mcp.dataBusWidth/72)* - (mc->frontend->frontendBuffer->local_result.power.searchOp.dynamic); - - value+= (mc->frontend->mcp.llcBlockSize*8.0/mc->frontend->mcp.dataBusWidth*mc->frontend->mcp.dataBusWidth/72)* - (mc->frontend->frontendBuffer->local_result.power.readOp.dynamic); - -//TODO: Jingwen this should only compute for one time? - //value+=(mc->frontend->mcp.llcBlockSize*8.0/mc->frontend->mcp.dataBusWidth*mc->frontend->mcp.dataBusWidth/72) - //*(mc->frontend->frontendBuffer->local_result.power.readOp.dynamic); - - value+=(mc->frontend->mcp.llcBlockSize*8.0/mc->mcp.dataBusWidth)* - (mc->frontend->readBuffer->local_result.power.readOp.dynamic); - - value+=(mc->frontend->mcp.llcBlockSize*8.0/mc->mcp.dataBusWidth)* - (mc->frontend->readBuffer->local_result.power.writeOp.dynamic); - - value+=mc->dram->dramp.rd_coeff; - /* - value+=mc->frontend->PRT->local_result.power.readOp.dynamic; - value+=mc->frontend->threadMasks->local_result.power.readOp.dynamic; - value+=mc->frontend->PRC->local_result.power.readOp.dynamic; - value+=perAccessCoalescingEnergy; - */ - value+=(mc->transecEngine->mcp.llcBlockSize*8.0/mc->transecEngine->mcp.dataBusWidth*mc->transecEngine->power_t.readOp.dynamic); - - //if mcp.type ==1 TODO: add this check here - value += (mc->PHY->power_t.readOp.dynamic)*(mc->PHY->mcp.llcBlockSize)*8/1e9/mc->PHY->mcp.executionTime*(mc->PHY->mcp.executionTime); - //printf("MC PHY read power coeff: %f\n",(mc->PHY->power_t.readOp.dynamic)*(mc->PHY->mcp.llcBlockSize)*8/1e9/mc->PHY->mcp.executionTime*(mc->PHY->mcp.executionTime)); - //printf("MC trans read power coeff: %f\n",(mc->transecEngine->mcp.llcBlockSize*8.0/mc->transecEngine->mcp.dataBusWidth*mc->transecEngine->power_t.readOp.dynamic)); - -//TODO: Jingwen nocs stats should not be here -// value+= nocs[0]->router->buffer.power.readOp.dynamic*(32/4); -// value+= nocs[0]->router->buffer.power.writeOp.dynamic*(32/4); -// value+= nocs[0]->router->crossbar.power.readOp.dynamic*(32/4); -// value+= nocs[0]->router->arbiter.power.readOp.dynamic*(32/4); - - //return 0.4*value; - return value; - } - - - double get_coefficient_mem_writes() - { - double value=0; - - value+=(mc->frontend->mcp.llcBlockSize*8.0/mc->frontend->mcp.dataBusWidth*mc->frontend->mcp.dataBusWidth/72)* - (mc->frontend->frontendBuffer->local_result.power.searchOp.dynamic); - - value+=(mc->frontend->mcp.llcBlockSize*8.0/mc->frontend->mcp.dataBusWidth*mc->frontend->mcp.dataBusWidth/72)* - (mc->frontend->frontendBuffer->local_result.power.writeOp.dynamic); - - //value+=(mc->frontend->mcp.llcBlockSize*8.0/mc->frontend->mcp.dataBusWidth*mc->frontend->mcp.dataBusWidth/72)* - // (mc->frontend->frontendBuffer->local_result.power.writeOp.dynamic); - - value+=(mc->frontend->mcp.llcBlockSize*8.0/mc->frontend->mcp.dataBusWidth)* - (mc->frontend->writeBuffer->local_result.power.readOp.dynamic); - - value+=(mc->frontend->mcp.llcBlockSize*8.0/mc->frontend->mcp.dataBusWidth)* - (mc->frontend->writeBuffer->local_result.power.writeOp.dynamic); - - value+=mc->dram->dramp.wr_coeff; - /* - value+=(mc->frontend->PRT->local_result.power.writeOp.dynamic); - - value+=mc->frontend->threadMasks->local_result.power.writeOp.dynamic; - - value+=mc->frontend->PRC->local_result.power.writeOp.dynamic; - - value+=perAccessCoalescingEnergy; - */ - - value+=(mc->transecEngine->mcp.llcBlockSize*8.0/mc->transecEngine->mcp.dataBusWidth*mc->transecEngine->power_t.readOp.dynamic); - - - //if mcp.type ==1 TODO: add this check here - value += (mc->PHY->power_t.readOp.dynamic)*(mc->PHY->mcp.llcBlockSize)*8/1e9/mc->PHY->mcp.executionTime*(mc->PHY->mcp.executionTime); - - -//TODO: Jingwen nocs stats should not be here -// value+= nocs[0]->router->buffer.power.readOp.dynamic*(32/4); -// -// value+= nocs[0]->router->buffer.power.writeOp.dynamic*(32/4); -// -// value+= nocs[0]->router->crossbar.power.readOp.dynamic*(32/4); -// -// value+= nocs[0]->router->arbiter.power.readOp.dynamic*(32/4); -// - //return 0.4*value; - return value; - } - - double get_coefficient_mem_pre() - { - double value=0; - value+=mc->dram->dramp.pre_coeff; - //return 0.4*value; - return value; - - } - - //nonlinear scale - void nonlinear_scale(int, double, int); - void coefficient_scale(); - void iterative_lse(double *, double* ); - ~Processor(); + return read_coef; + } + + double get_coefficient_mem_reads() { + double value = 0; + value += + (mc->frontend->mcp.llcBlockSize * 8.0 / mc->frontend->mcp.dataBusWidth * + mc->frontend->mcp.dataBusWidth / 72) * + (mc->frontend->frontendBuffer->local_result.power.searchOp.dynamic); + + value += + (mc->frontend->mcp.llcBlockSize * 8.0 / mc->frontend->mcp.dataBusWidth * + mc->frontend->mcp.dataBusWidth / 72) * + (mc->frontend->frontendBuffer->local_result.power.readOp.dynamic); + + // TODO: Jingwen this should only compute for one time? + // value+=(mc->frontend->mcp.llcBlockSize*8.0/mc->frontend->mcp.dataBusWidth*mc->frontend->mcp.dataBusWidth/72) + //*(mc->frontend->frontendBuffer->local_result.power.readOp.dynamic); + + value += (mc->frontend->mcp.llcBlockSize * 8.0 / mc->mcp.dataBusWidth) * + (mc->frontend->readBuffer->local_result.power.readOp.dynamic); + + value += (mc->frontend->mcp.llcBlockSize * 8.0 / mc->mcp.dataBusWidth) * + (mc->frontend->readBuffer->local_result.power.writeOp.dynamic); + + value += mc->dram->dramp.rd_coeff; + /* + value+=mc->frontend->PRT->local_result.power.readOp.dynamic; + value+=mc->frontend->threadMasks->local_result.power.readOp.dynamic; + value+=mc->frontend->PRC->local_result.power.readOp.dynamic; + value+=perAccessCoalescingEnergy; + */ + value += (mc->transecEngine->mcp.llcBlockSize * 8.0 / + mc->transecEngine->mcp.dataBusWidth * + mc->transecEngine->power_t.readOp.dynamic); + + // if mcp.type ==1 TODO: add this check here + value += (mc->PHY->power_t.readOp.dynamic) * (mc->PHY->mcp.llcBlockSize) * + 8 / 1e9 / mc->PHY->mcp.executionTime * + (mc->PHY->mcp.executionTime); + // printf("MC PHY read power coeff: + // %f\n",(mc->PHY->power_t.readOp.dynamic)*(mc->PHY->mcp.llcBlockSize)*8/1e9/mc->PHY->mcp.executionTime*(mc->PHY->mcp.executionTime)); + // printf("MC trans read power coeff: + // %f\n",(mc->transecEngine->mcp.llcBlockSize*8.0/mc->transecEngine->mcp.dataBusWidth*mc->transecEngine->power_t.readOp.dynamic)); + + // TODO: Jingwen nocs stats should not be here + // value+= nocs[0]->router->buffer.power.readOp.dynamic*(32/4); + // value+= nocs[0]->router->buffer.power.writeOp.dynamic*(32/4); + // value+= nocs[0]->router->crossbar.power.readOp.dynamic*(32/4); + // value+= nocs[0]->router->arbiter.power.readOp.dynamic*(32/4); + + // return 0.4*value; + return value; + } + + double get_coefficient_mem_writes() { + double value = 0; + + value += + (mc->frontend->mcp.llcBlockSize * 8.0 / mc->frontend->mcp.dataBusWidth * + mc->frontend->mcp.dataBusWidth / 72) * + (mc->frontend->frontendBuffer->local_result.power.searchOp.dynamic); + + value += + (mc->frontend->mcp.llcBlockSize * 8.0 / mc->frontend->mcp.dataBusWidth * + mc->frontend->mcp.dataBusWidth / 72) * + (mc->frontend->frontendBuffer->local_result.power.writeOp.dynamic); + + // value+=(mc->frontend->mcp.llcBlockSize*8.0/mc->frontend->mcp.dataBusWidth*mc->frontend->mcp.dataBusWidth/72)* + // (mc->frontend->frontendBuffer->local_result.power.writeOp.dynamic); + + value += (mc->frontend->mcp.llcBlockSize * 8.0 / + mc->frontend->mcp.dataBusWidth) * + (mc->frontend->writeBuffer->local_result.power.readOp.dynamic); + + value += (mc->frontend->mcp.llcBlockSize * 8.0 / + mc->frontend->mcp.dataBusWidth) * + (mc->frontend->writeBuffer->local_result.power.writeOp.dynamic); + + value += mc->dram->dramp.wr_coeff; + /* + value+=(mc->frontend->PRT->local_result.power.writeOp.dynamic); + + value+=mc->frontend->threadMasks->local_result.power.writeOp.dynamic; + + value+=mc->frontend->PRC->local_result.power.writeOp.dynamic; + + value+=perAccessCoalescingEnergy; + */ + + value += (mc->transecEngine->mcp.llcBlockSize * 8.0 / + mc->transecEngine->mcp.dataBusWidth * + mc->transecEngine->power_t.readOp.dynamic); + + // if mcp.type ==1 TODO: add this check here + value += (mc->PHY->power_t.readOp.dynamic) * (mc->PHY->mcp.llcBlockSize) * + 8 / 1e9 / mc->PHY->mcp.executionTime * + (mc->PHY->mcp.executionTime); + + // TODO: Jingwen nocs stats should not be here + // value+= nocs[0]->router->buffer.power.readOp.dynamic*(32/4); + // + // value+= nocs[0]->router->buffer.power.writeOp.dynamic*(32/4); + // + // value+= nocs[0]->router->crossbar.power.readOp.dynamic*(32/4); + // + // value+= nocs[0]->router->arbiter.power.readOp.dynamic*(32/4); + // + // return 0.4*value; + return value; + } + + double get_coefficient_mem_pre() { + double value = 0; + value += mc->dram->dramp.pre_coeff; + // return 0.4*value; + return value; + } + + // nonlinear scale + void nonlinear_scale(int, double, int); + void coefficient_scale(); + void iterative_lse(double *, double *); + + ~Processor(); }; #endif /* PROCESSOR_H_ */ diff --git a/src/gpuwattch/sharedcache.cc b/src/gpuwattch/sharedcache.cc index 9d4a045..e28202d 100644 --- a/src/gpuwattch/sharedcache.cc +++ b/src/gpuwattch/sharedcache.cc @@ -29,257 +29,263 @@ * ***************************************************************************/ -#include "io.h" -#include "cacti/parameter.h" -#include "array.h" -#include "const.h" -#include "logic.h" -#include "cacti/basic_circuit.h" -#include "cacti/arbiter.h" +#include "sharedcache.h" +#include #include -#include #include -#include "XML_Parse.h" -#include #include -#include -#include "sharedcache.h" - - +#include +#include "XML_Parse.h" +#include "array.h" +#include "cacti/arbiter.h" +#include "cacti/basic_circuit.h" +#include "cacti/parameter.h" +#include "const.h" +#include "io.h" +#include "logic.h" -SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, InputParameter* interface_ip_, enum cache_level cacheL_) -:XML(XML_interface), - ithCache(ithCache_), - interface_ip(*interface_ip_), - cacheL(cacheL_), - dir_overhead(0) -{ +SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, + InputParameter* interface_ip_, + enum cache_level cacheL_) + : XML(XML_interface), + ithCache(ithCache_), + interface_ip(*interface_ip_), + cacheL(cacheL_), + dir_overhead(0) { int idx; int tag, data; - bool debug; + bool debug; enum Device_ty device_t; - enum Core_type core_t; + enum Core_type core_t; double size, line, assoc, banks; - if (cacheL==L2 && XML->sys.Private_L2) - { - device_t=Core_device; - core_t = (enum Core_type)XML->sys.core[ithCache].machine_type; - } - else - { - device_t=LLC_device; - core_t = Inorder; + if (cacheL == L2 && XML->sys.Private_L2) { + device_t = Core_device; + core_t = (enum Core_type)XML->sys.core[ithCache].machine_type; + } else { + device_t = LLC_device; + core_t = Inorder; } - debug = false; - if (XML->sys.Embedded) - { - interface_ip.wt =Global_30; - interface_ip.wire_is_mat_type = 0; - interface_ip.wire_os_mat_type = 1; - } - else - { - interface_ip.wt =Global; - interface_ip.wire_is_mat_type = 2; - interface_ip.wire_os_mat_type = 2; - } - set_cache_param(); - - //All lower level cache are physically indexed and tagged. - size = cachep.capacity; - line = cachep.blockW; - assoc = cachep.assoc; - banks = cachep.nbanks; - if ((cachep.dir_ty==ST&& cacheL==L1Directory)||(cachep.dir_ty==ST&& cacheL==L2Directory)) - { - assoc = 0; - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - interface_ip.num_search_ports = 1; + debug = false; + if (XML->sys.Embedded) { + interface_ip.wt = Global_30; + interface_ip.wire_is_mat_type = 0; + interface_ip.wire_os_mat_type = 1; + } else { + interface_ip.wt = Global; + interface_ip.wire_is_mat_type = 2; + interface_ip.wire_os_mat_type = 2; } - else - { - idx = debug?9:int(ceil(log2(size/line/assoc))); - tag = debug?51:XML->sys.physical_address_width-idx-int(ceil(log2(line))) + EXTRA_TAG_BITS; - interface_ip.num_search_ports = 0; - if (cachep.dir_ty==SBT) - { - dir_overhead = ceil(XML->sys.number_of_cores/8.0)*8/(cachep.blockW*8); - line = cachep.blockW*(1+ dir_overhead) ; - size = cachep.capacity*(1+ dir_overhead); + set_cache_param(); - } + // All lower level cache are physically indexed and tagged. + size = cachep.capacity; + line = cachep.blockW; + assoc = cachep.assoc; + banks = cachep.nbanks; + if ((cachep.dir_ty == ST && cacheL == L1Directory) || + (cachep.dir_ty == ST && cacheL == L2Directory)) { + assoc = 0; + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + interface_ip.num_search_ports = 1; + } else { + idx = debug ? 9 : int(ceil(log2(size / line / assoc))); + tag = debug ? 51 + : XML->sys.physical_address_width - idx - + int(ceil(log2(line))) + EXTRA_TAG_BITS; + interface_ip.num_search_ports = 0; + if (cachep.dir_ty == SBT) { + dir_overhead = + ceil(XML->sys.number_of_cores / 8.0) * 8 / (cachep.blockW * 8); + line = cachep.blockW * (1 + dir_overhead); + size = cachep.capacity * (1 + dir_overhead); + } } -// if (XML->sys.first_level_dir==2) -// tag += int(XML->sys.domain_size + 5); - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.cache_sz = (int)size; - interface_ip.line_sz = (int)line; - interface_ip.assoc = (int)assoc; - interface_ip.nbanks = (int)banks; - interface_ip.out_w = interface_ip.line_sz*8/2; - interface_ip.access_mode = 1; - interface_ip.throughput = cachep.throughput; - interface_ip.latency = cachep.latency; - interface_ip.is_cache = true; - interface_ip.pure_ram = false; - interface_ip.pure_cam = false; + // if (XML->sys.first_level_dir==2) + // tag += int(XML->sys.domain_size + 5); + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.cache_sz = (int)size; + interface_ip.line_sz = (int)line; + interface_ip.assoc = (int)assoc; + interface_ip.nbanks = (int)banks; + interface_ip.out_w = interface_ip.line_sz * 8 / 2; + interface_ip.access_mode = 1; + interface_ip.throughput = cachep.throughput; + interface_ip.latency = cachep.latency; + interface_ip.is_cache = true; + interface_ip.pure_ram = false; + interface_ip.pure_cam = false; interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1;//lower level cache usually has one port. - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; -// interface_ip.force_cache_config =true; -// interface_ip.ndwl = 4; -// interface_ip.ndbl = 8; -// interface_ip.nspd = 1; -// interface_ip.ndcm =1 ; -// interface_ip.ndsam1 =1; -// interface_ip.ndsam2 =1; - unicache.caches = new ArrayST(&interface_ip, cachep.name + "cache", device_t, true, core_t); - unicache.area.set_area(unicache.area.get_area()+ unicache.caches->local_result.area); - area.set_area(area.get_area()+ unicache.caches->local_result.area); - interface_ip.force_cache_config =false; - + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1; // lower level cache usually has one port. + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + // interface_ip.force_cache_config =true; + // interface_ip.ndwl = 4; + // interface_ip.ndbl = 8; + // interface_ip.nspd = 1; + // interface_ip.ndcm =1 ; + // interface_ip.ndsam1 =1; + // interface_ip.ndsam2 =1; + unicache.caches = + new ArrayST(&interface_ip, cachep.name + "cache", device_t, true, core_t); + unicache.area.set_area(unicache.area.get_area() + + unicache.caches->local_result.area); + area.set_area(area.get_area() + unicache.caches->local_result.area); + interface_ip.force_cache_config = false; - if (!((cachep.dir_ty==ST&& cacheL==L1Directory)||(cachep.dir_ty==ST&& cacheL==L2Directory))) - { - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = (XML->sys.physical_address_width) + int(ceil(log2(size/line))) + unicache.caches->l_ip.line_sz; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = int(ceil(data/8.0));//int(ceil(pow(2.0,ceil(log2(data)))/8.0)); - interface_ip.cache_sz = cachep.missb_size*interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.is_cache = true; - interface_ip.pure_ram = false; - interface_ip.pure_cam = false; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8/2; - interface_ip.access_mode = 0; - interface_ip.throughput = cachep.throughput;//means cycle time - interface_ip.latency = cachep.latency;//means access time - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - interface_ip.num_search_ports = 1; - unicache.missb = new ArrayST(&interface_ip, cachep.name + "MissB", device_t, true, core_t); - unicache.area.set_area(unicache.area.get_area()+ unicache.missb->local_result.area); - area.set_area(area.get_area()+ unicache.missb->local_result.area); - //fill buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = unicache.caches->l_ip.line_sz; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); - interface_ip.cache_sz = data*cachep.fu_size ; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8/2; - interface_ip.access_mode = 0; - interface_ip.throughput = cachep.throughput; - interface_ip.latency = cachep.latency; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - unicache.ifb = new ArrayST(&interface_ip, cachep.name + "FillB", device_t, true, core_t); - unicache.area.set_area(unicache.area.get_area()+ unicache.ifb->local_result.area); - area.set_area(area.get_area()+ unicache.ifb->local_result.area); - //prefetch buffer - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS;//check with previous entries to decide wthether to merge. - data = unicache.caches->l_ip.line_sz;//separate queue to prevent from cache polution. - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); - interface_ip.cache_sz = cachep.prefetchb_size*interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8/2; - interface_ip.access_mode = 0; - interface_ip.throughput = cachep.throughput; - interface_ip.latency = cachep.latency; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - unicache.prefetchb = new ArrayST(&interface_ip, cachep.name + "PrefetchB", device_t, true, core_t); - unicache.area.set_area(unicache.area.get_area()+ unicache.prefetchb->local_result.area); - area.set_area(area.get_area()+ unicache.prefetchb->local_result.area); - //WBB - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = unicache.caches->l_ip.line_sz; - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data; - interface_ip.cache_sz = cachep.wbb_size*interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8/2; - interface_ip.access_mode = 0; - interface_ip.throughput = cachep.throughput; - interface_ip.latency = cachep.latency; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - unicache.wbb = new ArrayST(&interface_ip, cachep.name + "WBB", device_t, true, core_t); - unicache.area.set_area(unicache.area.get_area()+ unicache.wbb->local_result.area); - area.set_area(area.get_area()+ unicache.wbb->local_result.area); + if (!((cachep.dir_ty == ST && cacheL == L1Directory) || + (cachep.dir_ty == ST && cacheL == L2Directory))) { + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = (XML->sys.physical_address_width) + int(ceil(log2(size / line))) + + unicache.caches->l_ip.line_sz; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = + int(ceil(data / 8.0)); // int(ceil(pow(2.0,ceil(log2(data)))/8.0)); + interface_ip.cache_sz = cachep.missb_size * interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.is_cache = true; + interface_ip.pure_ram = false; + interface_ip.pure_cam = false; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8 / 2; + interface_ip.access_mode = 0; + interface_ip.throughput = cachep.throughput; // means cycle time + interface_ip.latency = cachep.latency; // means access time + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + interface_ip.num_search_ports = 1; + unicache.missb = new ArrayST(&interface_ip, cachep.name + "MissB", device_t, + true, core_t); + unicache.area.set_area(unicache.area.get_area() + + unicache.missb->local_result.area); + area.set_area(area.get_area() + unicache.missb->local_result.area); + // fill buffer + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = unicache.caches->l_ip.line_sz; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data; // int(pow(2.0,ceil(log2(data)))); + interface_ip.cache_sz = data * cachep.fu_size; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8 / 2; + interface_ip.access_mode = 0; + interface_ip.throughput = cachep.throughput; + interface_ip.latency = cachep.latency; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + unicache.ifb = new ArrayST(&interface_ip, cachep.name + "FillB", device_t, + true, core_t); + unicache.area.set_area(unicache.area.get_area() + + unicache.ifb->local_result.area); + area.set_area(area.get_area() + unicache.ifb->local_result.area); + // prefetch buffer + tag = XML->sys.physical_address_width + + EXTRA_TAG_BITS; // check with previous entries to decide wthether to + // merge. + data = unicache.caches->l_ip + .line_sz; // separate queue to prevent from cache polution. + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data; // int(pow(2.0,ceil(log2(data)))); + interface_ip.cache_sz = cachep.prefetchb_size * interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8 / 2; + interface_ip.access_mode = 0; + interface_ip.throughput = cachep.throughput; + interface_ip.latency = cachep.latency; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + unicache.prefetchb = new ArrayST(&interface_ip, cachep.name + "PrefetchB", + device_t, true, core_t); + unicache.area.set_area(unicache.area.get_area() + + unicache.prefetchb->local_result.area); + area.set_area(area.get_area() + unicache.prefetchb->local_result.area); + // WBB + tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = unicache.caches->l_ip.line_sz; + interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data; + interface_ip.cache_sz = cachep.wbb_size * interface_ip.line_sz; + interface_ip.assoc = 0; + interface_ip.nbanks = 1; + interface_ip.out_w = interface_ip.line_sz * 8 / 2; + interface_ip.access_mode = 0; + interface_ip.throughput = cachep.throughput; + interface_ip.latency = cachep.latency; + interface_ip.obj_func_dyn_energy = 0; + interface_ip.obj_func_dyn_power = 0; + interface_ip.obj_func_leak_power = 0; + interface_ip.obj_func_cycle_t = 1; + interface_ip.num_rw_ports = 1; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + unicache.wbb = + new ArrayST(&interface_ip, cachep.name + "WBB", device_t, true, core_t); + unicache.area.set_area(unicache.area.get_area() + + unicache.wbb->local_result.area); + area.set_area(area.get_area() + unicache.wbb->local_result.area); } // //pipeline -// interface_ip.pipeline_stages = int(ceil(llCache.caches.local_result.access_time/llCache.caches.local_result.cycle_time)); -// interface_ip.per_stage_vector = llCache.caches.l_ip.out_w + llCache.caches.l_ip.tag_w ; -// pipeLogicCache.init_pipeline(is_default, &interface_ip); -// pipeLogicCache.compute_pipeline(); + // interface_ip.pipeline_stages = + // int(ceil(llCache.caches.local_result.access_time/llCache.caches.local_result.cycle_time)); + // interface_ip.per_stage_vector = llCache.caches.l_ip.out_w + + // llCache.caches.l_ip.tag_w ; pipeLogicCache.init_pipeline(is_default, + // &interface_ip); pipeLogicCache.compute_pipeline(); /* if (!((XML->sys.number_of_dir_levels==1 && XML->sys.first_level_dir ==1) - ||(XML->sys.number_of_dir_levels==1 && XML->sys.first_level_dir ==2)))//not single level IC and DIC + ||(XML->sys.number_of_dir_levels==1 && + XML->sys.first_level_dir ==2)))//not single level IC and DIC { //directory Now assuming one directory per bank, TODO:should change it later size = XML->sys.L2directory.L2Dir_config[0]; line = XML->sys.L2directory.L2Dir_config[1]; assoc = XML->sys.L2directory.L2Dir_config[2]; banks = XML->sys.L2directory.L2Dir_config[3]; - tag = debug?51:XML->sys.physical_address_width + EXTRA_TAG_BITS;//TODO: a little bit over estimate - interface_ip.specific_tag = 0; - interface_ip.tag_w = tag; + tag = + debug?51:XML->sys.physical_address_width + EXTRA_TAG_BITS;//TODO: a little bit + over estimate interface_ip.specific_tag = 0; interface_ip.tag_w = tag; interface_ip.cache_sz = XML->sys.L2directory.L2Dir_config[0]; interface_ip.line_sz = XML->sys.L2directory.L2Dir_config[1]; interface_ip.assoc = XML->sys.L2directory.L2Dir_config[2]; interface_ip.nbanks = XML->sys.L2directory.L2Dir_config[3]; interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 0;//debug?0:XML->sys.core[ithCore].icache.icache_config[5]; - interface_ip.throughput = XML->sys.L2directory.L2Dir_config[4]/clockRate; - interface_ip.latency = XML->sys.L2directory.L2Dir_config[5]/clockRate; - interface_ip.is_cache = true; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1;//lower level cache usually has one port. + interface_ip.access_mode = + 0;//debug?0:XML->sys.core[ithCore].icache.icache_config[5]; + interface_ip.throughput = + XML->sys.L2directory.L2Dir_config[4]/clockRate; interface_ip.latency = + XML->sys.L2directory.L2Dir_config[5]/clockRate; interface_ip.is_cache + = true; interface_ip.obj_func_dyn_energy = 0; interface_ip.obj_func_dyn_power + = 0; interface_ip.obj_func_leak_power = 0; interface_ip.obj_func_cycle_t = + 1; interface_ip.num_rw_ports = 1;//lower level cache usually has one port. interface_ip.num_rd_ports = 0; interface_ip.num_wr_ports = 0; interface_ip.num_se_rd_ports = 0; @@ -291,21 +297,27 @@ SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, InputParameter* //output_data_csv(directory.caches.local_result); ///cout<<"area="<sys.physical_address_width + EXTRA_TAG_BITS; - data = (XML->sys.physical_address_width) + int(ceil(log2(size/line))) + directory.caches.l_ip.line_sz; - interface_ip.specific_tag = 1; + //miss buffer Each MSHR contains enough state to handle one or more accesses + of any type to a single memory line. + //Due to the generality of the MSHR mechanism, the amount of state involved is + non-trivial, + //including the address, pointers to the cache entry and destination register, + written data, and various other pieces of state. tag + = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = + (XML->sys.physical_address_width) + int(ceil(log2(size/line))) + + directory.caches.l_ip.line_sz; interface_ip.specific_tag = 1; interface_ip.tag_w = tag; - interface_ip.line_sz = int(ceil(data/8.0));//int(ceil(pow(2.0,ceil(log2(data)))/8.0)); - interface_ip.cache_sz = XML->sys.L2[ithCache].buffer_sizes[0]*interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 0; - interface_ip.throughput = XML->sys.L2[ithCache].L2_config[4]/clockRate;//means cycle time - interface_ip.latency = XML->sys.L2[ithCache].L2_config[5]/clockRate;//means access time + interface_ip.line_sz = + int(ceil(data/8.0));//int(ceil(pow(2.0,ceil(log2(data)))/8.0)); + interface_ip.cache_sz = + XML->sys.L2[ithCache].buffer_sizes[0]*interface_ip.line_sz; interface_ip.assoc + = 0; interface_ip.nbanks = 1; interface_ip.out_w = + interface_ip.line_sz*8; interface_ip.access_mode = 0; + interface_ip.throughput = + XML->sys.L2[ithCache].L2_config[4]/clockRate;//means cycle time + interface_ip.latency = + XML->sys.L2[ithCache].L2_config[5]/clockRate;//means access time interface_ip.obj_func_dyn_energy = 0; interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = 0; @@ -322,9 +334,9 @@ SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, InputParameter* ///cout<<"area="<sys.physical_address_width + EXTRA_TAG_BITS; - data = directory.caches.l_ip.line_sz; - interface_ip.specific_tag = 1; + tag = + XML->sys.physical_address_width + EXTRA_TAG_BITS; data + = directory.caches.l_ip.line_sz; interface_ip.specific_tag = 1; interface_ip.tag_w = tag; interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); interface_ip.cache_sz = data*XML->sys.L2[ithCache].buffer_sizes[1]; @@ -332,13 +344,11 @@ SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, InputParameter* interface_ip.nbanks = 1; interface_ip.out_w = interface_ip.line_sz*8; interface_ip.access_mode = 0; - interface_ip.throughput = XML->sys.L2[ithCache].L2_config[4]/clockRate; - interface_ip.latency = XML->sys.L2[ithCache].L2_config[5]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; + interface_ip.throughput = + XML->sys.L2[ithCache].L2_config[4]/clockRate; interface_ip.latency = + XML->sys.L2[ithCache].L2_config[5]/clockRate; interface_ip.obj_func_dyn_energy + = 0; interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = + 0; interface_ip.obj_func_cycle_t = 1; interface_ip.num_rw_ports = 1; interface_ip.num_rd_ports = 0; interface_ip.num_wr_ports = 0; interface_ip.num_se_rd_ports = 0; @@ -350,23 +360,23 @@ SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, InputParameter* ///cout<<"area="<sys.physical_address_width + EXTRA_TAG_BITS;//check with previous entries to decide wthether to merge. - data = directory.caches.l_ip.line_sz;//separate queue to prevent from cache polution. + tag = + XML->sys.physical_address_width + EXTRA_TAG_BITS;//check with previous entries + to decide wthether to merge. + data = + directory.caches.l_ip.line_sz;//separate queue to prevent from cache polution. interface_ip.specific_tag = 1; interface_ip.tag_w = tag; interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); - interface_ip.cache_sz = XML->sys.L2[ithCache].buffer_sizes[2]*interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 0; - interface_ip.throughput = XML->sys.L2[ithCache].L2_config[4]/clockRate; - interface_ip.latency = XML->sys.L2[ithCache].L2_config[5]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; + interface_ip.cache_sz = + XML->sys.L2[ithCache].buffer_sizes[2]*interface_ip.line_sz; interface_ip.assoc + = 0; interface_ip.nbanks = 1; interface_ip.out_w = + interface_ip.line_sz*8; interface_ip.access_mode = 0; + interface_ip.throughput = + XML->sys.L2[ithCache].L2_config[4]/clockRate; interface_ip.latency = + XML->sys.L2[ithCache].L2_config[5]/clockRate; interface_ip.obj_func_dyn_energy + = 0; interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = + 0; interface_ip.obj_func_cycle_t = 1; interface_ip.num_rw_ports = 1; interface_ip.num_rd_ports = 0; interface_ip.num_wr_ports = 0; interface_ip.num_se_rd_ports = 0; @@ -378,23 +388,20 @@ SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, InputParameter* ///cout<<"area="<sys.physical_address_width + EXTRA_TAG_BITS; - data = directory.caches.l_ip.line_sz; - interface_ip.specific_tag = 1; + tag = + XML->sys.physical_address_width + EXTRA_TAG_BITS; data + = directory.caches.l_ip.line_sz; interface_ip.specific_tag = 1; interface_ip.tag_w = tag; interface_ip.line_sz = data; - interface_ip.cache_sz = XML->sys.L2[ithCache].buffer_sizes[3]*interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 0; - interface_ip.throughput = XML->sys.L2[ithCache].L2_config[4]/clockRate; - interface_ip.latency = XML->sys.L2[ithCache].L2_config[4]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; + interface_ip.cache_sz = + XML->sys.L2[ithCache].buffer_sizes[3]*interface_ip.line_sz; interface_ip.assoc + = 0; interface_ip.nbanks = 1; interface_ip.out_w = + interface_ip.line_sz*8; interface_ip.access_mode = 0; + interface_ip.throughput = + XML->sys.L2[ithCache].L2_config[4]/clockRate; interface_ip.latency = + XML->sys.L2[ithCache].L2_config[4]/clockRate; interface_ip.obj_func_dyn_energy + = 0; interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = + 0; interface_ip.obj_func_cycle_t = 1; interface_ip.num_rw_ports = 1; interface_ip.num_rd_ports = 0; interface_ip.num_wr_ports = 0; interface_ip.num_se_rd_ports = 0; @@ -407,27 +414,26 @@ SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, InputParameter* if (XML->sys.number_of_dir_levels ==2 && XML->sys.first_level_dir==0) { //first level directory - size = XML->sys.L2directory.L2Dir_config[0]*XML->sys.domain_size/128; - line = int(ceil(XML->sys.domain_size/8.0)); - assoc = XML->sys.L2directory.L2Dir_config[2]; - banks = XML->sys.L2directory.L2Dir_config[3]; - tag = debug?51:XML->sys.physical_address_width + EXTRA_TAG_BITS;//TODO: a little bit over estimate - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.cache_sz = XML->sys.L2directory.L2Dir_config[0]; + size = + XML->sys.L2directory.L2Dir_config[0]*XML->sys.domain_size/128; line = + int(ceil(XML->sys.domain_size/8.0)); assoc = + XML->sys.L2directory.L2Dir_config[2]; banks = + XML->sys.L2directory.L2Dir_config[3]; tag + = debug?51:XML->sys.physical_address_width + EXTRA_TAG_BITS;//TODO: a little + bit over estimate interface_ip.specific_tag = 1; interface_ip.tag_w = + tag; interface_ip.cache_sz = XML->sys.L2directory.L2Dir_config[0]; interface_ip.line_sz = XML->sys.L2directory.L2Dir_config[1]; interface_ip.assoc = XML->sys.L2directory.L2Dir_config[2]; interface_ip.nbanks = XML->sys.L2directory.L2Dir_config[3]; interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 0;//debug?0:XML->sys.core[ithCore].icache.icache_config[5]; - interface_ip.throughput = XML->sys.L2directory.L2Dir_config[4]/clockRate; - interface_ip.latency = XML->sys.L2directory.L2Dir_config[5]/clockRate; - interface_ip.is_cache = true; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1;//lower level cache usually has one port. + interface_ip.access_mode = + 0;//debug?0:XML->sys.core[ithCore].icache.icache_config[5]; + interface_ip.throughput = + XML->sys.L2directory.L2Dir_config[4]/clockRate; interface_ip.latency = + XML->sys.L2directory.L2Dir_config[5]/clockRate; interface_ip.is_cache + = true; interface_ip.obj_func_dyn_energy = 0; interface_ip.obj_func_dyn_power + = 0; interface_ip.obj_func_leak_power = 0; interface_ip.obj_func_cycle_t = + 1; interface_ip.num_rw_ports = 1;//lower level cache usually has one port. interface_ip.num_rd_ports = 0; interface_ip.num_wr_ports = 0; interface_ip.num_se_rd_ports = 0; @@ -439,21 +445,27 @@ SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, InputParameter* //output_data_csv(directory.caches.local_result); ///cout<<"area="<sys.physical_address_width + EXTRA_TAG_BITS; - data = (XML->sys.physical_address_width) + int(ceil(log2(size/line))) + directory1.caches.l_ip.line_sz; - interface_ip.specific_tag = 1; + //miss buffer Each MSHR contains enough state to handle one or more accesses + of any type to a single memory line. + //Due to the generality of the MSHR mechanism, the amount of state involved is + non-trivial, + //including the address, pointers to the cache entry and destination register, + written data, and various other pieces of state. tag + = XML->sys.physical_address_width + EXTRA_TAG_BITS; + data = + (XML->sys.physical_address_width) + int(ceil(log2(size/line))) + + directory1.caches.l_ip.line_sz; interface_ip.specific_tag = 1; interface_ip.tag_w = tag; - interface_ip.line_sz = int(ceil(data/8.0));//int(ceil(pow(2.0,ceil(log2(data)))/8.0)); - interface_ip.cache_sz = XML->sys.L2[ithCache].buffer_sizes[0]*interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 0; - interface_ip.throughput = XML->sys.L2[ithCache].L2_config[4]/clockRate;//means cycle time - interface_ip.latency = XML->sys.L2[ithCache].L2_config[5]/clockRate;//means access time + interface_ip.line_sz = + int(ceil(data/8.0));//int(ceil(pow(2.0,ceil(log2(data)))/8.0)); + interface_ip.cache_sz = + XML->sys.L2[ithCache].buffer_sizes[0]*interface_ip.line_sz; interface_ip.assoc + = 0; interface_ip.nbanks = 1; interface_ip.out_w = + interface_ip.line_sz*8; interface_ip.access_mode = 0; + interface_ip.throughput = + XML->sys.L2[ithCache].L2_config[4]/clockRate;//means cycle time + interface_ip.latency = + XML->sys.L2[ithCache].L2_config[5]/clockRate;//means access time interface_ip.obj_func_dyn_energy = 0; interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = 0; @@ -470,9 +482,9 @@ SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, InputParameter* ///cout<<"area="<sys.physical_address_width + EXTRA_TAG_BITS; - data = directory1.caches.l_ip.line_sz; - interface_ip.specific_tag = 1; + tag = + XML->sys.physical_address_width + EXTRA_TAG_BITS; data + = directory1.caches.l_ip.line_sz; interface_ip.specific_tag = 1; interface_ip.tag_w = tag; interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); interface_ip.cache_sz = data*XML->sys.L2[ithCache].buffer_sizes[1]; @@ -480,13 +492,11 @@ SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, InputParameter* interface_ip.nbanks = 1; interface_ip.out_w = interface_ip.line_sz*8; interface_ip.access_mode = 0; - interface_ip.throughput = XML->sys.L2[ithCache].L2_config[4]/clockRate; - interface_ip.latency = XML->sys.L2[ithCache].L2_config[5]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; + interface_ip.throughput = + XML->sys.L2[ithCache].L2_config[4]/clockRate; interface_ip.latency = + XML->sys.L2[ithCache].L2_config[5]/clockRate; interface_ip.obj_func_dyn_energy + = 0; interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = + 0; interface_ip.obj_func_cycle_t = 1; interface_ip.num_rw_ports = 1; interface_ip.num_rd_ports = 0; interface_ip.num_wr_ports = 0; interface_ip.num_se_rd_ports = 0; @@ -498,23 +508,22 @@ SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, InputParameter* ///cout<<"area="<sys.physical_address_width + EXTRA_TAG_BITS;//check with previous entries to decide wthether to merge. - data = directory1.caches.l_ip.line_sz;//separate queue to prevent from cache polution. - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; + tag = + XML->sys.physical_address_width + EXTRA_TAG_BITS;//check with previous entries + to decide wthether to merge. + data = + directory1.caches.l_ip.line_sz;//separate queue to prevent from cache + polution. interface_ip.specific_tag = 1; interface_ip.tag_w = tag; interface_ip.line_sz = data;//int(pow(2.0,ceil(log2(data)))); - interface_ip.cache_sz = XML->sys.L2[ithCache].buffer_sizes[2]*interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 0; - interface_ip.throughput = XML->sys.L2[ithCache].L2_config[4]/clockRate; - interface_ip.latency = XML->sys.L2[ithCache].L2_config[5]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; + interface_ip.cache_sz = + XML->sys.L2[ithCache].buffer_sizes[2]*interface_ip.line_sz; interface_ip.assoc + = 0; interface_ip.nbanks = 1; interface_ip.out_w = + interface_ip.line_sz*8; interface_ip.access_mode = 0; + interface_ip.throughput = + XML->sys.L2[ithCache].L2_config[4]/clockRate; interface_ip.latency = + XML->sys.L2[ithCache].L2_config[5]/clockRate; interface_ip.obj_func_dyn_energy + = 0; interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = + 0; interface_ip.obj_func_cycle_t = 1; interface_ip.num_rw_ports = 1; interface_ip.num_rd_ports = 0; interface_ip.num_wr_ports = 0; interface_ip.num_se_rd_ports = 0; @@ -526,23 +535,20 @@ SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, InputParameter* ///cout<<"area="<sys.physical_address_width + EXTRA_TAG_BITS; - data = directory1.caches.l_ip.line_sz; - interface_ip.specific_tag = 1; + tag = + XML->sys.physical_address_width + EXTRA_TAG_BITS; data + = directory1.caches.l_ip.line_sz; interface_ip.specific_tag = 1; interface_ip.tag_w = tag; interface_ip.line_sz = data; - interface_ip.cache_sz = XML->sys.L2[ithCache].buffer_sizes[3]*interface_ip.line_sz; - interface_ip.assoc = 0; - interface_ip.nbanks = 1; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 0; - interface_ip.throughput = XML->sys.L2[ithCache].L2_config[4]/clockRate; - interface_ip.latency = XML->sys.L2[ithCache].L2_config[5]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; + interface_ip.cache_sz = + XML->sys.L2[ithCache].buffer_sizes[3]*interface_ip.line_sz; interface_ip.assoc + = 0; interface_ip.nbanks = 1; interface_ip.out_w = + interface_ip.line_sz*8; interface_ip.access_mode = 0; + interface_ip.throughput = + XML->sys.L2[ithCache].L2_config[4]/clockRate; interface_ip.latency = + XML->sys.L2[ithCache].L2_config[5]/clockRate; interface_ip.obj_func_dyn_energy + = 0; interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = + 0; interface_ip.obj_func_cycle_t = 1; interface_ip.num_rw_ports = 1; interface_ip.num_rd_ports = 0; interface_ip.num_wr_ports = 0; interface_ip.num_se_rd_ports = 0; @@ -554,357 +560,462 @@ SharedCache::SharedCache(ParseXML* XML_interface, int ithCache_, InputParameter* if (XML->sys.first_level_dir==1)//IC { - tag = XML->sys.physical_address_width + EXTRA_TAG_BITS; - data = int(ceil(XML->sys.domain_size/8.0)); - interface_ip.specific_tag = 1; - interface_ip.tag_w = tag; - interface_ip.line_sz = data; - interface_ip.cache_sz = XML->sys.domain_size*data*XML->sys.L2[ithCache].L2_config[0]/XML->sys.L2[ithCache].L2_config[1]; - interface_ip.assoc = 0; - interface_ip.nbanks = 1024; - interface_ip.out_w = interface_ip.line_sz*8; - interface_ip.access_mode = 0; - interface_ip.throughput = XML->sys.L2[ithCache].L2_config[4]/clockRate; - interface_ip.latency = XML->sys.L2[ithCache].L2_config[5]/clockRate; - interface_ip.obj_func_dyn_energy = 0; - interface_ip.obj_func_dyn_power = 0; - interface_ip.obj_func_leak_power = 0; - interface_ip.obj_func_cycle_t = 1; - interface_ip.num_rw_ports = 1; - interface_ip.num_rd_ports = 0; - interface_ip.num_wr_ports = 0; - interface_ip.num_se_rd_ports = 0; - strcpy(inv_dir.caches.name,"inv_dir"); - inv_dir.caches.init_cache(&interface_ip); - inv_dir.caches.optimize_array(); - inv_dir.area = inv_dir.caches.local_result.area; + tag = + XML->sys.physical_address_width + EXTRA_TAG_BITS; data + = int(ceil(XML->sys.domain_size/8.0)); interface_ip.specific_tag = 1; + interface_ip.tag_w = tag; + interface_ip.line_sz = data; + interface_ip.cache_sz = + XML->sys.domain_size*data*XML->sys.L2[ithCache].L2_config[0]/XML->sys.L2[ithCache].L2_config[1]; + interface_ip.assoc = 0; + interface_ip.nbanks = 1024; + interface_ip.out_w = interface_ip.line_sz*8; + interface_ip.access_mode = 0; + interface_ip.throughput = + XML->sys.L2[ithCache].L2_config[4]/clockRate; interface_ip.latency = + XML->sys.L2[ithCache].L2_config[5]/clockRate; interface_ip.obj_func_dyn_energy + = 0; interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = + 0; interface_ip.obj_func_cycle_t = 1; interface_ip.num_rw_ports = 1; + interface_ip.num_rd_ports = 0; + interface_ip.num_wr_ports = 0; + interface_ip.num_se_rd_ports = 0; + strcpy(inv_dir.caches.name,"inv_dir"); + inv_dir.caches.init_cache(&interface_ip); + inv_dir.caches.optimize_array(); + inv_dir.area = inv_dir.caches.local_result.area; } */ -// //pipeline -// interface_ip.pipeline_stages = int(ceil(directory.caches.local_result.access_time/directory.caches.local_result.cycle_time)); -// interface_ip.per_stage_vector = directory.caches.l_ip.out_w + directory.caches.l_ip.tag_w ; -// pipeLogicDirectory.init_pipeline(is_default, &interface_ip); -// pipeLogicDirectory.compute_pipeline(); -// -// //clock power -// clockNetwork.init_wire_external(is_default, &interface_ip); -// clockNetwork.clk_area =area*1.1;//10% of placement overhead. rule of thumb -// clockNetwork.end_wiring_level =5;//toplevel metal -// clockNetwork.start_wiring_level =5;//toplevel metal -// clockNetwork.num_regs = pipeLogicCache.tot_stage_vector + pipeLogicDirectory.tot_stage_vector; -// clockNetwork.optimize_wire(); - + // //pipeline + // interface_ip.pipeline_stages = + // int(ceil(directory.caches.local_result.access_time/directory.caches.local_result.cycle_time)); + // interface_ip.per_stage_vector = directory.caches.l_ip.out_w + + // directory.caches.l_ip.tag_w ; pipeLogicDirectory.init_pipeline(is_default, + // &interface_ip); pipeLogicDirectory.compute_pipeline(); + // + // //clock power + // clockNetwork.init_wire_external(is_default, &interface_ip); + // clockNetwork.clk_area =area*1.1;//10% of placement overhead. + // rule of thumb clockNetwork.end_wiring_level =5;//toplevel metal + // clockNetwork.start_wiring_level =5;//toplevel metal + // clockNetwork.num_regs = pipeLogicCache.tot_stage_vector + + // pipeLogicDirectory.tot_stage_vector; clockNetwork.optimize_wire(); } +void SharedCache::computeEnergy(bool is_tdp) { + double homenode_data_access = (cachep.dir_ty == SBT) ? 0.9 : 1.0; + if (is_tdp) { + if (!((cachep.dir_ty == ST && cacheL == L1Directory) || + (cachep.dir_ty == ST && cacheL == L2Directory))) { + // init stats for Peak + unicache.caches->stats_t.readAc.access = + .67 * unicache.caches->l_ip.num_rw_ports * cachep.duty_cycle * + homenode_data_access; + unicache.caches->stats_t.readAc.miss = 0; + unicache.caches->stats_t.readAc.hit = + unicache.caches->stats_t.readAc.access - + unicache.caches->stats_t.readAc.miss; + unicache.caches->stats_t.writeAc.access = + .33 * unicache.caches->l_ip.num_rw_ports * cachep.duty_cycle * + homenode_data_access; + unicache.caches->stats_t.writeAc.miss = 0; + unicache.caches->stats_t.writeAc.hit = + unicache.caches->stats_t.writeAc.access - + unicache.caches->stats_t.writeAc.miss; + unicache.caches->tdp_stats = unicache.caches->stats_t; -void SharedCache::computeEnergy(bool is_tdp) -{ - double homenode_data_access = (cachep.dir_ty==SBT)? 0.9:1.0; - if (is_tdp) - { - if (!((cachep.dir_ty==ST&& cacheL==L1Directory)||(cachep.dir_ty==ST&& cacheL==L2Directory))) - { - //init stats for Peak - unicache.caches->stats_t.readAc.access = .67*unicache.caches->l_ip.num_rw_ports*cachep.duty_cycle*homenode_data_access; - unicache.caches->stats_t.readAc.miss = 0; - unicache.caches->stats_t.readAc.hit = unicache.caches->stats_t.readAc.access - unicache.caches->stats_t.readAc.miss; - unicache.caches->stats_t.writeAc.access = .33*unicache.caches->l_ip.num_rw_ports*cachep.duty_cycle*homenode_data_access; - unicache.caches->stats_t.writeAc.miss = 0; - unicache.caches->stats_t.writeAc.hit = unicache.caches->stats_t.writeAc.access - unicache.caches->stats_t.writeAc.miss; - unicache.caches->tdp_stats = unicache.caches->stats_t; - - if (cachep.dir_ty==SBT) - { - homenode_stats_t.readAc.access = .67*unicache.caches->l_ip.num_rw_ports*cachep.dir_duty_cycle*(1-homenode_data_access); - homenode_stats_t.readAc.miss = 0; - homenode_stats_t.readAc.hit = homenode_stats_t.readAc.access - homenode_stats_t.readAc.miss; - homenode_stats_t.writeAc.access = .67*unicache.caches->l_ip.num_rw_ports*cachep.dir_duty_cycle*(1-homenode_data_access); - homenode_stats_t.writeAc.miss = 0; - homenode_stats_t.writeAc.hit = homenode_stats_t.writeAc.access - homenode_stats_t.writeAc.miss; - homenode_tdp_stats = homenode_stats_t; - } + if (cachep.dir_ty == SBT) { + homenode_stats_t.readAc.access = + .67 * unicache.caches->l_ip.num_rw_ports * cachep.dir_duty_cycle * + (1 - homenode_data_access); + homenode_stats_t.readAc.miss = 0; + homenode_stats_t.readAc.hit = + homenode_stats_t.readAc.access - homenode_stats_t.readAc.miss; + homenode_stats_t.writeAc.access = + .67 * unicache.caches->l_ip.num_rw_ports * cachep.dir_duty_cycle * + (1 - homenode_data_access); + homenode_stats_t.writeAc.miss = 0; + homenode_stats_t.writeAc.hit = + homenode_stats_t.writeAc.access - homenode_stats_t.writeAc.miss; + homenode_tdp_stats = homenode_stats_t; + } - unicache.missb->stats_t.readAc.access = unicache.missb->l_ip.num_search_ports; - unicache.missb->stats_t.writeAc.access = unicache.missb->l_ip.num_search_ports; - unicache.missb->tdp_stats = unicache.missb->stats_t; + unicache.missb->stats_t.readAc.access = + unicache.missb->l_ip.num_search_ports; + unicache.missb->stats_t.writeAc.access = + unicache.missb->l_ip.num_search_ports; + unicache.missb->tdp_stats = unicache.missb->stats_t; - unicache.ifb->stats_t.readAc.access = unicache.ifb->l_ip.num_search_ports; - unicache.ifb->stats_t.writeAc.access = unicache.ifb->l_ip.num_search_ports; - unicache.ifb->tdp_stats = unicache.ifb->stats_t; + unicache.ifb->stats_t.readAc.access = unicache.ifb->l_ip.num_search_ports; + unicache.ifb->stats_t.writeAc.access = + unicache.ifb->l_ip.num_search_ports; + unicache.ifb->tdp_stats = unicache.ifb->stats_t; - unicache.prefetchb->stats_t.readAc.access = unicache.prefetchb->l_ip.num_search_ports; - unicache.prefetchb->stats_t.writeAc.access = unicache.ifb->l_ip.num_search_ports; - unicache.prefetchb->tdp_stats = unicache.prefetchb->stats_t; + unicache.prefetchb->stats_t.readAc.access = + unicache.prefetchb->l_ip.num_search_ports; + unicache.prefetchb->stats_t.writeAc.access = + unicache.ifb->l_ip.num_search_ports; + unicache.prefetchb->tdp_stats = unicache.prefetchb->stats_t; - unicache.wbb->stats_t.readAc.access = unicache.wbb->l_ip.num_search_ports; - unicache.wbb->stats_t.writeAc.access = unicache.wbb->l_ip.num_search_ports; - unicache.wbb->tdp_stats = unicache.wbb->stats_t; - } - else - { - unicache.caches->stats_t.readAc.access = unicache.caches->l_ip.num_search_ports*cachep.duty_cycle; - unicache.caches->stats_t.readAc.miss = 0; - unicache.caches->stats_t.readAc.hit = unicache.caches->stats_t.readAc.access - unicache.caches->stats_t.readAc.miss; - unicache.caches->stats_t.writeAc.access = 0; - unicache.caches->stats_t.writeAc.miss = 0; - unicache.caches->stats_t.writeAc.hit = unicache.caches->stats_t.writeAc.access - unicache.caches->stats_t.writeAc.miss; - unicache.caches->tdp_stats = unicache.caches->stats_t; + unicache.wbb->stats_t.readAc.access = unicache.wbb->l_ip.num_search_ports; + unicache.wbb->stats_t.writeAc.access = + unicache.wbb->l_ip.num_search_ports; + unicache.wbb->tdp_stats = unicache.wbb->stats_t; + } else { + unicache.caches->stats_t.readAc.access = + unicache.caches->l_ip.num_search_ports * cachep.duty_cycle; + unicache.caches->stats_t.readAc.miss = 0; + unicache.caches->stats_t.readAc.hit = + unicache.caches->stats_t.readAc.access - + unicache.caches->stats_t.readAc.miss; + unicache.caches->stats_t.writeAc.access = 0; + unicache.caches->stats_t.writeAc.miss = 0; + unicache.caches->stats_t.writeAc.hit = + unicache.caches->stats_t.writeAc.access - + unicache.caches->stats_t.writeAc.miss; + unicache.caches->tdp_stats = unicache.caches->stats_t; + } - } + } else { + // init stats for runtime power (RTP) + if (cacheL == L2) { + // Copy stats from l1 to L1[0] + XML->sys.L2[ithCache].total_accesses = XML->sys.l2.total_accesses; + XML->sys.L2[ithCache].read_accesses = XML->sys.l2.read_accesses; + XML->sys.L2[ithCache].write_accesses = XML->sys.l2.write_accesses; + XML->sys.L2[ithCache].read_hits = XML->sys.l2.read_hits; + XML->sys.L2[ithCache].read_misses = XML->sys.l2.read_misses; + XML->sys.L2[ithCache].write_hits = XML->sys.l2.write_hits; + XML->sys.L2[ithCache].write_misses = XML->sys.l2.write_misses; - } - else - { - //init stats for runtime power (RTP) - if (cacheL==L2) - { - //Copy stats from l1 to L1[0] - XML->sys.L2[ithCache].total_accesses=XML->sys.l2.total_accesses; - XML->sys.L2[ithCache].read_accesses=XML->sys.l2.read_accesses; - XML->sys.L2[ithCache].write_accesses=XML->sys.l2.write_accesses; - XML->sys.L2[ithCache].read_hits=XML->sys.l2.read_hits; - XML->sys.L2[ithCache].read_misses=XML->sys.l2.read_misses; - XML->sys.L2[ithCache].write_hits=XML->sys.l2.write_hits; - XML->sys.L2[ithCache].write_misses=XML->sys.l2.write_misses; + unicache.caches->stats_t.readAc.access = + XML->sys.L2[ithCache].read_accesses; + unicache.caches->stats_t.readAc.miss = XML->sys.L2[ithCache].read_misses; + unicache.caches->stats_t.readAc.hit = + unicache.caches->stats_t.readAc.access - + unicache.caches->stats_t.readAc.miss; + unicache.caches->stats_t.writeAc.access = + XML->sys.L2[ithCache].write_accesses; + unicache.caches->stats_t.writeAc.miss = + XML->sys.L2[ithCache].write_misses; + unicache.caches->stats_t.writeAc.hit = + unicache.caches->stats_t.writeAc.access - + unicache.caches->stats_t.writeAc.miss; + unicache.caches->rtp_stats = unicache.caches->stats_t; - unicache.caches->stats_t.readAc.access = XML->sys.L2[ithCache].read_accesses; - unicache.caches->stats_t.readAc.miss = XML->sys.L2[ithCache].read_misses; - unicache.caches->stats_t.readAc.hit = unicache.caches->stats_t.readAc.access - unicache.caches->stats_t.readAc.miss; - unicache.caches->stats_t.writeAc.access = XML->sys.L2[ithCache].write_accesses; - unicache.caches->stats_t.writeAc.miss = XML->sys.L2[ithCache].write_misses; - unicache.caches->stats_t.writeAc.hit = unicache.caches->stats_t.writeAc.access - unicache.caches->stats_t.writeAc.miss; - unicache.caches->rtp_stats = unicache.caches->stats_t; + if (cachep.dir_ty == SBT) { + homenode_rtp_stats.readAc.access = + XML->sys.L2[ithCache].homenode_read_accesses; + homenode_rtp_stats.readAc.miss = + XML->sys.L2[ithCache].homenode_read_misses; + homenode_rtp_stats.readAc.hit = + homenode_rtp_stats.readAc.access - homenode_rtp_stats.readAc.miss; + homenode_rtp_stats.writeAc.access = + XML->sys.L2[ithCache].homenode_write_accesses; + homenode_rtp_stats.writeAc.miss = + XML->sys.L2[ithCache].homenode_write_misses; + homenode_rtp_stats.writeAc.hit = + homenode_rtp_stats.writeAc.access - homenode_rtp_stats.writeAc.miss; + } + } else if (cacheL == L3) { + unicache.caches->stats_t.readAc.access = + XML->sys.L3[ithCache].read_accesses; + unicache.caches->stats_t.readAc.miss = XML->sys.L3[ithCache].read_misses; + unicache.caches->stats_t.readAc.hit = + unicache.caches->stats_t.readAc.access - + unicache.caches->stats_t.readAc.miss; + unicache.caches->stats_t.writeAc.access = + XML->sys.L3[ithCache].write_accesses; + unicache.caches->stats_t.writeAc.miss = + XML->sys.L3[ithCache].write_misses; + unicache.caches->stats_t.writeAc.hit = + unicache.caches->stats_t.writeAc.access - + unicache.caches->stats_t.writeAc.miss; + unicache.caches->rtp_stats = unicache.caches->stats_t; - if (cachep.dir_ty==SBT) - { - homenode_rtp_stats.readAc.access = XML->sys.L2[ithCache].homenode_read_accesses; - homenode_rtp_stats.readAc.miss = XML->sys.L2[ithCache].homenode_read_misses; - homenode_rtp_stats.readAc.hit = homenode_rtp_stats.readAc.access - homenode_rtp_stats.readAc.miss; - homenode_rtp_stats.writeAc.access = XML->sys.L2[ithCache].homenode_write_accesses; - homenode_rtp_stats.writeAc.miss = XML->sys.L2[ithCache].homenode_write_misses; - homenode_rtp_stats.writeAc.hit = homenode_rtp_stats.writeAc.access - homenode_rtp_stats.writeAc.miss; - } - } - else if (cacheL==L3) - { - unicache.caches->stats_t.readAc.access = XML->sys.L3[ithCache].read_accesses; - unicache.caches->stats_t.readAc.miss = XML->sys.L3[ithCache].read_misses; - unicache.caches->stats_t.readAc.hit = unicache.caches->stats_t.readAc.access - unicache.caches->stats_t.readAc.miss; - unicache.caches->stats_t.writeAc.access = XML->sys.L3[ithCache].write_accesses; - unicache.caches->stats_t.writeAc.miss = XML->sys.L3[ithCache].write_misses; - unicache.caches->stats_t.writeAc.hit = unicache.caches->stats_t.writeAc.access - unicache.caches->stats_t.writeAc.miss; - unicache.caches->rtp_stats = unicache.caches->stats_t; + if (cachep.dir_ty == SBT) { + homenode_rtp_stats.readAc.access = + XML->sys.L3[ithCache].homenode_read_accesses; + homenode_rtp_stats.readAc.miss = + XML->sys.L3[ithCache].homenode_read_misses; + homenode_rtp_stats.readAc.hit = + homenode_rtp_stats.readAc.access - homenode_rtp_stats.readAc.miss; + homenode_rtp_stats.writeAc.access = + XML->sys.L3[ithCache].homenode_write_accesses; + homenode_rtp_stats.writeAc.miss = + XML->sys.L3[ithCache].homenode_write_misses; + homenode_rtp_stats.writeAc.hit = + homenode_rtp_stats.writeAc.access - homenode_rtp_stats.writeAc.miss; + } + } else if (cacheL == L1Directory) { + unicache.caches->stats_t.readAc.access = + XML->sys.L1Directory[ithCache].read_accesses; + unicache.caches->stats_t.readAc.miss = + XML->sys.L1Directory[ithCache].read_misses; + unicache.caches->stats_t.readAc.hit = + unicache.caches->stats_t.readAc.access - + unicache.caches->stats_t.readAc.miss; + unicache.caches->stats_t.writeAc.access = + XML->sys.L1Directory[ithCache].write_accesses; + unicache.caches->stats_t.writeAc.miss = + XML->sys.L1Directory[ithCache].write_misses; + unicache.caches->stats_t.writeAc.hit = + unicache.caches->stats_t.writeAc.access - + unicache.caches->stats_t.writeAc.miss; + unicache.caches->rtp_stats = unicache.caches->stats_t; + } else if (cacheL == L2Directory) { // cout<<"L2 directory"<sys.L2[ithCache].total_accesses=XML->sys.l2.total_accesses; + // XML->sys.L2[ithCache].read_accesses=XML->sys.l2.read_accesses; + // XML->sys.L2[ithCache].write_accesses=XML->sys.l2.write_accesses; + // XML->sys.L2[ithCache].read_hits=XML->sys.l2.read_hits; + // XML->sys.L2[ithCache].read_misses=XML->sys.l2.read_misses; + // XML->sys.L2[ithCache].write_hits=XML->sys.l2.write_hits; + // XML->sys.L2[ithCache].write_misses=XML->sys.l2.write_misses; + unicache.caches->stats_t.readAc.access = + XML->sys.L2Directory[ithCache].read_accesses; + unicache.caches->stats_t.readAc.miss = + XML->sys.L2Directory[ithCache].read_misses; + unicache.caches->stats_t.readAc.hit = + unicache.caches->stats_t.readAc.access - + unicache.caches->stats_t.readAc.miss; + unicache.caches->stats_t.writeAc.access = + XML->sys.L2Directory[ithCache].write_accesses; + unicache.caches->stats_t.writeAc.miss = + XML->sys.L2Directory[ithCache].write_misses; + unicache.caches->stats_t.writeAc.hit = + unicache.caches->stats_t.writeAc.access - + unicache.caches->stats_t.writeAc.miss; + unicache.caches->rtp_stats = unicache.caches->stats_t; + } + if (!((cachep.dir_ty == ST && cacheL == L1Directory) || + (cachep.dir_ty == ST && + cacheL == + L2Directory))) { // Assuming write back and write-allocate cache - if (cachep.dir_ty==SBT) - { - homenode_rtp_stats.readAc.access = XML->sys.L3[ithCache].homenode_read_accesses; - homenode_rtp_stats.readAc.miss = XML->sys.L3[ithCache].homenode_read_misses; - homenode_rtp_stats.readAc.hit = homenode_rtp_stats.readAc.access - homenode_rtp_stats.readAc.miss; - homenode_rtp_stats.writeAc.access = XML->sys.L3[ithCache].homenode_write_accesses; - homenode_rtp_stats.writeAc.miss = XML->sys.L3[ithCache].homenode_write_misses; - homenode_rtp_stats.writeAc.hit = homenode_rtp_stats.writeAc.access - homenode_rtp_stats.writeAc.miss; - } - } - else if (cacheL==L1Directory) - { - unicache.caches->stats_t.readAc.access = XML->sys.L1Directory[ithCache].read_accesses; - unicache.caches->stats_t.readAc.miss = XML->sys.L1Directory[ithCache].read_misses; - unicache.caches->stats_t.readAc.hit = unicache.caches->stats_t.readAc.access - unicache.caches->stats_t.readAc.miss; - unicache.caches->stats_t.writeAc.access = XML->sys.L1Directory[ithCache].write_accesses; - unicache.caches->stats_t.writeAc.miss = XML->sys.L1Directory[ithCache].write_misses; - unicache.caches->stats_t.writeAc.hit = unicache.caches->stats_t.writeAc.access - unicache.caches->stats_t.writeAc.miss; - unicache.caches->rtp_stats = unicache.caches->stats_t; - } - else if (cacheL==L2Directory) - { //cout<<"L2 directory"<sys.L2[ithCache].total_accesses=XML->sys.l2.total_accesses; - //XML->sys.L2[ithCache].read_accesses=XML->sys.l2.read_accesses; - //XML->sys.L2[ithCache].write_accesses=XML->sys.l2.write_accesses; - //XML->sys.L2[ithCache].read_hits=XML->sys.l2.read_hits; - //XML->sys.L2[ithCache].read_misses=XML->sys.l2.read_misses; - //XML->sys.L2[ithCache].write_hits=XML->sys.l2.write_hits; - //XML->sys.L2[ithCache].write_misses=XML->sys.l2.write_misses; - unicache.caches->stats_t.readAc.access = XML->sys.L2Directory[ithCache].read_accesses; - unicache.caches->stats_t.readAc.miss = XML->sys.L2Directory[ithCache].read_misses; - unicache.caches->stats_t.readAc.hit = unicache.caches->stats_t.readAc.access - unicache.caches->stats_t.readAc.miss; - unicache.caches->stats_t.writeAc.access = XML->sys.L2Directory[ithCache].write_accesses; - unicache.caches->stats_t.writeAc.miss = XML->sys.L2Directory[ithCache].write_misses; - unicache.caches->stats_t.writeAc.hit = unicache.caches->stats_t.writeAc.access - unicache.caches->stats_t.writeAc.miss; - unicache.caches->rtp_stats = unicache.caches->stats_t; - } - if (!((cachep.dir_ty==ST&& cacheL==L1Directory)||(cachep.dir_ty==ST&& cacheL==L2Directory))) - { //Assuming write back and write-allocate cache + unicache.missb->stats_t.readAc.access = + unicache.caches->stats_t.writeAc.miss; + unicache.missb->stats_t.writeAc.access = + unicache.caches->stats_t.writeAc.miss; + unicache.missb->rtp_stats = unicache.missb->stats_t; - unicache.missb->stats_t.readAc.access = unicache.caches->stats_t.writeAc.miss ; - unicache.missb->stats_t.writeAc.access = unicache.caches->stats_t.writeAc.miss; - unicache.missb->rtp_stats = unicache.missb->stats_t; + unicache.ifb->stats_t.readAc.access = + unicache.caches->stats_t.writeAc.miss; + unicache.ifb->stats_t.writeAc.access = + unicache.caches->stats_t.writeAc.miss; + unicache.ifb->rtp_stats = unicache.ifb->stats_t; - unicache.ifb->stats_t.readAc.access = unicache.caches->stats_t.writeAc.miss; - unicache.ifb->stats_t.writeAc.access = unicache.caches->stats_t.writeAc.miss; - unicache.ifb->rtp_stats = unicache.ifb->stats_t; + unicache.prefetchb->stats_t.readAc.access = + unicache.caches->stats_t.writeAc.miss; + unicache.prefetchb->stats_t.writeAc.access = + unicache.caches->stats_t.writeAc.miss; + unicache.prefetchb->rtp_stats = unicache.prefetchb->stats_t; - unicache.prefetchb->stats_t.readAc.access = unicache.caches->stats_t.writeAc.miss; - unicache.prefetchb->stats_t.writeAc.access = unicache.caches->stats_t.writeAc.miss; - unicache.prefetchb->rtp_stats = unicache.prefetchb->stats_t; + unicache.wbb->stats_t.readAc.access = + unicache.caches->stats_t.writeAc.miss; + unicache.wbb->stats_t.writeAc.access = + unicache.caches->stats_t.writeAc.miss; + if (cachep.dir_ty == SBT) { + unicache.missb->stats_t.readAc.access += + homenode_rtp_stats.writeAc.miss; + unicache.missb->stats_t.writeAc.access += + homenode_rtp_stats.writeAc.miss; + unicache.missb->rtp_stats = unicache.missb->stats_t; - unicache.wbb->stats_t.readAc.access = unicache.caches->stats_t.writeAc.miss; - unicache.wbb->stats_t.writeAc.access = unicache.caches->stats_t.writeAc.miss; - if (cachep.dir_ty==SBT) - { - unicache.missb->stats_t.readAc.access += homenode_rtp_stats.writeAc.miss; - unicache.missb->stats_t.writeAc.access += homenode_rtp_stats.writeAc.miss; - unicache.missb->rtp_stats = unicache.missb->stats_t; + unicache.missb->stats_t.readAc.access += + homenode_rtp_stats.writeAc.miss; + unicache.missb->stats_t.writeAc.access += + homenode_rtp_stats.writeAc.miss; + unicache.missb->rtp_stats = unicache.missb->stats_t; - unicache.missb->stats_t.readAc.access += homenode_rtp_stats.writeAc.miss; - unicache.missb->stats_t.writeAc.access += homenode_rtp_stats.writeAc.miss; - unicache.missb->rtp_stats = unicache.missb->stats_t; + unicache.ifb->stats_t.readAc.access += homenode_rtp_stats.writeAc.miss; + unicache.ifb->stats_t.writeAc.access += homenode_rtp_stats.writeAc.miss; + unicache.ifb->rtp_stats = unicache.ifb->stats_t; - unicache.ifb->stats_t.readAc.access += homenode_rtp_stats.writeAc.miss; - unicache.ifb->stats_t.writeAc.access += homenode_rtp_stats.writeAc.miss; - unicache.ifb->rtp_stats = unicache.ifb->stats_t; - - unicache.prefetchb->stats_t.readAc.access += homenode_rtp_stats.writeAc.miss; - unicache.prefetchb->stats_t.writeAc.access += homenode_rtp_stats.writeAc.miss; - unicache.prefetchb->rtp_stats = unicache.prefetchb->stats_t; - - unicache.wbb->stats_t.readAc.access += homenode_rtp_stats.writeAc.miss; - unicache.wbb->stats_t.writeAc.access += homenode_rtp_stats.writeAc.miss; - } - unicache.wbb->rtp_stats = unicache.wbb->stats_t; - - } - - } - - unicache.power_t.reset(); - unicache.rt_power.reset(); - if (!((cachep.dir_ty==ST&& cacheL==L1Directory)||(cachep.dir_ty==ST&& cacheL==L2Directory))) - { - - unicache.power_t.readOp.dynamic += (unicache.caches->stats_t.readAc.hit*unicache.caches->local_result.power.readOp.dynamic+ - unicache.caches->stats_t.readAc.miss*unicache.caches->local_result.tag_array2->power.readOp.dynamic+ - unicache.caches->stats_t.writeAc.miss*unicache.caches->local_result.tag_array2->power.writeOp.dynamic+ - unicache.caches->stats_t.writeAc.access*unicache.caches->local_result.power.writeOp.dynamic);//write miss will also generate a write later - - if (cachep.dir_ty==SBT) - { - unicache.power_t.readOp.dynamic += homenode_stats_t.readAc.hit * (unicache.caches->local_result.data_array2->power.readOp.dynamic*dir_overhead + - unicache.caches->local_result.tag_array2->power.readOp.dynamic) + - homenode_stats_t.readAc.miss*unicache.caches->local_result.tag_array2->power.readOp.dynamic + - homenode_stats_t.writeAc.miss*unicache.caches->local_result.tag_array2->power.readOp.dynamic + - homenode_stats_t.writeAc.hit*(unicache.caches->local_result.data_array2->power.writeOp.dynamic*dir_overhead + - unicache.caches->local_result.tag_array2->power.readOp.dynamic+ - homenode_stats_t.writeAc.miss*unicache.caches->local_result.power.writeOp.dynamic);//write miss on dynamic home node will generate a replacement write on whole cache block + unicache.prefetchb->stats_t.readAc.access += + homenode_rtp_stats.writeAc.miss; + unicache.prefetchb->stats_t.writeAc.access += + homenode_rtp_stats.writeAc.miss; + unicache.prefetchb->rtp_stats = unicache.prefetchb->stats_t; + unicache.wbb->stats_t.readAc.access += homenode_rtp_stats.writeAc.miss; + unicache.wbb->stats_t.writeAc.access += homenode_rtp_stats.writeAc.miss; + } + unicache.wbb->rtp_stats = unicache.wbb->stats_t; + } + } - } + unicache.power_t.reset(); + unicache.rt_power.reset(); + if (!((cachep.dir_ty == ST && cacheL == L1Directory) || + (cachep.dir_ty == ST && cacheL == L2Directory))) { + unicache.power_t.readOp.dynamic += + (unicache.caches->stats_t.readAc.hit * + unicache.caches->local_result.power.readOp.dynamic + + unicache.caches->stats_t.readAc.miss * + unicache.caches->local_result.tag_array2->power.readOp.dynamic + + unicache.caches->stats_t.writeAc.miss * + unicache.caches->local_result.tag_array2->power.writeOp.dynamic + + unicache.caches->stats_t.writeAc.access * + unicache.caches->local_result.power.writeOp + .dynamic); // write miss will also generate a write later - unicache.power_t.readOp.dynamic += unicache.missb->stats_t.readAc.access*unicache.missb->local_result.power.searchOp.dynamic + - unicache.missb->stats_t.writeAc.access*unicache.missb->local_result.power.writeOp.dynamic;//each access to missb involves a CAM and a write - unicache.power_t.readOp.dynamic += unicache.ifb->stats_t.readAc.access*unicache.ifb->local_result.power.searchOp.dynamic + - unicache.ifb->stats_t.writeAc.access*unicache.ifb->local_result.power.writeOp.dynamic; - unicache.power_t.readOp.dynamic += unicache.prefetchb->stats_t.readAc.access*unicache.prefetchb->local_result.power.searchOp.dynamic + - unicache.prefetchb->stats_t.writeAc.access*unicache.prefetchb->local_result.power.writeOp.dynamic; - unicache.power_t.readOp.dynamic += unicache.wbb->stats_t.readAc.access*unicache.wbb->local_result.power.searchOp.dynamic + - unicache.wbb->stats_t.writeAc.access*unicache.wbb->local_result.power.writeOp.dynamic; - } - else - { - unicache.power_t.readOp.dynamic += (unicache.caches->stats_t.readAc.access*unicache.caches->local_result.power.searchOp.dynamic+ - unicache.caches->stats_t.writeAc.access*unicache.caches->local_result.power.writeOp.dynamic); - } + if (cachep.dir_ty == SBT) { + unicache.power_t.readOp.dynamic += + homenode_stats_t.readAc.hit * + (unicache.caches->local_result.data_array2->power.readOp.dynamic * + dir_overhead + + unicache.caches->local_result.tag_array2->power.readOp.dynamic) + + homenode_stats_t.readAc.miss * + unicache.caches->local_result.tag_array2->power.readOp.dynamic + + homenode_stats_t.writeAc.miss * + unicache.caches->local_result.tag_array2->power.readOp.dynamic + + homenode_stats_t.writeAc.hit * + (unicache.caches->local_result.data_array2->power.writeOp + .dynamic * + dir_overhead + + unicache.caches->local_result.tag_array2->power.readOp.dynamic + + homenode_stats_t.writeAc.miss * + unicache.caches->local_result.power.writeOp + .dynamic); // write miss on dynamic home node will + // generate a replacement write on whole + // cache block + } - if (is_tdp) - { - unicache.power = unicache.power_t + (unicache.caches->local_result.power)*pppm_lkg; - if (!((cachep.dir_ty==ST&& cacheL==L1Directory)||(cachep.dir_ty==ST&& cacheL==L2Directory))) - { - unicache.power = unicache.power+ - (unicache.missb->local_result.power + - unicache.ifb->local_result.power + - unicache.prefetchb->local_result.power + - unicache.wbb->local_result.power)*pppm_lkg; - } - power = power + unicache.power; - // cout<<"unicache.caches->local_result.power.readOp.dynamic"<local_result.power.readOp.dynamic<local_result.power.writeOp.dynamic"<local_result.power.writeOp.dynamic<stats_t.readAc.access * + unicache.missb->local_result.power.searchOp.dynamic + + unicache.missb->stats_t.writeAc.access * + unicache.missb->local_result.power.writeOp + .dynamic; // each access to missb involves a CAM and a write + unicache.power_t.readOp.dynamic += + unicache.ifb->stats_t.readAc.access * + unicache.ifb->local_result.power.searchOp.dynamic + + unicache.ifb->stats_t.writeAc.access * + unicache.ifb->local_result.power.writeOp.dynamic; + unicache.power_t.readOp.dynamic += + unicache.prefetchb->stats_t.readAc.access * + unicache.prefetchb->local_result.power.searchOp.dynamic + + unicache.prefetchb->stats_t.writeAc.access * + unicache.prefetchb->local_result.power.writeOp.dynamic; + unicache.power_t.readOp.dynamic += + unicache.wbb->stats_t.readAc.access * + unicache.wbb->local_result.power.searchOp.dynamic + + unicache.wbb->stats_t.writeAc.access * + unicache.wbb->local_result.power.writeOp.dynamic; + } else { + unicache.power_t.readOp.dynamic += + (unicache.caches->stats_t.readAc.access * + unicache.caches->local_result.power.searchOp.dynamic + + unicache.caches->stats_t.writeAc.access * + unicache.caches->local_result.power.writeOp.dynamic); + } - unicache.rt_power = unicache.power_t + (unicache.caches->local_result.power)*pppm_lkg; - if (!((cachep.dir_ty==ST&& cacheL==L1Directory)||(cachep.dir_ty==ST&& cacheL==L2Directory))) - { - unicache.rt_power = unicache.rt_power + - (unicache.missb->local_result.power + - unicache.ifb->local_result.power + - unicache.prefetchb->local_result.power + - unicache.wbb->local_result.power)*pppm_lkg; - } + if (is_tdp) { + unicache.power = + unicache.power_t + (unicache.caches->local_result.power) * pppm_lkg; + if (!((cachep.dir_ty == ST && cacheL == L1Directory) || + (cachep.dir_ty == ST && cacheL == L2Directory))) { + unicache.power = + unicache.power + (unicache.missb->local_result.power + + unicache.ifb->local_result.power + + unicache.prefetchb->local_result.power + + unicache.wbb->local_result.power) * + pppm_lkg; + } + power = power + unicache.power; + // cout<<"unicache.caches->local_result.power.readOp.dynamic"<local_result.power.readOp.dynamic<local_result.power.writeOp.dynamic"<local_result.power.writeOp.dynamic<local_result.power) * pppm_lkg; + if (!((cachep.dir_ty == ST && cacheL == L1Directory) || + (cachep.dir_ty == ST && cacheL == L2Directory))) { + unicache.rt_power = + unicache.rt_power + (unicache.missb->local_result.power + + unicache.ifb->local_result.power + + unicache.prefetchb->local_result.power + + unicache.wbb->local_result.power) * + pppm_lkg; + } - rt_power = rt_power + unicache.rt_power; - } + rt_power = rt_power + unicache.rt_power; + } } -void SharedCache::displayEnergy(uint32_t indent,bool is_tdp) -{ +void SharedCache::displayEnergy(uint32_t indent, bool is_tdp) { string indent_str(indent, ' '); - string indent_str_next(indent+2, ' '); + string indent_str_next(indent + 2, ' '); bool long_channel = XML->sys.longer_channel_device; - if (is_tdp) - { - cout << (XML->sys.Private_L2? indent_str:"")<< cachep.name << endl; - cout << indent_str << "Area = " << area.get_area()*1e-6<< " mm^2" << endl; - cout << indent_str << "Peak Dynamic = " << power.readOp.dynamic*cachep.clockRate << " W" << endl; - cout << indent_str << "Subthreshold Leakage = " - << (long_channel? power.readOp.longer_channel_leakage:power.readOp.leakage) <<" W" << endl; - //cout << indent_str << "Subthreshold Leakage = " << power.readOp.longer_channel_leakage <<" W" << endl; - cout << indent_str << "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl; - cout << indent_str << "Runtime Dynamic = " << rt_power.readOp.dynamic/cachep.executionTime << " W" << endl; - cout <sys.Private_L2 ? indent_str : "") << cachep.name << endl; + cout << indent_str << "Area = " << area.get_area() * 1e-6 << " mm^2" + << endl; + cout << indent_str + << "Peak Dynamic = " << power.readOp.dynamic * cachep.clockRate << " W" + << endl; + cout << indent_str << "Subthreshold Leakage = " + << (long_channel ? power.readOp.longer_channel_leakage + : power.readOp.leakage) + << " W" << endl; + // cout << indent_str << "Subthreshold Leakage = " << + // power.readOp.longer_channel_leakage <<" W" << endl; + cout << indent_str << "Gate Leakage = " << power.readOp.gate_leakage << " W" + << endl; + cout << indent_str << "Runtime Dynamic = " + << rt_power.readOp.dynamic / cachep.executionTime << " W" << endl; + cout << endl; + } else { } } -//void SharedCache::computeMaxPower() +// void SharedCache::computeMaxPower() //{ // //Compute maximum power and runtime power. -// //When computing runtime power, McPAT gets or reasons out the statistics based on XML input. -// maxPower = 0.0; +// //When computing runtime power, McPAT gets or reasons out the statistics +// based on XML input. maxPower = 0.0; // //llCache,itlb // llCache.maxPower = 0.0; -// llCache.maxPower += (llCache.caches.l_ip.num_rw_ports*(0.67*llCache.caches.local_result.power.readOp.dynamic+0.33*llCache.caches.local_result.power.writeOp.dynamic) +// llCache.maxPower += +// (llCache.caches.l_ip.num_rw_ports*(0.67*llCache.caches.local_result.power.readOp.dynamic+0.33*llCache.caches.local_result.power.writeOp.dynamic) // +llCache.caches.l_ip.num_rd_ports*llCache.caches.local_result.power.readOp.dynamic+llCache.caches.l_ip.num_wr_ports*llCache.caches.local_result.power.writeOp.dynamic // +llCache.caches.l_ip.num_se_rd_ports*llCache.caches.local_result.power.readOp.dynamic)*clockRate; // ///cout<<"llCache.maxPower=" <sys.first_level_dir==1) // { -// inv_dir.maxPower = inv_dir.caches.local_result.power.searchOp.dynamic*clockRate*XML->sys.domain_size; -// cc.power.readOp.dynamic = inv_dir.maxPower*scktRatio*64/XML->sys.domain_size; -// cc.power.readOp.leakage = inv_dir.caches.local_result.power.readOp.leakage*inv_dir.caches.l_ip.nbanks*64/XML->sys.domain_size; +// inv_dir.maxPower = +// inv_dir.caches.local_result.power.searchOp.dynamic*clockRate*XML->sys.domain_size; +// cc.power.readOp.dynamic = +// inv_dir.maxPower*scktRatio*64/XML->sys.domain_size; +// cc.power.readOp.leakage = +// inv_dir.caches.local_result.power.readOp.leakage*inv_dir.caches.l_ip.nbanks*64/XML->sys.domain_size; // // cc.area.set_area(inv_dir.area*64/XML->sys.domain_size); // cout<<"CC area="<sys.L2[ithCache].clockrate; - cachep.clockRate *= 1e6; - cachep.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); - interface_ip.data_arr_ram_cell_tech_type = XML->sys.L2[ithCache].device_type;//long channel device LSTP - interface_ip.data_arr_peri_global_tech_type = XML->sys.L2[ithCache].device_type; - interface_ip.tag_arr_ram_cell_tech_type = XML->sys.L2[ithCache].device_type; - interface_ip.tag_arr_peri_global_tech_type = XML->sys.L2[ithCache].device_type; - cachep.capacity = XML->sys.L2[ithCache].L2_config[0]; - cachep.blockW = XML->sys.L2[ithCache].L2_config[1]; - cachep.assoc = XML->sys.L2[ithCache].L2_config[2]; - cachep.nbanks = XML->sys.L2[ithCache].L2_config[3]; - cachep.throughput = XML->sys.L2[ithCache].L2_config[4]/cachep.clockRate; - cachep.latency = XML->sys.L2[ithCache].L2_config[5]/cachep.clockRate; - cachep.missb_size = XML->sys.L2[ithCache].buffer_sizes[0]; - cachep.fu_size = XML->sys.L2[ithCache].buffer_sizes[1]; - cachep.prefetchb_size= XML->sys.L2[ithCache].buffer_sizes[2]; - cachep.wbb_size = XML->sys.L2[ithCache].buffer_sizes[3]; - cachep.duty_cycle = XML->sys.L2[ithCache].duty_cycle; - if (!XML->sys.L2[ithCache].merged_dir) - { - cachep.dir_ty = NonDir; - } - else - { - cachep.dir_ty = SBT; - cachep.dir_duty_cycle = XML->sys.L2[ithCache].dir_duty_cycle; - } +void SharedCache::set_cache_param() { + if (cacheL == L2) { + cachep.name = "L2"; + cachep.clockRate = XML->sys.L2[ithCache].clockrate; + cachep.clockRate *= 1e6; + cachep.executionTime = + XML->sys.total_cycles / (XML->sys.target_core_clockrate * 1e6); + interface_ip.data_arr_ram_cell_tech_type = + XML->sys.L2[ithCache].device_type; // long channel device LSTP + interface_ip.data_arr_peri_global_tech_type = + XML->sys.L2[ithCache].device_type; + interface_ip.tag_arr_ram_cell_tech_type = XML->sys.L2[ithCache].device_type; + interface_ip.tag_arr_peri_global_tech_type = + XML->sys.L2[ithCache].device_type; + cachep.capacity = XML->sys.L2[ithCache].L2_config[0]; + cachep.blockW = XML->sys.L2[ithCache].L2_config[1]; + cachep.assoc = XML->sys.L2[ithCache].L2_config[2]; + cachep.nbanks = XML->sys.L2[ithCache].L2_config[3]; + cachep.throughput = XML->sys.L2[ithCache].L2_config[4] / cachep.clockRate; + cachep.latency = XML->sys.L2[ithCache].L2_config[5] / cachep.clockRate; + cachep.missb_size = XML->sys.L2[ithCache].buffer_sizes[0]; + cachep.fu_size = XML->sys.L2[ithCache].buffer_sizes[1]; + cachep.prefetchb_size = XML->sys.L2[ithCache].buffer_sizes[2]; + cachep.wbb_size = XML->sys.L2[ithCache].buffer_sizes[3]; + cachep.duty_cycle = XML->sys.L2[ithCache].duty_cycle; + if (!XML->sys.L2[ithCache].merged_dir) { + cachep.dir_ty = NonDir; + } else { + cachep.dir_ty = SBT; + cachep.dir_duty_cycle = XML->sys.L2[ithCache].dir_duty_cycle; + } + } else if (cacheL == L3) { + cachep.name = "L3"; + cachep.clockRate = XML->sys.L3[ithCache].clockrate; + cachep.clockRate *= 1e6; + cachep.executionTime = + XML->sys.total_cycles / (XML->sys.target_core_clockrate * 1e6); + interface_ip.data_arr_ram_cell_tech_type = + XML->sys.L3[ithCache].device_type; // long channel device LSTP + interface_ip.data_arr_peri_global_tech_type = + XML->sys.L3[ithCache].device_type; + interface_ip.tag_arr_ram_cell_tech_type = XML->sys.L3[ithCache].device_type; + interface_ip.tag_arr_peri_global_tech_type = + XML->sys.L3[ithCache].device_type; + cachep.capacity = XML->sys.L3[ithCache].L3_config[0]; + cachep.blockW = XML->sys.L3[ithCache].L3_config[1]; + cachep.assoc = XML->sys.L3[ithCache].L3_config[2]; + cachep.nbanks = XML->sys.L3[ithCache].L3_config[3]; + cachep.throughput = XML->sys.L3[ithCache].L3_config[4] / cachep.clockRate; + cachep.latency = XML->sys.L3[ithCache].L3_config[5] / cachep.clockRate; + cachep.missb_size = XML->sys.L3[ithCache].buffer_sizes[0]; + cachep.fu_size = XML->sys.L3[ithCache].buffer_sizes[1]; + cachep.prefetchb_size = XML->sys.L3[ithCache].buffer_sizes[2]; + cachep.wbb_size = XML->sys.L3[ithCache].buffer_sizes[3]; + cachep.duty_cycle = XML->sys.L3[ithCache].duty_cycle; + if (!XML->sys.L2[ithCache].merged_dir) { + cachep.dir_ty = NonDir; + } else { + cachep.dir_ty = SBT; + cachep.dir_duty_cycle = XML->sys.L2[ithCache].dir_duty_cycle; + } + } else if (cacheL == L1Directory) { + cachep.name = "First Level Directory"; + cachep.dir_ty = + (enum Dir_type)XML->sys.L1Directory[ithCache].Directory_type; + cachep.clockRate = XML->sys.L1Directory[ithCache].clockrate; + cachep.clockRate *= 1e6; + cachep.executionTime = + XML->sys.total_cycles / (XML->sys.target_core_clockrate * 1e6); + interface_ip.data_arr_ram_cell_tech_type = + XML->sys.L1Directory[ithCache].device_type; // long channel device LSTP + interface_ip.data_arr_peri_global_tech_type = + XML->sys.L1Directory[ithCache].device_type; + interface_ip.tag_arr_ram_cell_tech_type = + XML->sys.L1Directory[ithCache].device_type; + interface_ip.tag_arr_peri_global_tech_type = + XML->sys.L1Directory[ithCache].device_type; + cachep.capacity = XML->sys.L1Directory[ithCache].Dir_config[0]; + cachep.blockW = XML->sys.L1Directory[ithCache].Dir_config[1]; + cachep.assoc = XML->sys.L1Directory[ithCache].Dir_config[2]; + cachep.nbanks = XML->sys.L1Directory[ithCache].Dir_config[3]; + cachep.throughput = + XML->sys.L1Directory[ithCache].Dir_config[4] / cachep.clockRate; + cachep.latency = + XML->sys.L1Directory[ithCache].Dir_config[5] / cachep.clockRate; + cachep.missb_size = XML->sys.L1Directory[ithCache].buffer_sizes[0]; + cachep.fu_size = XML->sys.L1Directory[ithCache].buffer_sizes[1]; + cachep.prefetchb_size = XML->sys.L1Directory[ithCache].buffer_sizes[2]; + cachep.wbb_size = XML->sys.L1Directory[ithCache].buffer_sizes[3]; + cachep.duty_cycle = XML->sys.L1Directory[ithCache].duty_cycle; + } else if (cacheL == L2Directory) { + cachep.name = "Second Level Directory"; + cachep.dir_ty = + (enum Dir_type)XML->sys.L2Directory[ithCache].Directory_type; + cachep.clockRate = XML->sys.L2Directory[ithCache].clockrate; + cachep.clockRate *= 1e6; + cachep.executionTime = + XML->sys.total_cycles / (XML->sys.target_core_clockrate * 1e6); + interface_ip.data_arr_ram_cell_tech_type = + XML->sys.L2Directory[ithCache].device_type; // long channel device LSTP + interface_ip.data_arr_peri_global_tech_type = + XML->sys.L2Directory[ithCache].device_type; + interface_ip.tag_arr_ram_cell_tech_type = + XML->sys.L2Directory[ithCache].device_type; + interface_ip.tag_arr_peri_global_tech_type = + XML->sys.L2Directory[ithCache].device_type; + cachep.capacity = XML->sys.L2Directory[ithCache].Dir_config[0]; + cachep.blockW = XML->sys.L2Directory[ithCache].Dir_config[1]; + cachep.assoc = XML->sys.L2Directory[ithCache].Dir_config[2]; + cachep.nbanks = XML->sys.L2Directory[ithCache].Dir_config[3]; + cachep.throughput = + XML->sys.L2Directory[ithCache].Dir_config[4] / cachep.clockRate; + cachep.latency = + XML->sys.L2Directory[ithCache].Dir_config[5] / cachep.clockRate; + cachep.missb_size = XML->sys.L2Directory[ithCache].buffer_sizes[0]; + cachep.fu_size = XML->sys.L2Directory[ithCache].buffer_sizes[1]; + cachep.prefetchb_size = XML->sys.L2Directory[ithCache].buffer_sizes[2]; + cachep.wbb_size = XML->sys.L2Directory[ithCache].buffer_sizes[3]; + cachep.duty_cycle = XML->sys.L2Directory[ithCache].duty_cycle; } - else if (cacheL==L3) - { - cachep.name = "L3"; - cachep.clockRate = XML->sys.L3[ithCache].clockrate; - cachep.clockRate *= 1e6; - cachep.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); - interface_ip.data_arr_ram_cell_tech_type = XML->sys.L3[ithCache].device_type;//long channel device LSTP - interface_ip.data_arr_peri_global_tech_type = XML->sys.L3[ithCache].device_type; - interface_ip.tag_arr_ram_cell_tech_type = XML->sys.L3[ithCache].device_type; - interface_ip.tag_arr_peri_global_tech_type = XML->sys.L3[ithCache].device_type; - cachep.capacity = XML->sys.L3[ithCache].L3_config[0]; - cachep.blockW = XML->sys.L3[ithCache].L3_config[1]; - cachep.assoc = XML->sys.L3[ithCache].L3_config[2]; - cachep.nbanks = XML->sys.L3[ithCache].L3_config[3]; - cachep.throughput = XML->sys.L3[ithCache].L3_config[4]/cachep.clockRate; - cachep.latency = XML->sys.L3[ithCache].L3_config[5]/cachep.clockRate; - cachep.missb_size = XML->sys.L3[ithCache].buffer_sizes[0]; - cachep.fu_size = XML->sys.L3[ithCache].buffer_sizes[1]; - cachep.prefetchb_size= XML->sys.L3[ithCache].buffer_sizes[2]; - cachep.wbb_size = XML->sys.L3[ithCache].buffer_sizes[3]; - cachep.duty_cycle = XML->sys.L3[ithCache].duty_cycle; - if (!XML->sys.L2[ithCache].merged_dir) - { - cachep.dir_ty = NonDir; - } - else - { - cachep.dir_ty = SBT; - cachep.dir_duty_cycle = XML->sys.L2[ithCache].dir_duty_cycle; - } - } - else if (cacheL==L1Directory) - { - cachep.name = "First Level Directory"; - cachep.dir_ty = (enum Dir_type) XML->sys.L1Directory[ithCache].Directory_type; - cachep.clockRate = XML->sys.L1Directory[ithCache].clockrate; - cachep.clockRate *= 1e6; - cachep.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); - interface_ip.data_arr_ram_cell_tech_type = XML->sys.L1Directory[ithCache].device_type;//long channel device LSTP - interface_ip.data_arr_peri_global_tech_type = XML->sys.L1Directory[ithCache].device_type; - interface_ip.tag_arr_ram_cell_tech_type = XML->sys.L1Directory[ithCache].device_type; - interface_ip.tag_arr_peri_global_tech_type = XML->sys.L1Directory[ithCache].device_type; - cachep.capacity = XML->sys.L1Directory[ithCache].Dir_config[0]; - cachep.blockW = XML->sys.L1Directory[ithCache].Dir_config[1]; - cachep.assoc = XML->sys.L1Directory[ithCache].Dir_config[2]; - cachep.nbanks = XML->sys.L1Directory[ithCache].Dir_config[3]; - cachep.throughput = XML->sys.L1Directory[ithCache].Dir_config[4]/cachep.clockRate; - cachep.latency = XML->sys.L1Directory[ithCache].Dir_config[5]/cachep.clockRate; - cachep.missb_size = XML->sys.L1Directory[ithCache].buffer_sizes[0]; - cachep.fu_size = XML->sys.L1Directory[ithCache].buffer_sizes[1]; - cachep.prefetchb_size= XML->sys.L1Directory[ithCache].buffer_sizes[2]; - cachep.wbb_size = XML->sys.L1Directory[ithCache].buffer_sizes[3]; - cachep.duty_cycle = XML->sys.L1Directory[ithCache].duty_cycle; - } - else if (cacheL==L2Directory) - { - cachep.name = "Second Level Directory"; - cachep.dir_ty = (enum Dir_type) XML->sys.L2Directory[ithCache].Directory_type; - cachep.clockRate = XML->sys.L2Directory[ithCache].clockrate; - cachep.clockRate *= 1e6; - cachep.executionTime = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6); - interface_ip.data_arr_ram_cell_tech_type = XML->sys.L2Directory[ithCache].device_type;//long channel device LSTP - interface_ip.data_arr_peri_global_tech_type = XML->sys.L2Directory[ithCache].device_type; - interface_ip.tag_arr_ram_cell_tech_type = XML->sys.L2Directory[ithCache].device_type; - interface_ip.tag_arr_peri_global_tech_type = XML->sys.L2Directory[ithCache].device_type; - cachep.capacity = XML->sys.L2Directory[ithCache].Dir_config[0]; - cachep.blockW = XML->sys.L2Directory[ithCache].Dir_config[1]; - cachep.assoc = XML->sys.L2Directory[ithCache].Dir_config[2]; - cachep.nbanks = XML->sys.L2Directory[ithCache].Dir_config[3]; - cachep.throughput = XML->sys.L2Directory[ithCache].Dir_config[4]/cachep.clockRate; - cachep.latency = XML->sys.L2Directory[ithCache].Dir_config[5]/cachep.clockRate; - cachep.missb_size = XML->sys.L2Directory[ithCache].buffer_sizes[0]; - cachep.fu_size = XML->sys.L2Directory[ithCache].buffer_sizes[1]; - cachep.prefetchb_size= XML->sys.L2Directory[ithCache].buffer_sizes[2]; - cachep.wbb_size = XML->sys.L2Directory[ithCache].buffer_sizes[3]; - cachep.duty_cycle = XML->sys.L2Directory[ithCache].duty_cycle; - } - //cachep.cache_duty_cycle=cachep.dir_duty_cycle = 0.35; + // cachep.cache_duty_cycle=cachep.dir_duty_cycle = 0.35; } - diff --git a/src/gpuwattch/sharedcache.h b/src/gpuwattch/sharedcache.h index 3041137..c5aba19 100644 --- a/src/gpuwattch/sharedcache.h +++ b/src/gpuwattch/sharedcache.h @@ -31,58 +31,59 @@ #ifndef SHAREDCACHE_H_ #define SHAREDCACHE_H_ +#include #include "XML_Parse.h" +#include "array.h" +#include "basic_components.h" #include "cacti/area.h" #include "cacti/parameter.h" -#include "array.h" #include "logic.h" -#include -#include "basic_components.h" -class SharedCache :public Component{ - public: - ParseXML * XML; - int ithCache; - InputParameter interface_ip; - enum cache_level cacheL; - DataCache unicache;//Shared cache - CacheDynParam cachep; - statsDef homenode_tdp_stats; - statsDef homenode_rtp_stats; - statsDef homenode_stats_t; - double dir_overhead; - // cache_processor llCache,directory, directory1, inv_dir; +class SharedCache : public Component { + public: + ParseXML* XML; + int ithCache; + InputParameter interface_ip; + enum cache_level cacheL; + DataCache unicache; // Shared cache + CacheDynParam cachep; + statsDef homenode_tdp_stats; + statsDef homenode_rtp_stats; + statsDef homenode_stats_t; + double dir_overhead; + // cache_processor llCache,directory, directory1, inv_dir; - //pipeline pipeLogicCache, pipeLogicDirectory; - //clock_network clockNetwork; - double scktRatio, executionTime; - // Component L2Tot, cc, cc1, ccTot; + // pipeline pipeLogicCache, pipeLogicDirectory; + // clock_network clockNetwork; + double scktRatio, executionTime; + // Component L2Tot, cc, cc1, ccTot; - SharedCache(ParseXML *XML_interface, int ithCache_, InputParameter* interface_ip_,enum cache_level cacheL_ =L2); - void set_cache_param(); - void computeEnergy(bool is_tdp=true); - void displayEnergy(uint32_t indent = 0,bool is_tdp=true); - ~SharedCache(){}; + SharedCache(ParseXML* XML_interface, int ithCache_, + InputParameter* interface_ip_, enum cache_level cacheL_ = L2); + void set_cache_param(); + void computeEnergy(bool is_tdp = true); + void displayEnergy(uint32_t indent = 0, bool is_tdp = true); + ~SharedCache(){}; }; -class CCdir :public Component{ - public: - ParseXML * XML; - int ithCache; - InputParameter interface_ip; - DataCache dc;//Shared cache - ArrayST * shadow_dir; -// cache_processor llCache,directory, directory1, inv_dir; +class CCdir : public Component { + public: + ParseXML* XML; + int ithCache; + InputParameter interface_ip; + DataCache dc; // Shared cache + ArrayST* shadow_dir; + // cache_processor llCache,directory, directory1, inv_dir; - //pipeline pipeLogicCache, pipeLogicDirectory; - //clock_network clockNetwork; - double scktRatio, clockRate, executionTime; - Component L2Tot, cc, cc1, ccTot; + // pipeline pipeLogicCache, pipeLogicDirectory; + // clock_network clockNetwork; + double scktRatio, clockRate, executionTime; + Component L2Tot, cc, cc1, ccTot; - CCdir(ParseXML *XML_interface, int ithCache_, InputParameter* interface_ip_); - void computeEnergy(bool is_tdp=true); - void displayEnergy(uint32_t indent = 0,bool is_tdp=true); - ~CCdir(); + CCdir(ParseXML* XML_interface, int ithCache_, InputParameter* interface_ip_); + void computeEnergy(bool is_tdp = true); + void displayEnergy(uint32_t indent = 0, bool is_tdp = true); + ~CCdir(); }; #endif /* SHAREDCACHE_H_ */ diff --git a/src/gpuwattch/technology_xeon_core.cc b/src/gpuwattch/technology_xeon_core.cc index ef16087..86bbd84 100644 --- a/src/gpuwattch/technology_xeon_core.cc +++ b/src/gpuwattch/technology_xeon_core.cc @@ -29,57 +29,64 @@ * ***************************************************************************/ - #include "basic_circuit.h" #include "parameter.h" -double wire_resistance(double resistivity, double wire_width, double wire_thickness, - double barrier_thickness, double dishing_thickness, double alpha_scatter) -{ +double wire_resistance(double resistivity, double wire_width, + double wire_thickness, double barrier_thickness, + double dishing_thickness, double alpha_scatter) { double resistance; - resistance = alpha_scatter * resistivity /((wire_thickness - barrier_thickness - dishing_thickness)*(wire_width - 2 * barrier_thickness)); - return(resistance); + resistance = alpha_scatter * resistivity / + ((wire_thickness - barrier_thickness - dishing_thickness) * + (wire_width - 2 * barrier_thickness)); + return (resistance); } -double wire_capacitance(double wire_width, double wire_thickness, double wire_spacing, - double ild_thickness, double miller_value, double horiz_dielectric_constant, - double vert_dielectric_constant, double fringe_cap) -{ +double wire_capacitance(double wire_width, double wire_thickness, + double wire_spacing, double ild_thickness, + double miller_value, double horiz_dielectric_constant, + double vert_dielectric_constant, double fringe_cap) { double vertical_cap, sidewall_cap, total_cap; - vertical_cap = 2 * PERMITTIVITY_FREE_SPACE * vert_dielectric_constant * wire_width / ild_thickness; - sidewall_cap = 2 * PERMITTIVITY_FREE_SPACE * miller_value * horiz_dielectric_constant * wire_thickness / wire_spacing; + vertical_cap = 2 * PERMITTIVITY_FREE_SPACE * vert_dielectric_constant * + wire_width / ild_thickness; + sidewall_cap = 2 * PERMITTIVITY_FREE_SPACE * miller_value * + horiz_dielectric_constant * wire_thickness / wire_spacing; total_cap = vertical_cap + sidewall_cap + fringe_cap; - return(total_cap); + return (total_cap); } - -void init_tech_params(double technology, bool is_tag) -{ - int iter, tech, tech_lo, tech_hi; +void init_tech_params(double technology, bool is_tag) { + int iter, tech, tech_lo, tech_hi; double curr_alpha, curr_vpp; - double wire_width, wire_thickness, wire_spacing, - fringe_cap, pmos_to_nmos_sizing_r; -// double aspect_ratio,ild_thickness, miller_value = 1.5, horiz_dielectric_constant, vert_dielectric_constant; + double wire_width, wire_thickness, wire_spacing, fringe_cap, + pmos_to_nmos_sizing_r; + // double aspect_ratio,ild_thickness, miller_value = 1.5, + // horiz_dielectric_constant, vert_dielectric_constant; double barrier_thickness, dishing_thickness, alpha_scatter; - double curr_vdd_dram_cell, curr_v_th_dram_access_transistor, curr_I_on_dram_cell, curr_c_dram_cell; + double curr_vdd_dram_cell, curr_v_th_dram_access_transistor, + curr_I_on_dram_cell, curr_c_dram_cell; - uint32_t ram_cell_tech_type = (is_tag) ? g_ip->tag_arr_ram_cell_tech_type : g_ip->data_arr_ram_cell_tech_type; - uint32_t peri_global_tech_type = (is_tag) ? g_ip->tag_arr_peri_global_tech_type : g_ip->data_arr_peri_global_tech_type; + uint32_t ram_cell_tech_type = (is_tag) ? g_ip->tag_arr_ram_cell_tech_type + : g_ip->data_arr_ram_cell_tech_type; + uint32_t peri_global_tech_type = (is_tag) + ? g_ip->tag_arr_peri_global_tech_type + : g_ip->data_arr_peri_global_tech_type; - technology = technology * 1000.0; // in the unit of nm + technology = technology * 1000.0; // in the unit of nm // initialize parameters g_tp.reset(); double gmp_to_gmn_multiplier_periph_global = 0; double curr_Wmemcella_dram, curr_Wmemcellpmos_dram, curr_Wmemcellnmos_dram, - curr_area_cell_dram, curr_asp_ratio_cell_dram, curr_Wmemcella_sram, - curr_Wmemcellpmos_sram, curr_Wmemcellnmos_sram, curr_area_cell_sram, - curr_asp_ratio_cell_sram, curr_I_off_dram_cell_worst_case_length_temp; - double curr_Wmemcella_cam, curr_Wmemcellpmos_cam, curr_Wmemcellnmos_cam, curr_area_cell_cam,//Sheng: CAM data - curr_asp_ratio_cell_cam; - double SENSE_AMP_D, SENSE_AMP_P; // J + curr_area_cell_dram, curr_asp_ratio_cell_dram, curr_Wmemcella_sram, + curr_Wmemcellpmos_sram, curr_Wmemcellnmos_sram, curr_area_cell_sram, + curr_asp_ratio_cell_sram, curr_I_off_dram_cell_worst_case_length_temp; + double curr_Wmemcella_cam, curr_Wmemcellpmos_cam, curr_Wmemcellnmos_cam, + curr_area_cell_cam, // Sheng: CAM data + curr_asp_ratio_cell_cam; + double SENSE_AMP_D, SENSE_AMP_P; // J double area_cell_dram = 0; double asp_ratio_cell_dram = 0; double area_cell_sram = 0; @@ -91,77 +98,63 @@ void init_tech_params(double technology, bool is_tag) double nmos_effective_resistance_multiplier; double width_dram_access_transistor; - double curr_logic_scaling_co_eff = 0;//This is based on the reported numbers of Intel Merom 65nm, Penryn45nm and IBM cell 90/65/45 date - double curr_core_tx_density = 0;//this is density per um^2; 90, ...22nm based on Intel Penryn + double curr_logic_scaling_co_eff = + 0; // This is based on the reported numbers of Intel Merom 65nm, + // Penryn45nm and IBM cell 90/65/45 date + double curr_core_tx_density = + 0; // this is density per um^2; 90, ...22nm based on Intel Penryn double curr_chip_layout_overhead = 0; double curr_macro_layout_overhead = 0; double curr_sckt_co_eff = 0; - if (technology < 91 && technology > 89) - { + if (technology < 91 && technology > 89) { tech_lo = 90; tech_hi = 90; - } - else if (technology < 66 && technology > 64) - { + } else if (technology < 66 && technology > 64) { tech_lo = 65; tech_hi = 65; - } - else if (technology < 46 && technology > 44) - { + } else if (technology < 46 && technology > 44) { tech_lo = 45; tech_hi = 45; - } - else if (technology < 33 && technology > 31) - { + } else if (technology < 33 && technology > 31) { tech_lo = 32; tech_hi = 32; - } - else if (technology < 23 && technology > 21) - { + } else if (technology < 23 && technology > 21) { tech_lo = 22; tech_hi = 22; - if (ram_cell_tech_type == 3) - { - cout<<"current version does not support eDRAM technologies at 22nm"< 15) -// { -// tech_lo = 16; -// tech_hi = 16; -// } - else if (technology < 90 && technology > 65) - { + // else if (technology < 17 && technology > 15) + // { + // tech_lo = 16; + // tech_hi = 16; + // } + else if (technology < 90 && technology > 65) { tech_lo = 90; tech_hi = 65; - } - else if (technology < 65 && technology > 45) - { + } else if (technology < 65 && technology > 45) { tech_lo = 65; tech_hi = 45; - } - else if (technology < 45 && technology > 32) - { + } else if (technology < 45 && technology > 32) { tech_lo = 45; tech_hi = 32; + } else if (technology < 32 && technology > 22) { + tech_lo = 32; + tech_hi = 22; + } + // else if (technology < 22 && technology > 16) + // { + // tech_lo = 22; + // tech_hi = 16; + // } + else { + cout << "Invalid technology nodes" << endl; + exit(0); } - else if (technology < 32 && technology > 22) - { - tech_lo = 32; - tech_hi = 22; - } -// else if (technology < 22 && technology > 16) -// { -// tech_lo = 22; -// tech_hi = 16; -// } - else - { - cout<<"Invalid technology nodes"<F_sz_um; curr_Wmemcellpmos_sram = 1.23 * g_ip->F_sz_um; curr_Wmemcellnmos_sram = 2.08 * g_ip->F_sz_um; curr_area_cell_sram = 146 * g_ip->F_sz_um * g_ip->F_sz_um; curr_asp_ratio_cell_sram = 1.46; - //CAM cell properties //TODO: data need to be revisited + // CAM cell properties //TODO: data need to be revisited curr_Wmemcella_cam = 1.31 * g_ip->F_sz_um; curr_Wmemcellpmos_cam = 1.23 * g_ip->F_sz_um; curr_Wmemcellnmos_cam = 2.08 * g_ip->F_sz_um; - curr_area_cell_cam = 292 * g_ip->F_sz_um * g_ip->F_sz_um;//360 - curr_asp_ratio_cell_cam = 2.92;//2.5 - //Empirical undifferetiated core/FU coefficient - curr_logic_scaling_co_eff = 1; - curr_core_tx_density = 1.25*0.7*0.7; - curr_sckt_co_eff = 1.1539; - curr_chip_layout_overhead = 1.2;//die measurement results based on Niagara 1 and 2 - curr_macro_layout_overhead = 1.1;//EDA placement and routing tool rule of thumb - - + curr_area_cell_cam = 292 * g_ip->F_sz_um * g_ip->F_sz_um; // 360 + curr_asp_ratio_cell_cam = 2.92; // 2.5 + // Empirical undifferetiated core/FU coefficient + curr_logic_scaling_co_eff = 1; + curr_core_tx_density = 1.25 * 0.7 * 0.7; + curr_sckt_co_eff = 1.1539; + curr_chip_layout_overhead = + 1.2; // die measurement results based on Niagara 1 and 2 + curr_macro_layout_overhead = + 1.1; // EDA placement and routing tool rule of thumb } - if (tech == 65) - { //65nm technology-node. Corresponds to year 2007 in ITRS - //ITRS HP device type -// SENSE_AMP_D = .2e-9; // s -// SENSE_AMP_P = 5.7e-15; // J -// vdd[0] = 1.1; -// Lphy[0] = 0.025; -// Lelec[0] = 0.019; -// t_ox[0] = 1.1e-3; -// v_th[0] = .19491; -// c_ox[0] = 1.88e-14; -// mobility_eff[0] = 436.24 * (1e-2 * 1e6 * 1e-2 * 1e6); -// Vdsat[0] = 7.71e-2; -// c_g_ideal[0] = 4.69e-16; -// c_fringe[0] = 0.077e-15; -// c_junc[0] = 1e-15; -// I_on_n[0] = 1197.2e-6; -// I_on_p[0] = 870.8e-6; -// nmos_effective_resistance_multiplier = 1.50; -// n_to_p_eff_curr_drv_ratio[0] = 2.41; -// gmp_to_gmn_multiplier[0] = 1.38; -// Rnchannelon[0] = nmos_effective_resistance_multiplier * vdd[0] / I_on_n[0]; -// Rpchannelon[0] = n_to_p_eff_curr_drv_ratio[0] * Rnchannelon[0]; -// long_channel_leakage_reduction[0] = 1/3.74; -// //Using MASTAR, @380K, increase Lgate until Ion reduces to 90% or Lgate increase by 10%, whichever comes first -// //Ioff(Lgate normal)/Ioff(Lgate long)= 3.74. -// I_off_n[0][0] = 1.96e-7; -// I_off_n[0][10] = 2.29e-7; -// I_off_n[0][20] = 2.66e-7; -// I_off_n[0][30] = 3.05e-7; -// I_off_n[0][40] = 3.49e-7; -// I_off_n[0][50] = 3.95e-7; -// I_off_n[0][60] = 4.45e-7; -// I_off_n[0][70] = 4.97e-7; -// I_off_n[0][80] = 5.48e-7; -// I_off_n[0][90] = 5.94e-7; -// I_off_n[0][100] = 6.3e-7; -// I_g_on_n[0][0] = 4.09e-8;//A/micron -// I_g_on_n[0][10] = 4.09e-8; -// I_g_on_n[0][20] = 4.09e-8; -// I_g_on_n[0][30] = 4.09e-8; -// I_g_on_n[0][40] = 4.09e-8; -// I_g_on_n[0][50] = 4.09e-8; -// I_g_on_n[0][60] = 4.09e-8; -// I_g_on_n[0][70] = 4.09e-8; -// I_g_on_n[0][80] = 4.09e-8; -// I_g_on_n[0][90] = 4.09e-8; -// I_g_on_n[0][100] = 4.09e-8; - - SENSE_AMP_D = .2e-9; // s - SENSE_AMP_P = 5.7e-15; // J - vdd[0] = 1.25; - Lphy[0] = 0.025; - Lelec[0] = 0.019; - t_ox[0] = 1.1e-3; - v_th[0] = .12491; - c_ox[0] = 1.88e-14; - mobility_eff[0] = 409.31 * (1e-2 * 1e6 * 1e-2 * 1e6); - Vdsat[0] = 9.08e-2; - c_g_ideal[0] = 4.72e-16; - c_fringe[0] = 0.08e-15; - c_junc[0] = 1e-15; - I_on_n[0] = 1486.4e-6; - I_on_p[0] = 1131.5e-6; - nmos_effective_resistance_multiplier = 1.57; - n_to_p_eff_curr_drv_ratio[0] = 2; - gmp_to_gmn_multiplier[0] = 1.38; - Rnchannelon[0] = nmos_effective_resistance_multiplier * vdd[0] / I_on_n[0]; - Rpchannelon[0] = n_to_p_eff_curr_drv_ratio[0] * Rnchannelon[0]; - long_channel_leakage_reduction[0] = 1.0/4.97; - //Using MASTAR, @380K, increase Lgate until Ion reduces to 90% or Lgate increase by 10%, whichever comes first - //Ioff(Lgate normal)/Ioff(Lgate long)= 4.97@Vdd=1.25; (3.74@Vdd=1.1), however, Intel paper suggest the reduction factor is 3. - I_off_n[0][0] = 8.62e-7; - I_off_n[0][10] = 9.08e-7; - I_off_n[0][20] = 9.55e-7; - I_off_n[0][30] = 1.00e-6; - I_off_n[0][40] = 1.05e-6; - I_off_n[0][50] = 1.09e-6; - I_off_n[0][60] = 1.14e-6; - I_off_n[0][70] = 1.18e-6; - I_off_n[0][80] = 1.23e-6; - I_off_n[0][90] = 1.27e-6; - I_off_n[0][100] = 1.31e-6; - - - I_g_on_n[0][0] = 7.02e-8;//A/micron - I_g_on_n[0][10] = 7.02e-8; - I_g_on_n[0][20] = 7.02e-8; - I_g_on_n[0][30] = 7.02e-8; - I_g_on_n[0][40] = 7.02e-8; - I_g_on_n[0][50] = 7.02e-8; - I_g_on_n[0][60] = 7.02e-8; - I_g_on_n[0][70] = 7.02e-8; - I_g_on_n[0][80] = 7.02e-8; - I_g_on_n[0][90] = 7.02e-8; - I_g_on_n[0][100] = 7.02e-8; - - //ITRS LSTP device type + if (tech == 65) { // 65nm technology-node. Corresponds to year 2007 in ITRS + // ITRS HP device type + // SENSE_AMP_D = .2e-9; // s + // SENSE_AMP_P = 5.7e-15; // J + // vdd[0] = 1.1; + // Lphy[0] = 0.025; + // Lelec[0] = 0.019; + // t_ox[0] = 1.1e-3; + // v_th[0] = .19491; + // c_ox[0] = 1.88e-14; + // mobility_eff[0] = 436.24 * (1e-2 * 1e6 * 1e-2 * 1e6); + // Vdsat[0] = 7.71e-2; + // c_g_ideal[0] = 4.69e-16; + // c_fringe[0] = 0.077e-15; + // c_junc[0] = 1e-15; + // I_on_n[0] = 1197.2e-6; + // I_on_p[0] = 870.8e-6; + // nmos_effective_resistance_multiplier = 1.50; + // n_to_p_eff_curr_drv_ratio[0] = 2.41; + // gmp_to_gmn_multiplier[0] = 1.38; + // Rnchannelon[0] = nmos_effective_resistance_multiplier * vdd[0] / + // I_on_n[0]; Rpchannelon[0] = n_to_p_eff_curr_drv_ratio[0] * + // Rnchannelon[0]; long_channel_leakage_reduction[0] = 1/3.74; + // //Using MASTAR, @380K, increase Lgate until Ion reduces to 90% or + // Lgate increase by 10%, whichever comes first + // //Ioff(Lgate normal)/Ioff(Lgate long)= 3.74. + // I_off_n[0][0] = 1.96e-7; + // I_off_n[0][10] = 2.29e-7; + // I_off_n[0][20] = 2.66e-7; + // I_off_n[0][30] = 3.05e-7; + // I_off_n[0][40] = 3.49e-7; + // I_off_n[0][50] = 3.95e-7; + // I_off_n[0][60] = 4.45e-7; + // I_off_n[0][70] = 4.97e-7; + // I_off_n[0][80] = 5.48e-7; + // I_off_n[0][90] = 5.94e-7; + // I_off_n[0][100] = 6.3e-7; + // I_g_on_n[0][0] = 4.09e-8;//A/micron + // I_g_on_n[0][10] = 4.09e-8; + // I_g_on_n[0][20] = 4.09e-8; + // I_g_on_n[0][30] = 4.09e-8; + // I_g_on_n[0][40] = 4.09e-8; + // I_g_on_n[0][50] = 4.09e-8; + // I_g_on_n[0][60] = 4.09e-8; + // I_g_on_n[0][70] = 4.09e-8; + // I_g_on_n[0][80] = 4.09e-8; + // I_g_on_n[0][90] = 4.09e-8; + // I_g_on_n[0][100] = 4.09e-8; + + SENSE_AMP_D = .2e-9; // s + SENSE_AMP_P = 5.7e-15; // J + vdd[0] = 1.25; + Lphy[0] = 0.025; + Lelec[0] = 0.019; + t_ox[0] = 1.1e-3; + v_th[0] = .12491; + c_ox[0] = 1.88e-14; + mobility_eff[0] = 409.31 * (1e-2 * 1e6 * 1e-2 * 1e6); + Vdsat[0] = 9.08e-2; + c_g_ideal[0] = 4.72e-16; + c_fringe[0] = 0.08e-15; + c_junc[0] = 1e-15; + I_on_n[0] = 1486.4e-6; + I_on_p[0] = 1131.5e-6; + nmos_effective_resistance_multiplier = 1.57; + n_to_p_eff_curr_drv_ratio[0] = 2; + gmp_to_gmn_multiplier[0] = 1.38; + Rnchannelon[0] = + nmos_effective_resistance_multiplier * vdd[0] / I_on_n[0]; + Rpchannelon[0] = n_to_p_eff_curr_drv_ratio[0] * Rnchannelon[0]; + long_channel_leakage_reduction[0] = 1.0 / 4.97; + // Using MASTAR, @380K, increase Lgate until Ion reduces to 90% or Lgate + // increase by 10%, whichever comes first Ioff(Lgate normal)/Ioff(Lgate + // long)= 4.97@Vdd=1.25; (3.74@Vdd=1.1), however, Intel paper suggest the + // reduction factor is 3. + I_off_n[0][0] = 8.62e-7; + I_off_n[0][10] = 9.08e-7; + I_off_n[0][20] = 9.55e-7; + I_off_n[0][30] = 1.00e-6; + I_off_n[0][40] = 1.05e-6; + I_off_n[0][50] = 1.09e-6; + I_off_n[0][60] = 1.14e-6; + I_off_n[0][70] = 1.18e-6; + I_off_n[0][80] = 1.23e-6; + I_off_n[0][90] = 1.27e-6; + I_off_n[0][100] = 1.31e-6; + + I_g_on_n[0][0] = 7.02e-8; // A/micron + I_g_on_n[0][10] = 7.02e-8; + I_g_on_n[0][20] = 7.02e-8; + I_g_on_n[0][30] = 7.02e-8; + I_g_on_n[0][40] = 7.02e-8; + I_g_on_n[0][50] = 7.02e-8; + I_g_on_n[0][60] = 7.02e-8; + I_g_on_n[0][70] = 7.02e-8; + I_g_on_n[0][80] = 7.02e-8; + I_g_on_n[0][90] = 7.02e-8; + I_g_on_n[0][100] = 7.02e-8; + + // ITRS LSTP device type vdd[1] = 1.2; Lphy[1] = 0.045; Lelec[1] = 0.0298; @@ -583,9 +572,10 @@ void init_tech_params(double technology, bool is_tag) nmos_effective_resistance_multiplier = 1.96; n_to_p_eff_curr_drv_ratio[1] = 2.23; gmp_to_gmn_multiplier[1] = 0.99; - Rnchannelon[1] = nmos_effective_resistance_multiplier * vdd[1] / I_on_n[1]; + Rnchannelon[1] = + nmos_effective_resistance_multiplier * vdd[1] / I_on_n[1]; Rpchannelon[1] = n_to_p_eff_curr_drv_ratio[1] * Rnchannelon[1]; - long_channel_leakage_reduction[1] = 1/2.82; + long_channel_leakage_reduction[1] = 1 / 2.82; I_off_n[1][0] = 9.12e-12; I_off_n[1][10] = 1.49e-11; I_off_n[1][20] = 2.36e-11; @@ -598,7 +588,7 @@ void init_tech_params(double technology, bool is_tag) I_off_n[1][90] = 2.62e-10; I_off_n[1][100] = 3.21e-10; - I_g_on_n[1][0] = 1.09e-10;//A/micron + I_g_on_n[1][0] = 1.09e-10; // A/micron I_g_on_n[1][10] = 1.09e-10; I_g_on_n[1][20] = 1.09e-10; I_g_on_n[1][30] = 1.09e-10; @@ -610,7 +600,7 @@ void init_tech_params(double technology, bool is_tag) I_g_on_n[1][90] = 1.09e-10; I_g_on_n[1][100] = 1.09e-10; - //ITRS LOP device type + // ITRS LOP device type vdd[2] = 0.8; Lphy[2] = 0.032; Lelec[2] = 0.0216; @@ -627,9 +617,10 @@ void init_tech_params(double technology, bool is_tag) nmos_effective_resistance_multiplier = 1.82; n_to_p_eff_curr_drv_ratio[2] = 2.28; gmp_to_gmn_multiplier[2] = 1.11; - Rnchannelon[2] = nmos_effective_resistance_multiplier * vdd[2] / I_on_n[2]; + Rnchannelon[2] = + nmos_effective_resistance_multiplier * vdd[2] / I_on_n[2]; Rpchannelon[2] = n_to_p_eff_curr_drv_ratio[2] * Rnchannelon[2]; - long_channel_leakage_reduction[2] = 1/2.05; + long_channel_leakage_reduction[2] = 1 / 2.05; I_off_n[2][0] = 4.9e-9; I_off_n[2][10] = 6.49e-9; I_off_n[2][20] = 8.45e-9; @@ -642,7 +633,7 @@ void init_tech_params(double technology, bool is_tag) I_off_n[2][90] = 3.13e-8; I_off_n[2][100] = 3.42e-8; - I_g_on_n[2][0] = 9.61e-9;//A/micron + I_g_on_n[2][0] = 9.61e-9; // A/micron I_g_on_n[2][10] = 9.61e-9; I_g_on_n[2][20] = 9.61e-9; I_g_on_n[2][30] = 9.61e-9; @@ -654,9 +645,8 @@ void init_tech_params(double technology, bool is_tag) I_g_on_n[2][90] = 9.61e-9; I_g_on_n[2][100] = 9.61e-9; - if (ram_cell_tech_type == lp_dram) - { - //LP-DRAM cell access transistor technology parameters + if (ram_cell_tech_type == lp_dram) { + // LP-DRAM cell access transistor technology parameters curr_vdd_dram_cell = 1.2; Lphy[3] = 0.12; Lelec[3] = 0.0756; @@ -671,25 +661,26 @@ void init_tech_params(double technology, bool is_tag) curr_asp_ratio_cell_dram = 1.46; curr_c_dram_cell = 20e-15; - //LP-DRAM wordline transistor parameters + // LP-DRAM wordline transistor parameters curr_vpp = 1.6; t_ox[3] = 2.2e-3; v_th[3] = 0.43806; c_ox[3] = 1.22e-14; - mobility_eff[3] = 328.32 * (1e-2 * 1e6 * 1e-2 * 1e6); + mobility_eff[3] = 328.32 * (1e-2 * 1e6 * 1e-2 * 1e6); Vdsat[3] = 0.43806; c_g_ideal[3] = 1.46e-15; c_fringe[3] = 0.08e-15; - c_junc[3] = 1e-15 ; + c_junc[3] = 1e-15; I_on_n[3] = 399.8e-6; I_on_p[3] = 243.4e-6; nmos_effective_resistance_multiplier = 1.65; n_to_p_eff_curr_drv_ratio[3] = 2.05; gmp_to_gmn_multiplier[3] = 0.90; - Rnchannelon[3] = nmos_effective_resistance_multiplier * curr_vpp / I_on_n[3]; + Rnchannelon[3] = + nmos_effective_resistance_multiplier * curr_vpp / I_on_n[3]; Rpchannelon[3] = n_to_p_eff_curr_drv_ratio[3] * Rnchannelon[3]; long_channel_leakage_reduction[3] = 1; - I_off_n[3][0] = 2.23e-11; + I_off_n[3][0] = 2.23e-11; I_off_n[3][10] = 3.46e-11; I_off_n[3][20] = 5.24e-11; I_off_n[3][30] = 7.75e-11; @@ -700,10 +691,8 @@ void init_tech_params(double technology, bool is_tag) I_off_n[3][80] = 3.63e-10; I_off_n[3][90] = 4.41e-10; I_off_n[3][100] = 5.36e-10; - } - else if (ram_cell_tech_type == comm_dram) - { - //COMM-DRAM cell access transistor technology parameters + } else if (ram_cell_tech_type == comm_dram) { + // COMM-DRAM cell access transistor technology parameters curr_vdd_dram_cell = 1.3; Lphy[3] = 0.065; Lelec[3] = 0.0426; @@ -714,29 +703,30 @@ void init_tech_params(double technology, bool is_tag) curr_Wmemcella_dram = width_dram_access_transistor; curr_Wmemcellpmos_dram = 0; curr_Wmemcellnmos_dram = 0; - curr_area_cell_dram = 6*0.065*0.065; + curr_area_cell_dram = 6 * 0.065 * 0.065; curr_asp_ratio_cell_dram = 1.5; curr_c_dram_cell = 30e-15; - //COMM-DRAM wordline transistor parameters + // COMM-DRAM wordline transistor parameters curr_vpp = 3.3; t_ox[3] = 5e-3; v_th[3] = 1.0; c_ox[3] = 6.16e-15; - mobility_eff[3] = 303.44 * (1e-2 * 1e6 * 1e-2 * 1e6); + mobility_eff[3] = 303.44 * (1e-2 * 1e6 * 1e-2 * 1e6); Vdsat[3] = 0.385; c_g_ideal[3] = 4e-16; c_fringe[3] = 0.08e-15; - c_junc[3] = 1e-15 ; + c_junc[3] = 1e-15; I_on_n[3] = 1031e-6; I_on_p[3] = I_on_n[3] / 2; nmos_effective_resistance_multiplier = 1.69; n_to_p_eff_curr_drv_ratio[3] = 2.39; gmp_to_gmn_multiplier[3] = 0.90; - Rnchannelon[3] = nmos_effective_resistance_multiplier * curr_vpp / I_on_n[3]; + Rnchannelon[3] = + nmos_effective_resistance_multiplier * curr_vpp / I_on_n[3]; Rpchannelon[3] = n_to_p_eff_curr_drv_ratio[3] * Rnchannelon[3]; long_channel_leakage_reduction[3] = 1; - I_off_n[3][0] = 1.80e-14; + I_off_n[3][0] = 1.80e-14; I_off_n[3][10] = 3.64e-14; I_off_n[3][20] = 7.03e-14; I_off_n[3][30] = 1.31e-13; @@ -749,31 +739,32 @@ void init_tech_params(double technology, bool is_tag) I_off_n[3][100] = 3.99e-12; } - //SRAM cell properties + // SRAM cell properties curr_Wmemcella_sram = 1.31 * g_ip->F_sz_um; curr_Wmemcellpmos_sram = 1.23 * g_ip->F_sz_um; curr_Wmemcellnmos_sram = 2.08 * g_ip->F_sz_um; curr_area_cell_sram = 146 * g_ip->F_sz_um * g_ip->F_sz_um; curr_asp_ratio_cell_sram = 1.46; - //CAM cell properties //TODO: data need to be revisited + // CAM cell properties //TODO: data need to be revisited curr_Wmemcella_cam = 1.31 * g_ip->F_sz_um; curr_Wmemcellpmos_cam = 1.23 * g_ip->F_sz_um; curr_Wmemcellnmos_cam = 2.08 * g_ip->F_sz_um; curr_area_cell_cam = 292 * g_ip->F_sz_um * g_ip->F_sz_um; curr_asp_ratio_cell_cam = 2.92; - //Empirical undifferetiated core/FU coefficient + // Empirical undifferetiated core/FU coefficient curr_logic_scaling_co_eff = 0.7; - curr_core_tx_density = 1.25*0.7; - curr_sckt_co_eff = 1.1359; - curr_chip_layout_overhead = 1.2;//die measurement results based on Niagara 1 and 2 - curr_macro_layout_overhead = 1.1;//EDA placement and routing tool rule of thumb + curr_core_tx_density = 1.25 * 0.7; + curr_sckt_co_eff = 1.1359; + curr_chip_layout_overhead = + 1.2; // die measurement results based on Niagara 1 and 2 + curr_macro_layout_overhead = + 1.1; // EDA placement and routing tool rule of thumb } - if (tech == 45) - { //45nm technology-node. Corresponds to year 2010 in ITRS - //ITRS HP device type - SENSE_AMP_D = .04e-9; // s - SENSE_AMP_P = 2.7e-15; // J + if (tech == 45) { // 45nm technology-node. Corresponds to year 2010 in ITRS + // ITRS HP device type + SENSE_AMP_D = .04e-9; // s + SENSE_AMP_P = 2.7e-15; // J vdd[0] = 1.0; Lphy[0] = 0.018; Lelec[0] = 0.01345; @@ -786,15 +777,20 @@ void init_tech_params(double technology, bool is_tag) c_fringe[0] = 0.05e-15; c_junc[0] = 1e-15; I_on_n[0] = 2046.6e-6; - //There are certain problems with the ITRS PMOS numbers in MASTAR for 45nm. So we are using 65nm values of - //n_to_p_eff_curr_drv_ratio and gmp_to_gmn_multiplier for 45nm - I_on_p[0] = I_on_n[0] / 2;//This value is fixed arbitrarily but I_on_p is not being used in CACTI + // There are certain problems with the ITRS PMOS numbers in MASTAR for + // 45nm. So we are using 65nm values of n_to_p_eff_curr_drv_ratio and + // gmp_to_gmn_multiplier for 45nm + I_on_p[0] = I_on_n[0] / 2; // This value is fixed arbitrarily but I_on_p + // is not being used in CACTI nmos_effective_resistance_multiplier = 1.51; n_to_p_eff_curr_drv_ratio[0] = 2.41; gmp_to_gmn_multiplier[0] = 1.38; - Rnchannelon[0] = nmos_effective_resistance_multiplier * vdd[0] / I_on_n[0]; + Rnchannelon[0] = + nmos_effective_resistance_multiplier * vdd[0] / I_on_n[0]; Rpchannelon[0] = n_to_p_eff_curr_drv_ratio[0] * Rnchannelon[0]; - long_channel_leakage_reduction[0] = 1/3.546;//Using MASTAR, @380K, increase Lgate until Ion reduces to 90%, Ioff(Lgate normal)/Ioff(Lgate long)= 3.74 + long_channel_leakage_reduction[0] = + 1 / 3.546; // Using MASTAR, @380K, increase Lgate until Ion reduces + // to 90%, Ioff(Lgate normal)/Ioff(Lgate long)= 3.74 I_off_n[0][0] = 2.8e-7; I_off_n[0][10] = 3.28e-7; I_off_n[0][20] = 3.81e-7; @@ -807,7 +803,7 @@ void init_tech_params(double technology, bool is_tag) I_off_n[0][90] = 8.91e-7; I_off_n[0][100] = 9.84e-7; - I_g_on_n[0][0] = 3.59e-8;//A/micron + I_g_on_n[0][0] = 3.59e-8; // A/micron I_g_on_n[0][10] = 3.59e-8; I_g_on_n[0][20] = 3.59e-8; I_g_on_n[0][30] = 3.59e-8; @@ -819,14 +815,14 @@ void init_tech_params(double technology, bool is_tag) I_g_on_n[0][90] = 3.59e-8; I_g_on_n[0][100] = 3.59e-8; - //ITRS LSTP device type + // ITRS LSTP device type vdd[1] = 1.1; - Lphy[1] = 0.028; + Lphy[1] = 0.028; Lelec[1] = 0.0212; t_ox[1] = 1.4e-3; v_th[1] = 0.50245; c_ox[1] = 2.01e-14; - mobility_eff[1] = 363.96 * (1e-2 * 1e6 * 1e-2 * 1e6); + mobility_eff[1] = 363.96 * (1e-2 * 1e6 * 1e-2 * 1e6); Vdsat[1] = 9.12e-2; c_g_ideal[1] = 5.18e-16; c_fringe[1] = 0.08e-15; @@ -836,9 +832,10 @@ void init_tech_params(double technology, bool is_tag) nmos_effective_resistance_multiplier = 1.99; n_to_p_eff_curr_drv_ratio[1] = 2.23; gmp_to_gmn_multiplier[1] = 0.99; - Rnchannelon[1] = nmos_effective_resistance_multiplier * vdd[1] / I_on_n[1]; + Rnchannelon[1] = + nmos_effective_resistance_multiplier * vdd[1] / I_on_n[1]; Rpchannelon[1] = n_to_p_eff_curr_drv_ratio[1] * Rnchannelon[1]; - long_channel_leakage_reduction[1] = 1/2.08; + long_channel_leakage_reduction[1] = 1 / 2.08; I_off_n[1][0] = 1.01e-11; I_off_n[1][10] = 1.65e-11; I_off_n[1][20] = 2.62e-11; @@ -851,7 +848,7 @@ void init_tech_params(double technology, bool is_tag) I_off_n[1][90] = 3.29e-10; I_off_n[1][100] = 4.1e-10; - I_g_on_n[1][0] = 9.47e-12;//A/micron + I_g_on_n[1][0] = 9.47e-12; // A/micron I_g_on_n[1][10] = 9.47e-12; I_g_on_n[1][20] = 9.47e-12; I_g_on_n[1][30] = 9.47e-12; @@ -863,13 +860,13 @@ void init_tech_params(double technology, bool is_tag) I_g_on_n[1][90] = 9.47e-12; I_g_on_n[1][100] = 9.47e-12; - //ITRS LOP device type + // ITRS LOP device type vdd[2] = 0.7; Lphy[2] = 0.022; Lelec[2] = 0.016; t_ox[2] = 0.9e-3; v_th[2] = 0.22599; - c_ox[2] = 2.82e-14;//F/micron2 + c_ox[2] = 2.82e-14; // F/micron2 mobility_eff[2] = 508.9 * (1e-2 * 1e6 * 1e-2 * 1e6); Vdsat[2] = 5.71e-2; c_g_ideal[2] = 6.2e-16; @@ -880,9 +877,10 @@ void init_tech_params(double technology, bool is_tag) nmos_effective_resistance_multiplier = 1.76; n_to_p_eff_curr_drv_ratio[2] = 2.28; gmp_to_gmn_multiplier[2] = 1.11; - Rnchannelon[2] = nmos_effective_resistance_multiplier * vdd[2] / I_on_n[2]; + Rnchannelon[2] = + nmos_effective_resistance_multiplier * vdd[2] / I_on_n[2]; Rpchannelon[2] = n_to_p_eff_curr_drv_ratio[2] * Rnchannelon[2]; - long_channel_leakage_reduction[2] = 1/1.92; + long_channel_leakage_reduction[2] = 1 / 1.92; I_off_n[2][0] = 4.03e-9; I_off_n[2][10] = 5.02e-9; I_off_n[2][20] = 6.18e-9; @@ -895,7 +893,7 @@ void init_tech_params(double technology, bool is_tag) I_off_n[2][90] = 1.84e-8; I_off_n[2][100] = 2.03e-8; - I_g_on_n[2][0] = 3.24e-8;//A/micron + I_g_on_n[2][0] = 3.24e-8; // A/micron I_g_on_n[2][10] = 4.01e-8; I_g_on_n[2][20] = 4.90e-8; I_g_on_n[2][30] = 5.92e-8; @@ -907,29 +905,29 @@ void init_tech_params(double technology, bool is_tag) I_g_on_n[2][90] = 1.43e-7; I_g_on_n[2][100] = 1.54e-7; - if (ram_cell_tech_type == lp_dram) - { - //LP-DRAM cell access transistor technology parameters + if (ram_cell_tech_type == lp_dram) { + // LP-DRAM cell access transistor technology parameters curr_vdd_dram_cell = 1.1; Lphy[3] = 0.078; - Lelec[3] = 0.0504;// Assume Lelec is 30% lesser than Lphy for DRAM access and wordline transistors. + Lelec[3] = 0.0504; // Assume Lelec is 30% lesser than Lphy for DRAM + // access and wordline transistors. curr_v_th_dram_access_transistor = 0.44559; width_dram_access_transistor = 0.079; - curr_I_on_dram_cell = 36e-6;//A + curr_I_on_dram_cell = 36e-6; // A curr_I_off_dram_cell_worst_case_length_temp = 19.5e-12; curr_Wmemcella_dram = width_dram_access_transistor; curr_Wmemcellpmos_dram = 0; - curr_Wmemcellnmos_dram = 0; + curr_Wmemcellnmos_dram = 0; curr_area_cell_dram = width_dram_access_transistor * Lphy[3] * 10.0; curr_asp_ratio_cell_dram = 1.46; curr_c_dram_cell = 20e-15; - //LP-DRAM wordline transistor parameters + // LP-DRAM wordline transistor parameters curr_vpp = 1.5; t_ox[3] = 2.1e-3; v_th[3] = 0.44559; c_ox[3] = 1.41e-14; - mobility_eff[3] = 426.30 * (1e-2 * 1e6 * 1e-2 * 1e6); + mobility_eff[3] = 426.30 * (1e-2 * 1e6 * 1e-2 * 1e6); Vdsat[3] = 0.181; c_g_ideal[3] = 1.10e-15; c_fringe[3] = 0.08e-15; @@ -939,7 +937,8 @@ void init_tech_params(double technology, bool is_tag) nmos_effective_resistance_multiplier = 1.65; n_to_p_eff_curr_drv_ratio[3] = 2.05; gmp_to_gmn_multiplier[3] = 0.90; - Rnchannelon[3] = nmos_effective_resistance_multiplier * curr_vpp / I_on_n[3]; + Rnchannelon[3] = + nmos_effective_resistance_multiplier * curr_vpp / I_on_n[3]; Rpchannelon[3] = n_to_p_eff_curr_drv_ratio[3] * Rnchannelon[3]; long_channel_leakage_reduction[3] = 1; I_off_n[3][0] = 2.54e-11; @@ -953,25 +952,23 @@ void init_tech_params(double technology, bool is_tag) I_off_n[3][80] = 4.26e-10; I_off_n[3][90] = 5.27e-10; I_off_n[3][100] = 6.46e-10; - } - else if (ram_cell_tech_type == comm_dram) - { - //COMM-DRAM cell access transistor technology parameters + } else if (ram_cell_tech_type == comm_dram) { + // COMM-DRAM cell access transistor technology parameters curr_vdd_dram_cell = 1.1; Lphy[3] = 0.045; Lelec[3] = 0.0298; curr_v_th_dram_access_transistor = 1; width_dram_access_transistor = 0.045; - curr_I_on_dram_cell = 20e-6;//A + curr_I_on_dram_cell = 20e-6; // A curr_I_off_dram_cell_worst_case_length_temp = 1e-15; curr_Wmemcella_dram = width_dram_access_transistor; curr_Wmemcellpmos_dram = 0; - curr_Wmemcellnmos_dram = 0; - curr_area_cell_dram = 6*0.045*0.045; + curr_Wmemcellnmos_dram = 0; + curr_area_cell_dram = 6 * 0.045 * 0.045; curr_asp_ratio_cell_dram = 1.5; curr_c_dram_cell = 30e-15; - //COMM-DRAM wordline transistor parameters + // COMM-DRAM wordline transistor parameters curr_vpp = 2.7; t_ox[3] = 4e-3; v_th[3] = 1.0; @@ -986,7 +983,8 @@ void init_tech_params(double technology, bool is_tag) nmos_effective_resistance_multiplier = 1.69; n_to_p_eff_curr_drv_ratio[3] = 1.95; gmp_to_gmn_multiplier[3] = 0.90; - Rnchannelon[3] = nmos_effective_resistance_multiplier * curr_vpp / I_on_n[3]; + Rnchannelon[3] = + nmos_effective_resistance_multiplier * curr_vpp / I_on_n[3]; Rpchannelon[3] = n_to_p_eff_curr_drv_ratio[3] * Rnchannelon[3]; long_channel_leakage_reduction[3] = 1; I_off_n[3][0] = 1.31e-14; @@ -1002,34 +1000,34 @@ void init_tech_params(double technology, bool is_tag) I_off_n[3][100] = 3.29e-12; } - - //SRAM cell properties + // SRAM cell properties curr_Wmemcella_sram = 1.31 * g_ip->F_sz_um; curr_Wmemcellpmos_sram = 1.23 * g_ip->F_sz_um; curr_Wmemcellnmos_sram = 2.08 * g_ip->F_sz_um; curr_area_cell_sram = 146 * g_ip->F_sz_um * g_ip->F_sz_um; curr_asp_ratio_cell_sram = 1.46; - //CAM cell properties //TODO: data need to be revisited + // CAM cell properties //TODO: data need to be revisited curr_Wmemcella_cam = 1.31 * g_ip->F_sz_um; curr_Wmemcellpmos_cam = 1.23 * g_ip->F_sz_um; curr_Wmemcellnmos_cam = 2.08 * g_ip->F_sz_um; curr_area_cell_cam = 292 * g_ip->F_sz_um * g_ip->F_sz_um; curr_asp_ratio_cell_cam = 2.92; - //Empirical undifferetiated core/FU coefficient - curr_logic_scaling_co_eff = 0.7*0.7; - curr_core_tx_density = 1.25; - curr_sckt_co_eff = 1.1387; - curr_chip_layout_overhead = 1.2;//die measurement results based on Niagara 1 and 2 - curr_macro_layout_overhead = 1.1;//EDA placement and routing tool rule of thumb + // Empirical undifferetiated core/FU coefficient + curr_logic_scaling_co_eff = 0.7 * 0.7; + curr_core_tx_density = 1.25; + curr_sckt_co_eff = 1.1387; + curr_chip_layout_overhead = + 1.2; // die measurement results based on Niagara 1 and 2 + curr_macro_layout_overhead = + 1.1; // EDA placement and routing tool rule of thumb } - if (tech == 32) - { - SENSE_AMP_D = .03e-9; // s - SENSE_AMP_P = 2.16e-15; // J - //For 2013, MPU/ASIC stagger-contacted M1 half-pitch is 32 nm (so this is 32 nm - //technology i.e. FEATURESIZE = 0.032). Using the SOI process numbers for - //HP and LSTP. + if (tech == 32) { + SENSE_AMP_D = .03e-9; // s + SENSE_AMP_P = 2.16e-15; // J + // For 2013, MPU/ASIC stagger-contacted M1 half-pitch is 32 nm (so this is + // 32 nm technology i.e. FEATURESIZE = 0.032). Using the SOI process + // numbers for HP and LSTP. vdd[0] = 0.9; Lphy[0] = 0.013; Lelec[0] = 0.01013; @@ -1041,16 +1039,19 @@ void init_tech_params(double technology, bool is_tag) c_g_ideal[0] = 5.34e-16; c_fringe[0] = 0.04e-15; c_junc[0] = 1e-15; - I_on_n[0] = 2211.7e-6; + I_on_n[0] = 2211.7e-6; I_on_p[0] = I_on_n[0] / 2; nmos_effective_resistance_multiplier = 1.49; n_to_p_eff_curr_drv_ratio[0] = 2.41; gmp_to_gmn_multiplier[0] = 1.38; - Rnchannelon[0] = nmos_effective_resistance_multiplier * vdd[0] / I_on_n[0];//ohm-micron - Rpchannelon[0] = n_to_p_eff_curr_drv_ratio[0] * Rnchannelon[0];//ohm-micron - long_channel_leakage_reduction[0] = 1/3.706; - //Using MASTAR, @300K (380K does not work in MASTAR), increase Lgate until Ion reduces to 95% or Lgate increase by 5% (DG device can only increase by 5%), - //whichever comes first + Rnchannelon[0] = nmos_effective_resistance_multiplier * vdd[0] / + I_on_n[0]; // ohm-micron + Rpchannelon[0] = + n_to_p_eff_curr_drv_ratio[0] * Rnchannelon[0]; // ohm-micron + long_channel_leakage_reduction[0] = 1 / 3.706; + // Using MASTAR, @300K (380K does not work in MASTAR), increase Lgate + // until Ion reduces to 95% or Lgate increase by 5% (DG device can only + // increase by 5%), whichever comes first I_off_n[0][0] = 1.52e-7; I_off_n[0][10] = 1.55e-7; I_off_n[0][20] = 1.59e-7; @@ -1063,7 +1064,7 @@ void init_tech_params(double technology, bool is_tag) I_off_n[0][90] = 2.73e-6; I_off_n[0][100] = 6.1e-6; - I_g_on_n[0][0] = 6.55e-8;//A/micron + I_g_on_n[0][0] = 6.55e-8; // A/micron I_g_on_n[0][10] = 6.55e-8; I_g_on_n[0][20] = 6.55e-8; I_g_on_n[0][30] = 6.55e-8; @@ -1075,27 +1076,27 @@ void init_tech_params(double technology, bool is_tag) I_g_on_n[0][90] = 6.55e-8; I_g_on_n[0][100] = 6.55e-8; -// 32 DG -// I_g_on_n[0][0] = 2.71e-9;//A/micron -// I_g_on_n[0][10] = 2.71e-9; -// I_g_on_n[0][20] = 2.71e-9; -// I_g_on_n[0][30] = 2.71e-9; -// I_g_on_n[0][40] = 2.71e-9; -// I_g_on_n[0][50] = 2.71e-9; -// I_g_on_n[0][60] = 2.71e-9; -// I_g_on_n[0][70] = 2.71e-9; -// I_g_on_n[0][80] = 2.71e-9; -// I_g_on_n[0][90] = 2.71e-9; -// I_g_on_n[0][100] = 2.71e-9; - - //LSTP device type + // 32 DG + // I_g_on_n[0][0] = 2.71e-9;//A/micron + // I_g_on_n[0][10] = 2.71e-9; + // I_g_on_n[0][20] = 2.71e-9; + // I_g_on_n[0][30] = 2.71e-9; + // I_g_on_n[0][40] = 2.71e-9; + // I_g_on_n[0][50] = 2.71e-9; + // I_g_on_n[0][60] = 2.71e-9; + // I_g_on_n[0][70] = 2.71e-9; + // I_g_on_n[0][80] = 2.71e-9; + // I_g_on_n[0][90] = 2.71e-9; + // I_g_on_n[0][100] = 2.71e-9; + + // LSTP device type vdd[1] = 1; Lphy[1] = 0.020; Lelec[1] = 0.0173; t_ox[1] = 1.2e-3; v_th[1] = 0.513; c_ox[1] = 2.29e-14; - mobility_eff[1] = 347.46 * (1e-2 * 1e6 * 1e-2 * 1e6); + mobility_eff[1] = 347.46 * (1e-2 * 1e6 * 1e-2 * 1e6); Vdsat[1] = 8.64e-2; c_g_ideal[1] = 4.58e-16; c_fringe[1] = 0.053e-15; @@ -1105,9 +1106,10 @@ void init_tech_params(double technology, bool is_tag) nmos_effective_resistance_multiplier = 1.99; n_to_p_eff_curr_drv_ratio[1] = 2.23; gmp_to_gmn_multiplier[1] = 0.99; - Rnchannelon[1] = nmos_effective_resistance_multiplier * vdd[1] / I_on_n[1]; + Rnchannelon[1] = + nmos_effective_resistance_multiplier * vdd[1] / I_on_n[1]; Rpchannelon[1] = n_to_p_eff_curr_drv_ratio[1] * Rnchannelon[1]; - long_channel_leakage_reduction[1] = 1/1.93; + long_channel_leakage_reduction[1] = 1 / 1.93; I_off_n[1][0] = 2.06e-11; I_off_n[1][10] = 3.30e-11; I_off_n[1][20] = 5.15e-11; @@ -1120,7 +1122,7 @@ void init_tech_params(double technology, bool is_tag) I_off_n[1][90] = 5.96e-10; I_off_n[1][100] = 7.44e-10; - I_g_on_n[1][0] = 3.73e-11;//A/micron + I_g_on_n[1][0] = 3.73e-11; // A/micron I_g_on_n[1][10] = 3.73e-11; I_g_on_n[1][20] = 3.73e-11; I_g_on_n[1][30] = 3.73e-11; @@ -1132,15 +1134,14 @@ void init_tech_params(double technology, bool is_tag) I_g_on_n[1][90] = 3.73e-11; I_g_on_n[1][100] = 3.73e-11; - - //LOP device type + // LOP device type vdd[2] = 0.6; Lphy[2] = 0.016; Lelec[2] = 0.01232; t_ox[2] = 0.9e-3; v_th[2] = 0.24227; c_ox[2] = 2.84e-14; - mobility_eff[2] = 513.52 * (1e-2 * 1e6 * 1e-2 * 1e6); + mobility_eff[2] = 513.52 * (1e-2 * 1e6 * 1e-2 * 1e6); Vdsat[2] = 4.64e-2; c_g_ideal[2] = 4.54e-16; c_fringe[2] = 0.057e-15; @@ -1150,9 +1151,10 @@ void init_tech_params(double technology, bool is_tag) nmos_effective_resistance_multiplier = 1.73; n_to_p_eff_curr_drv_ratio[2] = 2.28; gmp_to_gmn_multiplier[2] = 1.11; - Rnchannelon[2] = nmos_effective_resistance_multiplier * vdd[2] / I_on_n[2]; + Rnchannelon[2] = + nmos_effective_resistance_multiplier * vdd[2] / I_on_n[2]; Rpchannelon[2] = n_to_p_eff_curr_drv_ratio[2] * Rnchannelon[2]; - long_channel_leakage_reduction[2] = 1/1.89; + long_channel_leakage_reduction[2] = 1 / 1.89; I_off_n[2][0] = 5.94e-8; I_off_n[2][10] = 7.23e-8; I_off_n[2][20] = 8.7e-8; @@ -1165,7 +1167,7 @@ void init_tech_params(double technology, bool is_tag) I_off_n[2][90] = 2.39e-7; I_off_n[2][100] = 2.63e-7; - I_g_on_n[2][0] = 2.93e-9;//A/micron + I_g_on_n[2][0] = 2.93e-9; // A/micron I_g_on_n[2][10] = 2.93e-9; I_g_on_n[2][20] = 2.93e-9; I_g_on_n[2][30] = 2.93e-9; @@ -1177,12 +1179,12 @@ void init_tech_params(double technology, bool is_tag) I_g_on_n[2][90] = 2.93e-9; I_g_on_n[2][100] = 2.93e-9; - if (ram_cell_tech_type == lp_dram) - { - //LP-DRAM cell access transistor technology parameters + if (ram_cell_tech_type == lp_dram) { + // LP-DRAM cell access transistor technology parameters curr_vdd_dram_cell = 1.0; Lphy[3] = 0.056; - Lelec[3] = 0.0419;//Assume Lelec is 30% lesser than Lphy for DRAM access and wordline transistors. + Lelec[3] = 0.0419; // Assume Lelec is 30% lesser than Lphy for DRAM + // access and wordline transistors. curr_v_th_dram_access_transistor = 0.44129; width_dram_access_transistor = 0.056; curr_I_on_dram_cell = 36e-6; @@ -1194,12 +1196,12 @@ void init_tech_params(double technology, bool is_tag) curr_asp_ratio_cell_dram = 1.46; curr_c_dram_cell = 20e-15; - //LP-DRAM wordline transistor parameters + // LP-DRAM wordline transistor parameters curr_vpp = 1.5; t_ox[3] = 2e-3; v_th[3] = 0.44467; c_ox[3] = 1.48e-14; - mobility_eff[3] = 408.12 * (1e-2 * 1e6 * 1e-2 * 1e6); + mobility_eff[3] = 408.12 * (1e-2 * 1e6 * 1e-2 * 1e6); Vdsat[3] = 0.174; c_g_ideal[3] = 7.45e-16; c_fringe[3] = 0.053e-15; @@ -1209,10 +1211,11 @@ void init_tech_params(double technology, bool is_tag) nmos_effective_resistance_multiplier = 1.65; n_to_p_eff_curr_drv_ratio[3] = 2.05; gmp_to_gmn_multiplier[3] = 0.90; - Rnchannelon[3] = nmos_effective_resistance_multiplier * curr_vpp / I_on_n[3]; + Rnchannelon[3] = + nmos_effective_resistance_multiplier * curr_vpp / I_on_n[3]; Rpchannelon[3] = n_to_p_eff_curr_drv_ratio[3] * Rnchannelon[3]; long_channel_leakage_reduction[3] = 1; - I_off_n[3][0] = 3.57e-11; + I_off_n[3][0] = 3.57e-11; I_off_n[3][10] = 5.51e-11; I_off_n[3][20] = 8.27e-11; I_off_n[3][30] = 1.21e-10; @@ -1223,13 +1226,12 @@ void init_tech_params(double technology, bool is_tag) I_off_n[3][80] = 5.87e-10; I_off_n[3][90] = 7.29e-10; I_off_n[3][100] = 8.87e-10; - } - else if (ram_cell_tech_type == comm_dram) - { - //COMM-DRAM cell access transistor technology parameters + } else if (ram_cell_tech_type == comm_dram) { + // COMM-DRAM cell access transistor technology parameters curr_vdd_dram_cell = 1.0; Lphy[3] = 0.032; - Lelec[3] = 0.0205;//Assume Lelec is 30% lesser than Lphy for DRAM access and wordline transistors. + Lelec[3] = 0.0205; // Assume Lelec is 30% lesser than Lphy for DRAM + // access and wordline transistors. curr_v_th_dram_access_transistor = 1; width_dram_access_transistor = 0.032; curr_I_on_dram_cell = 20e-6; @@ -1237,16 +1239,16 @@ void init_tech_params(double technology, bool is_tag) curr_Wmemcella_dram = width_dram_access_transistor; curr_Wmemcellpmos_dram = 0; curr_Wmemcellnmos_dram = 0; - curr_area_cell_dram = 6*0.032*0.032; + curr_area_cell_dram = 6 * 0.032 * 0.032; curr_asp_ratio_cell_dram = 1.5; curr_c_dram_cell = 30e-15; - //COMM-DRAM wordline transistor parameters + // COMM-DRAM wordline transistor parameters curr_vpp = 2.6; t_ox[3] = 4e-3; v_th[3] = 1.0; c_ox[3] = 7.99e-15; - mobility_eff[3] = 380.76 * (1e-2 * 1e6 * 1e-2 * 1e6); + mobility_eff[3] = 380.76 * (1e-2 * 1e6 * 1e-2 * 1e6); Vdsat[3] = 0.129; c_g_ideal[3] = 2.56e-16; c_fringe[3] = 0.053e-15; @@ -1256,10 +1258,11 @@ void init_tech_params(double technology, bool is_tag) nmos_effective_resistance_multiplier = 1.69; n_to_p_eff_curr_drv_ratio[3] = 1.95; gmp_to_gmn_multiplier[3] = 0.90; - Rnchannelon[3] = nmos_effective_resistance_multiplier * curr_vpp / I_on_n[3]; + Rnchannelon[3] = + nmos_effective_resistance_multiplier * curr_vpp / I_on_n[3]; Rpchannelon[3] = n_to_p_eff_curr_drv_ratio[3] * Rnchannelon[3]; long_channel_leakage_reduction[3] = 1; - I_off_n[3][0] = 3.63e-14; + I_off_n[3][0] = 3.63e-14; I_off_n[3][10] = 7.18e-14; I_off_n[3][20] = 1.36e-13; I_off_n[3][30] = 2.49e-13; @@ -1272,550 +1275,612 @@ void init_tech_params(double technology, bool is_tag) I_off_n[3][100] = 7.16e-12; } - //SRAM cell properties - curr_Wmemcella_sram = 1.31 * g_ip->F_sz_um; + // SRAM cell properties + curr_Wmemcella_sram = 1.31 * g_ip->F_sz_um; + curr_Wmemcellpmos_sram = 1.23 * g_ip->F_sz_um; + curr_Wmemcellnmos_sram = 2.08 * g_ip->F_sz_um; + curr_area_cell_sram = 146 * g_ip->F_sz_um * g_ip->F_sz_um; + curr_asp_ratio_cell_sram = 1.46; + // CAM cell properties //TODO: data need to be revisited + curr_Wmemcella_cam = 1.31 * g_ip->F_sz_um; + curr_Wmemcellpmos_cam = 1.23 * g_ip->F_sz_um; + curr_Wmemcellnmos_cam = 2.08 * g_ip->F_sz_um; + curr_area_cell_cam = 292 * g_ip->F_sz_um * g_ip->F_sz_um; + curr_asp_ratio_cell_cam = 2.92; + // Empirical undifferetiated core/FU coefficient + curr_logic_scaling_co_eff = 0.7 * 0.7 * 0.7; + curr_core_tx_density = 1.25 / 0.7; + curr_sckt_co_eff = 1.1111; + curr_chip_layout_overhead = + 1.2; // die measurement results based on Niagara 1 and 2 + curr_macro_layout_overhead = + 1.1; // EDA placement and routing tool rule of thumb + } + + if (tech == 22) { + // For 2016, MPU/ASIC stagger-contacted M1 half-pitch is 22 nm (so this is + // 22 nm technology i.e. FEATURESIZE = 0.022). Using the DG process + // numbers for HP. 22 nm HP + vdd[0] = 0.8; + Lphy[0] = 0.009; // Lphy is the physical gate-length. + Lelec[0] = 0.00468; // Lelec is the electrical gate-length. + t_ox[0] = 0.55e-3; // micron + v_th[0] = 0.1395; // V + c_ox[0] = 3.63e-14; // F/micron2 + mobility_eff[0] = 426.07 * (1e-2 * 1e6 * 1e-2 * 1e6); // micron2 / Vs + Vdsat[0] = 2.33e-2; // V/micron + c_g_ideal[0] = 3.27e-16; // F/micron + c_fringe[0] = 0.06e-15; // F/micron + c_junc[0] = 0; // F/micron2 + I_on_n[0] = 2626.4e-6; // A/micron + I_on_p[0] = I_on_n[0] / + 2; // A/micron //This value for I_on_p is not really used. + nmos_effective_resistance_multiplier = 1.45; + n_to_p_eff_curr_drv_ratio[0] = + 2; // Wpmos/Wnmos = 2 in 2007 MASTAR. Look in + //"Dynamic" tab of Device workspace. + gmp_to_gmn_multiplier[0] = 1.38; // Just using the 32nm SOI value. + Rnchannelon[0] = nmos_effective_resistance_multiplier * vdd[0] / + I_on_n[0]; // ohm-micron + Rpchannelon[0] = + n_to_p_eff_curr_drv_ratio[0] * Rnchannelon[0]; // ohm-micron + long_channel_leakage_reduction[0] = 1 / 3.274; + I_off_n[0][0] = + 1.52e-7 / 1.5 * + 1.2; // From 22nm, leakage current are directly from ITRS report + // rather than MASTAR, since MASTAR has serious bugs there. + I_off_n[0][10] = 1.55e-7 / 1.5 * 1.2; + I_off_n[0][20] = 1.59e-7 / 1.5 * 1.2; + I_off_n[0][30] = 1.68e-7 / 1.5 * 1.2; + I_off_n[0][40] = 1.90e-7 / 1.5 * 1.2; + I_off_n[0][50] = 2.69e-7 / 1.5 * 1.2; + I_off_n[0][60] = 5.32e-7 / 1.5 * 1.2; + I_off_n[0][70] = 1.02e-6 / 1.5 * 1.2; + I_off_n[0][80] = 1.62e-6 / 1.5 * 1.2; + I_off_n[0][90] = 2.73e-6 / 1.5 * 1.2; + I_off_n[0][100] = 6.1e-6 / 1.5 * 1.2; + // for 22nm DG HP + I_g_on_n[0][0] = 1.81e-9; // A/micron + I_g_on_n[0][10] = 1.81e-9; + I_g_on_n[0][20] = 1.81e-9; + I_g_on_n[0][30] = 1.81e-9; + I_g_on_n[0][40] = 1.81e-9; + I_g_on_n[0][50] = 1.81e-9; + I_g_on_n[0][60] = 1.81e-9; + I_g_on_n[0][70] = 1.81e-9; + I_g_on_n[0][80] = 1.81e-9; + I_g_on_n[0][90] = 1.81e-9; + I_g_on_n[0][100] = 1.81e-9; + + // 22 nm LSTP DG + vdd[1] = 0.8; + Lphy[1] = 0.014; + Lelec[1] = 0.008; // Lelec is the electrical gate-length. + t_ox[1] = 1.1e-3; // micron + v_th[1] = 0.40126; // V + c_ox[1] = 2.30e-14; // F/micron2 + mobility_eff[1] = 738.09 * (1e-2 * 1e6 * 1e-2 * 1e6); // micron2 / Vs + Vdsat[1] = 6.64e-2; // V/micron + c_g_ideal[1] = 3.22e-16; // F/micron + c_fringe[1] = 0.08e-15; + c_junc[1] = 0; // F/micron2 + I_on_n[1] = 727.6e-6; // A/micron + I_on_p[1] = I_on_n[1] / 2; + nmos_effective_resistance_multiplier = 1.99; + n_to_p_eff_curr_drv_ratio[1] = 2; + gmp_to_gmn_multiplier[1] = 0.99; + Rnchannelon[1] = nmos_effective_resistance_multiplier * vdd[1] / + I_on_n[1]; // ohm-micron + Rpchannelon[1] = + n_to_p_eff_curr_drv_ratio[1] * Rnchannelon[1]; // ohm-micron + long_channel_leakage_reduction[1] = 1 / 1.89; + I_off_n[1][0] = 2.43e-11; + I_off_n[1][10] = 4.85e-11; + I_off_n[1][20] = 9.68e-11; + I_off_n[1][30] = 1.94e-10; + I_off_n[1][40] = 3.87e-10; + I_off_n[1][50] = 7.73e-10; + I_off_n[1][60] = 3.55e-10; + I_off_n[1][70] = 3.09e-9; + I_off_n[1][80] = 6.19e-9; + I_off_n[1][90] = 1.24e-8; + I_off_n[1][100] = 2.48e-8; + + I_g_on_n[1][0] = 4.51e-10; // A/micron + I_g_on_n[1][10] = 4.51e-10; + I_g_on_n[1][20] = 4.51e-10; + I_g_on_n[1][30] = 4.51e-10; + I_g_on_n[1][40] = 4.51e-10; + I_g_on_n[1][50] = 4.51e-10; + I_g_on_n[1][60] = 4.51e-10; + I_g_on_n[1][70] = 4.51e-10; + I_g_on_n[1][80] = 4.51e-10; + I_g_on_n[1][90] = 4.51e-10; + I_g_on_n[1][100] = 4.51e-10; + + // 22 nm LOP + vdd[2] = 0.6; + Lphy[2] = 0.011; + Lelec[2] = 0.00604; // Lelec is the electrical gate-length. + t_ox[2] = 0.8e-3; // micron + v_th[2] = 0.2315; // V + c_ox[2] = 2.87e-14; // F/micron2 + mobility_eff[2] = 698.37 * (1e-2 * 1e6 * 1e-2 * 1e6); // micron2 / Vs + Vdsat[2] = 1.81e-2; // V/micron + c_g_ideal[2] = 3.16e-16; // F/micron + c_fringe[2] = 0.08e-15; + c_junc[2] = + 0; // F/micron2 This is Cj0 not Cjunc in MASTAR results->Dynamic Tab + I_on_n[2] = 916.1e-6; // A/micron + I_on_p[2] = I_on_n[2] / 2; + nmos_effective_resistance_multiplier = 1.73; + n_to_p_eff_curr_drv_ratio[2] = 2; + gmp_to_gmn_multiplier[2] = 1.11; + Rnchannelon[2] = nmos_effective_resistance_multiplier * vdd[2] / + I_on_n[2]; // ohm-micron + Rpchannelon[2] = + n_to_p_eff_curr_drv_ratio[2] * Rnchannelon[2]; // ohm-micron + long_channel_leakage_reduction[2] = 1 / 2.38; + + I_off_n[2][0] = 1.31e-8; + I_off_n[2][10] = 2.60e-8; + I_off_n[2][20] = 5.14e-8; + I_off_n[2][30] = 1.02e-7; + I_off_n[2][40] = 2.02e-7; + I_off_n[2][50] = 3.99e-7; + I_off_n[2][60] = 7.91e-7; + I_off_n[2][70] = 1.09e-6; + I_off_n[2][80] = 2.09e-6; + I_off_n[2][90] = 4.04e-6; + I_off_n[2][100] = 4.48e-6; + + I_g_on_n[2][0] = 2.74e-9; // A/micron + I_g_on_n[2][10] = 2.74e-9; + I_g_on_n[2][20] = 2.74e-9; + I_g_on_n[2][30] = 2.74e-9; + I_g_on_n[2][40] = 2.74e-9; + I_g_on_n[2][50] = 2.74e-9; + I_g_on_n[2][60] = 2.74e-9; + I_g_on_n[2][70] = 2.74e-9; + I_g_on_n[2][80] = 2.74e-9; + I_g_on_n[2][90] = 2.74e-9; + I_g_on_n[2][100] = 2.74e-9; + + if (ram_cell_tech_type == 3) { + } else if (ram_cell_tech_type == 4) { + // 22 nm commodity DRAM cell access transistor technology parameters. + // parameters + curr_vdd_dram_cell = 0.9; // 0.45;//This value has reduced greatly in + // 2007 ITRS for all technology nodes. In + // 2005 ITRS, the value was about twice the value in 2007 ITRS + Lphy[3] = 0.022; // micron + Lelec[3] = 0.0181; // micron. + curr_v_th_dram_access_transistor = 1; // V + width_dram_access_transistor = 0.022; // micron + curr_I_on_dram_cell = + 20e-6; // This is a typical value that I have always + // kept constant. In reality this could perhaps be lower + curr_I_off_dram_cell_worst_case_length_temp = 1e-15; // A + curr_Wmemcella_dram = width_dram_access_transistor; + curr_Wmemcellpmos_dram = 0; + curr_Wmemcellnmos_dram = 0; + curr_area_cell_dram = 6 * 0.022 * 0.022; // micron2. + curr_asp_ratio_cell_dram = 0.667; + curr_c_dram_cell = 30e-15; // This is a typical value that I have + // alwaus + // kept constant. + + // 22 nm commodity DRAM wordline transistor parameters obtained using + // MASTAR. + curr_vpp = 2.3; // vpp. V + t_ox[3] = 3.5e-3; // micron + v_th[3] = 1.0; // V + c_ox[3] = 9.06e-15; // F/micron2 + mobility_eff[3] = 367.29 * (1e-2 * 1e6 * 1e-2 * 1e6); // micron2 / Vs + Vdsat[3] = 0.0972; // V/micron + c_g_ideal[3] = 1.99e-16; // F/micron + c_fringe[3] = 0.053e-15; // F/micron + c_junc[3] = 1e-15; // F/micron2 + I_on_n[3] = 910.5e-6; // A/micron + I_on_p[3] = I_on_n[3] / 2; // This value for I_on_p is not really used. + nmos_effective_resistance_multiplier = + 1.69; // Using the value from 32nm. + // + n_to_p_eff_curr_drv_ratio[3] = 1.95; // Using the value from 32nm + gmp_to_gmn_multiplier[3] = 0.90; + Rnchannelon[3] = nmos_effective_resistance_multiplier * curr_vpp / + I_on_n[3]; // ohm-micron + Rpchannelon[3] = + n_to_p_eff_curr_drv_ratio[3] * Rnchannelon[3]; // ohm-micron + long_channel_leakage_reduction[3] = 1; + I_off_n[3][0] = 1.1e-13; // A/micron + I_off_n[3][10] = 2.11e-13; + I_off_n[3][20] = 3.88e-13; + I_off_n[3][30] = 6.9e-13; + I_off_n[3][40] = 1.19e-12; + I_off_n[3][50] = 1.98e-12; + I_off_n[3][60] = 3.22e-12; + I_off_n[3][70] = 5.09e-12; + I_off_n[3][80] = 7.85e-12; + I_off_n[3][90] = 1.18e-11; + I_off_n[3][100] = 1.72e-11; + + } else { + // some error handler + } + + // SRAM cell properties + curr_Wmemcella_sram = 1.31 * g_ip->F_sz_um; + curr_Wmemcellpmos_sram = 1.23 * g_ip->F_sz_um; + curr_Wmemcellnmos_sram = 2.08 * g_ip->F_sz_um; + curr_area_cell_sram = 146 * g_ip->F_sz_um * g_ip->F_sz_um; + curr_asp_ratio_cell_sram = 1.46; + // CAM cell properties //TODO: data need to be revisited + curr_Wmemcella_cam = 1.31 * g_ip->F_sz_um; + curr_Wmemcellpmos_cam = 1.23 * g_ip->F_sz_um; + curr_Wmemcellnmos_cam = 2.08 * g_ip->F_sz_um; + curr_area_cell_cam = 292 * g_ip->F_sz_um * g_ip->F_sz_um; + curr_asp_ratio_cell_cam = 2.92; + // Empirical undifferetiated core/FU coefficient + curr_logic_scaling_co_eff = 0.7 * 0.7 * 0.7 * 0.7; + curr_core_tx_density = 1.25 / 0.7 / 0.7; + curr_sckt_co_eff = 1.1296; + curr_chip_layout_overhead = + 1.2; // die measurement results based on Niagara 1 and 2 + curr_macro_layout_overhead = + 1.1; // EDA placement and routing tool rule of thumb + } + + if (tech == 16) { + // For 2019, MPU/ASIC stagger-contacted M1 half-pitch is 16 nm (so this is + // 16 nm technology i.e. FEATURESIZE = 0.016). Using the DG process + // numbers for HP. 16 nm HP + vdd[0] = 0.7; + Lphy[0] = 0.006; // Lphy is the physical gate-length. + Lelec[0] = 0.00315; // Lelec is the electrical gate-length. + t_ox[0] = 0.5e-3; // micron + v_th[0] = 0.1489; // V + c_ox[0] = 3.83e-14; // F/micron2 Cox_elec in MASTAR + mobility_eff[0] = 476.15 * (1e-2 * 1e6 * 1e-2 * 1e6); // micron2 / Vs + Vdsat[0] = 1.42e-2; // V/micron calculated in spreadsheet + c_g_ideal[0] = 2.30e-16; // F/micron + c_fringe[0] = 0.06e-15; // F/micron MASTAR inputdynamic/3 + c_junc[0] = 0; // F/micron2 MASTAR result dynamic + I_on_n[0] = 2768.4e-6; // A/micron + I_on_p[0] = I_on_n[0] / + 2; // A/micron //This value for I_on_p is not really used. + nmos_effective_resistance_multiplier = + 1.48; // nmos_effective_resistance_multiplier is the ratio of Ieff + // to Idsat where Ieff is the effective NMOS current and Idsat + // is the saturation current. + n_to_p_eff_curr_drv_ratio[0] = + 2; // Wpmos/Wnmos = 2 in 2007 MASTAR. Look in + //"Dynamic" tab of Device workspace. + gmp_to_gmn_multiplier[0] = 1.38; // Just using the 32nm SOI value. + Rnchannelon[0] = nmos_effective_resistance_multiplier * vdd[0] / + I_on_n[0]; // ohm-micron + Rpchannelon[0] = + n_to_p_eff_curr_drv_ratio[0] * Rnchannelon[0]; // ohm-micron + long_channel_leakage_reduction[0] = 1 / 2.655; + I_off_n[0][0] = 1.52e-7 / 1.5 * 1.2 * 1.07; + I_off_n[0][10] = 1.55e-7 / 1.5 * 1.2 * 1.07; + I_off_n[0][20] = 1.59e-7 / 1.5 * 1.2 * 1.07; + I_off_n[0][30] = 1.68e-7 / 1.5 * 1.2 * 1.07; + I_off_n[0][40] = 1.90e-7 / 1.5 * 1.2 * 1.07; + I_off_n[0][50] = 2.69e-7 / 1.5 * 1.2 * 1.07; + I_off_n[0][60] = 5.32e-7 / 1.5 * 1.2 * 1.07; + I_off_n[0][70] = 1.02e-6 / 1.5 * 1.2 * 1.07; + I_off_n[0][80] = 1.62e-6 / 1.5 * 1.2 * 1.07; + I_off_n[0][90] = 2.73e-6 / 1.5 * 1.2 * 1.07; + I_off_n[0][100] = 6.1e-6 / 1.5 * 1.2 * 1.07; + // for 16nm DG HP + I_g_on_n[0][0] = 1.07e-9; // A/micron + I_g_on_n[0][10] = 1.07e-9; + I_g_on_n[0][20] = 1.07e-9; + I_g_on_n[0][30] = 1.07e-9; + I_g_on_n[0][40] = 1.07e-9; + I_g_on_n[0][50] = 1.07e-9; + I_g_on_n[0][60] = 1.07e-9; + I_g_on_n[0][70] = 1.07e-9; + I_g_on_n[0][80] = 1.07e-9; + I_g_on_n[0][90] = 1.07e-9; + I_g_on_n[0][100] = 1.07e-9; + + // //16 nm LSTP DG + // vdd[1] = 0.8; + // Lphy[1] = 0.014; + // Lelec[1] = 0.008;//Lelec is the electrical gate-length. + // t_ox[1] = 1.1e-3;//micron + // v_th[1] = 0.40126;//V + // c_ox[1] = 2.30e-14;//F/micron2 + // mobility_eff[1] = 738.09 * (1e-2 * 1e6 * 1e-2 * 1e6); //micron2 + // / Vs Vdsat[1] = 6.64e-2; //V/micron c_g_ideal[1] + // = 3.22e-16;//F/micron c_fringe[1] = 0.008e-15; c_junc[1] + // = + // 0;//F/micron2 I_on_n[1] = 727.6e-6;//A/micron I_on_p[1] + // = I_on_n[1] / 2; nmos_effective_resistance_multiplier = 1.99; + // n_to_p_eff_curr_drv_ratio[1] = 2; + // gmp_to_gmn_multiplier[1] = 0.99; + // Rnchannelon[1] = nmos_effective_resistance_multiplier * vdd[1] / + // I_on_n[1];//ohm-micron Rpchannelon[1] = + // n_to_p_eff_curr_drv_ratio[1] + // * Rnchannelon[1];//ohm-micron I_off_n[1][0] = 2.43e-11; + // I_off_n[1][10] = 4.85e-11; + // I_off_n[1][20] = 9.68e-11; + // I_off_n[1][30] = 1.94e-10; + // I_off_n[1][40] = 3.87e-10; + // I_off_n[1][50] = 7.73e-10; + // I_off_n[1][60] = 3.55e-10; + // I_off_n[1][70] = 3.09e-9; + // I_off_n[1][80] = 6.19e-9; + // I_off_n[1][90] = 1.24e-8; + // I_off_n[1][100]= 2.48e-8; + // + // // for 22nm LSTP HP + // I_g_on_n[1][0] = 4.51e-10;//A/micron + // I_g_on_n[1][10] = 4.51e-10; + // I_g_on_n[1][20] = 4.51e-10; + // I_g_on_n[1][30] = 4.51e-10; + // I_g_on_n[1][40] = 4.51e-10; + // I_g_on_n[1][50] = 4.51e-10; + // I_g_on_n[1][60] = 4.51e-10; + // I_g_on_n[1][70] = 4.51e-10; + // I_g_on_n[1][80] = 4.51e-10; + // I_g_on_n[1][90] = 4.51e-10; + // I_g_on_n[1][100] = 4.51e-10; + + if (ram_cell_tech_type == 3) { + } else if (ram_cell_tech_type == 4) { + // 22 nm commodity DRAM cell access transistor technology parameters. + // parameters + curr_vdd_dram_cell = 0.9; // 0.45;//This value has reduced greatly in + // 2007 ITRS for all technology nodes. In + // 2005 ITRS, the value was about twice the value in 2007 ITRS + Lphy[3] = 0.022; // micron + Lelec[3] = 0.0181; // micron. + curr_v_th_dram_access_transistor = 1; // V + width_dram_access_transistor = 0.022; // micron + curr_I_on_dram_cell = + 20e-6; // This is a typical value that I have always + // kept constant. In reality this could perhaps be lower + curr_I_off_dram_cell_worst_case_length_temp = 1e-15; // A + curr_Wmemcella_dram = width_dram_access_transistor; + curr_Wmemcellpmos_dram = 0; + curr_Wmemcellnmos_dram = 0; + curr_area_cell_dram = 6 * 0.022 * 0.022; // micron2. + curr_asp_ratio_cell_dram = 0.667; + curr_c_dram_cell = 30e-15; // This is a typical value that I have + // alwaus + // kept constant. + + // 22 nm commodity DRAM wordline transistor parameters obtained using + // MASTAR. + curr_vpp = 2.3; // vpp. V + t_ox[3] = 3.5e-3; // micron + v_th[3] = 1.0; // V + c_ox[3] = 9.06e-15; // F/micron2 + mobility_eff[3] = 367.29 * (1e-2 * 1e6 * 1e-2 * 1e6); // micron2 / Vs + Vdsat[3] = 0.0972; // V/micron + c_g_ideal[3] = 1.99e-16; // F/micron + c_fringe[3] = 0.053e-15; // F/micron + c_junc[3] = 1e-15; // F/micron2 + I_on_n[3] = 910.5e-6; // A/micron + I_on_p[3] = I_on_n[3] / 2; // This value for I_on_p is not really used. + nmos_effective_resistance_multiplier = + 1.69; // Using the value from 32nm. + // + n_to_p_eff_curr_drv_ratio[3] = 1.95; // Using the value from 32nm + gmp_to_gmn_multiplier[3] = 0.90; + Rnchannelon[3] = nmos_effective_resistance_multiplier * curr_vpp / + I_on_n[3]; // ohm-micron + Rpchannelon[3] = + n_to_p_eff_curr_drv_ratio[3] * Rnchannelon[3]; // ohm-micron + long_channel_leakage_reduction[3] = 1; + I_off_n[3][0] = 1.1e-13; // A/micron + I_off_n[3][10] = 2.11e-13; + I_off_n[3][20] = 3.88e-13; + I_off_n[3][30] = 6.9e-13; + I_off_n[3][40] = 1.19e-12; + I_off_n[3][50] = 1.98e-12; + I_off_n[3][60] = 3.22e-12; + I_off_n[3][70] = 5.09e-12; + I_off_n[3][80] = 7.85e-12; + I_off_n[3][90] = 1.18e-11; + I_off_n[3][100] = 1.72e-11; + + } else { + // some error handler + } + + // SRAM cell properties + curr_Wmemcella_sram = 1.31 * g_ip->F_sz_um; curr_Wmemcellpmos_sram = 1.23 * g_ip->F_sz_um; curr_Wmemcellnmos_sram = 2.08 * g_ip->F_sz_um; - curr_area_cell_sram = 146 * g_ip->F_sz_um * g_ip->F_sz_um; + curr_area_cell_sram = 146 * g_ip->F_sz_um * g_ip->F_sz_um; curr_asp_ratio_cell_sram = 1.46; - //CAM cell properties //TODO: data need to be revisited + // CAM cell properties //TODO: data need to be revisited curr_Wmemcella_cam = 1.31 * g_ip->F_sz_um; curr_Wmemcellpmos_cam = 1.23 * g_ip->F_sz_um; curr_Wmemcellnmos_cam = 2.08 * g_ip->F_sz_um; curr_area_cell_cam = 292 * g_ip->F_sz_um * g_ip->F_sz_um; curr_asp_ratio_cell_cam = 2.92; - //Empirical undifferetiated core/FU coefficient - curr_logic_scaling_co_eff = 0.7*0.7*0.7; - curr_core_tx_density = 1.25/0.7; - curr_sckt_co_eff = 1.1111; - curr_chip_layout_overhead = 1.2;//die measurement results based on Niagara 1 and 2 - curr_macro_layout_overhead = 1.1;//EDA placement and routing tool rule of thumb + // Empirical undifferetiated core/FU coefficient + curr_logic_scaling_co_eff = 0.7 * 0.7 * 0.7 * 0.7 * 0.7; + curr_core_tx_density = 1.25 / 0.7 / 0.7 / 0.7; + curr_sckt_co_eff = 1.1296; + curr_chip_layout_overhead = + 1.2; // die measurement results based on Niagara 1 and 2 + curr_macro_layout_overhead = + 1.1; // EDA placement and routing tool rule of thumb } - if(tech == 22){ - //For 2016, MPU/ASIC stagger-contacted M1 half-pitch is 22 nm (so this is 22 nm - //technology i.e. FEATURESIZE = 0.022). Using the DG process numbers for HP. - //22 nm HP - vdd[0] = 0.8; - Lphy[0] = 0.009;//Lphy is the physical gate-length. - Lelec[0] = 0.00468;//Lelec is the electrical gate-length. - t_ox[0] = 0.55e-3;//micron - v_th[0] = 0.1395;//V - c_ox[0] = 3.63e-14;//F/micron2 - mobility_eff[0] = 426.07 * (1e-2 * 1e6 * 1e-2 * 1e6); //micron2 / Vs - Vdsat[0] = 2.33e-2; //V/micron - c_g_ideal[0] = 3.27e-16;//F/micron - c_fringe[0] = 0.06e-15;//F/micron - c_junc[0] = 0;//F/micron2 - I_on_n[0] = 2626.4e-6;//A/micron - I_on_p[0] = I_on_n[0] / 2;//A/micron //This value for I_on_p is not really used. - nmos_effective_resistance_multiplier = 1.45; - n_to_p_eff_curr_drv_ratio[0] = 2; //Wpmos/Wnmos = 2 in 2007 MASTAR. Look in - //"Dynamic" tab of Device workspace. - gmp_to_gmn_multiplier[0] = 1.38; //Just using the 32nm SOI value. - Rnchannelon[0] = nmos_effective_resistance_multiplier * vdd[0] / I_on_n[0];//ohm-micron - Rpchannelon[0] = n_to_p_eff_curr_drv_ratio[0] * Rnchannelon[0];//ohm-micron - long_channel_leakage_reduction[0] = 1/3.274; - I_off_n[0][0] = 1.52e-7/1.5*1.2;//From 22nm, leakage current are directly from ITRS report rather than MASTAR, since MASTAR has serious bugs there. - I_off_n[0][10] = 1.55e-7/1.5*1.2; - I_off_n[0][20] = 1.59e-7/1.5*1.2; - I_off_n[0][30] = 1.68e-7/1.5*1.2; - I_off_n[0][40] = 1.90e-7/1.5*1.2; - I_off_n[0][50] = 2.69e-7/1.5*1.2; - I_off_n[0][60] = 5.32e-7/1.5*1.2; - I_off_n[0][70] = 1.02e-6/1.5*1.2; - I_off_n[0][80] = 1.62e-6/1.5*1.2; - I_off_n[0][90] = 2.73e-6/1.5*1.2; - I_off_n[0][100] = 6.1e-6/1.5*1.2; - //for 22nm DG HP - I_g_on_n[0][0] = 1.81e-9;//A/micron - I_g_on_n[0][10] = 1.81e-9; - I_g_on_n[0][20] = 1.81e-9; - I_g_on_n[0][30] = 1.81e-9; - I_g_on_n[0][40] = 1.81e-9; - I_g_on_n[0][50] = 1.81e-9; - I_g_on_n[0][60] = 1.81e-9; - I_g_on_n[0][70] = 1.81e-9; - I_g_on_n[0][80] = 1.81e-9; - I_g_on_n[0][90] = 1.81e-9; - I_g_on_n[0][100] = 1.81e-9; - - //22 nm LSTP DG - vdd[1] = 0.8; - Lphy[1] = 0.014; - Lelec[1] = 0.008;//Lelec is the electrical gate-length. - t_ox[1] = 1.1e-3;//micron - v_th[1] = 0.40126;//V - c_ox[1] = 2.30e-14;//F/micron2 - mobility_eff[1] = 738.09 * (1e-2 * 1e6 * 1e-2 * 1e6); //micron2 / Vs - Vdsat[1] = 6.64e-2; //V/micron - c_g_ideal[1] = 3.22e-16;//F/micron - c_fringe[1] = 0.08e-15; - c_junc[1] = 0;//F/micron2 - I_on_n[1] = 727.6e-6;//A/micron - I_on_p[1] = I_on_n[1] / 2; - nmos_effective_resistance_multiplier = 1.99; - n_to_p_eff_curr_drv_ratio[1] = 2; - gmp_to_gmn_multiplier[1] = 0.99; - Rnchannelon[1] = nmos_effective_resistance_multiplier * vdd[1] / I_on_n[1];//ohm-micron - Rpchannelon[1] = n_to_p_eff_curr_drv_ratio[1] * Rnchannelon[1];//ohm-micron - long_channel_leakage_reduction[1] = 1/1.89; - I_off_n[1][0] = 2.43e-11; - I_off_n[1][10] = 4.85e-11; - I_off_n[1][20] = 9.68e-11; - I_off_n[1][30] = 1.94e-10; - I_off_n[1][40] = 3.87e-10; - I_off_n[1][50] = 7.73e-10; - I_off_n[1][60] = 3.55e-10; - I_off_n[1][70] = 3.09e-9; - I_off_n[1][80] = 6.19e-9; - I_off_n[1][90] = 1.24e-8; - I_off_n[1][100]= 2.48e-8; - - I_g_on_n[1][0] = 4.51e-10;//A/micron - I_g_on_n[1][10] = 4.51e-10; - I_g_on_n[1][20] = 4.51e-10; - I_g_on_n[1][30] = 4.51e-10; - I_g_on_n[1][40] = 4.51e-10; - I_g_on_n[1][50] = 4.51e-10; - I_g_on_n[1][60] = 4.51e-10; - I_g_on_n[1][70] = 4.51e-10; - I_g_on_n[1][80] = 4.51e-10; - I_g_on_n[1][90] = 4.51e-10; - I_g_on_n[1][100] = 4.51e-10; - - //22 nm LOP - vdd[2] = 0.6; - Lphy[2] = 0.011; - Lelec[2] = 0.00604;//Lelec is the electrical gate-length. - t_ox[2] = 0.8e-3;//micron - v_th[2] = 0.2315;//V - c_ox[2] = 2.87e-14;//F/micron2 - mobility_eff[2] = 698.37 * (1e-2 * 1e6 * 1e-2 * 1e6); //micron2 / Vs - Vdsat[2] = 1.81e-2; //V/micron - c_g_ideal[2] = 3.16e-16;//F/micron - c_fringe[2] = 0.08e-15; - c_junc[2] = 0;//F/micron2 This is Cj0 not Cjunc in MASTAR results->Dynamic Tab - I_on_n[2] = 916.1e-6;//A/micron - I_on_p[2] = I_on_n[2] / 2; - nmos_effective_resistance_multiplier = 1.73; - n_to_p_eff_curr_drv_ratio[2] = 2; - gmp_to_gmn_multiplier[2] = 1.11; - Rnchannelon[2] = nmos_effective_resistance_multiplier * vdd[2] / I_on_n[2];//ohm-micron - Rpchannelon[2] = n_to_p_eff_curr_drv_ratio[2] * Rnchannelon[2];//ohm-micron - long_channel_leakage_reduction[2] = 1/2.38; - - I_off_n[2][0] = 1.31e-8; - I_off_n[2][10] = 2.60e-8; - I_off_n[2][20] = 5.14e-8; - I_off_n[2][30] = 1.02e-7; - I_off_n[2][40] = 2.02e-7; - I_off_n[2][50] = 3.99e-7; - I_off_n[2][60] = 7.91e-7; - I_off_n[2][70] = 1.09e-6; - I_off_n[2][80] = 2.09e-6; - I_off_n[2][90] = 4.04e-6; - I_off_n[2][100]= 4.48e-6; - - I_g_on_n[2][0] = 2.74e-9;//A/micron - I_g_on_n[2][10] = 2.74e-9; - I_g_on_n[2][20] = 2.74e-9; - I_g_on_n[2][30] = 2.74e-9; - I_g_on_n[2][40] = 2.74e-9; - I_g_on_n[2][50] = 2.74e-9; - I_g_on_n[2][60] = 2.74e-9; - I_g_on_n[2][70] = 2.74e-9; - I_g_on_n[2][80] = 2.74e-9; - I_g_on_n[2][90] = 2.74e-9; - I_g_on_n[2][100] = 2.74e-9; - - - - if (ram_cell_tech_type == 3) - {} - else if (ram_cell_tech_type == 4) - { - //22 nm commodity DRAM cell access transistor technology parameters. - //parameters - curr_vdd_dram_cell = 0.9;//0.45;//This value has reduced greatly in 2007 ITRS for all technology nodes. In - //2005 ITRS, the value was about twice the value in 2007 ITRS - Lphy[3] = 0.022;//micron - Lelec[3] = 0.0181;//micron. - curr_v_th_dram_access_transistor = 1;//V - width_dram_access_transistor = 0.022;//micron - curr_I_on_dram_cell = 20e-6; //This is a typical value that I have always - //kept constant. In reality this could perhaps be lower - curr_I_off_dram_cell_worst_case_length_temp = 1e-15;//A - curr_Wmemcella_dram = width_dram_access_transistor; - curr_Wmemcellpmos_dram = 0; - curr_Wmemcellnmos_dram = 0; - curr_area_cell_dram = 6*0.022*0.022;//micron2. - curr_asp_ratio_cell_dram = 0.667; - curr_c_dram_cell = 30e-15;//This is a typical value that I have alwaus - //kept constant. - - //22 nm commodity DRAM wordline transistor parameters obtained using MASTAR. - curr_vpp = 2.3;//vpp. V - t_ox[3] = 3.5e-3;//micron - v_th[3] = 1.0;//V - c_ox[3] = 9.06e-15;//F/micron2 - mobility_eff[3] = 367.29 * (1e-2 * 1e6 * 1e-2 * 1e6);//micron2 / Vs - Vdsat[3] = 0.0972; //V/micron - c_g_ideal[3] = 1.99e-16;//F/micron - c_fringe[3] = 0.053e-15;//F/micron - c_junc[3] = 1e-15;//F/micron2 - I_on_n[3] = 910.5e-6;//A/micron - I_on_p[3] = I_on_n[3] / 2;//This value for I_on_p is not really used. - nmos_effective_resistance_multiplier = 1.69;//Using the value from 32nm. - // - n_to_p_eff_curr_drv_ratio[3] = 1.95;//Using the value from 32nm - gmp_to_gmn_multiplier[3] = 0.90; - Rnchannelon[3] = nmos_effective_resistance_multiplier * curr_vpp / I_on_n[3];//ohm-micron - Rpchannelon[3] = n_to_p_eff_curr_drv_ratio[3] * Rnchannelon[3];//ohm-micron - long_channel_leakage_reduction[3] = 1; - I_off_n[3][0] = 1.1e-13; //A/micron - I_off_n[3][10] = 2.11e-13; - I_off_n[3][20] = 3.88e-13; - I_off_n[3][30] = 6.9e-13; - I_off_n[3][40] = 1.19e-12; - I_off_n[3][50] = 1.98e-12; - I_off_n[3][60] = 3.22e-12; - I_off_n[3][70] = 5.09e-12; - I_off_n[3][80] = 7.85e-12; - I_off_n[3][90] = 1.18e-11; - I_off_n[3][100] = 1.72e-11; - - } - else - { - //some error handler - } - - //SRAM cell properties - curr_Wmemcella_sram = 1.31 * g_ip->F_sz_um; - curr_Wmemcellpmos_sram = 1.23 * g_ip->F_sz_um; - curr_Wmemcellnmos_sram = 2.08 * g_ip->F_sz_um; - curr_area_cell_sram = 146 * g_ip->F_sz_um * g_ip->F_sz_um; - curr_asp_ratio_cell_sram = 1.46; - //CAM cell properties //TODO: data need to be revisited - curr_Wmemcella_cam = 1.31 * g_ip->F_sz_um; - curr_Wmemcellpmos_cam = 1.23 * g_ip->F_sz_um; - curr_Wmemcellnmos_cam = 2.08 * g_ip->F_sz_um; - curr_area_cell_cam = 292 * g_ip->F_sz_um * g_ip->F_sz_um; - curr_asp_ratio_cell_cam = 2.92; - //Empirical undifferetiated core/FU coefficient - curr_logic_scaling_co_eff = 0.7*0.7*0.7*0.7; - curr_core_tx_density = 1.25/0.7/0.7; - curr_sckt_co_eff = 1.1296; - curr_chip_layout_overhead = 1.2;//die measurement results based on Niagara 1 and 2 - curr_macro_layout_overhead = 1.1;//EDA placement and routing tool rule of thumb - } - - if(tech == 16){ - //For 2019, MPU/ASIC stagger-contacted M1 half-pitch is 16 nm (so this is 16 nm - //technology i.e. FEATURESIZE = 0.016). Using the DG process numbers for HP. - //16 nm HP - vdd[0] = 0.7; - Lphy[0] = 0.006;//Lphy is the physical gate-length. - Lelec[0] = 0.00315;//Lelec is the electrical gate-length. - t_ox[0] = 0.5e-3;//micron - v_th[0] = 0.1489;//V - c_ox[0] = 3.83e-14;//F/micron2 Cox_elec in MASTAR - mobility_eff[0] = 476.15 * (1e-2 * 1e6 * 1e-2 * 1e6); //micron2 / Vs - Vdsat[0] = 1.42e-2; //V/micron calculated in spreadsheet - c_g_ideal[0] = 2.30e-16;//F/micron - c_fringe[0] = 0.06e-15;//F/micron MASTAR inputdynamic/3 - c_junc[0] = 0;//F/micron2 MASTAR result dynamic - I_on_n[0] = 2768.4e-6;//A/micron - I_on_p[0] = I_on_n[0] / 2;//A/micron //This value for I_on_p is not really used. - nmos_effective_resistance_multiplier = 1.48;//nmos_effective_resistance_multiplier is the ratio of Ieff to Idsat where Ieff is the effective NMOS current and Idsat is the saturation current. - n_to_p_eff_curr_drv_ratio[0] = 2; //Wpmos/Wnmos = 2 in 2007 MASTAR. Look in - //"Dynamic" tab of Device workspace. - gmp_to_gmn_multiplier[0] = 1.38; //Just using the 32nm SOI value. - Rnchannelon[0] = nmos_effective_resistance_multiplier * vdd[0] / I_on_n[0];//ohm-micron - Rpchannelon[0] = n_to_p_eff_curr_drv_ratio[0] * Rnchannelon[0];//ohm-micron - long_channel_leakage_reduction[0] = 1/2.655; - I_off_n[0][0] = 1.52e-7/1.5*1.2*1.07; - I_off_n[0][10] = 1.55e-7/1.5*1.2*1.07; - I_off_n[0][20] = 1.59e-7/1.5*1.2*1.07; - I_off_n[0][30] = 1.68e-7/1.5*1.2*1.07; - I_off_n[0][40] = 1.90e-7/1.5*1.2*1.07; - I_off_n[0][50] = 2.69e-7/1.5*1.2*1.07; - I_off_n[0][60] = 5.32e-7/1.5*1.2*1.07; - I_off_n[0][70] = 1.02e-6/1.5*1.2*1.07; - I_off_n[0][80] = 1.62e-6/1.5*1.2*1.07; - I_off_n[0][90] = 2.73e-6/1.5*1.2*1.07; - I_off_n[0][100] = 6.1e-6/1.5*1.2*1.07; - //for 16nm DG HP - I_g_on_n[0][0] = 1.07e-9;//A/micron - I_g_on_n[0][10] = 1.07e-9; - I_g_on_n[0][20] = 1.07e-9; - I_g_on_n[0][30] = 1.07e-9; - I_g_on_n[0][40] = 1.07e-9; - I_g_on_n[0][50] = 1.07e-9; - I_g_on_n[0][60] = 1.07e-9; - I_g_on_n[0][70] = 1.07e-9; - I_g_on_n[0][80] = 1.07e-9; - I_g_on_n[0][90] = 1.07e-9; - I_g_on_n[0][100] = 1.07e-9; - -// //16 nm LSTP DG -// vdd[1] = 0.8; -// Lphy[1] = 0.014; -// Lelec[1] = 0.008;//Lelec is the electrical gate-length. -// t_ox[1] = 1.1e-3;//micron -// v_th[1] = 0.40126;//V -// c_ox[1] = 2.30e-14;//F/micron2 -// mobility_eff[1] = 738.09 * (1e-2 * 1e6 * 1e-2 * 1e6); //micron2 / Vs -// Vdsat[1] = 6.64e-2; //V/micron -// c_g_ideal[1] = 3.22e-16;//F/micron -// c_fringe[1] = 0.008e-15; -// c_junc[1] = 0;//F/micron2 -// I_on_n[1] = 727.6e-6;//A/micron -// I_on_p[1] = I_on_n[1] / 2; -// nmos_effective_resistance_multiplier = 1.99; -// n_to_p_eff_curr_drv_ratio[1] = 2; -// gmp_to_gmn_multiplier[1] = 0.99; -// Rnchannelon[1] = nmos_effective_resistance_multiplier * vdd[1] / I_on_n[1];//ohm-micron -// Rpchannelon[1] = n_to_p_eff_curr_drv_ratio[1] * Rnchannelon[1];//ohm-micron -// I_off_n[1][0] = 2.43e-11; -// I_off_n[1][10] = 4.85e-11; -// I_off_n[1][20] = 9.68e-11; -// I_off_n[1][30] = 1.94e-10; -// I_off_n[1][40] = 3.87e-10; -// I_off_n[1][50] = 7.73e-10; -// I_off_n[1][60] = 3.55e-10; -// I_off_n[1][70] = 3.09e-9; -// I_off_n[1][80] = 6.19e-9; -// I_off_n[1][90] = 1.24e-8; -// I_off_n[1][100]= 2.48e-8; -// -// // for 22nm LSTP HP -// I_g_on_n[1][0] = 4.51e-10;//A/micron -// I_g_on_n[1][10] = 4.51e-10; -// I_g_on_n[1][20] = 4.51e-10; -// I_g_on_n[1][30] = 4.51e-10; -// I_g_on_n[1][40] = 4.51e-10; -// I_g_on_n[1][50] = 4.51e-10; -// I_g_on_n[1][60] = 4.51e-10; -// I_g_on_n[1][70] = 4.51e-10; -// I_g_on_n[1][80] = 4.51e-10; -// I_g_on_n[1][90] = 4.51e-10; -// I_g_on_n[1][100] = 4.51e-10; - - - if (ram_cell_tech_type == 3) - {} - else if (ram_cell_tech_type == 4) - { - //22 nm commodity DRAM cell access transistor technology parameters. - //parameters - curr_vdd_dram_cell = 0.9;//0.45;//This value has reduced greatly in 2007 ITRS for all technology nodes. In - //2005 ITRS, the value was about twice the value in 2007 ITRS - Lphy[3] = 0.022;//micron - Lelec[3] = 0.0181;//micron. - curr_v_th_dram_access_transistor = 1;//V - width_dram_access_transistor = 0.022;//micron - curr_I_on_dram_cell = 20e-6; //This is a typical value that I have always - //kept constant. In reality this could perhaps be lower - curr_I_off_dram_cell_worst_case_length_temp = 1e-15;//A - curr_Wmemcella_dram = width_dram_access_transistor; - curr_Wmemcellpmos_dram = 0; - curr_Wmemcellnmos_dram = 0; - curr_area_cell_dram = 6*0.022*0.022;//micron2. - curr_asp_ratio_cell_dram = 0.667; - curr_c_dram_cell = 30e-15;//This is a typical value that I have alwaus - //kept constant. - - //22 nm commodity DRAM wordline transistor parameters obtained using MASTAR. - curr_vpp = 2.3;//vpp. V - t_ox[3] = 3.5e-3;//micron - v_th[3] = 1.0;//V - c_ox[3] = 9.06e-15;//F/micron2 - mobility_eff[3] = 367.29 * (1e-2 * 1e6 * 1e-2 * 1e6);//micron2 / Vs - Vdsat[3] = 0.0972; //V/micron - c_g_ideal[3] = 1.99e-16;//F/micron - c_fringe[3] = 0.053e-15;//F/micron - c_junc[3] = 1e-15;//F/micron2 - I_on_n[3] = 910.5e-6;//A/micron - I_on_p[3] = I_on_n[3] / 2;//This value for I_on_p is not really used. - nmos_effective_resistance_multiplier = 1.69;//Using the value from 32nm. - // - n_to_p_eff_curr_drv_ratio[3] = 1.95;//Using the value from 32nm - gmp_to_gmn_multiplier[3] = 0.90; - Rnchannelon[3] = nmos_effective_resistance_multiplier * curr_vpp / I_on_n[3];//ohm-micron - Rpchannelon[3] = n_to_p_eff_curr_drv_ratio[3] * Rnchannelon[3];//ohm-micron - long_channel_leakage_reduction[3] = 1; - I_off_n[3][0] = 1.1e-13; //A/micron - I_off_n[3][10] = 2.11e-13; - I_off_n[3][20] = 3.88e-13; - I_off_n[3][30] = 6.9e-13; - I_off_n[3][40] = 1.19e-12; - I_off_n[3][50] = 1.98e-12; - I_off_n[3][60] = 3.22e-12; - I_off_n[3][70] = 5.09e-12; - I_off_n[3][80] = 7.85e-12; - I_off_n[3][90] = 1.18e-11; - I_off_n[3][100] = 1.72e-11; - - } - else - { - //some error handler - } - - //SRAM cell properties - curr_Wmemcella_sram = 1.31 * g_ip->F_sz_um; - curr_Wmemcellpmos_sram = 1.23 * g_ip->F_sz_um; - curr_Wmemcellnmos_sram = 2.08 * g_ip->F_sz_um; - curr_area_cell_sram = 146 * g_ip->F_sz_um * g_ip->F_sz_um; - curr_asp_ratio_cell_sram = 1.46; - //CAM cell properties //TODO: data need to be revisited - curr_Wmemcella_cam = 1.31 * g_ip->F_sz_um; - curr_Wmemcellpmos_cam = 1.23 * g_ip->F_sz_um; - curr_Wmemcellnmos_cam = 2.08 * g_ip->F_sz_um; - curr_area_cell_cam = 292 * g_ip->F_sz_um * g_ip->F_sz_um; - curr_asp_ratio_cell_cam = 2.92; - //Empirical undifferetiated core/FU coefficient - curr_logic_scaling_co_eff = 0.7*0.7*0.7*0.7*0.7; - curr_core_tx_density = 1.25/0.7/0.7/0.7; - curr_sckt_co_eff = 1.1296; - curr_chip_layout_overhead = 1.2;//die measurement results based on Niagara 1 and 2 - curr_macro_layout_overhead = 1.1;//EDA placement and routing tool rule of thumb - } - - - g_tp.peri_global.Vdd += curr_alpha * vdd[peri_global_tech_type]; - g_tp.peri_global.t_ox += curr_alpha * t_ox[peri_global_tech_type]; - g_tp.peri_global.Vth += curr_alpha * v_th[peri_global_tech_type]; - g_tp.peri_global.C_ox += curr_alpha * c_ox[peri_global_tech_type]; + g_tp.peri_global.Vdd += curr_alpha * vdd[peri_global_tech_type]; + g_tp.peri_global.t_ox += curr_alpha * t_ox[peri_global_tech_type]; + g_tp.peri_global.Vth += curr_alpha * v_th[peri_global_tech_type]; + g_tp.peri_global.C_ox += curr_alpha * c_ox[peri_global_tech_type]; g_tp.peri_global.C_g_ideal += curr_alpha * c_g_ideal[peri_global_tech_type]; - g_tp.peri_global.C_fringe += curr_alpha * c_fringe[peri_global_tech_type]; - g_tp.peri_global.C_junc += curr_alpha * c_junc[peri_global_tech_type]; + g_tp.peri_global.C_fringe += curr_alpha * c_fringe[peri_global_tech_type]; + g_tp.peri_global.C_junc += curr_alpha * c_junc[peri_global_tech_type]; g_tp.peri_global.C_junc_sidewall = 0.25e-15; // F/micron - g_tp.peri_global.l_phy += curr_alpha * Lphy[peri_global_tech_type]; - g_tp.peri_global.l_elec += curr_alpha * Lelec[peri_global_tech_type]; - g_tp.peri_global.I_on_n += curr_alpha * I_on_n[peri_global_tech_type]; - g_tp.peri_global.R_nch_on += curr_alpha * Rnchannelon[peri_global_tech_type]; - g_tp.peri_global.R_pch_on += curr_alpha * Rpchannelon[peri_global_tech_type]; - g_tp.peri_global.n_to_p_eff_curr_drv_ratio - += curr_alpha * n_to_p_eff_curr_drv_ratio[peri_global_tech_type]; - g_tp.peri_global.long_channel_leakage_reduction - += curr_alpha * long_channel_leakage_reduction[peri_global_tech_type]; - g_tp.peri_global.I_off_n += curr_alpha * I_off_n[peri_global_tech_type][g_ip->temp - 300]; - g_tp.peri_global.I_off_p += curr_alpha * I_off_n[peri_global_tech_type][g_ip->temp - 300]; - g_tp.peri_global.I_g_on_n += curr_alpha * I_g_on_n[peri_global_tech_type][g_ip->temp - 300]; - g_tp.peri_global.I_g_on_p += curr_alpha * I_g_on_n[peri_global_tech_type][g_ip->temp - 300]; - gmp_to_gmn_multiplier_periph_global += curr_alpha * gmp_to_gmn_multiplier[peri_global_tech_type]; - - g_tp.sram_cell.Vdd += curr_alpha * vdd[ram_cell_tech_type]; - g_tp.sram_cell.l_phy += curr_alpha * Lphy[ram_cell_tech_type]; - g_tp.sram_cell.l_elec += curr_alpha * Lelec[ram_cell_tech_type]; - g_tp.sram_cell.t_ox += curr_alpha * t_ox[ram_cell_tech_type]; - g_tp.sram_cell.Vth += curr_alpha * v_th[ram_cell_tech_type]; + g_tp.peri_global.l_phy += curr_alpha * Lphy[peri_global_tech_type]; + g_tp.peri_global.l_elec += curr_alpha * Lelec[peri_global_tech_type]; + g_tp.peri_global.I_on_n += curr_alpha * I_on_n[peri_global_tech_type]; + g_tp.peri_global.R_nch_on += + curr_alpha * Rnchannelon[peri_global_tech_type]; + g_tp.peri_global.R_pch_on += + curr_alpha * Rpchannelon[peri_global_tech_type]; + g_tp.peri_global.n_to_p_eff_curr_drv_ratio += + curr_alpha * n_to_p_eff_curr_drv_ratio[peri_global_tech_type]; + g_tp.peri_global.long_channel_leakage_reduction += + curr_alpha * long_channel_leakage_reduction[peri_global_tech_type]; + g_tp.peri_global.I_off_n += + curr_alpha * I_off_n[peri_global_tech_type][g_ip->temp - 300]; + g_tp.peri_global.I_off_p += + curr_alpha * I_off_n[peri_global_tech_type][g_ip->temp - 300]; + g_tp.peri_global.I_g_on_n += + curr_alpha * I_g_on_n[peri_global_tech_type][g_ip->temp - 300]; + g_tp.peri_global.I_g_on_p += + curr_alpha * I_g_on_n[peri_global_tech_type][g_ip->temp - 300]; + gmp_to_gmn_multiplier_periph_global += + curr_alpha * gmp_to_gmn_multiplier[peri_global_tech_type]; + + g_tp.sram_cell.Vdd += curr_alpha * vdd[ram_cell_tech_type]; + g_tp.sram_cell.l_phy += curr_alpha * Lphy[ram_cell_tech_type]; + g_tp.sram_cell.l_elec += curr_alpha * Lelec[ram_cell_tech_type]; + g_tp.sram_cell.t_ox += curr_alpha * t_ox[ram_cell_tech_type]; + g_tp.sram_cell.Vth += curr_alpha * v_th[ram_cell_tech_type]; g_tp.sram_cell.C_g_ideal += curr_alpha * c_g_ideal[ram_cell_tech_type]; - g_tp.sram_cell.C_fringe += curr_alpha * c_fringe[ram_cell_tech_type]; - g_tp.sram_cell.C_junc += curr_alpha * c_junc[ram_cell_tech_type]; + g_tp.sram_cell.C_fringe += curr_alpha * c_fringe[ram_cell_tech_type]; + g_tp.sram_cell.C_junc += curr_alpha * c_junc[ram_cell_tech_type]; g_tp.sram_cell.C_junc_sidewall = 0.25e-15; // F/micron - g_tp.sram_cell.I_on_n += curr_alpha * I_on_n[ram_cell_tech_type]; - g_tp.sram_cell.R_nch_on += curr_alpha * Rnchannelon[ram_cell_tech_type]; - g_tp.sram_cell.R_pch_on += curr_alpha * Rpchannelon[ram_cell_tech_type]; - g_tp.sram_cell.n_to_p_eff_curr_drv_ratio += curr_alpha * n_to_p_eff_curr_drv_ratio[ram_cell_tech_type]; - g_tp.sram_cell.long_channel_leakage_reduction += curr_alpha * long_channel_leakage_reduction[ram_cell_tech_type]; - g_tp.sram_cell.I_off_n += curr_alpha * I_off_n[ram_cell_tech_type][g_ip->temp - 300]; - g_tp.sram_cell.I_off_p += curr_alpha * I_off_n[ram_cell_tech_type][g_ip->temp - 300]; - g_tp.sram_cell.I_g_on_n += curr_alpha * I_g_on_n[ram_cell_tech_type][g_ip->temp - 300]; - g_tp.sram_cell.I_g_on_p += curr_alpha * I_g_on_n[ram_cell_tech_type][g_ip->temp - 300]; - - g_tp.dram_cell_Vdd += curr_alpha * curr_vdd_dram_cell; - g_tp.dram_acc.Vth += curr_alpha * curr_v_th_dram_access_transistor; - g_tp.dram_acc.l_phy += curr_alpha * Lphy[dram_cell_tech_flavor]; - g_tp.dram_acc.l_elec += curr_alpha * Lelec[dram_cell_tech_flavor]; + g_tp.sram_cell.I_on_n += curr_alpha * I_on_n[ram_cell_tech_type]; + g_tp.sram_cell.R_nch_on += curr_alpha * Rnchannelon[ram_cell_tech_type]; + g_tp.sram_cell.R_pch_on += curr_alpha * Rpchannelon[ram_cell_tech_type]; + g_tp.sram_cell.n_to_p_eff_curr_drv_ratio += + curr_alpha * n_to_p_eff_curr_drv_ratio[ram_cell_tech_type]; + g_tp.sram_cell.long_channel_leakage_reduction += + curr_alpha * long_channel_leakage_reduction[ram_cell_tech_type]; + g_tp.sram_cell.I_off_n += + curr_alpha * I_off_n[ram_cell_tech_type][g_ip->temp - 300]; + g_tp.sram_cell.I_off_p += + curr_alpha * I_off_n[ram_cell_tech_type][g_ip->temp - 300]; + g_tp.sram_cell.I_g_on_n += + curr_alpha * I_g_on_n[ram_cell_tech_type][g_ip->temp - 300]; + g_tp.sram_cell.I_g_on_p += + curr_alpha * I_g_on_n[ram_cell_tech_type][g_ip->temp - 300]; + + g_tp.dram_cell_Vdd += curr_alpha * curr_vdd_dram_cell; + g_tp.dram_acc.Vth += curr_alpha * curr_v_th_dram_access_transistor; + g_tp.dram_acc.l_phy += curr_alpha * Lphy[dram_cell_tech_flavor]; + g_tp.dram_acc.l_elec += curr_alpha * Lelec[dram_cell_tech_flavor]; g_tp.dram_acc.C_g_ideal += curr_alpha * c_g_ideal[dram_cell_tech_flavor]; - g_tp.dram_acc.C_fringe += curr_alpha * c_fringe[dram_cell_tech_flavor]; - g_tp.dram_acc.C_junc += curr_alpha * c_junc[dram_cell_tech_flavor]; + g_tp.dram_acc.C_fringe += curr_alpha * c_fringe[dram_cell_tech_flavor]; + g_tp.dram_acc.C_junc += curr_alpha * c_junc[dram_cell_tech_flavor]; g_tp.dram_acc.C_junc_sidewall = 0.25e-15; // F/micron - g_tp.dram_cell_I_on += curr_alpha * curr_I_on_dram_cell; - g_tp.dram_cell_I_off_worst_case_len_temp += curr_alpha * curr_I_off_dram_cell_worst_case_length_temp; - g_tp.dram_acc.I_on_n += curr_alpha * I_on_n[dram_cell_tech_flavor]; - g_tp.dram_cell_C += curr_alpha * curr_c_dram_cell; - g_tp.vpp += curr_alpha * curr_vpp; - g_tp.dram_wl.l_phy += curr_alpha * Lphy[dram_cell_tech_flavor]; - g_tp.dram_wl.l_elec += curr_alpha * Lelec[dram_cell_tech_flavor]; - g_tp.dram_wl.C_g_ideal += curr_alpha * c_g_ideal[dram_cell_tech_flavor]; - g_tp.dram_wl.C_fringe += curr_alpha * c_fringe[dram_cell_tech_flavor]; - g_tp.dram_wl.C_junc += curr_alpha * c_junc[dram_cell_tech_flavor]; + g_tp.dram_cell_I_on += curr_alpha * curr_I_on_dram_cell; + g_tp.dram_cell_I_off_worst_case_len_temp += + curr_alpha * curr_I_off_dram_cell_worst_case_length_temp; + g_tp.dram_acc.I_on_n += curr_alpha * I_on_n[dram_cell_tech_flavor]; + g_tp.dram_cell_C += curr_alpha * curr_c_dram_cell; + g_tp.vpp += curr_alpha * curr_vpp; + g_tp.dram_wl.l_phy += curr_alpha * Lphy[dram_cell_tech_flavor]; + g_tp.dram_wl.l_elec += curr_alpha * Lelec[dram_cell_tech_flavor]; + g_tp.dram_wl.C_g_ideal += curr_alpha * c_g_ideal[dram_cell_tech_flavor]; + g_tp.dram_wl.C_fringe += curr_alpha * c_fringe[dram_cell_tech_flavor]; + g_tp.dram_wl.C_junc += curr_alpha * c_junc[dram_cell_tech_flavor]; g_tp.dram_wl.C_junc_sidewall = 0.25e-15; // F/micron - g_tp.dram_wl.I_on_n += curr_alpha * I_on_n[dram_cell_tech_flavor]; - g_tp.dram_wl.R_nch_on += curr_alpha * Rnchannelon[dram_cell_tech_flavor]; - g_tp.dram_wl.R_pch_on += curr_alpha * Rpchannelon[dram_cell_tech_flavor]; - g_tp.dram_wl.n_to_p_eff_curr_drv_ratio += curr_alpha * n_to_p_eff_curr_drv_ratio[dram_cell_tech_flavor]; - g_tp.dram_wl.long_channel_leakage_reduction += curr_alpha * long_channel_leakage_reduction[dram_cell_tech_flavor]; - g_tp.dram_wl.I_off_n += curr_alpha * I_off_n[dram_cell_tech_flavor][g_ip->temp - 300]; - g_tp.dram_wl.I_off_p += curr_alpha * I_off_n[dram_cell_tech_flavor][g_ip->temp - 300]; - - g_tp.cam_cell.Vdd += curr_alpha * vdd[ram_cell_tech_type]; - g_tp.cam_cell.l_phy += curr_alpha * Lphy[ram_cell_tech_type]; - g_tp.cam_cell.l_elec += curr_alpha * Lelec[ram_cell_tech_type]; - g_tp.cam_cell.t_ox += curr_alpha * t_ox[ram_cell_tech_type]; - g_tp.cam_cell.Vth += curr_alpha * v_th[ram_cell_tech_type]; + g_tp.dram_wl.I_on_n += curr_alpha * I_on_n[dram_cell_tech_flavor]; + g_tp.dram_wl.R_nch_on += curr_alpha * Rnchannelon[dram_cell_tech_flavor]; + g_tp.dram_wl.R_pch_on += curr_alpha * Rpchannelon[dram_cell_tech_flavor]; + g_tp.dram_wl.n_to_p_eff_curr_drv_ratio += + curr_alpha * n_to_p_eff_curr_drv_ratio[dram_cell_tech_flavor]; + g_tp.dram_wl.long_channel_leakage_reduction += + curr_alpha * long_channel_leakage_reduction[dram_cell_tech_flavor]; + g_tp.dram_wl.I_off_n += + curr_alpha * I_off_n[dram_cell_tech_flavor][g_ip->temp - 300]; + g_tp.dram_wl.I_off_p += + curr_alpha * I_off_n[dram_cell_tech_flavor][g_ip->temp - 300]; + + g_tp.cam_cell.Vdd += curr_alpha * vdd[ram_cell_tech_type]; + g_tp.cam_cell.l_phy += curr_alpha * Lphy[ram_cell_tech_type]; + g_tp.cam_cell.l_elec += curr_alpha * Lelec[ram_cell_tech_type]; + g_tp.cam_cell.t_ox += curr_alpha * t_ox[ram_cell_tech_type]; + g_tp.cam_cell.Vth += curr_alpha * v_th[ram_cell_tech_type]; g_tp.cam_cell.C_g_ideal += curr_alpha * c_g_ideal[ram_cell_tech_type]; - g_tp.cam_cell.C_fringe += curr_alpha * c_fringe[ram_cell_tech_type]; - g_tp.cam_cell.C_junc += curr_alpha * c_junc[ram_cell_tech_type]; + g_tp.cam_cell.C_fringe += curr_alpha * c_fringe[ram_cell_tech_type]; + g_tp.cam_cell.C_junc += curr_alpha * c_junc[ram_cell_tech_type]; g_tp.cam_cell.C_junc_sidewall = 0.25e-15; // F/micron - g_tp.cam_cell.I_on_n += curr_alpha * I_on_n[ram_cell_tech_type]; - g_tp.cam_cell.R_nch_on += curr_alpha * Rnchannelon[ram_cell_tech_type]; - g_tp.cam_cell.R_pch_on += curr_alpha * Rpchannelon[ram_cell_tech_type]; - g_tp.cam_cell.n_to_p_eff_curr_drv_ratio += curr_alpha * n_to_p_eff_curr_drv_ratio[ram_cell_tech_type]; - g_tp.cam_cell.long_channel_leakage_reduction += curr_alpha * long_channel_leakage_reduction[ram_cell_tech_type]; - g_tp.cam_cell.I_off_n += curr_alpha * I_off_n[ram_cell_tech_type][g_ip->temp - 300]; - g_tp.cam_cell.I_off_p += curr_alpha * I_off_n[ram_cell_tech_type][g_ip->temp - 300]; - g_tp.cam_cell.I_g_on_n += curr_alpha * I_g_on_n[ram_cell_tech_type][g_ip->temp - 300]; - g_tp.cam_cell.I_g_on_p += curr_alpha * I_g_on_n[ram_cell_tech_type][g_ip->temp - 300]; - - g_tp.dram.cell_a_w += curr_alpha * curr_Wmemcella_dram; + g_tp.cam_cell.I_on_n += curr_alpha * I_on_n[ram_cell_tech_type]; + g_tp.cam_cell.R_nch_on += curr_alpha * Rnchannelon[ram_cell_tech_type]; + g_tp.cam_cell.R_pch_on += curr_alpha * Rpchannelon[ram_cell_tech_type]; + g_tp.cam_cell.n_to_p_eff_curr_drv_ratio += + curr_alpha * n_to_p_eff_curr_drv_ratio[ram_cell_tech_type]; + g_tp.cam_cell.long_channel_leakage_reduction += + curr_alpha * long_channel_leakage_reduction[ram_cell_tech_type]; + g_tp.cam_cell.I_off_n += + curr_alpha * I_off_n[ram_cell_tech_type][g_ip->temp - 300]; + g_tp.cam_cell.I_off_p += + curr_alpha * I_off_n[ram_cell_tech_type][g_ip->temp - 300]; + g_tp.cam_cell.I_g_on_n += + curr_alpha * I_g_on_n[ram_cell_tech_type][g_ip->temp - 300]; + g_tp.cam_cell.I_g_on_p += + curr_alpha * I_g_on_n[ram_cell_tech_type][g_ip->temp - 300]; + + g_tp.dram.cell_a_w += curr_alpha * curr_Wmemcella_dram; g_tp.dram.cell_pmos_w += curr_alpha * curr_Wmemcellpmos_dram; g_tp.dram.cell_nmos_w += curr_alpha * curr_Wmemcellnmos_dram; - area_cell_dram += curr_alpha * curr_area_cell_dram; - asp_ratio_cell_dram += curr_alpha * curr_asp_ratio_cell_dram; + area_cell_dram += curr_alpha * curr_area_cell_dram; + asp_ratio_cell_dram += curr_alpha * curr_asp_ratio_cell_dram; - g_tp.sram.cell_a_w += curr_alpha * curr_Wmemcella_sram; + g_tp.sram.cell_a_w += curr_alpha * curr_Wmemcella_sram; g_tp.sram.cell_pmos_w += curr_alpha * curr_Wmemcellpmos_sram; g_tp.sram.cell_nmos_w += curr_alpha * curr_Wmemcellnmos_sram; area_cell_sram += curr_alpha * curr_area_cell_sram; asp_ratio_cell_sram += curr_alpha * curr_asp_ratio_cell_sram; - g_tp.cam.cell_a_w += curr_alpha * curr_Wmemcella_cam;//sheng + g_tp.cam.cell_a_w += curr_alpha * curr_Wmemcella_cam; // sheng g_tp.cam.cell_pmos_w += curr_alpha * curr_Wmemcellpmos_cam; g_tp.cam.cell_nmos_w += curr_alpha * curr_Wmemcellnmos_cam; area_cell_cam += curr_alpha * curr_area_cell_cam; asp_ratio_cell_cam += curr_alpha * curr_asp_ratio_cell_cam; - //Sense amplifier latch Gm calculation - mobility_eff_periph_global += curr_alpha * mobility_eff[peri_global_tech_type]; + // Sense amplifier latch Gm calculation + mobility_eff_periph_global += + curr_alpha * mobility_eff[peri_global_tech_type]; Vdsat_periph_global += curr_alpha * Vdsat[peri_global_tech_type]; - //Empirical undifferetiated core/FU coefficient - g_tp.scaling_factor.logic_scaling_co_eff += curr_alpha * curr_logic_scaling_co_eff; + // Empirical undifferetiated core/FU coefficient + g_tp.scaling_factor.logic_scaling_co_eff += + curr_alpha * curr_logic_scaling_co_eff; g_tp.scaling_factor.core_tx_density += curr_alpha * curr_core_tx_density; - g_tp.chip_layout_overhead += curr_alpha * curr_chip_layout_overhead; + g_tp.chip_layout_overhead += curr_alpha * curr_chip_layout_overhead; g_tp.macro_layout_overhead += curr_alpha * curr_macro_layout_overhead; - g_tp.sckt_co_eff += curr_alpha * curr_sckt_co_eff; + g_tp.sckt_co_eff += curr_alpha * curr_sckt_co_eff; } - - //Currently we are not modeling the resistance/capacitance of poly anywhere. - //Continuous function (or date have been processed) does not need linear interpolation - g_tp.w_comp_inv_p1 = 12.5 * g_ip->F_sz_um;//this was 10 micron for the 0.8 micron process - g_tp.w_comp_inv_n1 = 7.5 * g_ip->F_sz_um;//this was 6 micron for the 0.8 micron process - g_tp.w_comp_inv_p2 = 25 * g_ip->F_sz_um;//this was 20 micron for the 0.8 micron process - g_tp.w_comp_inv_n2 = 15 * g_ip->F_sz_um;//this was 12 micron for the 0.8 micron process - g_tp.w_comp_inv_p3 = 50 * g_ip->F_sz_um;//this was 40 micron for the 0.8 micron process - g_tp.w_comp_inv_n3 = 30 * g_ip->F_sz_um;//this was 24 micron for the 0.8 micron process - g_tp.w_eval_inv_p = 100 * g_ip->F_sz_um;//this was 80 micron for the 0.8 micron process - g_tp.w_eval_inv_n = 50 * g_ip->F_sz_um;//this was 40 micron for the 0.8 micron process - g_tp.w_comp_n = 12.5 * g_ip->F_sz_um;//this was 10 micron for the 0.8 micron process - g_tp.w_comp_p = 37.5 * g_ip->F_sz_um;//this was 30 micron for the 0.8 micron process + // Currently we are not modeling the resistance/capacitance of poly anywhere. + // Continuous function (or date have been processed) does not need linear + // interpolation + g_tp.w_comp_inv_p1 = + 12.5 * g_ip->F_sz_um; // this was 10 micron for the 0.8 micron process + g_tp.w_comp_inv_n1 = + 7.5 * g_ip->F_sz_um; // this was 6 micron for the 0.8 micron process + g_tp.w_comp_inv_p2 = + 25 * g_ip->F_sz_um; // this was 20 micron for the 0.8 micron process + g_tp.w_comp_inv_n2 = + 15 * g_ip->F_sz_um; // this was 12 micron for the 0.8 micron process + g_tp.w_comp_inv_p3 = + 50 * g_ip->F_sz_um; // this was 40 micron for the 0.8 micron process + g_tp.w_comp_inv_n3 = + 30 * g_ip->F_sz_um; // this was 24 micron for the 0.8 micron process + g_tp.w_eval_inv_p = + 100 * g_ip->F_sz_um; // this was 80 micron for the 0.8 micron process + g_tp.w_eval_inv_n = + 50 * g_ip->F_sz_um; // this was 40 micron for the 0.8 micron process + g_tp.w_comp_n = + 12.5 * g_ip->F_sz_um; // this was 10 micron for the 0.8 micron process + g_tp.w_comp_p = + 37.5 * g_ip->F_sz_um; // this was 30 micron for the 0.8 micron process g_tp.MIN_GAP_BET_P_AND_N_DIFFS = 5 * g_ip->F_sz_um; g_tp.MIN_GAP_BET_SAME_TYPE_DIFFS = 1.5 * g_ip->F_sz_um; @@ -1828,255 +1893,264 @@ void init_tech_params(double technology, bool is_tag) g_tp.min_w_nmos_ = 3 * g_ip->F_sz_um / 2; g_tp.max_w_nmos_ = 100 * g_ip->F_sz_um; - g_tp.w_iso = 12.5*g_ip->F_sz_um;//was 10 micron for the 0.8 micron process - g_tp.w_sense_n = 3.75*g_ip->F_sz_um; // sense amplifier N-trans; was 3 micron for the 0.8 micron process - g_tp.w_sense_p = 7.5*g_ip->F_sz_um; // sense amplifier P-trans; was 6 micron for the 0.8 micron process - g_tp.w_sense_en = 5*g_ip->F_sz_um; // Sense enable transistor of the sense amplifier; was 4 micron for the 0.8 micron process - g_tp.w_nmos_b_mux = 6 * g_tp.min_w_nmos_; + g_tp.w_iso = 12.5 * g_ip->F_sz_um; // was 10 micron for the 0.8 micron + // process + g_tp.w_sense_n = 3.75 * g_ip->F_sz_um; // sense amplifier N-trans; was 3 + // micron for the 0.8 micron process + g_tp.w_sense_p = 7.5 * g_ip->F_sz_um; // sense amplifier P-trans; was 6 + // micron for the 0.8 micron process + g_tp.w_sense_en = + 5 * g_ip->F_sz_um; // Sense enable transistor of the sense amplifier; was + // 4 micron for the 0.8 micron process + g_tp.w_nmos_b_mux = 6 * g_tp.min_w_nmos_; g_tp.w_nmos_sa_mux = 6 * g_tp.min_w_nmos_; - if (ram_cell_tech_type == comm_dram) - { + if (ram_cell_tech_type == comm_dram) { g_tp.max_w_nmos_dec = 8 * g_ip->F_sz_um; - g_tp.h_dec = 8; // in the unit of memory cell height - } - else - { + g_tp.h_dec = 8; // in the unit of memory cell height + } else { g_tp.max_w_nmos_dec = g_tp.max_w_nmos_; - g_tp.h_dec = 4; // in the unit of memory cell height + g_tp.h_dec = 4; // in the unit of memory cell height } g_tp.peri_global.C_overlap = 0.2 * g_tp.peri_global.C_g_ideal; - g_tp.sram_cell.C_overlap = 0.2 * g_tp.sram_cell.C_g_ideal; - g_tp.cam_cell.C_overlap = 0.2 * g_tp.cam_cell.C_g_ideal; + g_tp.sram_cell.C_overlap = 0.2 * g_tp.sram_cell.C_g_ideal; + g_tp.cam_cell.C_overlap = 0.2 * g_tp.cam_cell.C_g_ideal; g_tp.dram_acc.C_overlap = 0.2 * g_tp.dram_acc.C_g_ideal; g_tp.dram_acc.R_nch_on = g_tp.dram_cell_Vdd / g_tp.dram_acc.I_on_n; - //g_tp.dram_acc.R_pch_on = g_tp.dram_cell_Vdd / g_tp.dram_acc.I_on_p; + // g_tp.dram_acc.R_pch_on = g_tp.dram_cell_Vdd / g_tp.dram_acc.I_on_p; g_tp.dram_wl.C_overlap = 0.2 * g_tp.dram_wl.C_g_ideal; - double gmn_sense_amp_latch = (mobility_eff_periph_global / 2) * g_tp.peri_global.C_ox * (g_tp.w_sense_n / g_tp.peri_global.l_elec) * Vdsat_periph_global; - double gmp_sense_amp_latch = gmp_to_gmn_multiplier_periph_global * gmn_sense_amp_latch; + double gmn_sense_amp_latch = + (mobility_eff_periph_global / 2) * g_tp.peri_global.C_ox * + (g_tp.w_sense_n / g_tp.peri_global.l_elec) * Vdsat_periph_global; + double gmp_sense_amp_latch = + gmp_to_gmn_multiplier_periph_global * gmn_sense_amp_latch; g_tp.gm_sense_amp_latch = gmn_sense_amp_latch + gmp_sense_amp_latch; g_tp.dram.b_w = sqrt(area_cell_dram / (asp_ratio_cell_dram)); g_tp.dram.b_h = asp_ratio_cell_dram * g_tp.dram.b_w; g_tp.sram.b_w = sqrt(area_cell_sram / (asp_ratio_cell_sram)); g_tp.sram.b_h = asp_ratio_cell_sram * g_tp.sram.b_w; - g_tp.cam.b_w = sqrt(area_cell_cam / (asp_ratio_cell_cam));//Sheng + g_tp.cam.b_w = sqrt(area_cell_cam / (asp_ratio_cell_cam)); // Sheng g_tp.cam.b_h = asp_ratio_cell_cam * g_tp.cam.b_w; g_tp.dram.Vbitpre = g_tp.dram_cell_Vdd; g_tp.sram.Vbitpre = vdd[ram_cell_tech_type]; - g_tp.cam.Vbitpre = vdd[ram_cell_tech_type];//Sheng + g_tp.cam.Vbitpre = vdd[ram_cell_tech_type]; // Sheng pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio(); g_tp.w_pmos_bl_precharge = 6 * pmos_to_nmos_sizing_r * g_tp.min_w_nmos_; g_tp.w_pmos_bl_eq = pmos_to_nmos_sizing_r * g_tp.min_w_nmos_; - - double wire_pitch [NUMBER_INTERCONNECT_PROJECTION_TYPES][NUMBER_WIRE_TYPES], - wire_r_per_micron[NUMBER_INTERCONNECT_PROJECTION_TYPES][NUMBER_WIRE_TYPES], - wire_c_per_micron[NUMBER_INTERCONNECT_PROJECTION_TYPES][NUMBER_WIRE_TYPES], - horiz_dielectric_constant[NUMBER_INTERCONNECT_PROJECTION_TYPES][NUMBER_WIRE_TYPES], - vert_dielectric_constant[NUMBER_INTERCONNECT_PROJECTION_TYPES][NUMBER_WIRE_TYPES], - aspect_ratio[NUMBER_INTERCONNECT_PROJECTION_TYPES][NUMBER_WIRE_TYPES], - miller_value[NUMBER_INTERCONNECT_PROJECTION_TYPES][NUMBER_WIRE_TYPES], - ild_thickness[NUMBER_INTERCONNECT_PROJECTION_TYPES][NUMBER_WIRE_TYPES]; - - for (iter=0; iter<=1; ++iter) - { + double wire_pitch[NUMBER_INTERCONNECT_PROJECTION_TYPES][NUMBER_WIRE_TYPES], + wire_r_per_micron[NUMBER_INTERCONNECT_PROJECTION_TYPES] + [NUMBER_WIRE_TYPES], + wire_c_per_micron[NUMBER_INTERCONNECT_PROJECTION_TYPES] + [NUMBER_WIRE_TYPES], + horiz_dielectric_constant[NUMBER_INTERCONNECT_PROJECTION_TYPES] + [NUMBER_WIRE_TYPES], + vert_dielectric_constant[NUMBER_INTERCONNECT_PROJECTION_TYPES] + [NUMBER_WIRE_TYPES], + aspect_ratio[NUMBER_INTERCONNECT_PROJECTION_TYPES][NUMBER_WIRE_TYPES], + miller_value[NUMBER_INTERCONNECT_PROJECTION_TYPES][NUMBER_WIRE_TYPES], + ild_thickness[NUMBER_INTERCONNECT_PROJECTION_TYPES][NUMBER_WIRE_TYPES]; + + for (iter = 0; iter <= 1; ++iter) { // linear interpolation - if (iter == 0) - { + if (iter == 0) { tech = tech_lo; - if (tech_lo == tech_hi) - { + if (tech_lo == tech_hi) { curr_alpha = 1; + } else { + curr_alpha = (technology - tech_hi) / (tech_lo - tech_hi); } - else - { - curr_alpha = (technology - tech_hi)/(tech_lo - tech_hi); - } - } - else - { + } else { tech = tech_hi; - if (tech_lo == tech_hi) - { + if (tech_lo == tech_hi) { break; - } - else - { - curr_alpha = (tech_lo - technology)/(tech_lo - tech_hi); + } else { + curr_alpha = (tech_lo - technology) / (tech_lo - tech_hi); } } - if (tech == 90) - { - //Aggressive projections - wire_pitch[0][0] = 2.5 * g_ip->F_sz_um;//micron + if (tech == 90) { + // Aggressive projections + wire_pitch[0][0] = 2.5 * g_ip->F_sz_um; // micron aspect_ratio[0][0] = 2.4; - wire_width = wire_pitch[0][0] / 2; //micron - wire_thickness = aspect_ratio[0][0] * wire_width;//micron - wire_spacing = wire_pitch[0][0] - wire_width;//micron - barrier_thickness = 0.01;//micron - dishing_thickness = 0;//micron + wire_width = wire_pitch[0][0] / 2; // micron + wire_thickness = aspect_ratio[0][0] * wire_width; // micron + wire_spacing = wire_pitch[0][0] - wire_width; // micron + barrier_thickness = 0.01; // micron + dishing_thickness = 0; // micron alpha_scatter = 1; - wire_r_per_micron[0][0] = wire_resistance(CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter);//ohm/micron - ild_thickness[0][0] = 0.48;//micron + wire_r_per_micron[0][0] = wire_resistance( + CU_RESISTIVITY, wire_width, wire_thickness, barrier_thickness, + dishing_thickness, alpha_scatter); // ohm/micron + ild_thickness[0][0] = 0.48; // micron miller_value[0][0] = 1.5; horiz_dielectric_constant[0][0] = 2.709; vert_dielectric_constant[0][0] = 3.9; - fringe_cap = 0.115e-15; //F/micron - wire_c_per_micron[0][0] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[0][0], miller_value[0][0], horiz_dielectric_constant[0][0], + fringe_cap = 0.115e-15; // F/micron + wire_c_per_micron[0][0] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[0][0], + miller_value[0][0], horiz_dielectric_constant[0][0], vert_dielectric_constant[0][0], - fringe_cap);//F/micron. + fringe_cap); // F/micron. wire_pitch[0][1] = 4 * g_ip->F_sz_um; wire_width = wire_pitch[0][1] / 2; aspect_ratio[0][1] = 2.4; wire_thickness = aspect_ratio[0][1] * wire_width; wire_spacing = wire_pitch[0][1] - wire_width; - wire_r_per_micron[0][1] = wire_resistance(CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[0][1] = 0.48;//micron + wire_r_per_micron[0][1] = + wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[0][1] = 0.48; // micron miller_value[0][1] = 1.5; horiz_dielectric_constant[0][1] = 2.709; vert_dielectric_constant[0][1] = 3.9; - wire_c_per_micron[0][1] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[0][1], miller_value[0][1], horiz_dielectric_constant[0][1], - vert_dielectric_constant[0][1], - fringe_cap); + wire_c_per_micron[0][1] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[0][1], + miller_value[0][1], horiz_dielectric_constant[0][1], + vert_dielectric_constant[0][1], fringe_cap); wire_pitch[0][2] = 8 * g_ip->F_sz_um; aspect_ratio[0][2] = 2.7; wire_width = wire_pitch[0][2] / 2; wire_thickness = aspect_ratio[0][2] * wire_width; wire_spacing = wire_pitch[0][2] - wire_width; - wire_r_per_micron[0][2] = wire_resistance(CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + wire_r_per_micron[0][2] = + wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[0][2] = 0.96; miller_value[0][2] = 1.5; horiz_dielectric_constant[0][2] = 2.709; vert_dielectric_constant[0][2] = 3.9; - wire_c_per_micron[0][2] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[0][2], miller_value[0][2], horiz_dielectric_constant[0][2], vert_dielectric_constant[0][2], - fringe_cap); + wire_c_per_micron[0][2] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[0][2], + miller_value[0][2], horiz_dielectric_constant[0][2], + vert_dielectric_constant[0][2], fringe_cap); - //Conservative projections + // Conservative projections wire_pitch[1][0] = 2.5 * g_ip->F_sz_um; - aspect_ratio[1][0] = 2.0; + aspect_ratio[1][0] = 2.0; wire_width = wire_pitch[1][0] / 2; wire_thickness = aspect_ratio[1][0] * wire_width; wire_spacing = wire_pitch[1][0] - wire_width; barrier_thickness = 0.008; dishing_thickness = 0; alpha_scatter = 1; - wire_r_per_micron[1][0] = wire_resistance(CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[1][0] = 0.48; - miller_value[1][0] = 1.5; - horiz_dielectric_constant[1][0] = 3.038; - vert_dielectric_constant[1][0] = 3.9; + wire_r_per_micron[1][0] = + wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[1][0] = 0.48; + miller_value[1][0] = 1.5; + horiz_dielectric_constant[1][0] = 3.038; + vert_dielectric_constant[1][0] = 3.9; fringe_cap = 0.115e-15; - wire_c_per_micron[1][0] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[1][0], miller_value[1][0], horiz_dielectric_constant[1][0], - vert_dielectric_constant[1][0], - fringe_cap); + wire_c_per_micron[1][0] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[1][0], + miller_value[1][0], horiz_dielectric_constant[1][0], + vert_dielectric_constant[1][0], fringe_cap); wire_pitch[1][1] = 4 * g_ip->F_sz_um; wire_width = wire_pitch[1][1] / 2; aspect_ratio[1][1] = 2.0; wire_thickness = aspect_ratio[1][1] * wire_width; wire_spacing = wire_pitch[1][1] - wire_width; - wire_r_per_micron[1][1] = wire_resistance(CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[1][1] = 0.48; - miller_value[1][1] = 1.5; - horiz_dielectric_constant[1][1] = 3.038; - vert_dielectric_constant[1][1] = 3.9; - wire_c_per_micron[1][1] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[1][1], miller_value[1][1], horiz_dielectric_constant[1][1], - vert_dielectric_constant[1][1], - fringe_cap); + wire_r_per_micron[1][1] = + wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[1][1] = 0.48; + miller_value[1][1] = 1.5; + horiz_dielectric_constant[1][1] = 3.038; + vert_dielectric_constant[1][1] = 3.9; + wire_c_per_micron[1][1] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[1][1], + miller_value[1][1], horiz_dielectric_constant[1][1], + vert_dielectric_constant[1][1], fringe_cap); wire_pitch[1][2] = 8 * g_ip->F_sz_um; - aspect_ratio[1][2] = 2.2; + aspect_ratio[1][2] = 2.2; wire_width = wire_pitch[1][2] / 2; wire_thickness = aspect_ratio[1][2] * wire_width; wire_spacing = wire_pitch[1][2] - wire_width; - dishing_thickness = 0.1 * wire_thickness; - wire_r_per_micron[1][2] = wire_resistance(CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[1][2] = 1.1; - miller_value[1][2] = 1.5; - horiz_dielectric_constant[1][2] = 3.038; - vert_dielectric_constant[1][2] = 3.9; - wire_c_per_micron[1][2] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[1][2] , miller_value[1][2], horiz_dielectric_constant[1][2], vert_dielectric_constant[1][2], - fringe_cap); - //Nominal projections for commodity DRAM wordline/bitline + dishing_thickness = 0.1 * wire_thickness; + wire_r_per_micron[1][2] = + wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[1][2] = 1.1; + miller_value[1][2] = 1.5; + horiz_dielectric_constant[1][2] = 3.038; + vert_dielectric_constant[1][2] = 3.9; + wire_c_per_micron[1][2] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[1][2], + miller_value[1][2], horiz_dielectric_constant[1][2], + vert_dielectric_constant[1][2], fringe_cap); + // Nominal projections for commodity DRAM wordline/bitline wire_pitch[1][3] = 2 * 0.09; wire_c_per_micron[1][3] = 60e-15 / (256 * 2 * 0.09); wire_r_per_micron[1][3] = 12 / 0.09; - } - else if (tech == 65) - { - //Aggressive projections + } else if (tech == 65) { + // Aggressive projections wire_pitch[0][0] = 2.5 * g_ip->F_sz_um; - aspect_ratio[0][0] = 2.7; + aspect_ratio[0][0] = 2.7; wire_width = wire_pitch[0][0] / 2; - wire_thickness = aspect_ratio[0][0] * wire_width; + wire_thickness = aspect_ratio[0][0] * wire_width; wire_spacing = wire_pitch[0][0] - wire_width; barrier_thickness = 0; dishing_thickness = 0; alpha_scatter = 1; - wire_r_per_micron[0][0] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[0][0] = 0.405; - miller_value[0][0] = 1.5; - horiz_dielectric_constant[0][0] = 2.303; - vert_dielectric_constant[0][0] = 3.9; + wire_r_per_micron[0][0] = + wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[0][0] = 0.405; + miller_value[0][0] = 1.5; + horiz_dielectric_constant[0][0] = 2.303; + vert_dielectric_constant[0][0] = 3.9; fringe_cap = 0.115e-15; - wire_c_per_micron[0][0] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[0][0] , miller_value[0][0] , horiz_dielectric_constant[0][0] , vert_dielectric_constant[0][0] , - fringe_cap); + wire_c_per_micron[0][0] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[0][0], + miller_value[0][0], horiz_dielectric_constant[0][0], + vert_dielectric_constant[0][0], fringe_cap); wire_pitch[0][1] = 4 * g_ip->F_sz_um; wire_width = wire_pitch[0][1] / 2; - aspect_ratio[0][1] = 2.7; - wire_thickness = aspect_ratio[0][1] * wire_width; + aspect_ratio[0][1] = 2.7; + wire_thickness = aspect_ratio[0][1] * wire_width; wire_spacing = wire_pitch[0][1] - wire_width; - wire_r_per_micron[0][1] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[0][1] = 0.405; - miller_value[0][1] = 1.5; - horiz_dielectric_constant[0][1] = 2.303; - vert_dielectric_constant[0][1] = 3.9; - wire_c_per_micron[0][1] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[0][1], miller_value[0][1], horiz_dielectric_constant[0][1], - vert_dielectric_constant[0][1], - fringe_cap); + wire_r_per_micron[0][1] = + wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[0][1] = 0.405; + miller_value[0][1] = 1.5; + horiz_dielectric_constant[0][1] = 2.303; + vert_dielectric_constant[0][1] = 3.9; + wire_c_per_micron[0][1] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[0][1], + miller_value[0][1], horiz_dielectric_constant[0][1], + vert_dielectric_constant[0][1], fringe_cap); wire_pitch[0][2] = 8 * g_ip->F_sz_um; aspect_ratio[0][2] = 2.8; wire_width = wire_pitch[0][2] / 2; wire_thickness = aspect_ratio[0][2] * wire_width; wire_spacing = wire_pitch[0][2] - wire_width; - wire_r_per_micron[0][2] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + wire_r_per_micron[0][2] = + wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[0][2] = 0.81; - miller_value[0][2] = 1.5; - horiz_dielectric_constant[0][2] = 2.303; - vert_dielectric_constant[0][2] = 3.9; - wire_c_per_micron[0][2] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[0][2], miller_value[0][2], horiz_dielectric_constant[0][2], vert_dielectric_constant[0][2], - fringe_cap); - - //Conservative projections + miller_value[0][2] = 1.5; + horiz_dielectric_constant[0][2] = 2.303; + vert_dielectric_constant[0][2] = 3.9; + wire_c_per_micron[0][2] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[0][2], + miller_value[0][2], horiz_dielectric_constant[0][2], + vert_dielectric_constant[0][2], fringe_cap); + + // Conservative projections wire_pitch[1][0] = 2.5 * g_ip->F_sz_um; aspect_ratio[1][0] = 2.0; wire_width = wire_pitch[1][0] / 2; @@ -2085,105 +2159,115 @@ void init_tech_params(double technology, bool is_tag) barrier_thickness = 0.006; dishing_thickness = 0; alpha_scatter = 1; - wire_r_per_micron[1][0] = wire_resistance(CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + wire_r_per_micron[1][0] = + wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[1][0] = 0.405; miller_value[1][0] = 1.5; horiz_dielectric_constant[1][0] = 2.734; vert_dielectric_constant[1][0] = 3.9; fringe_cap = 0.115e-15; - wire_c_per_micron[1][0] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[1][0], miller_value[1][0], horiz_dielectric_constant[1][0], vert_dielectric_constant[1][0], - fringe_cap); + wire_c_per_micron[1][0] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[1][0], + miller_value[1][0], horiz_dielectric_constant[1][0], + vert_dielectric_constant[1][0], fringe_cap); wire_pitch[1][1] = 4 * g_ip->F_sz_um; wire_width = wire_pitch[1][1] / 2; aspect_ratio[1][1] = 2.0; wire_thickness = aspect_ratio[1][1] * wire_width; wire_spacing = wire_pitch[1][1] - wire_width; - wire_r_per_micron[1][1] = wire_resistance(CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + wire_r_per_micron[1][1] = + wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[1][1] = 0.405; miller_value[1][1] = 1.5; horiz_dielectric_constant[1][1] = 2.734; vert_dielectric_constant[1][1] = 3.9; - wire_c_per_micron[1][1] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[1][1], miller_value[1][1], horiz_dielectric_constant[1][1], vert_dielectric_constant[1][1], - fringe_cap); + wire_c_per_micron[1][1] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[1][1], + miller_value[1][1], horiz_dielectric_constant[1][1], + vert_dielectric_constant[1][1], fringe_cap); wire_pitch[1][2] = 8 * g_ip->F_sz_um; aspect_ratio[1][2] = 2.2; wire_width = wire_pitch[1][2] / 2; wire_thickness = aspect_ratio[1][2] * wire_width; wire_spacing = wire_pitch[1][2] - wire_width; - dishing_thickness = 0.1 * wire_thickness; - wire_r_per_micron[1][2] = wire_resistance(CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + dishing_thickness = 0.1 * wire_thickness; + wire_r_per_micron[1][2] = + wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[1][2] = 0.77; miller_value[1][2] = 1.5; horiz_dielectric_constant[1][2] = 2.734; vert_dielectric_constant[1][2] = 3.9; - wire_c_per_micron[1][2] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[1][2], miller_value[1][2], horiz_dielectric_constant[1][2], vert_dielectric_constant[1][2], - fringe_cap); - //Nominal projections for commodity DRAM wordline/bitline + wire_c_per_micron[1][2] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[1][2], + miller_value[1][2], horiz_dielectric_constant[1][2], + vert_dielectric_constant[1][2], fringe_cap); + // Nominal projections for commodity DRAM wordline/bitline wire_pitch[1][3] = 2 * 0.065; wire_c_per_micron[1][3] = 52.5e-15 / (256 * 2 * 0.065); wire_r_per_micron[1][3] = 12 / 0.065; - } - else if (tech == 45) - { - //Aggressive projections. + } else if (tech == 45) { + // Aggressive projections. wire_pitch[0][0] = 2.5 * g_ip->F_sz_um; - aspect_ratio[0][0] = 3.0; + aspect_ratio[0][0] = 3.0; wire_width = wire_pitch[0][0] / 2; - wire_thickness = aspect_ratio[0][0] * wire_width; + wire_thickness = aspect_ratio[0][0] * wire_width; wire_spacing = wire_pitch[0][0] - wire_width; barrier_thickness = 0; dishing_thickness = 0; alpha_scatter = 1; - wire_r_per_micron[0][0] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[0][0] = 0.315; - miller_value[0][0] = 1.5; - horiz_dielectric_constant[0][0] = 1.958; - vert_dielectric_constant[0][0] = 3.9; + wire_r_per_micron[0][0] = + wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[0][0] = 0.315; + miller_value[0][0] = 1.5; + horiz_dielectric_constant[0][0] = 1.958; + vert_dielectric_constant[0][0] = 3.9; fringe_cap = 0.115e-15; - wire_c_per_micron[0][0] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[0][0] , miller_value[0][0] , horiz_dielectric_constant[0][0] , vert_dielectric_constant[0][0] , - fringe_cap); + wire_c_per_micron[0][0] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[0][0], + miller_value[0][0], horiz_dielectric_constant[0][0], + vert_dielectric_constant[0][0], fringe_cap); wire_pitch[0][1] = 4 * g_ip->F_sz_um; wire_width = wire_pitch[0][1] / 2; - aspect_ratio[0][1] = 3.0; + aspect_ratio[0][1] = 3.0; wire_thickness = aspect_ratio[0][1] * wire_width; wire_spacing = wire_pitch[0][1] - wire_width; - wire_r_per_micron[0][1] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[0][1] = 0.315; - miller_value[0][1] = 1.5; - horiz_dielectric_constant[0][1] = 1.958; - vert_dielectric_constant[0][1] = 3.9; - wire_c_per_micron[0][1] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[0][1], miller_value[0][1], horiz_dielectric_constant[0][1], vert_dielectric_constant[0][1], - fringe_cap); + wire_r_per_micron[0][1] = + wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[0][1] = 0.315; + miller_value[0][1] = 1.5; + horiz_dielectric_constant[0][1] = 1.958; + vert_dielectric_constant[0][1] = 3.9; + wire_c_per_micron[0][1] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[0][1], + miller_value[0][1], horiz_dielectric_constant[0][1], + vert_dielectric_constant[0][1], fringe_cap); wire_pitch[0][2] = 8 * g_ip->F_sz_um; aspect_ratio[0][2] = 3.0; wire_width = wire_pitch[0][2] / 2; wire_thickness = aspect_ratio[0][2] * wire_width; wire_spacing = wire_pitch[0][2] - wire_width; - wire_r_per_micron[0][2] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + wire_r_per_micron[0][2] = + wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[0][2] = 0.63; - miller_value[0][2] = 1.5; - horiz_dielectric_constant[0][2] = 1.958; - vert_dielectric_constant[0][2] = 3.9; - wire_c_per_micron[0][2] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[0][2], miller_value[0][2], horiz_dielectric_constant[0][2], vert_dielectric_constant[0][2], - fringe_cap); - - //Conservative projections + miller_value[0][2] = 1.5; + horiz_dielectric_constant[0][2] = 1.958; + vert_dielectric_constant[0][2] = 3.9; + wire_c_per_micron[0][2] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[0][2], + miller_value[0][2], horiz_dielectric_constant[0][2], + vert_dielectric_constant[0][2], fringe_cap); + + // Conservative projections wire_pitch[1][0] = 2.5 * g_ip->F_sz_um; aspect_ratio[1][0] = 2.0; wire_width = wire_pitch[1][0] / 2; @@ -2192,32 +2276,36 @@ void init_tech_params(double technology, bool is_tag) barrier_thickness = 0.004; dishing_thickness = 0; alpha_scatter = 1; - wire_r_per_micron[1][0] = wire_resistance(CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + wire_r_per_micron[1][0] = + wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[1][0] = 0.315; miller_value[1][0] = 1.5; horiz_dielectric_constant[1][0] = 2.46; vert_dielectric_constant[1][0] = 3.9; fringe_cap = 0.115e-15; - wire_c_per_micron[1][0] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[1][0], miller_value[1][0], horiz_dielectric_constant[1][0], vert_dielectric_constant[1][0], - fringe_cap); + wire_c_per_micron[1][0] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[1][0], + miller_value[1][0], horiz_dielectric_constant[1][0], + vert_dielectric_constant[1][0], fringe_cap); wire_pitch[1][1] = 4 * g_ip->F_sz_um; wire_width = wire_pitch[1][1] / 2; aspect_ratio[1][1] = 2.0; wire_thickness = aspect_ratio[1][1] * wire_width; wire_spacing = wire_pitch[1][1] - wire_width; - wire_r_per_micron[1][1] = wire_resistance(CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + wire_r_per_micron[1][1] = + wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[1][1] = 0.315; miller_value[1][1] = 1.5; horiz_dielectric_constant[1][1] = 2.46; vert_dielectric_constant[1][1] = 3.9; fringe_cap = 0.115e-15; - wire_c_per_micron[1][1] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[1][1], miller_value[1][1], horiz_dielectric_constant[1][1], vert_dielectric_constant[1][1], - fringe_cap); + wire_c_per_micron[1][1] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[1][1], + miller_value[1][1], horiz_dielectric_constant[1][1], + vert_dielectric_constant[1][1], fringe_cap); wire_pitch[1][2] = 8 * g_ip->F_sz_um; aspect_ratio[1][2] = 2.2; @@ -2225,23 +2313,23 @@ void init_tech_params(double technology, bool is_tag) wire_thickness = aspect_ratio[1][2] * wire_width; wire_spacing = wire_pitch[1][2] - wire_width; dishing_thickness = 0.1 * wire_thickness; - wire_r_per_micron[1][2] = wire_resistance(CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + wire_r_per_micron[1][2] = + wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[1][2] = 0.55; miller_value[1][2] = 1.5; horiz_dielectric_constant[1][2] = 2.46; vert_dielectric_constant[1][2] = 3.9; - wire_c_per_micron[1][2] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[1][2], miller_value[1][2], horiz_dielectric_constant[1][2], vert_dielectric_constant[1][2], - fringe_cap); - //Nominal projections for commodity DRAM wordline/bitline + wire_c_per_micron[1][2] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[1][2], + miller_value[1][2], horiz_dielectric_constant[1][2], + vert_dielectric_constant[1][2], fringe_cap); + // Nominal projections for commodity DRAM wordline/bitline wire_pitch[1][3] = 2 * 0.045; wire_c_per_micron[1][3] = 37.5e-15 / (256 * 2 * 0.045); wire_r_per_micron[1][3] = 12 / 0.045; - } - else if (tech == 32) - { - //Aggressive projections. + } else if (tech == 32) { + // Aggressive projections. wire_pitch[0][0] = 2.5 * g_ip->F_sz_um; aspect_ratio[0][0] = 3.0; wire_width = wire_pitch[0][0] / 2; @@ -2250,48 +2338,54 @@ void init_tech_params(double technology, bool is_tag) barrier_thickness = 0; dishing_thickness = 0; alpha_scatter = 1; - wire_r_per_micron[0][0] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + wire_r_per_micron[0][0] = + wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[0][0] = 0.21; miller_value[0][0] = 1.5; horiz_dielectric_constant[0][0] = 1.664; vert_dielectric_constant[0][0] = 3.9; fringe_cap = 0.115e-15; - wire_c_per_micron[0][0] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[0][0], miller_value[0][0], horiz_dielectric_constant[0][0], vert_dielectric_constant[0][0], - fringe_cap); + wire_c_per_micron[0][0] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[0][0], + miller_value[0][0], horiz_dielectric_constant[0][0], + vert_dielectric_constant[0][0], fringe_cap); wire_pitch[0][1] = 4 * g_ip->F_sz_um; wire_width = wire_pitch[0][1] / 2; aspect_ratio[0][1] = 3.0; wire_thickness = aspect_ratio[0][1] * wire_width; wire_spacing = wire_pitch[0][1] - wire_width; - wire_r_per_micron[0][1] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + wire_r_per_micron[0][1] = + wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[0][1] = 0.21; miller_value[0][1] = 1.5; horiz_dielectric_constant[0][1] = 1.664; vert_dielectric_constant[0][1] = 3.9; - wire_c_per_micron[0][1] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[0][1], miller_value[0][1], horiz_dielectric_constant[0][1], vert_dielectric_constant[0][1], - fringe_cap); + wire_c_per_micron[0][1] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[0][1], + miller_value[0][1], horiz_dielectric_constant[0][1], + vert_dielectric_constant[0][1], fringe_cap); wire_pitch[0][2] = 8 * g_ip->F_sz_um; aspect_ratio[0][2] = 3.0; wire_width = wire_pitch[0][2] / 2; wire_thickness = aspect_ratio[0][2] * wire_width; wire_spacing = wire_pitch[0][2] - wire_width; - wire_r_per_micron[0][2] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + wire_r_per_micron[0][2] = + wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[0][2] = 0.42; miller_value[0][2] = 1.5; horiz_dielectric_constant[0][2] = 1.664; vert_dielectric_constant[0][2] = 3.9; - wire_c_per_micron[0][2] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[0][2], miller_value[0][2], horiz_dielectric_constant[0][2], vert_dielectric_constant[0][2], - fringe_cap); + wire_c_per_micron[0][2] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[0][2], + miller_value[0][2], horiz_dielectric_constant[0][2], + vert_dielectric_constant[0][2], fringe_cap); - //Conservative projections + // Conservative projections wire_pitch[1][0] = 2.5 * g_ip->F_sz_um; aspect_ratio[1][0] = 2.0; wire_width = wire_pitch[1][0] / 2; @@ -2300,460 +2394,561 @@ void init_tech_params(double technology, bool is_tag) barrier_thickness = 0.003; dishing_thickness = 0; alpha_scatter = 1; - wire_r_per_micron[1][0] = wire_resistance(CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + wire_r_per_micron[1][0] = + wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[1][0] = 0.21; miller_value[1][0] = 1.5; horiz_dielectric_constant[1][0] = 2.214; vert_dielectric_constant[1][0] = 3.9; fringe_cap = 0.115e-15; - wire_c_per_micron[1][0] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[1][0], miller_value[1][0], horiz_dielectric_constant[1][0], vert_dielectric_constant[1][0], - fringe_cap); + wire_c_per_micron[1][0] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[1][0], + miller_value[1][0], horiz_dielectric_constant[1][0], + vert_dielectric_constant[1][0], fringe_cap); wire_pitch[1][1] = 4 * g_ip->F_sz_um; aspect_ratio[1][1] = 2.0; wire_width = wire_pitch[1][1] / 2; wire_thickness = aspect_ratio[1][1] * wire_width; wire_spacing = wire_pitch[1][1] - wire_width; - wire_r_per_micron[1][1] = wire_resistance(CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + wire_r_per_micron[1][1] = + wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[1][1] = 0.21; miller_value[1][1] = 1.5; horiz_dielectric_constant[1][1] = 2.214; vert_dielectric_constant[1][1] = 3.9; - wire_c_per_micron[1][1] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[1][1], miller_value[1][1], horiz_dielectric_constant[1][1], vert_dielectric_constant[1][1], - fringe_cap); + wire_c_per_micron[1][1] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[1][1], + miller_value[1][1], horiz_dielectric_constant[1][1], + vert_dielectric_constant[1][1], fringe_cap); wire_pitch[1][2] = 8 * g_ip->F_sz_um; aspect_ratio[1][2] = 2.2; wire_width = wire_pitch[1][2] / 2; wire_thickness = aspect_ratio[1][2] * wire_width; wire_spacing = wire_pitch[1][2] - wire_width; - dishing_thickness = 0.1 * wire_thickness; - wire_r_per_micron[1][2] = wire_resistance(CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); + dishing_thickness = 0.1 * wire_thickness; + wire_r_per_micron[1][2] = + wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); ild_thickness[1][2] = 0.385; miller_value[1][2] = 1.5; horiz_dielectric_constant[1][2] = 2.214; vert_dielectric_constant[1][2] = 3.9; - wire_c_per_micron[1][2] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[1][2], miller_value[1][2], horiz_dielectric_constant[1][2], vert_dielectric_constant[1][2], - fringe_cap); - //Nominal projections for commodity DRAM wordline/bitline - wire_pitch[1][3] = 2 * 0.032;//micron - wire_c_per_micron[1][3] = 31e-15 / (256 * 2 * 0.032);//F/micron - wire_r_per_micron[1][3] = 12 / 0.032;//ohm/micron + wire_c_per_micron[1][2] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[1][2], + miller_value[1][2], horiz_dielectric_constant[1][2], + vert_dielectric_constant[1][2], fringe_cap); + // Nominal projections for commodity DRAM wordline/bitline + wire_pitch[1][3] = 2 * 0.032; // micron + wire_c_per_micron[1][3] = 31e-15 / (256 * 2 * 0.032); // F/micron + wire_r_per_micron[1][3] = 12 / 0.032; // ohm/micron + } else if (tech == 22) { + // Aggressive projections. + wire_pitch[0][0] = 2.5 * g_ip->F_sz_um; // local + aspect_ratio[0][0] = 3.0; + wire_width = wire_pitch[0][0] / 2; + wire_thickness = aspect_ratio[0][0] * wire_width; + wire_spacing = wire_pitch[0][0] - wire_width; + barrier_thickness = 0; + dishing_thickness = 0; + alpha_scatter = 1; + wire_r_per_micron[0][0] = + wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[0][0] = 0.15; + miller_value[0][0] = 1.5; + horiz_dielectric_constant[0][0] = 1.414; + vert_dielectric_constant[0][0] = 3.9; + fringe_cap = 0.115e-15; + wire_c_per_micron[0][0] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[0][0], + miller_value[0][0], horiz_dielectric_constant[0][0], + vert_dielectric_constant[0][0], fringe_cap); + + wire_pitch[0][1] = 4 * g_ip->F_sz_um; // semi-global + wire_width = wire_pitch[0][1] / 2; + aspect_ratio[0][1] = 3.0; + wire_thickness = aspect_ratio[0][1] * wire_width; + wire_spacing = wire_pitch[0][1] - wire_width; + wire_r_per_micron[0][1] = + wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[0][1] = 0.15; + miller_value[0][1] = 1.5; + horiz_dielectric_constant[0][1] = 1.414; + vert_dielectric_constant[0][1] = 3.9; + wire_c_per_micron[0][1] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[0][1], + miller_value[0][1], horiz_dielectric_constant[0][1], + vert_dielectric_constant[0][1], fringe_cap); + + wire_pitch[0][2] = 8 * g_ip->F_sz_um; // global + aspect_ratio[0][2] = 3.0; + wire_width = wire_pitch[0][2] / 2; + wire_thickness = aspect_ratio[0][2] * wire_width; + wire_spacing = wire_pitch[0][2] - wire_width; + wire_r_per_micron[0][2] = + wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[0][2] = 0.3; + miller_value[0][2] = 1.5; + horiz_dielectric_constant[0][2] = 1.414; + vert_dielectric_constant[0][2] = 3.9; + wire_c_per_micron[0][2] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[0][2], + miller_value[0][2], horiz_dielectric_constant[0][2], + vert_dielectric_constant[0][2], fringe_cap); + + // //************************* + // wire_pitch[0][4] = 16 * g_ip.F_sz_um;//global + // aspect_ratio = 3.0; + // wire_width = wire_pitch[0][4] / 2; + // wire_thickness = aspect_ratio * wire_width; + // wire_spacing = wire_pitch[0][4] - wire_width; + // wire_r_per_micron[0][4] = wire_resistance(BULK_CU_RESISTIVITY, + // wire_width, + // wire_thickness, barrier_thickness, + // dishing_thickness, alpha_scatter); + // ild_thickness = 0.3; + // wire_c_per_micron[0][4] = wire_capacitance(wire_width, + // wire_thickness, wire_spacing, + // ild_thickness, miller_value, + // horiz_dielectric_constant, vert_dielectric_constant, + // fringe_cap); + // + // wire_pitch[0][5] = 24 * g_ip.F_sz_um;//global + // aspect_ratio = 3.0; + // wire_width = wire_pitch[0][5] / 2; + // wire_thickness = aspect_ratio * wire_width; + // wire_spacing = wire_pitch[0][5] - wire_width; + // wire_r_per_micron[0][5] = wire_resistance(BULK_CU_RESISTIVITY, + // wire_width, + // wire_thickness, barrier_thickness, + // dishing_thickness, alpha_scatter); + // ild_thickness = 0.3; + // wire_c_per_micron[0][5] = wire_capacitance(wire_width, + // wire_thickness, wire_spacing, + // ild_thickness, miller_value, + // horiz_dielectric_constant, vert_dielectric_constant, + // fringe_cap); + // + // wire_pitch[0][6] = 32 * g_ip.F_sz_um;//global + // aspect_ratio = 3.0; + // wire_width = wire_pitch[0][6] / 2; + // wire_thickness = aspect_ratio * wire_width; + // wire_spacing = wire_pitch[0][6] - wire_width; + // wire_r_per_micron[0][6] = wire_resistance(BULK_CU_RESISTIVITY, + // wire_width, + // wire_thickness, barrier_thickness, + // dishing_thickness, alpha_scatter); + // ild_thickness = 0.3; + // wire_c_per_micron[0][6] = wire_capacitance(wire_width, + // wire_thickness, wire_spacing, + // ild_thickness, miller_value, + // horiz_dielectric_constant, vert_dielectric_constant, + // fringe_cap); + //************************* + + // Conservative projections + wire_pitch[1][0] = 2.5 * g_ip->F_sz_um; + aspect_ratio[1][0] = 2.0; + wire_width = wire_pitch[1][0] / 2; + wire_thickness = aspect_ratio[1][0] * wire_width; + wire_spacing = wire_pitch[1][0] - wire_width; + barrier_thickness = 0.003; + dishing_thickness = 0; + alpha_scatter = 1.05; + wire_r_per_micron[1][0] = + wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[1][0] = 0.15; + miller_value[1][0] = 1.5; + horiz_dielectric_constant[1][0] = 2.104; + vert_dielectric_constant[1][0] = 3.9; + fringe_cap = 0.115e-15; + wire_c_per_micron[1][0] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[1][0], + miller_value[1][0], horiz_dielectric_constant[1][0], + vert_dielectric_constant[1][0], fringe_cap); + + wire_pitch[1][1] = 4 * g_ip->F_sz_um; + wire_width = wire_pitch[1][1] / 2; + aspect_ratio[1][1] = 2.0; + wire_thickness = aspect_ratio[1][1] * wire_width; + wire_spacing = wire_pitch[1][1] - wire_width; + wire_r_per_micron[1][1] = + wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[1][1] = 0.15; + miller_value[1][1] = 1.5; + horiz_dielectric_constant[1][1] = 2.104; + vert_dielectric_constant[1][1] = 3.9; + wire_c_per_micron[1][1] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[1][1], + miller_value[1][1], horiz_dielectric_constant[1][1], + vert_dielectric_constant[1][1], fringe_cap); + + wire_pitch[1][2] = 8 * g_ip->F_sz_um; + aspect_ratio[1][2] = 2.2; + wire_width = wire_pitch[1][2] / 2; + wire_thickness = aspect_ratio[1][2] * wire_width; + wire_spacing = wire_pitch[1][2] - wire_width; + dishing_thickness = 0.1 * wire_thickness; + wire_r_per_micron[1][2] = + wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[1][2] = 0.275; + miller_value[1][2] = 1.5; + horiz_dielectric_constant[1][2] = 2.104; + vert_dielectric_constant[1][2] = 3.9; + wire_c_per_micron[1][2] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[1][2], + miller_value[1][2], horiz_dielectric_constant[1][2], + vert_dielectric_constant[1][2], fringe_cap); + // Nominal projections for commodity DRAM wordline/bitline + wire_pitch[1][3] = 2 * 0.022; // micron + wire_c_per_micron[1][3] = 31e-15 / (256 * 2 * 0.022); // F/micron + wire_r_per_micron[1][3] = 12 / 0.022; // ohm/micron + + //****************** + // wire_pitch[1][4] = 16 * g_ip.F_sz_um; + // aspect_ratio = 2.2; + // wire_width = wire_pitch[1][4] / 2; + // wire_thickness = aspect_ratio * wire_width; + // wire_spacing = wire_pitch[1][4] - wire_width; + // dishing_thickness = 0.1 * wire_thickness; + // wire_r_per_micron[1][4] = wire_resistance(CU_RESISTIVITY, + // wire_width, wire_thickness, + // barrier_thickness, dishing_thickness, alpha_scatter); + // ild_thickness = 0.275; wire_c_per_micron[1][4] = + // wire_capacitance(wire_width, wire_thickness, wire_spacing, + // ild_thickness, miller_value, horiz_dielectric_constant, + // vert_dielectric_constant, fringe_cap); + // + // wire_pitch[1][5] = 24 * g_ip.F_sz_um; + // aspect_ratio = 2.2; + // wire_width = wire_pitch[1][5] / 2; + // wire_thickness = aspect_ratio * wire_width; + // wire_spacing = wire_pitch[1][5] - wire_width; + // dishing_thickness = 0.1 * wire_thickness; + // wire_r_per_micron[1][5] = wire_resistance(CU_RESISTIVITY, + // wire_width, wire_thickness, + // barrier_thickness, dishing_thickness, alpha_scatter); + // ild_thickness = 0.275; wire_c_per_micron[1][5] = + // wire_capacitance(wire_width, wire_thickness, wire_spacing, + // ild_thickness, miller_value, horiz_dielectric_constant, + // vert_dielectric_constant, fringe_cap); + // + // wire_pitch[1][6] = 32 * g_ip.F_sz_um; + // aspect_ratio = 2.2; + // wire_width = wire_pitch[1][6] / 2; + // wire_thickness = aspect_ratio * wire_width; + // wire_spacing = wire_pitch[1][6] - wire_width; + // dishing_thickness = 0.1 * wire_thickness; + // wire_r_per_micron[1][6] = wire_resistance(CU_RESISTIVITY, + // wire_width, wire_thickness, + // barrier_thickness, dishing_thickness, alpha_scatter); + // ild_thickness = 0.275; wire_c_per_micron[1][6] = + // wire_capacitance(wire_width, wire_thickness, wire_spacing, + // ild_thickness, miller_value, horiz_dielectric_constant, + // vert_dielectric_constant, fringe_cap); } - else if (tech == 22) - { - //Aggressive projections. - wire_pitch[0][0] = 2.5 * g_ip->F_sz_um;//local - aspect_ratio[0][0] = 3.0; - wire_width = wire_pitch[0][0] / 2; - wire_thickness = aspect_ratio[0][0] * wire_width; - wire_spacing = wire_pitch[0][0] - wire_width; - barrier_thickness = 0; - dishing_thickness = 0; - alpha_scatter = 1; - wire_r_per_micron[0][0] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[0][0] = 0.15; - miller_value[0][0] = 1.5; - horiz_dielectric_constant[0][0] = 1.414; - vert_dielectric_constant[0][0] = 3.9; - fringe_cap = 0.115e-15; - wire_c_per_micron[0][0] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[0][0], miller_value[0][0], horiz_dielectric_constant[0][0], vert_dielectric_constant[0][0], - fringe_cap); - - wire_pitch[0][1] = 4 * g_ip->F_sz_um;//semi-global - wire_width = wire_pitch[0][1] / 2; - aspect_ratio[0][1] = 3.0; - wire_thickness = aspect_ratio[0][1] * wire_width; - wire_spacing = wire_pitch[0][1] - wire_width; - wire_r_per_micron[0][1] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[0][1] = 0.15; - miller_value[0][1] = 1.5; - horiz_dielectric_constant[0][1] = 1.414; - vert_dielectric_constant[0][1] = 3.9; - wire_c_per_micron[0][1] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[0][1], miller_value[0][1], horiz_dielectric_constant[0][1], vert_dielectric_constant[0][1], - fringe_cap); - - wire_pitch[0][2] = 8 * g_ip->F_sz_um;//global - aspect_ratio[0][2] = 3.0; - wire_width = wire_pitch[0][2] / 2; - wire_thickness = aspect_ratio[0][2] * wire_width; - wire_spacing = wire_pitch[0][2] - wire_width; - wire_r_per_micron[0][2] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[0][2] = 0.3; - miller_value[0][2] = 1.5; - horiz_dielectric_constant[0][2] = 1.414; - vert_dielectric_constant[0][2] = 3.9; - wire_c_per_micron[0][2] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[0][2], miller_value[0][2], horiz_dielectric_constant[0][2], vert_dielectric_constant[0][2], - fringe_cap); - -// //************************* -// wire_pitch[0][4] = 16 * g_ip.F_sz_um;//global -// aspect_ratio = 3.0; -// wire_width = wire_pitch[0][4] / 2; -// wire_thickness = aspect_ratio * wire_width; -// wire_spacing = wire_pitch[0][4] - wire_width; -// wire_r_per_micron[0][4] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, -// wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); -// ild_thickness = 0.3; -// wire_c_per_micron[0][4] = wire_capacitance(wire_width, wire_thickness, wire_spacing, -// ild_thickness, miller_value, horiz_dielectric_constant, vert_dielectric_constant, -// fringe_cap); -// -// wire_pitch[0][5] = 24 * g_ip.F_sz_um;//global -// aspect_ratio = 3.0; -// wire_width = wire_pitch[0][5] / 2; -// wire_thickness = aspect_ratio * wire_width; -// wire_spacing = wire_pitch[0][5] - wire_width; -// wire_r_per_micron[0][5] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, -// wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); -// ild_thickness = 0.3; -// wire_c_per_micron[0][5] = wire_capacitance(wire_width, wire_thickness, wire_spacing, -// ild_thickness, miller_value, horiz_dielectric_constant, vert_dielectric_constant, -// fringe_cap); -// -// wire_pitch[0][6] = 32 * g_ip.F_sz_um;//global -// aspect_ratio = 3.0; -// wire_width = wire_pitch[0][6] / 2; -// wire_thickness = aspect_ratio * wire_width; -// wire_spacing = wire_pitch[0][6] - wire_width; -// wire_r_per_micron[0][6] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, -// wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); -// ild_thickness = 0.3; -// wire_c_per_micron[0][6] = wire_capacitance(wire_width, wire_thickness, wire_spacing, -// ild_thickness, miller_value, horiz_dielectric_constant, vert_dielectric_constant, -// fringe_cap); - //************************* - - //Conservative projections - wire_pitch[1][0] = 2.5 * g_ip->F_sz_um; - aspect_ratio[1][0] = 2.0; - wire_width = wire_pitch[1][0] / 2; - wire_thickness = aspect_ratio[1][0] * wire_width; - wire_spacing = wire_pitch[1][0] - wire_width; - barrier_thickness = 0.003; - dishing_thickness = 0; - alpha_scatter = 1.05; - wire_r_per_micron[1][0] = wire_resistance(CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[1][0] = 0.15; - miller_value[1][0] = 1.5; - horiz_dielectric_constant[1][0] = 2.104; - vert_dielectric_constant[1][0] = 3.9; - fringe_cap = 0.115e-15; - wire_c_per_micron[1][0] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[1][0], miller_value[1][0], horiz_dielectric_constant[1][0], vert_dielectric_constant[1][0], - fringe_cap); - - wire_pitch[1][1] = 4 * g_ip->F_sz_um; - wire_width = wire_pitch[1][1] / 2; - aspect_ratio[1][1] = 2.0; - wire_thickness = aspect_ratio[1][1] * wire_width; - wire_spacing = wire_pitch[1][1] - wire_width; - wire_r_per_micron[1][1] = wire_resistance(CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[1][1] = 0.15; - miller_value[1][1] = 1.5; - horiz_dielectric_constant[1][1] = 2.104; - vert_dielectric_constant[1][1] = 3.9; - wire_c_per_micron[1][1] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[1][1], miller_value[1][1], horiz_dielectric_constant[1][1], vert_dielectric_constant[1][1], - fringe_cap); - - wire_pitch[1][2] = 8 * g_ip->F_sz_um; - aspect_ratio[1][2] = 2.2; - wire_width = wire_pitch[1][2] / 2; - wire_thickness = aspect_ratio[1][2] * wire_width; - wire_spacing = wire_pitch[1][2] - wire_width; - dishing_thickness = 0.1 * wire_thickness; - wire_r_per_micron[1][2] = wire_resistance(CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[1][2] = 0.275; - miller_value[1][2] = 1.5; - horiz_dielectric_constant[1][2] = 2.104; - vert_dielectric_constant[1][2] = 3.9; - wire_c_per_micron[1][2] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[1][2], miller_value[1][2], horiz_dielectric_constant[1][2], vert_dielectric_constant[1][2], - fringe_cap); - //Nominal projections for commodity DRAM wordline/bitline - wire_pitch[1][3] = 2 * 0.022;//micron - wire_c_per_micron[1][3] = 31e-15 / (256 * 2 * 0.022);//F/micron - wire_r_per_micron[1][3] = 12 / 0.022;//ohm/micron - - //****************** -// wire_pitch[1][4] = 16 * g_ip.F_sz_um; -// aspect_ratio = 2.2; -// wire_width = wire_pitch[1][4] / 2; -// wire_thickness = aspect_ratio * wire_width; -// wire_spacing = wire_pitch[1][4] - wire_width; -// dishing_thickness = 0.1 * wire_thickness; -// wire_r_per_micron[1][4] = wire_resistance(CU_RESISTIVITY, wire_width, -// wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); -// ild_thickness = 0.275; -// wire_c_per_micron[1][4] = wire_capacitance(wire_width, wire_thickness, wire_spacing, -// ild_thickness, miller_value, horiz_dielectric_constant, vert_dielectric_constant, -// fringe_cap); -// -// wire_pitch[1][5] = 24 * g_ip.F_sz_um; -// aspect_ratio = 2.2; -// wire_width = wire_pitch[1][5] / 2; -// wire_thickness = aspect_ratio * wire_width; -// wire_spacing = wire_pitch[1][5] - wire_width; -// dishing_thickness = 0.1 * wire_thickness; -// wire_r_per_micron[1][5] = wire_resistance(CU_RESISTIVITY, wire_width, -// wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); -// ild_thickness = 0.275; -// wire_c_per_micron[1][5] = wire_capacitance(wire_width, wire_thickness, wire_spacing, -// ild_thickness, miller_value, horiz_dielectric_constant, vert_dielectric_constant, -// fringe_cap); -// -// wire_pitch[1][6] = 32 * g_ip.F_sz_um; -// aspect_ratio = 2.2; -// wire_width = wire_pitch[1][6] / 2; -// wire_thickness = aspect_ratio * wire_width; -// wire_spacing = wire_pitch[1][6] - wire_width; -// dishing_thickness = 0.1 * wire_thickness; -// wire_r_per_micron[1][6] = wire_resistance(CU_RESISTIVITY, wire_width, -// wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); -// ild_thickness = 0.275; -// wire_c_per_micron[1][6] = wire_capacitance(wire_width, wire_thickness, wire_spacing, -// ild_thickness, miller_value, horiz_dielectric_constant, vert_dielectric_constant, -// fringe_cap); - } - - else if (tech == 16) - { - //Aggressive projections. - wire_pitch[0][0] = 2.5 * g_ip->F_sz_um;//local - aspect_ratio[0][0] = 3.0; - wire_width = wire_pitch[0][0] / 2; - wire_thickness = aspect_ratio[0][0] * wire_width; - wire_spacing = wire_pitch[0][0] - wire_width; - barrier_thickness = 0; - dishing_thickness = 0; - alpha_scatter = 1; - wire_r_per_micron[0][0] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[0][0] = 0.108; - miller_value[0][0] = 1.5; - horiz_dielectric_constant[0][0] = 1.202; - vert_dielectric_constant[0][0] = 3.9; - fringe_cap = 0.115e-15; - wire_c_per_micron[0][0] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[0][0], miller_value[0][0], horiz_dielectric_constant[0][0], vert_dielectric_constant[0][0], - fringe_cap); - - wire_pitch[0][1] = 4 * g_ip->F_sz_um;//semi-global - aspect_ratio[0][1] = 3.0; - wire_width = wire_pitch[0][1] / 2; - wire_thickness = aspect_ratio[0][1] * wire_width; - wire_spacing = wire_pitch[0][1] - wire_width; - wire_r_per_micron[0][1] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[0][1] = 0.108; - miller_value[0][1] = 1.5; - horiz_dielectric_constant[0][1] = 1.202; - vert_dielectric_constant[0][1] = 3.9; - wire_c_per_micron[0][1] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[0][1], miller_value[0][1], horiz_dielectric_constant[0][1], vert_dielectric_constant[0][1], - fringe_cap); - - wire_pitch[0][2] = 8 * g_ip->F_sz_um;//global - aspect_ratio[0][2] = 3.0; - wire_width = wire_pitch[0][2] / 2; - wire_thickness = aspect_ratio[0][2] * wire_width; - wire_spacing = wire_pitch[0][2] - wire_width; - wire_r_per_micron[0][2] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[0][2] = 0.216; - miller_value[0][2] = 1.5; - horiz_dielectric_constant[0][2] = 1.202; - vert_dielectric_constant[0][2] = 3.9; - wire_c_per_micron[0][2] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[0][2], miller_value[0][2], horiz_dielectric_constant[0][2], vert_dielectric_constant[0][2], - fringe_cap); - -// //************************* -// wire_pitch[0][4] = 16 * g_ip.F_sz_um;//global -// aspect_ratio = 3.0; -// wire_width = wire_pitch[0][4] / 2; -// wire_thickness = aspect_ratio * wire_width; -// wire_spacing = wire_pitch[0][4] - wire_width; -// wire_r_per_micron[0][4] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, -// wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); -// ild_thickness = 0.3; -// wire_c_per_micron[0][4] = wire_capacitance(wire_width, wire_thickness, wire_spacing, -// ild_thickness, miller_value, horiz_dielectric_constant, vert_dielectric_constant, -// fringe_cap); -// -// wire_pitch[0][5] = 24 * g_ip.F_sz_um;//global -// aspect_ratio = 3.0; -// wire_width = wire_pitch[0][5] / 2; -// wire_thickness = aspect_ratio * wire_width; -// wire_spacing = wire_pitch[0][5] - wire_width; -// wire_r_per_micron[0][5] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, -// wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); -// ild_thickness = 0.3; -// wire_c_per_micron[0][5] = wire_capacitance(wire_width, wire_thickness, wire_spacing, -// ild_thickness, miller_value, horiz_dielectric_constant, vert_dielectric_constant, -// fringe_cap); -// -// wire_pitch[0][6] = 32 * g_ip.F_sz_um;//global -// aspect_ratio = 3.0; -// wire_width = wire_pitch[0][6] / 2; -// wire_thickness = aspect_ratio * wire_width; -// wire_spacing = wire_pitch[0][6] - wire_width; -// wire_r_per_micron[0][6] = wire_resistance(BULK_CU_RESISTIVITY, wire_width, -// wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); -// ild_thickness = 0.3; -// wire_c_per_micron[0][6] = wire_capacitance(wire_width, wire_thickness, wire_spacing, -// ild_thickness, miller_value, horiz_dielectric_constant, vert_dielectric_constant, -// fringe_cap); - //************************* - - //Conservative projections - wire_pitch[1][0] = 2.5 * g_ip->F_sz_um; - aspect_ratio[1][0] = 2.0; - wire_width = wire_pitch[1][0] / 2; - wire_thickness = aspect_ratio[1][0] * wire_width; - wire_spacing = wire_pitch[1][0] - wire_width; - barrier_thickness = 0.002; - dishing_thickness = 0; - alpha_scatter = 1.05; - wire_r_per_micron[1][0] = wire_resistance(CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[1][0] = 0.108; - miller_value[1][0] = 1.5; - horiz_dielectric_constant[1][0] = 1.998; - vert_dielectric_constant[1][0] = 3.9; - fringe_cap = 0.115e-15; - wire_c_per_micron[1][0] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[1][0], miller_value[1][0], horiz_dielectric_constant[1][0], vert_dielectric_constant[1][0], - fringe_cap); - - wire_pitch[1][1] = 4 * g_ip->F_sz_um; - wire_width = wire_pitch[1][1] / 2; - aspect_ratio[1][1] = 2.0; - wire_thickness = aspect_ratio[1][1] * wire_width; - wire_spacing = wire_pitch[1][1] - wire_width; - wire_r_per_micron[1][1] = wire_resistance(CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[1][1] = 0.108; - miller_value[1][1] = 1.5; - horiz_dielectric_constant[1][1] = 1.998; - vert_dielectric_constant[1][1] = 3.9; - wire_c_per_micron[1][1] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[1][1], miller_value[1][1], horiz_dielectric_constant[1][1], vert_dielectric_constant[1][1], - fringe_cap); - - wire_pitch[1][2] = 8 * g_ip->F_sz_um; - aspect_ratio[1][2] = 2.2; - wire_width = wire_pitch[1][2] / 2; - wire_thickness = aspect_ratio[1][2] * wire_width; - wire_spacing = wire_pitch[1][2] - wire_width; - dishing_thickness = 0.1 * wire_thickness; - wire_r_per_micron[1][2] = wire_resistance(CU_RESISTIVITY, wire_width, - wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); - ild_thickness[1][2] = 0.198; - miller_value[1][2] = 1.5; - horiz_dielectric_constant[1][2] = 1.998; - vert_dielectric_constant[1][2] = 3.9; - wire_c_per_micron[1][2] = wire_capacitance(wire_width, wire_thickness, wire_spacing, - ild_thickness[1][2], miller_value[1][2], horiz_dielectric_constant[1][2], vert_dielectric_constant[1][2], - fringe_cap); - //Nominal projections for commodity DRAM wordline/bitline - wire_pitch[1][3] = 2 * 0.016;//micron - wire_c_per_micron[1][3] = 31e-15 / (256 * 2 * 0.016);//F/micron - wire_r_per_micron[1][3] = 12 / 0.016;//ohm/micron - - //****************** -// wire_pitch[1][4] = 16 * g_ip.F_sz_um; -// aspect_ratio = 2.2; -// wire_width = wire_pitch[1][4] / 2; -// wire_thickness = aspect_ratio * wire_width; -// wire_spacing = wire_pitch[1][4] - wire_width; -// dishing_thickness = 0.1 * wire_thickness; -// wire_r_per_micron[1][4] = wire_resistance(CU_RESISTIVITY, wire_width, -// wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); -// ild_thickness = 0.275; -// wire_c_per_micron[1][4] = wire_capacitance(wire_width, wire_thickness, wire_spacing, -// ild_thickness, miller_value, horiz_dielectric_constant, vert_dielectric_constant, -// fringe_cap); -// -// wire_pitch[1][5] = 24 * g_ip.F_sz_um; -// aspect_ratio = 2.2; -// wire_width = wire_pitch[1][5] / 2; -// wire_thickness = aspect_ratio * wire_width; -// wire_spacing = wire_pitch[1][5] - wire_width; -// dishing_thickness = 0.1 * wire_thickness; -// wire_r_per_micron[1][5] = wire_resistance(CU_RESISTIVITY, wire_width, -// wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); -// ild_thickness = 0.275; -// wire_c_per_micron[1][5] = wire_capacitance(wire_width, wire_thickness, wire_spacing, -// ild_thickness, miller_value, horiz_dielectric_constant, vert_dielectric_constant, -// fringe_cap); -// -// wire_pitch[1][6] = 32 * g_ip.F_sz_um; -// aspect_ratio = 2.2; -// wire_width = wire_pitch[1][6] / 2; -// wire_thickness = aspect_ratio * wire_width; -// wire_spacing = wire_pitch[1][6] - wire_width; -// dishing_thickness = 0.1 * wire_thickness; -// wire_r_per_micron[1][6] = wire_resistance(CU_RESISTIVITY, wire_width, -// wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter); -// ild_thickness = 0.275; -// wire_c_per_micron[1][6] = wire_capacitance(wire_width, wire_thickness, wire_spacing, -// ild_thickness, miller_value, horiz_dielectric_constant, vert_dielectric_constant, -// fringe_cap); - } - g_tp.wire_local.pitch += curr_alpha * wire_pitch[g_ip->ic_proj_type][(ram_cell_tech_type == comm_dram)?3:0]; - g_tp.wire_local.R_per_um += curr_alpha * wire_r_per_micron[g_ip->ic_proj_type][(ram_cell_tech_type == comm_dram)?3:0]; - g_tp.wire_local.C_per_um += curr_alpha * wire_c_per_micron[g_ip->ic_proj_type][(ram_cell_tech_type == comm_dram)?3:0]; - g_tp.wire_local.aspect_ratio += curr_alpha * aspect_ratio[g_ip->ic_proj_type][(ram_cell_tech_type == comm_dram)?3:0]; - g_tp.wire_local.ild_thickness += curr_alpha * ild_thickness[g_ip->ic_proj_type][(ram_cell_tech_type == comm_dram)?3:0]; - g_tp.wire_local.miller_value += curr_alpha * miller_value[g_ip->ic_proj_type][(ram_cell_tech_type == comm_dram)?3:0]; - g_tp.wire_local.horiz_dielectric_constant += curr_alpha* horiz_dielectric_constant[g_ip->ic_proj_type][(ram_cell_tech_type == comm_dram)?3:0]; - g_tp.wire_local.vert_dielectric_constant += curr_alpha* vert_dielectric_constant [g_ip->ic_proj_type][(ram_cell_tech_type == comm_dram)?3:0]; - - g_tp.wire_inside_mat.pitch += curr_alpha * wire_pitch[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; - g_tp.wire_inside_mat.R_per_um += curr_alpha* wire_r_per_micron[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; - g_tp.wire_inside_mat.C_per_um += curr_alpha* wire_c_per_micron[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; - g_tp.wire_inside_mat.aspect_ratio += curr_alpha * aspect_ratio[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; - g_tp.wire_inside_mat.ild_thickness += curr_alpha * ild_thickness[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; - g_tp.wire_inside_mat.miller_value += curr_alpha * miller_value[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; - g_tp.wire_inside_mat.horiz_dielectric_constant += curr_alpha* horiz_dielectric_constant[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; - g_tp.wire_inside_mat.vert_dielectric_constant += curr_alpha* vert_dielectric_constant [g_ip->ic_proj_type][g_ip->wire_is_mat_type]; - - g_tp.wire_outside_mat.pitch += curr_alpha * wire_pitch[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; - g_tp.wire_outside_mat.R_per_um += curr_alpha*wire_r_per_micron[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; - g_tp.wire_outside_mat.C_per_um += curr_alpha*wire_c_per_micron[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; - g_tp.wire_outside_mat.aspect_ratio += curr_alpha * aspect_ratio[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; - g_tp.wire_outside_mat.ild_thickness += curr_alpha * ild_thickness[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; - g_tp.wire_outside_mat.miller_value += curr_alpha * miller_value[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; - g_tp.wire_outside_mat.horiz_dielectric_constant += curr_alpha* horiz_dielectric_constant[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; - g_tp.wire_outside_mat.vert_dielectric_constant += curr_alpha* vert_dielectric_constant [g_ip->ic_proj_type][g_ip->wire_os_mat_type]; - - g_tp.unit_len_wire_del = g_tp.wire_inside_mat.R_per_um * g_tp.wire_inside_mat.C_per_um / 2; - - g_tp.sense_delay += curr_alpha *SENSE_AMP_D; - g_tp.sense_dy_power += curr_alpha *SENSE_AMP_P; -// g_tp.horiz_dielectric_constant += horiz_dielectric_constant; -// g_tp.vert_dielectric_constant += vert_dielectric_constant; -// g_tp.aspect_ratio += aspect_ratio; -// g_tp.miller_value += miller_value; -// g_tp.ild_thickness += ild_thickness; + else if (tech == 16) { + // Aggressive projections. + wire_pitch[0][0] = 2.5 * g_ip->F_sz_um; // local + aspect_ratio[0][0] = 3.0; + wire_width = wire_pitch[0][0] / 2; + wire_thickness = aspect_ratio[0][0] * wire_width; + wire_spacing = wire_pitch[0][0] - wire_width; + barrier_thickness = 0; + dishing_thickness = 0; + alpha_scatter = 1; + wire_r_per_micron[0][0] = + wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[0][0] = 0.108; + miller_value[0][0] = 1.5; + horiz_dielectric_constant[0][0] = 1.202; + vert_dielectric_constant[0][0] = 3.9; + fringe_cap = 0.115e-15; + wire_c_per_micron[0][0] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[0][0], + miller_value[0][0], horiz_dielectric_constant[0][0], + vert_dielectric_constant[0][0], fringe_cap); + + wire_pitch[0][1] = 4 * g_ip->F_sz_um; // semi-global + aspect_ratio[0][1] = 3.0; + wire_width = wire_pitch[0][1] / 2; + wire_thickness = aspect_ratio[0][1] * wire_width; + wire_spacing = wire_pitch[0][1] - wire_width; + wire_r_per_micron[0][1] = + wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[0][1] = 0.108; + miller_value[0][1] = 1.5; + horiz_dielectric_constant[0][1] = 1.202; + vert_dielectric_constant[0][1] = 3.9; + wire_c_per_micron[0][1] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[0][1], + miller_value[0][1], horiz_dielectric_constant[0][1], + vert_dielectric_constant[0][1], fringe_cap); + + wire_pitch[0][2] = 8 * g_ip->F_sz_um; // global + aspect_ratio[0][2] = 3.0; + wire_width = wire_pitch[0][2] / 2; + wire_thickness = aspect_ratio[0][2] * wire_width; + wire_spacing = wire_pitch[0][2] - wire_width; + wire_r_per_micron[0][2] = + wire_resistance(BULK_CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[0][2] = 0.216; + miller_value[0][2] = 1.5; + horiz_dielectric_constant[0][2] = 1.202; + vert_dielectric_constant[0][2] = 3.9; + wire_c_per_micron[0][2] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[0][2], + miller_value[0][2], horiz_dielectric_constant[0][2], + vert_dielectric_constant[0][2], fringe_cap); + + // //************************* + // wire_pitch[0][4] = 16 * g_ip.F_sz_um;//global + // aspect_ratio = 3.0; + // wire_width = wire_pitch[0][4] / 2; + // wire_thickness = aspect_ratio * wire_width; + // wire_spacing = wire_pitch[0][4] - wire_width; + // wire_r_per_micron[0][4] = wire_resistance(BULK_CU_RESISTIVITY, + // wire_width, + // wire_thickness, barrier_thickness, + // dishing_thickness, alpha_scatter); + // ild_thickness = 0.3; + // wire_c_per_micron[0][4] = wire_capacitance(wire_width, + // wire_thickness, wire_spacing, + // ild_thickness, miller_value, + // horiz_dielectric_constant, vert_dielectric_constant, + // fringe_cap); + // + // wire_pitch[0][5] = 24 * g_ip.F_sz_um;//global + // aspect_ratio = 3.0; + // wire_width = wire_pitch[0][5] / 2; + // wire_thickness = aspect_ratio * wire_width; + // wire_spacing = wire_pitch[0][5] - wire_width; + // wire_r_per_micron[0][5] = wire_resistance(BULK_CU_RESISTIVITY, + // wire_width, + // wire_thickness, barrier_thickness, + // dishing_thickness, alpha_scatter); + // ild_thickness = 0.3; + // wire_c_per_micron[0][5] = wire_capacitance(wire_width, + // wire_thickness, wire_spacing, + // ild_thickness, miller_value, + // horiz_dielectric_constant, vert_dielectric_constant, + // fringe_cap); + // + // wire_pitch[0][6] = 32 * g_ip.F_sz_um;//global + // aspect_ratio = 3.0; + // wire_width = wire_pitch[0][6] / 2; + // wire_thickness = aspect_ratio * wire_width; + // wire_spacing = wire_pitch[0][6] - wire_width; + // wire_r_per_micron[0][6] = wire_resistance(BULK_CU_RESISTIVITY, + // wire_width, + // wire_thickness, barrier_thickness, + // dishing_thickness, alpha_scatter); + // ild_thickness = 0.3; + // wire_c_per_micron[0][6] = wire_capacitance(wire_width, + // wire_thickness, wire_spacing, + // ild_thickness, miller_value, + // horiz_dielectric_constant, vert_dielectric_constant, + // fringe_cap); + //************************* + + // Conservative projections + wire_pitch[1][0] = 2.5 * g_ip->F_sz_um; + aspect_ratio[1][0] = 2.0; + wire_width = wire_pitch[1][0] / 2; + wire_thickness = aspect_ratio[1][0] * wire_width; + wire_spacing = wire_pitch[1][0] - wire_width; + barrier_thickness = 0.002; + dishing_thickness = 0; + alpha_scatter = 1.05; + wire_r_per_micron[1][0] = + wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[1][0] = 0.108; + miller_value[1][0] = 1.5; + horiz_dielectric_constant[1][0] = 1.998; + vert_dielectric_constant[1][0] = 3.9; + fringe_cap = 0.115e-15; + wire_c_per_micron[1][0] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[1][0], + miller_value[1][0], horiz_dielectric_constant[1][0], + vert_dielectric_constant[1][0], fringe_cap); + + wire_pitch[1][1] = 4 * g_ip->F_sz_um; + wire_width = wire_pitch[1][1] / 2; + aspect_ratio[1][1] = 2.0; + wire_thickness = aspect_ratio[1][1] * wire_width; + wire_spacing = wire_pitch[1][1] - wire_width; + wire_r_per_micron[1][1] = + wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[1][1] = 0.108; + miller_value[1][1] = 1.5; + horiz_dielectric_constant[1][1] = 1.998; + vert_dielectric_constant[1][1] = 3.9; + wire_c_per_micron[1][1] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[1][1], + miller_value[1][1], horiz_dielectric_constant[1][1], + vert_dielectric_constant[1][1], fringe_cap); + + wire_pitch[1][2] = 8 * g_ip->F_sz_um; + aspect_ratio[1][2] = 2.2; + wire_width = wire_pitch[1][2] / 2; + wire_thickness = aspect_ratio[1][2] * wire_width; + wire_spacing = wire_pitch[1][2] - wire_width; + dishing_thickness = 0.1 * wire_thickness; + wire_r_per_micron[1][2] = + wire_resistance(CU_RESISTIVITY, wire_width, wire_thickness, + barrier_thickness, dishing_thickness, alpha_scatter); + ild_thickness[1][2] = 0.198; + miller_value[1][2] = 1.5; + horiz_dielectric_constant[1][2] = 1.998; + vert_dielectric_constant[1][2] = 3.9; + wire_c_per_micron[1][2] = wire_capacitance( + wire_width, wire_thickness, wire_spacing, ild_thickness[1][2], + miller_value[1][2], horiz_dielectric_constant[1][2], + vert_dielectric_constant[1][2], fringe_cap); + // Nominal projections for commodity DRAM wordline/bitline + wire_pitch[1][3] = 2 * 0.016; // micron + wire_c_per_micron[1][3] = 31e-15 / (256 * 2 * 0.016); // F/micron + wire_r_per_micron[1][3] = 12 / 0.016; // ohm/micron + + //****************** + // wire_pitch[1][4] = 16 * g_ip.F_sz_um; + // aspect_ratio = 2.2; + // wire_width = wire_pitch[1][4] / 2; + // wire_thickness = aspect_ratio * wire_width; + // wire_spacing = wire_pitch[1][4] - wire_width; + // dishing_thickness = 0.1 * wire_thickness; + // wire_r_per_micron[1][4] = wire_resistance(CU_RESISTIVITY, + // wire_width, wire_thickness, + // barrier_thickness, dishing_thickness, alpha_scatter); + // ild_thickness = 0.275; wire_c_per_micron[1][4] = + // wire_capacitance(wire_width, wire_thickness, wire_spacing, + // ild_thickness, miller_value, horiz_dielectric_constant, + // vert_dielectric_constant, fringe_cap); + // + // wire_pitch[1][5] = 24 * g_ip.F_sz_um; + // aspect_ratio = 2.2; + // wire_width = wire_pitch[1][5] / 2; + // wire_thickness = aspect_ratio * wire_width; + // wire_spacing = wire_pitch[1][5] - wire_width; + // dishing_thickness = 0.1 * wire_thickness; + // wire_r_per_micron[1][5] = wire_resistance(CU_RESISTIVITY, + // wire_width, wire_thickness, + // barrier_thickness, dishing_thickness, alpha_scatter); + // ild_thickness = 0.275; wire_c_per_micron[1][5] = + // wire_capacitance(wire_width, wire_thickness, wire_spacing, + // ild_thickness, miller_value, horiz_dielectric_constant, + // vert_dielectric_constant, fringe_cap); + // + // wire_pitch[1][6] = 32 * g_ip.F_sz_um; + // aspect_ratio = 2.2; + // wire_width = wire_pitch[1][6] / 2; + // wire_thickness = aspect_ratio * wire_width; + // wire_spacing = wire_pitch[1][6] - wire_width; + // dishing_thickness = 0.1 * wire_thickness; + // wire_r_per_micron[1][6] = wire_resistance(CU_RESISTIVITY, + // wire_width, wire_thickness, + // barrier_thickness, dishing_thickness, alpha_scatter); + // ild_thickness = 0.275; wire_c_per_micron[1][6] = + // wire_capacitance(wire_width, wire_thickness, wire_spacing, + // ild_thickness, miller_value, horiz_dielectric_constant, + // vert_dielectric_constant, fringe_cap); + } + g_tp.wire_local.pitch += + curr_alpha * wire_pitch[g_ip->ic_proj_type] + [(ram_cell_tech_type == comm_dram) ? 3 : 0]; + g_tp.wire_local.R_per_um += + curr_alpha * + wire_r_per_micron[g_ip->ic_proj_type] + [(ram_cell_tech_type == comm_dram) ? 3 : 0]; + g_tp.wire_local.C_per_um += + curr_alpha * + wire_c_per_micron[g_ip->ic_proj_type] + [(ram_cell_tech_type == comm_dram) ? 3 : 0]; + g_tp.wire_local.aspect_ratio += + curr_alpha * aspect_ratio[g_ip->ic_proj_type] + [(ram_cell_tech_type == comm_dram) ? 3 : 0]; + g_tp.wire_local.ild_thickness += + curr_alpha * ild_thickness[g_ip->ic_proj_type] + [(ram_cell_tech_type == comm_dram) ? 3 : 0]; + g_tp.wire_local.miller_value += + curr_alpha * miller_value[g_ip->ic_proj_type] + [(ram_cell_tech_type == comm_dram) ? 3 : 0]; + g_tp.wire_local.horiz_dielectric_constant += + curr_alpha * + horiz_dielectric_constant[g_ip->ic_proj_type] + [(ram_cell_tech_type == comm_dram) ? 3 : 0]; + g_tp.wire_local.vert_dielectric_constant += + curr_alpha * + vert_dielectric_constant[g_ip->ic_proj_type] + [(ram_cell_tech_type == comm_dram) ? 3 : 0]; + + g_tp.wire_inside_mat.pitch += + curr_alpha * wire_pitch[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; + g_tp.wire_inside_mat.R_per_um += + curr_alpha * + wire_r_per_micron[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; + g_tp.wire_inside_mat.C_per_um += + curr_alpha * + wire_c_per_micron[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; + g_tp.wire_inside_mat.aspect_ratio += + curr_alpha * aspect_ratio[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; + g_tp.wire_inside_mat.ild_thickness += + curr_alpha * ild_thickness[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; + g_tp.wire_inside_mat.miller_value += + curr_alpha * miller_value[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; + g_tp.wire_inside_mat.horiz_dielectric_constant += + curr_alpha * + horiz_dielectric_constant[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; + g_tp.wire_inside_mat.vert_dielectric_constant += + curr_alpha * + vert_dielectric_constant[g_ip->ic_proj_type][g_ip->wire_is_mat_type]; + + g_tp.wire_outside_mat.pitch += + curr_alpha * wire_pitch[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; + g_tp.wire_outside_mat.R_per_um += + curr_alpha * + wire_r_per_micron[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; + g_tp.wire_outside_mat.C_per_um += + curr_alpha * + wire_c_per_micron[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; + g_tp.wire_outside_mat.aspect_ratio += + curr_alpha * aspect_ratio[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; + g_tp.wire_outside_mat.ild_thickness += + curr_alpha * ild_thickness[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; + g_tp.wire_outside_mat.miller_value += + curr_alpha * miller_value[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; + g_tp.wire_outside_mat.horiz_dielectric_constant += + curr_alpha * + horiz_dielectric_constant[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; + g_tp.wire_outside_mat.vert_dielectric_constant += + curr_alpha * + vert_dielectric_constant[g_ip->ic_proj_type][g_ip->wire_os_mat_type]; + + g_tp.unit_len_wire_del = + g_tp.wire_inside_mat.R_per_um * g_tp.wire_inside_mat.C_per_um / 2; + + g_tp.sense_delay += curr_alpha * SENSE_AMP_D; + g_tp.sense_dy_power += curr_alpha * SENSE_AMP_P; + // g_tp.horiz_dielectric_constant += horiz_dielectric_constant; + // g_tp.vert_dielectric_constant += vert_dielectric_constant; + // g_tp.aspect_ratio += aspect_ratio; + // g_tp.miller_value += miller_value; + // g_tp.ild_thickness += ild_thickness; } g_tp.fringe_cap = fringe_cap; @@ -2764,9 +2959,9 @@ void init_tech_params(double technology, bool is_tag) g_tp.kinv = horowitz(0, tf, 0.5, 0.5, RISE); double KLOAD = 1; c_load = KLOAD * (drain_C_(g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def) + - drain_C_(g_tp.min_w_nmos_ * p_to_n_sizing_r, PCH, 1, 1, g_tp.cell_h_def) + + drain_C_(g_tp.min_w_nmos_ * p_to_n_sizing_r, PCH, 1, 1, + g_tp.cell_h_def) + gate_C(g_tp.min_w_nmos_ * 4 * (1 + p_to_n_sizing_r), 0.0)); tf = rd * c_load; g_tp.FO4 = horowitz(0, tf, 0.5, 0.5, RISE); } - diff --git a/src/gpuwattch/version.h b/src/gpuwattch/version.h index 76d8c75..41bd5b9 100644 --- a/src/gpuwattch/version.h +++ b/src/gpuwattch/version.h @@ -32,9 +32,9 @@ #ifndef VERSION_H_ #define VERSION_H_ -#define VER_MAJOR 0 /* beta release */ -#define VER_MINOR 8 +#define VER_MAJOR 0 /* beta release */ +#define VER_MINOR 8 -#define VER_UPDATE "Aug, 2010" +#define VER_UPDATE "Aug, 2010" #endif /* VERSION_H_ */ diff --git a/src/gpuwattch/xmlParser.cc b/src/gpuwattch/xmlParser.cc index 968658a..8f49b39 100644 --- a/src/gpuwattch/xmlParser.cc +++ b/src/gpuwattch/xmlParser.cc @@ -37,23 +37,23 @@ * * NOTE: * - * If you add "#define _XMLPARSER_NO_MESSAGEBOX_" on the first line of this file - * the "openFileHelper" function will always display error messages inside the - * console instead of inside a message-box-window. Message-box-windows are + * If you add "#define _XMLPARSER_NO_MESSAGEBOX_" on the first line of this + *file the "openFileHelper" function will always display error messages inside + *the console instead of inside a message-box-window. Message-box-windows are * available on windows 9x/NT/2000/XP/Vista only. * - * The following license terms for the "XMLParser library from Business-Insight" apply to projects - * that are in some way related to - * the "mcpat project", including applications - * using "mcpat project" and tools developed - * for enhancing "mcpat project". All other projects - * (not related to "mcpat project") have to use the "XMLParser library from Business-Insight" - * code under the Aladdin Free Public License (AFPL) - * See the file "AFPL-license.txt" for more informations about the AFPL license. - * (see http://www.artifex.com/downloads/doc/Public.htm for detailed AFPL terms) + * The following license terms for the "XMLParser library from Business-Insight" + *apply to projects that are in some way related to the "mcpat project", + *including applications using "mcpat project" and tools developed for enhancing + *"mcpat project". All other projects (not related to "mcpat project") have to + *use the "XMLParser library from Business-Insight" code under the Aladdin Free + *Public License (AFPL) See the file "AFPL-license.txt" for more informations + *about the AFPL license. (see http://www.artifex.com/downloads/doc/Public.htm + *for detailed AFPL terms) * - * Redistribution and use of the "XMLParser library from Business-Insight" in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * Redistribution and use of the "XMLParser library from Business-Insight" in + *source and binary forms, with or without modification, are permitted provided + *that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright @@ -90,266 +90,354 @@ //#include //#endif #define WIN32_LEAN_AND_MEAN -#include // to have IsTextUnicode, MultiByteToWideChar, WideCharToMultiByte to handle unicode files - // to have "MessageBoxA" to display error messages for openFilHelper +#include // to have IsTextUnicode, MultiByteToWideChar, WideCharToMultiByte to handle unicode files +// to have "MessageBoxA" to display error messages for openFilHelper #endif -#include #include +#include #include -#include #include +#include XMLCSTR XMLNode::getVersion() { return _CXML("v2.39"); } -void freeXMLString(XMLSTR t){if(t)free(t);} +void freeXMLString(XMLSTR t) { + if (t) free(t); +} -static XMLNode::XMLCharEncoding characterEncoding=XMLNode::char_encoding_UTF8; -static char guessWideCharChars=1, dropWhiteSpace=1, removeCommentsInMiddleOfText=1; +static XMLNode::XMLCharEncoding characterEncoding = XMLNode::char_encoding_UTF8; +static char guessWideCharChars = 1, dropWhiteSpace = 1, + removeCommentsInMiddleOfText = 1; -inline int mmin( const int t1, const int t2 ) { return t1 < t2 ? t1 : t2; } +inline int mmin(const int t1, const int t2) { return t1 < t2 ? t1 : t2; } // You can modify the initialization of the variable "XMLClearTags" below // to change the clearTags that are currently recognized by the library. // The number on the second columns is the length of the string inside the // first column. The "") }, - { _CXML("") }, - { _CXML("") }, - { _CXML("
")    ,5,  _CXML("
") }, -// { _CXML("")}, - { NULL ,0, NULL } -}; +typedef struct { + XMLCSTR lpszOpen; + int openTagLen; + XMLCSTR lpszClose; +} ALLXMLClearTag; +static ALLXMLClearTag XMLClearTags[] = { + {_CXML("")}, + {_CXML("")}, + {_CXML("")}, + {_CXML("
"), 5, _CXML("
")}, + // { _CXML("")}, + {NULL, 0, NULL}}; // You can modify the initialization of the variable "XMLEntities" below -// to change the character entities that are currently recognized by the library. -// The number on the second columns is the length of the string inside the -// first column. Additionally, the syntaxes " " and " " are recognized. -typedef struct { XMLCSTR s; int l; XMLCHAR c;} XMLCharacterEntity; -static XMLCharacterEntity XMLEntities[] = -{ - { _CXML("&" ), 5, _CXML('&' )}, - { _CXML("<" ), 4, _CXML('<' )}, - { _CXML(">" ), 4, _CXML('>' )}, - { _CXML("""), 6, _CXML('\"')}, - { _CXML("'"), 6, _CXML('\'')}, - { NULL , 0, '\0' } -}; - -// When rendering the XMLNode to a string (using the "createXMLString" function), -// you can ask for a beautiful formatting. This formatting is using the -// following indentation character: +// to change the character entities that are currently recognized by the +// library. The number on the second columns is the length of the string inside +// the first column. Additionally, the syntaxes " " and " " are +// recognized. +typedef struct { + XMLCSTR s; + int l; + XMLCHAR c; +} XMLCharacterEntity; +static XMLCharacterEntity XMLEntities[] = { + {_CXML("&"), 5, _CXML('&')}, {_CXML("<"), 4, _CXML('<')}, + {_CXML(">"), 4, _CXML('>')}, {_CXML("""), 6, _CXML('\"')}, + {_CXML("'"), 6, _CXML('\'')}, {NULL, 0, '\0'}}; + +// When rendering the XMLNode to a string (using the "createXMLString" +// function), you can ask for a beautiful formatting. This formatting is using +// the following indentation character: #define INDENTCHAR _CXML('\t') // The following function parses the XML errors into a user friendly string. -// You can edit this to change the output language of the library to something else. -XMLCSTR XMLNode::getError(XMLError xerror) -{ - switch (xerror) - { - case eXMLErrorNone: return _CXML("No error"); - case eXMLErrorMissingEndTag: return _CXML("Warning: Unmatched end tag"); - case eXMLErrorNoXMLTagFound: return _CXML("Warning: No XML tag found"); - case eXMLErrorEmpty: return _CXML("Error: No XML data"); - case eXMLErrorMissingTagName: return _CXML("Error: Missing start tag name"); - case eXMLErrorMissingEndTagName: return _CXML("Error: Missing end tag name"); - case eXMLErrorUnmatchedEndTag: return _CXML("Error: Unmatched end tag"); - case eXMLErrorUnmatchedEndClearTag: return _CXML("Error: Unmatched clear tag end"); - case eXMLErrorUnexpectedToken: return _CXML("Error: Unexpected token found"); - case eXMLErrorNoElements: return _CXML("Error: No elements found"); - case eXMLErrorFileNotFound: return _CXML("Error: File not found"); - case eXMLErrorFirstTagNotFound: return _CXML("Error: First Tag not found"); - case eXMLErrorUnknownCharacterEntity:return _CXML("Error: Unknown character entity"); - case eXMLErrorCharacterCodeAbove255: return _CXML("Error: Character code above 255 is forbidden in MultiByte char mode."); - case eXMLErrorCharConversionError: return _CXML("Error: unable to convert between WideChar and MultiByte chars"); - case eXMLErrorCannotOpenWriteFile: return _CXML("Error: unable to open file for writing"); - case eXMLErrorCannotWriteFile: return _CXML("Error: cannot write into file"); - - case eXMLErrorBase64DataSizeIsNotMultipleOf4: return _CXML("Warning: Base64-string length is not a multiple of 4"); - case eXMLErrorBase64DecodeTruncatedData: return _CXML("Warning: Base64-string is truncated"); - case eXMLErrorBase64DecodeIllegalCharacter: return _CXML("Error: Base64-string contains an illegal character"); - case eXMLErrorBase64DecodeBufferTooSmall: return _CXML("Error: Base64 decode output buffer is too small"); - }; - return _CXML("Unknown"); +// You can edit this to change the output language of the library to something +// else. +XMLCSTR XMLNode::getError(XMLError xerror) { + switch (xerror) { + case eXMLErrorNone: + return _CXML("No error"); + case eXMLErrorMissingEndTag: + return _CXML("Warning: Unmatched end tag"); + case eXMLErrorNoXMLTagFound: + return _CXML("Warning: No XML tag found"); + case eXMLErrorEmpty: + return _CXML("Error: No XML data"); + case eXMLErrorMissingTagName: + return _CXML("Error: Missing start tag name"); + case eXMLErrorMissingEndTagName: + return _CXML("Error: Missing end tag name"); + case eXMLErrorUnmatchedEndTag: + return _CXML("Error: Unmatched end tag"); + case eXMLErrorUnmatchedEndClearTag: + return _CXML("Error: Unmatched clear tag end"); + case eXMLErrorUnexpectedToken: + return _CXML("Error: Unexpected token found"); + case eXMLErrorNoElements: + return _CXML("Error: No elements found"); + case eXMLErrorFileNotFound: + return _CXML("Error: File not found"); + case eXMLErrorFirstTagNotFound: + return _CXML("Error: First Tag not found"); + case eXMLErrorUnknownCharacterEntity: + return _CXML("Error: Unknown character entity"); + case eXMLErrorCharacterCodeAbove255: + return _CXML( + "Error: Character code above 255 is forbidden in MultiByte char " + "mode."); + case eXMLErrorCharConversionError: + return _CXML( + "Error: unable to convert between WideChar and MultiByte chars"); + case eXMLErrorCannotOpenWriteFile: + return _CXML("Error: unable to open file for writing"); + case eXMLErrorCannotWriteFile: + return _CXML("Error: cannot write into file"); + + case eXMLErrorBase64DataSizeIsNotMultipleOf4: + return _CXML("Warning: Base64-string length is not a multiple of 4"); + case eXMLErrorBase64DecodeTruncatedData: + return _CXML("Warning: Base64-string is truncated"); + case eXMLErrorBase64DecodeIllegalCharacter: + return _CXML("Error: Base64-string contains an illegal character"); + case eXMLErrorBase64DecodeBufferTooSmall: + return _CXML("Error: Base64 decode output buffer is too small"); + }; + return _CXML("Unknown"); } ///////////////////////////////////////////////////////////////////////// // Here start the abstraction layer to be OS-independent // ///////////////////////////////////////////////////////////////////////// -// Here is an abstraction layer to access some common string manipulation functions. -// The abstraction layer is currently working for gcc, Microsoft Visual Studio 6.0, -// Microsoft Visual Studio .NET, CC (sun compiler) and Borland C++. -// If you plan to "port" the library to a new system/compiler, all you have to do is -// to edit the following lines. +// Here is an abstraction layer to access some common string manipulation +// functions. The abstraction layer is currently working for gcc, Microsoft +// Visual Studio 6.0, Microsoft Visual Studio .NET, CC (sun compiler) and +// Borland C++. If you plan to "port" the library to a new system/compiler, all +// you have to do is to edit the following lines. #ifdef XML_NO_WIDE_CHAR char myIsTextWideChar(const void *b, int len) { return FALSE; } #else - #if defined (UNDER_CE) || !defined(_XMLWINDOWS) - char myIsTextWideChar(const void *b, int len) // inspired by the Wine API: RtlIsTextUnicode - { +#if defined(UNDER_CE) || !defined(_XMLWINDOWS) +char myIsTextWideChar(const void *b, + int len) // inspired by the Wine API: RtlIsTextUnicode +{ #ifdef sun - // for SPARC processors: wchar_t* buffers must always be alligned, otherwise it's a char* buffer. - if ((((unsigned long)b)%sizeof(wchar_t))!=0) return FALSE; + // for SPARC processors: wchar_t* buffers must always be alligned, otherwise + // it's a char* buffer. + if ((((unsigned long)b) % sizeof(wchar_t)) != 0) return FALSE; #endif - const wchar_t *s=(const wchar_t*)b; + const wchar_t *s = (const wchar_t *)b; - // buffer too small: - if (len<(int)sizeof(wchar_t)) return FALSE; + // buffer too small: + if (len < (int)sizeof(wchar_t)) return FALSE; - // odd length test - if (len&1) return FALSE; + // odd length test + if (len & 1) return FALSE; - /* only checks the first 256 characters */ - len=mmin(256,len/sizeof(wchar_t)); + /* only checks the first 256 characters */ + len = mmin(256, len / sizeof(wchar_t)); - // Check for the special byte order: - if (*((unsigned short*)s) == 0xFFFE) return TRUE; // IS_TEXT_UNICODE_REVERSE_SIGNATURE; - if (*((unsigned short*)s) == 0xFEFF) return TRUE; // IS_TEXT_UNICODE_SIGNATURE + // Check for the special byte order: + if (*((unsigned short *)s) == 0xFFFE) + return TRUE; // IS_TEXT_UNICODE_REVERSE_SIGNATURE; + if (*((unsigned short *)s) == 0xFEFF) + return TRUE; // IS_TEXT_UNICODE_SIGNATURE - // checks for ASCII characters in the UNICODE stream - int i,stats=0; - for (i=0; ilen/2) return TRUE; + // checks for ASCII characters in the UNICODE stream + int i, stats = 0; + for (i = 0; i < len; i++) + if (s[i] <= (unsigned short)255) stats++; + if (stats > len / 2) return TRUE; - // Check for UNICODE NULL chars - for (i=0; i - static inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l) { return wsncasecmp(c1,c2,l);} - static inline int xstrncmp(XMLCSTR c1, XMLCSTR c2, int l) { return wsncmp(c1,c2,l);} - static inline int xstricmp(XMLCSTR c1, XMLCSTR c2) { return wscasecmp(c1,c2); } - #else - // for gcc - static inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l) { return wcsncasecmp(c1,c2,l);} - static inline int xstrncmp(XMLCSTR c1, XMLCSTR c2, int l) { return wcsncmp(c1,c2,l);} - static inline int xstricmp(XMLCSTR c1, XMLCSTR c2) { return wcscasecmp(c1,c2); } - #endif - static inline XMLSTR xstrstr(XMLCSTR c1, XMLCSTR c2) { return (XMLSTR)wcsstr(c1,c2); } - static inline XMLSTR xstrcpy(XMLSTR c1, XMLCSTR c2) { return (XMLSTR)wcscpy(c1,c2); } - static inline FILE *xfopen(XMLCSTR filename,XMLCSTR mode) - { - char *filenameAscii=myWideCharToMultiByte(filename); - FILE *f; - if (mode[0]==_CXML('r')) f=fopen(filenameAscii,"rb"); - else f=fopen(filenameAscii,"wb"); - free(filenameAscii); - return f; - } - #else - static inline FILE *xfopen(XMLCSTR filename,XMLCSTR mode) { return fopen(filename,mode); } - static inline int xstrlen(XMLCSTR c) { return strlen(c); } - static inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l) { return strncasecmp(c1,c2,l);} - static inline int xstrncmp(XMLCSTR c1, XMLCSTR c2, int l) { return strncmp(c1,c2,l);} - static inline int xstricmp(XMLCSTR c1, XMLCSTR c2) { return strcasecmp(c1,c2); } - static inline XMLSTR xstrstr(XMLCSTR c1, XMLCSTR c2) { return (XMLSTR)strstr(c1,c2); } - static inline XMLSTR xstrcpy(XMLSTR c1, XMLCSTR c2) { return (XMLSTR)strcpy(c1,c2); } - #endif - static inline int _strnicmp(const char *c1,const char *c2, int l) { return strncasecmp(c1,c2,l);} +#ifdef XML_NO_WIDE_CHAR +char *myWideCharToMultiByte(const wchar_t *s) { return NULL; } +#else +char *myWideCharToMultiByte(const wchar_t *s) { + const wchar_t *ss = s; + int i = (int)wcsrtombs(NULL, &ss, 0, NULL); + if (i < 0) return NULL; + char *d = (char *)malloc(i + 1); + wcsrtombs(d, &s, i, NULL); + d[i] = 0; + return d; +} +#endif +#ifdef _XMLWIDECHAR +wchar_t *myMultiByteToWideChar(const char *s, XMLNode::XMLCharEncoding ce) { + const char *ss = s; + int i = (int)mbsrtowcs(NULL, &ss, 0, NULL); + if (i < 0) return NULL; + wchar_t *d = (wchar_t *)malloc((i + 1) * sizeof(wchar_t)); + mbsrtowcs(d, &s, i, NULL); + d[i] = 0; + return d; +} +int xstrlen(XMLCSTR c) { return wcslen(c); } +#ifdef sun +// for CC +#include +static inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l) { + return wsncasecmp(c1, c2, l); +} +static inline int xstrncmp(XMLCSTR c1, XMLCSTR c2, int l) { + return wsncmp(c1, c2, l); +} +static inline int xstricmp(XMLCSTR c1, XMLCSTR c2) { return wscasecmp(c1, c2); } +#else +// for gcc +static inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l) { + return wcsncasecmp(c1, c2, l); +} +static inline int xstrncmp(XMLCSTR c1, XMLCSTR c2, int l) { + return wcsncmp(c1, c2, l); +} +static inline int xstricmp(XMLCSTR c1, XMLCSTR c2) { + return wcscasecmp(c1, c2); +} +#endif +static inline XMLSTR xstrstr(XMLCSTR c1, XMLCSTR c2) { + return (XMLSTR)wcsstr(c1, c2); +} +static inline XMLSTR xstrcpy(XMLSTR c1, XMLCSTR c2) { + return (XMLSTR)wcscpy(c1, c2); +} +static inline FILE *xfopen(XMLCSTR filename, XMLCSTR mode) { + char *filenameAscii = myWideCharToMultiByte(filename); + FILE *f; + if (mode[0] == _CXML('r')) + f = fopen(filenameAscii, "rb"); + else + f = fopen(filenameAscii, "wb"); + free(filenameAscii); + return f; +} +#else +static inline FILE *xfopen(XMLCSTR filename, XMLCSTR mode) { + return fopen(filename, mode); +} +static inline int xstrlen(XMLCSTR c) { return strlen(c); } +static inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l) { + return strncasecmp(c1, c2, l); +} +static inline int xstrncmp(XMLCSTR c1, XMLCSTR c2, int l) { + return strncmp(c1, c2, l); +} +static inline int xstricmp(XMLCSTR c1, XMLCSTR c2) { + return strcasecmp(c1, c2); +} +static inline XMLSTR xstrstr(XMLCSTR c1, XMLCSTR c2) { + return (XMLSTR)strstr(c1, c2); +} +static inline XMLSTR xstrcpy(XMLSTR c1, XMLCSTR c2) { + return (XMLSTR)strcpy(c1, c2); +} +#endif +static inline int _strnicmp(const char *c1, const char *c2, int l) { + return strncasecmp(c1, c2, l); +} #endif - /////////////////////////////////////////////////////////////////////////////// // the "xmltoc,xmltob,xmltoi,xmltol,xmltof,xmltoa" functions // @@ -358,82 +446,144 @@ char myIsTextWideChar(const void *b, int len) { return FALSE; } // There are only here as "convenience" functions for the user. // If you don't need them, you can delete them without any trouble. #ifdef _XMLWIDECHAR - #ifdef _XMLWINDOWS - // for Microsoft Visual Studio 6.0 and Microsoft Visual Studio .NET and Borland C++ Builder 6.0 - char xmltob(XMLCSTR t,int v){ if (t&&(*t)) return (char)_wtoi(t); return v; } - int xmltoi(XMLCSTR t,int v){ if (t&&(*t)) return _wtoi(t); return v; } - long xmltol(XMLCSTR t,long v){ if (t&&(*t)) return _wtol(t); return v; } - double xmltof(XMLCSTR t,double v){ if (t&&(*t)) wscanf(t, "%f", &v); /*v=_wtof(t);*/ return v; } - #else - #ifdef sun - // for CC - #include - char xmltob(XMLCSTR t,int v){ if (t) return (char)wstol(t,NULL,10); return v; } - int xmltoi(XMLCSTR t,int v){ if (t) return (int)wstol(t,NULL,10); return v; } - long xmltol(XMLCSTR t,long v){ if (t) return wstol(t,NULL,10); return v; } - #else - // for gcc - char xmltob(XMLCSTR t,int v){ if (t) return (char)wcstol(t,NULL,10); return v; } - int xmltoi(XMLCSTR t,int v){ if (t) return (int)wcstol(t,NULL,10); return v; } - long xmltol(XMLCSTR t,long v){ if (t) return wcstol(t,NULL,10); return v; } - #endif - double xmltof(XMLCSTR t,double v){ if (t&&(*t)) wscanf(t, "%f", &v); /*v=_wtof(t);*/ return v; } - #endif +#ifdef _XMLWINDOWS +// for Microsoft Visual Studio 6.0 and Microsoft Visual Studio .NET and Borland +// C++ Builder 6.0 +char xmltob(XMLCSTR t, int v) { + if (t && (*t)) return (char)_wtoi(t); + return v; +} +int xmltoi(XMLCSTR t, int v) { + if (t && (*t)) return _wtoi(t); + return v; +} +long xmltol(XMLCSTR t, long v) { + if (t && (*t)) return _wtol(t); + return v; +} +double xmltof(XMLCSTR t, double v) { + if (t && (*t)) wscanf(t, "%f", &v); /*v=_wtof(t);*/ + return v; +} +#else +#ifdef sun +// for CC +#include +char xmltob(XMLCSTR t, int v) { + if (t) return (char)wstol(t, NULL, 10); + return v; +} +int xmltoi(XMLCSTR t, int v) { + if (t) return (int)wstol(t, NULL, 10); + return v; +} +long xmltol(XMLCSTR t, long v) { + if (t) return wstol(t, NULL, 10); + return v; +} #else - char xmltob(XMLCSTR t,char v){ if (t&&(*t)) return (char)atoi(t); return v; } - int xmltoi(XMLCSTR t,int v){ if (t&&(*t)) return atoi(t); return v; } - long xmltol(XMLCSTR t,long v){ if (t&&(*t)) return atol(t); return v; } - double xmltof(XMLCSTR t,double v){ if (t&&(*t)) return atof(t); return v; } +// for gcc +char xmltob(XMLCSTR t, int v) { + if (t) return (char)wcstol(t, NULL, 10); + return v; +} +int xmltoi(XMLCSTR t, int v) { + if (t) return (int)wcstol(t, NULL, 10); + return v; +} +long xmltol(XMLCSTR t, long v) { + if (t) return wcstol(t, NULL, 10); + return v; +} +#endif +double xmltof(XMLCSTR t, double v) { + if (t && (*t)) wscanf(t, "%f", &v); /*v=_wtof(t);*/ + return v; +} #endif -XMLCSTR xmltoa(XMLCSTR t,XMLCSTR v){ if (t) return t; return v; } -XMLCHAR xmltoc(XMLCSTR t,XMLCHAR v){ if (t&&(*t)) return *t; return v; } - +#else +char xmltob(XMLCSTR t, char v) { + if (t && (*t)) return (char)atoi(t); + return v; +} +int xmltoi(XMLCSTR t, int v) { + if (t && (*t)) return atoi(t); + return v; +} +long xmltol(XMLCSTR t, long v) { + if (t && (*t)) return atol(t); + return v; +} +double xmltof(XMLCSTR t, double v) { + if (t && (*t)) return atof(t); + return v; +} +#endif +XMLCSTR xmltoa(XMLCSTR t, XMLCSTR v) { + if (t) return t; + return v; +} +XMLCHAR xmltoc(XMLCSTR t, XMLCHAR v) { + if (t && (*t)) return *t; + return v; +} + ///////////////////////////////////////////////////////////////////////// // the "openFileHelper" function // ///////////////////////////////////////////////////////////////////////// -// Since each application has its own way to report and deal with errors, you should modify & rewrite -// the following "openFileHelper" function to get an "error reporting mechanism" tailored to your needs. -XMLNode XMLNode::openFileHelper(XMLCSTR filename, XMLCSTR tag) -{ - // guess the value of the global parameter "characterEncoding" - // (the guess is based on the first 200 bytes of the file). - FILE *f=xfopen(filename,_CXML("rb")); - if (f) - { - char bb[205]; - int l=(int)fread(bb,1,200,f); - setGlobalOptions(guessCharEncoding(bb,l),guessWideCharChars,dropWhiteSpace,removeCommentsInMiddleOfText); - fclose(f); +// Since each application has its own way to report and deal with errors, you +// should modify & rewrite the following "openFileHelper" function to get an +// "error reporting mechanism" tailored to your needs. +XMLNode XMLNode::openFileHelper(XMLCSTR filename, XMLCSTR tag) { + // guess the value of the global parameter "characterEncoding" + // (the guess is based on the first 200 bytes of the file). + FILE *f = xfopen(filename, _CXML("rb")); + if (f) { + char bb[205]; + int l = (int)fread(bb, 1, 200, f); + setGlobalOptions(guessCharEncoding(bb, l), guessWideCharChars, + dropWhiteSpace, removeCommentsInMiddleOfText); + fclose(f); + } + + // parse the file + XMLResults pResults; + XMLNode xnode = XMLNode::parseFile(filename, tag, &pResults); + + // display error message (if any) + if (pResults.error != eXMLErrorNone) { + // create message + char message[2000], *s1 = (char *)"", *s3 = (char *)""; + XMLCSTR s2 = _CXML(""); + if (pResults.error == eXMLErrorFirstTagNotFound) { + s1 = (char *)"First Tag should be '"; + s2 = tag; + s3 = (char *)"'.\n"; } - - // parse the file - XMLResults pResults; - XMLNode xnode=XMLNode::parseFile(filename,tag,&pResults); - - // display error message (if any) - if (pResults.error != eXMLErrorNone) - { - // create message - char message[2000],*s1=(char*)"",*s3=(char*)""; XMLCSTR s2=_CXML(""); - if (pResults.error==eXMLErrorFirstTagNotFound) { s1=(char*)"First Tag should be '"; s2=tag; s3=(char*)"'.\n"; } - sprintf(message, + sprintf(message, #ifdef _XMLWIDECHAR - "XML Parsing error inside file '%S'.\n%S\nAt line %i, column %i.\n%s%S%s" + "XML Parsing error inside file '%S'.\n%S\nAt line %i, column " + "%i.\n%s%S%s" #else - "XML Parsing error inside file '%s'.\n%s\nAt line %i, column %i.\n%s%s%s" + "XML Parsing error inside file '%s'.\n%s\nAt line %i, column " + "%i.\n%s%s%s" #endif - ,filename,XMLNode::getError(pResults.error),pResults.nLine,pResults.nColumn,s1,s2,s3); - - // display message -#if defined(_XMLWINDOWS) && !defined(UNDER_CE) && !defined(_XMLPARSER_NO_MESSAGEBOX_) - MessageBoxA(NULL,message,"XML Parsing error",MB_OK|MB_ICONERROR|MB_TOPMOST); + , + filename, XMLNode::getError(pResults.error), pResults.nLine, + pResults.nColumn, s1, s2, s3); + + // display message +#if defined(_XMLWINDOWS) && !defined(UNDER_CE) && \ + !defined(_XMLPARSER_NO_MESSAGEBOX_) + MessageBoxA(NULL, message, "XML Parsing error", + MB_OK | MB_ICONERROR | MB_TOPMOST); #else - printf("%s",message); + printf("%s", message); #endif - exit(255); - } - return xnode; + exit(255); + } + return xnode; } ///////////////////////////////////////////////////////////////////////// @@ -443,400 +593,491 @@ XMLNode XMLNode::openFileHelper(XMLCSTR filename, XMLCSTR tag) // You should normally not change anything below this point. #ifndef _XMLWIDECHAR -// If "characterEncoding=ascii" then we assume that all characters have the same length of 1 byte. -// If "characterEncoding=UTF8" then the characters have different lengths (from 1 byte to 4 bytes). -// If "characterEncoding=ShiftJIS" then the characters have different lengths (from 1 byte to 2 bytes). -// This table is used as lookup-table to know the length of a character (in byte) based on the -// content of the first byte of the character. -// (note: if you modify this, you must always have XML_utf8ByteTable[0]=0 ). -static const char XML_utf8ByteTable[256] = -{ +// If "characterEncoding=ascii" then we assume that all characters have the same +// length of 1 byte. If "characterEncoding=UTF8" then the characters have +// different lengths (from 1 byte to 4 bytes). If "characterEncoding=ShiftJIS" +// then the characters have different lengths (from 1 byte to 2 bytes). This +// table is used as lookup-table to know the length of a character (in byte) +// based on the content of the first byte of the character. (note: if you modify +// this, you must always have XML_utf8ByteTable[0]=0 ). +static const char XML_utf8ByteTable[256] = { // 0 1 2 3 4 5 6 7 8 9 a b c d e f - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x00 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x10 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x20 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x30 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x40 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x50 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x60 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x70 End of ASCII range - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x80 0x80 to 0xc1 invalid - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x90 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0xa0 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0xb0 - 1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xc0 0xc2 to 0xdf 2 byte - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xd0 - 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,// 0xe0 0xe0 to 0xef 3 byte - 4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid -}; -static const char XML_legacyByteTable[256] = -{ - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 + 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 End of ASCII range + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 0x80 to 0xc1 invalid + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x90 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0 + 1, 1, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 0xc2 to 0xdf 2 byte + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0 + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, // 0xe0 0xe0 to 0xef 3 byte + 4, 4, 4, 4, 4, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid }; -static const char XML_sjisByteTable[256] = -{ +static const char XML_legacyByteTable[256] = { + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; +static const char XML_sjisByteTable[256] = { // 0 1 2 3 4 5 6 7 8 9 a b c d e f - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x00 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x10 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x20 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x30 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x40 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x50 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x60 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x70 - 1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0x80 0x81 to 0x9F 2 bytes - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0x90 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0xa0 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0xb0 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0xc0 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0xd0 - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xe0 0xe0 to 0xef 2 bytes - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 // 0xf0 + 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 + 1, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, // 0x80 0x81 to 0x9F 2 bytes + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, // 0x90 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0xc0 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0xd0 + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, // 0xe0 0xe0 to 0xef 2 bytes + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 }; -static const char XML_gb2312ByteTable[256] = -{ -// 0 1 2 3 4 5 6 7 8 9 a b c d e f - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x00 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x10 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x20 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x30 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x40 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x50 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x60 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x70 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x80 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x90 - 1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xa0 0xa1 to 0xf7 2 bytes - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xb0 - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xc0 - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xd0 - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xe0 - 2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1 // 0xf0 +static const char XML_gb2312ByteTable[256] = { + // 0 1 2 3 4 5 6 7 8 9 a b c d e f + 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x90 + 1, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, // 0xa0 0xa1 to 0xf7 2 bytes + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, // 0xb0 + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0 + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, // 0xe0 + 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 }; -static const char XML_gbk_big5_ByteTable[256] = -{ +static const char XML_gbk_big5_ByteTable[256] = { // 0 1 2 3 4 5 6 7 8 9 a b c d e f - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x00 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x10 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x20 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x30 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x40 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x50 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x60 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x70 - 1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0x80 0x81 to 0xfe 2 bytes - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0x90 - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xa0 - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xb0 - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xc0 - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xd0 - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xe0 - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1 // 0xf0 + 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 + 1, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, // 0x80 0x81 to 0xfe 2 bytes + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, // 0x90 + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, // 0xa0 + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, // 0xb0 + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0 + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, // 0xe0 + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 1 // 0xf0 }; -static const char *XML_ByteTable=(const char *)XML_utf8ByteTable; // the default is "characterEncoding=XMLNode::encoding_UTF8" +static const char *XML_ByteTable = (const char *) + XML_utf8ByteTable; // the default is + // "characterEncoding=XMLNode::encoding_UTF8" #endif - XMLNode XMLNode::emptyXMLNode; -XMLClear XMLNode::emptyXMLClear={ NULL, NULL, NULL}; -XMLAttribute XMLNode::emptyXMLAttribute={ NULL, NULL}; +XMLClear XMLNode::emptyXMLClear = {NULL, NULL, NULL}; +XMLAttribute XMLNode::emptyXMLAttribute = {NULL, NULL}; // Enumeration used to decipher what type a token is -typedef enum XMLTokenTypeTag -{ - eTokenText = 0, - eTokenQuotedText, - eTokenTagStart, /* "<" */ - eTokenTagEnd, /* "" */ - eTokenEquals, /* "=" */ - eTokenDeclaration, /* "" */ - eTokenClear, - eTokenError +typedef enum XMLTokenTypeTag { + eTokenText = 0, + eTokenQuotedText, + eTokenTagStart, /* "<" */ + eTokenTagEnd, /* "" */ + eTokenEquals, /* "=" */ + eTokenDeclaration, /* "" */ + eTokenClear, + eTokenError } XMLTokenType; // Main structure used for parsing XML -typedef struct XML -{ - XMLCSTR lpXML; - XMLCSTR lpszText; - int nIndex,nIndexMissigEndTag; - enum XMLError error; - XMLCSTR lpEndTag; - int cbEndTag; - XMLCSTR lpNewElement; - int cbNewElement; - int nFirst; +typedef struct XML { + XMLCSTR lpXML; + XMLCSTR lpszText; + int nIndex, nIndexMissigEndTag; + enum XMLError error; + XMLCSTR lpEndTag; + int cbEndTag; + XMLCSTR lpNewElement; + int cbNewElement; + int nFirst; } XML; -typedef struct -{ - ALLXMLClearTag *pClr; - XMLCSTR pStr; +typedef struct { + ALLXMLClearTag *pClr; + XMLCSTR pStr; } NextToken; // Enumeration used when parsing attributes -typedef enum Attrib -{ - eAttribName = 0, - eAttribEquals, - eAttribValue -} Attrib; +typedef enum Attrib { eAttribName = 0, eAttribEquals, eAttribValue } Attrib; // Enumeration used when parsing elements to dictate whether we are currently // inside a tag -typedef enum Status -{ - eInsideTag = 0, - eOutsideTag -} Status; +typedef enum Status { eInsideTag = 0, eOutsideTag } Status; -XMLError XMLNode::writeToFile(XMLCSTR filename, const char *encoding, char nFormat) const -{ - if (!d) return eXMLErrorNone; - FILE *f=xfopen(filename,_CXML("wb")); - if (!f) return eXMLErrorCannotOpenWriteFile; +XMLError XMLNode::writeToFile(XMLCSTR filename, const char *encoding, + char nFormat) const { + if (!d) return eXMLErrorNone; + FILE *f = xfopen(filename, _CXML("wb")); + if (!f) return eXMLErrorCannotOpenWriteFile; #ifdef _XMLWIDECHAR - unsigned char h[2]={ 0xFF, 0xFE }; - if (!fwrite(h,2,1,f)) return eXMLErrorCannotWriteFile; - if ((!isDeclaration())&&((d->lpszName)||(!getChildNode().isDeclaration()))) - { - if (!fwrite(L"\n",sizeof(wchar_t)*40,1,f)) - return eXMLErrorCannotWriteFile; - } + unsigned char h[2] = {0xFF, 0xFE}; + if (!fwrite(h, 2, 1, f)) return eXMLErrorCannotWriteFile; + if ((!isDeclaration()) && + ((d->lpszName) || (!getChildNode().isDeclaration()))) { + if (!fwrite(L"\n", + sizeof(wchar_t) * 40, 1, f)) + return eXMLErrorCannotWriteFile; + } #else - if ((!isDeclaration())&&((d->lpszName)||(!getChildNode().isDeclaration()))) - { - if (characterEncoding==char_encoding_UTF8) - { - // header so that windows recognize the file as UTF-8: - unsigned char h[3]={0xEF,0xBB,0xBF}; if (!fwrite(h,3,1,f)) return eXMLErrorCannotWriteFile; - encoding="utf-8"; - } else if (characterEncoding==char_encoding_ShiftJIS) encoding="SHIFT-JIS"; - - if (!encoding) encoding="ISO-8859-1"; - if (fprintf(f,"\n",encoding)<0) return eXMLErrorCannotWriteFile; - } else - { - if (characterEncoding==char_encoding_UTF8) - { - unsigned char h[3]={0xEF,0xBB,0xBF}; if (!fwrite(h,3,1,f)) return eXMLErrorCannotWriteFile; - } + if ((!isDeclaration()) && + ((d->lpszName) || (!getChildNode().isDeclaration()))) { + if (characterEncoding == char_encoding_UTF8) { + // header so that windows recognize the file as UTF-8: + unsigned char h[3] = {0xEF, 0xBB, 0xBF}; + if (!fwrite(h, 3, 1, f)) return eXMLErrorCannotWriteFile; + encoding = "utf-8"; + } else if (characterEncoding == char_encoding_ShiftJIS) + encoding = "SHIFT-JIS"; + + if (!encoding) encoding = "ISO-8859-1"; + if (fprintf(f, "\n", encoding) < 0) + return eXMLErrorCannotWriteFile; + } else { + if (characterEncoding == char_encoding_UTF8) { + unsigned char h[3] = {0xEF, 0xBB, 0xBF}; + if (!fwrite(h, 3, 1, f)) return eXMLErrorCannotWriteFile; } + } #endif - int i; - XMLSTR t=createXMLString(nFormat,&i); - if (!fwrite(t,sizeof(XMLCHAR)*i,1,f)) return eXMLErrorCannotWriteFile; - if (fclose(f)!=0) return eXMLErrorCannotWriteFile; - free(t); - return eXMLErrorNone; + int i; + XMLSTR t = createXMLString(nFormat, &i); + if (!fwrite(t, sizeof(XMLCHAR) * i, 1, f)) return eXMLErrorCannotWriteFile; + if (fclose(f) != 0) return eXMLErrorCannotWriteFile; + free(t); + return eXMLErrorNone; } // Duplicate a given string. -XMLSTR stringDup(XMLCSTR lpszData, int cbData) -{ - if (lpszData==NULL) return NULL; - - XMLSTR lpszNew; - if (cbData==-1) cbData=(int)xstrlen(lpszData); - lpszNew = (XMLSTR)malloc((cbData+1) * sizeof(XMLCHAR)); - if (lpszNew) - { - memcpy(lpszNew, lpszData, (cbData) * sizeof(XMLCHAR)); - lpszNew[cbData] = (XMLCHAR)NULL; - } - return lpszNew; -} - -XMLSTR ToXMLStringTool::toXMLUnSafe(XMLSTR dest,XMLCSTR source) -{ - XMLSTR dd=dest; - XMLCHAR ch; - XMLCharacterEntity *entity; - while ((ch=*source)) - { - entity=XMLEntities; - do - { - if (ch==entity->c) {xstrcpy(dest,entity->s); dest+=entity->l; source++; goto out_of_loop1; } - entity++; - } while(entity->s); +XMLSTR stringDup(XMLCSTR lpszData, int cbData) { + if (lpszData == NULL) return NULL; + + XMLSTR lpszNew; + if (cbData == -1) cbData = (int)xstrlen(lpszData); + lpszNew = (XMLSTR)malloc((cbData + 1) * sizeof(XMLCHAR)); + if (lpszNew) { + memcpy(lpszNew, lpszData, (cbData) * sizeof(XMLCHAR)); + lpszNew[cbData] = (XMLCHAR)NULL; + } + return lpszNew; +} + +XMLSTR ToXMLStringTool::toXMLUnSafe(XMLSTR dest, XMLCSTR source) { + XMLSTR dd = dest; + XMLCHAR ch; + XMLCharacterEntity *entity; + while ((ch = *source)) { + entity = XMLEntities; + do { + if (ch == entity->c) { + xstrcpy(dest, entity->s); + dest += entity->l; + source++; + goto out_of_loop1; + } + entity++; + } while (entity->s); #ifdef _XMLWIDECHAR - *(dest++)=*(source++); + *(dest++) = *(source++); #else - switch(XML_ByteTable[(unsigned char)ch]) - { - case 4: *(dest++)=*(source++); - case 3: *(dest++)=*(source++); - case 2: *(dest++)=*(source++); - case 1: *(dest++)=*(source++); - } -#endif -out_of_loop1: - ; + switch (XML_ByteTable[(unsigned char)ch]) { + case 4: + *(dest++) = *(source++); + case 3: + *(dest++) = *(source++); + case 2: + *(dest++) = *(source++); + case 1: + *(dest++) = *(source++); } - *dest=0; - return dd; +#endif + out_of_loop1:; + } + *dest = 0; + return dd; } // private (used while rendering): -int ToXMLStringTool::lengthXMLString(XMLCSTR source) -{ - int r=0; - XMLCharacterEntity *entity; - XMLCHAR ch; - while ((ch=*source)) - { - entity=XMLEntities; - do - { - if (ch==entity->c) { r+=entity->l; source++; goto out_of_loop1; } - entity++; - } while(entity->s); +int ToXMLStringTool::lengthXMLString(XMLCSTR source) { + int r = 0; + XMLCharacterEntity *entity; + XMLCHAR ch; + while ((ch = *source)) { + entity = XMLEntities; + do { + if (ch == entity->c) { + r += entity->l; + source++; + goto out_of_loop1; + } + entity++; + } while (entity->s); #ifdef _XMLWIDECHAR - r++; source++; + r++; + source++; #else - ch=XML_ByteTable[(unsigned char)ch]; r+=ch; source+=ch; + ch = XML_ByteTable[(unsigned char)ch]; + r += ch; + source += ch; #endif -out_of_loop1: - ; - } - return r; + out_of_loop1:; + } + return r; } -ToXMLStringTool::~ToXMLStringTool(){ freeBuffer(); } -void ToXMLStringTool::freeBuffer(){ if (buf) free(buf); buf=NULL; buflen=0; } -XMLSTR ToXMLStringTool::toXML(XMLCSTR source) -{ - int l=lengthXMLString(source)+1; - if (l>buflen) { buflen=l; buf=(XMLSTR)realloc(buf,l*sizeof(XMLCHAR)); } - return toXMLUnSafe(buf,source); +ToXMLStringTool::~ToXMLStringTool() { freeBuffer(); } +void ToXMLStringTool::freeBuffer() { + if (buf) free(buf); + buf = NULL; + buflen = 0; +} +XMLSTR ToXMLStringTool::toXML(XMLCSTR source) { + int l = lengthXMLString(source) + 1; + if (l > buflen) { + buflen = l; + buf = (XMLSTR)realloc(buf, l * sizeof(XMLCHAR)); + } + return toXMLUnSafe(buf, source); } // private: -XMLSTR fromXMLString(XMLCSTR s, int lo, XML *pXML) -{ - // This function is the opposite of the function "toXMLString". It decodes the escape - // sequences &, ", ', <, > and replace them by the characters - // &,",',<,>. This function is used internally by the XML Parser. All the calls to - // the XML library will always gives you back "decoded" strings. - // - // in: string (s) and length (lo) of string - // out: new allocated string converted from xml - if (!s) return NULL; - - int ll=0,j; - XMLSTR d; - XMLCSTR ss=s; - XMLCharacterEntity *entity; - while ((lo>0)&&(*s)) - { - if (*s==_CXML('&')) - { - if ((lo>2)&&(s[1]==_CXML('#'))) - { - s+=2; lo-=2; - if ((*s==_CXML('X'))||(*s==_CXML('x'))) { s++; lo--; } - while ((*s)&&(*s!=_CXML(';'))&&((lo--)>0)) s++; - if (*s!=_CXML(';')) - { - pXML->error=eXMLErrorUnknownCharacterEntity; - return NULL; - } - s++; lo--; - } else - { - entity=XMLEntities; - do - { - if ((lo>=entity->l)&&(xstrnicmp(s,entity->s,entity->l)==0)) { s+=entity->l; lo-=entity->l; break; } - entity++; - } while(entity->s); - if (!entity->s) - { - pXML->error=eXMLErrorUnknownCharacterEntity; - return NULL; - } - } - } else - { +XMLSTR fromXMLString(XMLCSTR s, int lo, XML *pXML) { + // This function is the opposite of the function "toXMLString". It decodes the + // escape sequences &, ", ', <, > and replace them by the + // characters + // &,",',<,>. This function is used internally by the XML Parser. All the + // calls to the XML library will always gives you back "decoded" strings. + // + // in: string (s) and length (lo) of string + // out: new allocated string converted from xml + if (!s) return NULL; + + int ll = 0, j; + XMLSTR d; + XMLCSTR ss = s; + XMLCharacterEntity *entity; + while ((lo > 0) && (*s)) { + if (*s == _CXML('&')) { + if ((lo > 2) && (s[1] == _CXML('#'))) { + s += 2; + lo -= 2; + if ((*s == _CXML('X')) || (*s == _CXML('x'))) { + s++; + lo--; + } + while ((*s) && (*s != _CXML(';')) && ((lo--) > 0)) s++; + if (*s != _CXML(';')) { + pXML->error = eXMLErrorUnknownCharacterEntity; + return NULL; + } + s++; + lo--; + } else { + entity = XMLEntities; + do { + if ((lo >= entity->l) && (xstrnicmp(s, entity->s, entity->l) == 0)) { + s += entity->l; + lo -= entity->l; + break; + } + entity++; + } while (entity->s); + if (!entity->s) { + pXML->error = eXMLErrorUnknownCharacterEntity; + return NULL; + } + } + } else { #ifdef _XMLWIDECHAR - s++; lo--; + s++; + lo--; #else - j=XML_ByteTable[(unsigned char)*s]; s+=j; lo-=j; ll+=j-1; + j = XML_ByteTable[(unsigned char)*s]; + s += j; + lo -= j; + ll += j - 1; #endif - } - ll++; } - - d=(XMLSTR)malloc((ll+1)*sizeof(XMLCHAR)); - s=d; - while (ll-->0) - { - if (*ss==_CXML('&')) - { - if (ss[1]==_CXML('#')) - { - ss+=2; j=0; - if ((*ss==_CXML('X'))||(*ss==_CXML('x'))) - { - ss++; - while (*ss!=_CXML(';')) - { - if ((*ss>=_CXML('0'))&&(*ss<=_CXML('9'))) j=(j<<4)+*ss-_CXML('0'); - else if ((*ss>=_CXML('A'))&&(*ss<=_CXML('F'))) j=(j<<4)+*ss-_CXML('A')+10; - else if ((*ss>=_CXML('a'))&&(*ss<=_CXML('f'))) j=(j<<4)+*ss-_CXML('a')+10; - else { free((void*)s); pXML->error=eXMLErrorUnknownCharacterEntity;return NULL;} - ss++; - } - } else - { - while (*ss!=_CXML(';')) - { - if ((*ss>=_CXML('0'))&&(*ss<=_CXML('9'))) j=(j*10)+*ss-_CXML('0'); - else { free((void*)s); pXML->error=eXMLErrorUnknownCharacterEntity;return NULL;} - ss++; - } - } + ll++; + } + + d = (XMLSTR)malloc((ll + 1) * sizeof(XMLCHAR)); + s = d; + while (ll-- > 0) { + if (*ss == _CXML('&')) { + if (ss[1] == _CXML('#')) { + ss += 2; + j = 0; + if ((*ss == _CXML('X')) || (*ss == _CXML('x'))) { + ss++; + while (*ss != _CXML(';')) { + if ((*ss >= _CXML('0')) && (*ss <= _CXML('9'))) + j = (j << 4) + *ss - _CXML('0'); + else if ((*ss >= _CXML('A')) && (*ss <= _CXML('F'))) + j = (j << 4) + *ss - _CXML('A') + 10; + else if ((*ss >= _CXML('a')) && (*ss <= _CXML('f'))) + j = (j << 4) + *ss - _CXML('a') + 10; + else { + free((void *)s); + pXML->error = eXMLErrorUnknownCharacterEntity; + return NULL; + } + ss++; + } + } else { + while (*ss != _CXML(';')) { + if ((*ss >= _CXML('0')) && (*ss <= _CXML('9'))) + j = (j * 10) + *ss - _CXML('0'); + else { + free((void *)s); + pXML->error = eXMLErrorUnknownCharacterEntity; + return NULL; + } + ss++; + } + } #ifndef _XMLWIDECHAR - if (j>255) { free((void*)s); pXML->error=eXMLErrorCharacterCodeAbove255;return NULL;} + if (j > 255) { + free((void *)s); + pXML->error = eXMLErrorCharacterCodeAbove255; + return NULL; + } #endif - (*d++)=(XMLCHAR)j; ss++; - } else - { - entity=XMLEntities; - do - { - if (xstrnicmp(ss,entity->s,entity->l)==0) { *(d++)=entity->c; ss+=entity->l; break; } - entity++; - } while(entity->s); - } - } else - { + (*d++) = (XMLCHAR)j; + ss++; + } else { + entity = XMLEntities; + do { + if (xstrnicmp(ss, entity->s, entity->l) == 0) { + *(d++) = entity->c; + ss += entity->l; + break; + } + entity++; + } while (entity->s); + } + } else { #ifdef _XMLWIDECHAR - *(d++)=*(ss++); + *(d++) = *(ss++); #else - switch(XML_ByteTable[(unsigned char)*ss]) - { - case 4: *(d++)=*(ss++); ll--; - case 3: *(d++)=*(ss++); ll--; - case 2: *(d++)=*(ss++); ll--; - case 1: *(d++)=*(ss++); - } + switch (XML_ByteTable[(unsigned char)*ss]) { + case 4: + *(d++) = *(ss++); + ll--; + case 3: + *(d++) = *(ss++); + ll--; + case 2: + *(d++) = *(ss++); + ll--; + case 1: + *(d++) = *(ss++); + } #endif - } } - *d=0; - return (XMLSTR)s; + } + *d = 0; + return (XMLSTR)s; } -#define XML_isSPACECHAR(ch) ((ch==_CXML('\n'))||(ch==_CXML(' '))||(ch== _CXML('\t'))||(ch==_CXML('\r'))) +#define XML_isSPACECHAR(ch) \ + ((ch == _CXML('\n')) || (ch == _CXML(' ')) || (ch == _CXML('\t')) || \ + (ch == _CXML('\r'))) // private: char myTagCompare(XMLCSTR cclose, XMLCSTR copen) @@ -844,1233 +1085,1259 @@ char myTagCompare(XMLCSTR cclose, XMLCSTR copen) // return 0 if equals // return 1 if different { - if (!cclose) return 1; - int l=(int)xstrlen(cclose); - if (xstrnicmp(cclose, copen, l)!=0) return 1; - const XMLCHAR c=copen[l]; - if (XML_isSPACECHAR(c)|| - (c==_CXML('/' ))|| - (c==_CXML('<' ))|| - (c==_CXML('>' ))|| - (c==_CXML('=' ))) return 0; - return 1; + if (!cclose) return 1; + int l = (int)xstrlen(cclose); + if (xstrnicmp(cclose, copen, l) != 0) return 1; + const XMLCHAR c = copen[l]; + if (XML_isSPACECHAR(c) || (c == _CXML('/')) || (c == _CXML('<')) || + (c == _CXML('>')) || (c == _CXML('='))) + return 0; + return 1; } // Obtain the next character from the string. -static inline XMLCHAR getNextChar(XML *pXML) -{ - XMLCHAR ch = pXML->lpXML[pXML->nIndex]; +static inline XMLCHAR getNextChar(XML *pXML) { + XMLCHAR ch = pXML->lpXML[pXML->nIndex]; #ifdef _XMLWIDECHAR - if (ch!=0) pXML->nIndex++; + if (ch != 0) pXML->nIndex++; #else - pXML->nIndex+=XML_ByteTable[(unsigned char)ch]; + pXML->nIndex += XML_ByteTable[(unsigned char)ch]; #endif - return ch; + return ch; } // Find the next token in a string. // pcbToken contains the number of characters that have been read. -static NextToken GetNextToken(XML *pXML, int *pcbToken, enum XMLTokenTypeTag *pType) -{ - NextToken result; - XMLCHAR ch; - XMLCHAR chTemp; - int indexStart,nFoundMatch,nIsText=FALSE; - result.pClr=NULL; // prevent warning - - // Find next non-white space character - do { indexStart=pXML->nIndex; ch=getNextChar(pXML); } while XML_isSPACECHAR(ch); - - if (ch) - { - // Cache the current string pointer - result.pStr = &pXML->lpXML[indexStart]; - - // First check whether the token is in the clear tag list (meaning it - // does not need formatting). - ALLXMLClearTag *ctag=XMLClearTags; - do - { - if (xstrncmp(ctag->lpszOpen, result.pStr, ctag->openTagLen)==0) - { - result.pClr=ctag; - pXML->nIndex+=ctag->openTagLen-1; - *pType=eTokenClear; - return result; - } - ctag++; - } while(ctag->lpszOpen); - - // If we didn't find a clear tag then check for standard tokens - switch(ch) - { - // Check for quotes - case _CXML('\''): - case _CXML('\"'): - // Type of token - *pType = eTokenQuotedText; - chTemp = ch; - - // Set the size - nFoundMatch = FALSE; - - // Search through the string to find a matching quote - while((ch = getNextChar(pXML))) - { - if (ch==chTemp) { nFoundMatch = TRUE; break; } - if (ch==_CXML('<')) break; - } +static NextToken GetNextToken(XML *pXML, int *pcbToken, + enum XMLTokenTypeTag *pType) { + NextToken result; + XMLCHAR ch; + XMLCHAR chTemp; + int indexStart, nFoundMatch, nIsText = FALSE; + result.pClr = NULL; // prevent warning + + // Find next non-white space character + do { + indexStart = pXML->nIndex; + ch = getNextChar(pXML); + } while XML_isSPACECHAR(ch); + + if (ch) { + // Cache the current string pointer + result.pStr = &pXML->lpXML[indexStart]; + + // First check whether the token is in the clear tag list (meaning it + // does not need formatting). + ALLXMLClearTag *ctag = XMLClearTags; + do { + if (xstrncmp(ctag->lpszOpen, result.pStr, ctag->openTagLen) == 0) { + result.pClr = ctag; + pXML->nIndex += ctag->openTagLen - 1; + *pType = eTokenClear; + return result; + } + ctag++; + } while (ctag->lpszOpen); + + // If we didn't find a clear tag then check for standard tokens + switch (ch) { + // Check for quotes + case _CXML('\''): + case _CXML('\"'): + // Type of token + *pType = eTokenQuotedText; + chTemp = ch; + + // Set the size + nFoundMatch = FALSE; + + // Search through the string to find a matching quote + while ((ch = getNextChar(pXML))) { + if (ch == chTemp) { + nFoundMatch = TRUE; + break; + } + if (ch == _CXML('<')) break; + } - // If we failed to find a matching quote - if (nFoundMatch == FALSE) - { - pXML->nIndex=indexStart+1; - nIsText=TRUE; - break; - } + // If we failed to find a matching quote + if (nFoundMatch == FALSE) { + pXML->nIndex = indexStart + 1; + nIsText = TRUE; + break; + } -// 4.02.2002 -// if (FindNonWhiteSpace(pXML)) pXML->nIndex--; + // 4.02.2002 + // if (FindNonWhiteSpace(pXML)) pXML->nIndex--; - break; + break; - // Equals (used with attribute values) - case _CXML('='): - *pType = eTokenEquals; - break; + // Equals (used with attribute values) + case _CXML('='): + *pType = eTokenEquals; + break; - // Close tag - case _CXML('>'): - *pType = eTokenCloseTag; - break; + // Close tag + case _CXML('>'): + *pType = eTokenCloseTag; + break; - // Check for tag start and tag end - case _CXML('<'): + // Check for tag start and tag end + case _CXML('<'): - // Peek at the next character to see if we have an end tag 'lpXML[pXML->nIndex]; + // Peek at the next character to see if we have an end tag 'lpXML[pXML->nIndex]; - // If we have a tag end... - if (chTemp == _CXML('/')) - { - // Set the type and ensure we point at the next character - getNextChar(pXML); - *pType = eTokenTagEnd; - } + // If we have a tag end... + if (chTemp == _CXML('/')) { + // Set the type and ensure we point at the next character + getNextChar(pXML); + *pType = eTokenTagEnd; + } - // If we have an XML declaration tag - else if (chTemp == _CXML('?')) - { + // If we have an XML declaration tag + else if (chTemp == _CXML('?')) { + // Set the type and ensure we point at the next character + getNextChar(pXML); + *pType = eTokenDeclaration; + } - // Set the type and ensure we point at the next character - getNextChar(pXML); - *pType = eTokenDeclaration; - } + // Otherwise we must have a start tag + else { + *pType = eTokenTagStart; + } + break; - // Otherwise we must have a start tag - else - { - *pType = eTokenTagStart; - } - break; + // Check to see if we have a short hand type end tag ('/>'). + case _CXML('/'): - // Check to see if we have a short hand type end tag ('/>'). - case _CXML('/'): + // Peek at the next character to see if we have a short end tag '/>' + chTemp = pXML->lpXML[pXML->nIndex]; - // Peek at the next character to see if we have a short end tag '/>' - chTemp = pXML->lpXML[pXML->nIndex]; + // If we have a short hand end tag... + if (chTemp == _CXML('>')) { + // Set the type and ensure we point at the next character + getNextChar(pXML); + *pType = eTokenShortHandClose; + break; + } - // If we have a short hand end tag... - if (chTemp == _CXML('>')) - { - // Set the type and ensure we point at the next character - getNextChar(pXML); - *pType = eTokenShortHandClose; - break; - } + // If we haven't found a short hand closing tag then drop into the + // text process - // If we haven't found a short hand closing tag then drop into the - // text process + // Other characters + default: + nIsText = TRUE; + } - // Other characters - default: - nIsText = TRUE; - } + // If this is a TEXT node + if (nIsText) { + // Indicate we are dealing with text + *pType = eTokenText; + while ((ch = getNextChar(pXML))) { + if + XML_isSPACECHAR(ch) { + indexStart++; + break; + } + else if (ch == _CXML('/')) { + // If we find a slash then this maybe text or a short hand end tag + // Peek at the next character to see it we have short hand end tag + ch = pXML->lpXML[pXML->nIndex]; + // If we found a short hand end tag then we need to exit the loop + if (ch == _CXML('>')) { + pXML->nIndex--; + break; + } - // If this is a TEXT node - if (nIsText) - { - // Indicate we are dealing with text - *pType = eTokenText; - while((ch = getNextChar(pXML))) - { - if XML_isSPACECHAR(ch) - { - indexStart++; break; - - } else if (ch==_CXML('/')) - { - // If we find a slash then this maybe text or a short hand end tag - // Peek at the next character to see it we have short hand end tag - ch=pXML->lpXML[pXML->nIndex]; - // If we found a short hand end tag then we need to exit the loop - if (ch==_CXML('>')) { pXML->nIndex--; break; } - - } else if ((ch==_CXML('<'))||(ch==_CXML('>'))||(ch==_CXML('='))) - { - pXML->nIndex--; break; - } - } + } else if ((ch == _CXML('<')) || (ch == _CXML('>')) || + (ch == _CXML('='))) { + pXML->nIndex--; + break; } - *pcbToken = pXML->nIndex-indexStart; - } else - { - // If we failed to obtain a valid character - *pcbToken = 0; - *pType = eTokenError; - result.pStr=NULL; + } } + *pcbToken = pXML->nIndex - indexStart; + } else { + // If we failed to obtain a valid character + *pcbToken = 0; + *pType = eTokenError; + result.pStr = NULL; + } - return result; + return result; } -XMLCSTR XMLNode::updateName_WOSD(XMLSTR lpszName) -{ - if (!d) { free(lpszName); return NULL; } - if (d->lpszName&&(lpszName!=d->lpszName)) free((void*)d->lpszName); - d->lpszName=lpszName; - return lpszName; +XMLCSTR XMLNode::updateName_WOSD(XMLSTR lpszName) { + if (!d) { + free(lpszName); + return NULL; + } + if (d->lpszName && (lpszName != d->lpszName)) free((void *)d->lpszName); + d->lpszName = lpszName; + return lpszName; } // private: -XMLNode::XMLNode(struct XMLNodeDataTag *p){ d=p; (p->ref_count)++; } -XMLNode::XMLNode(XMLNodeData *pParent, XMLSTR lpszName, char isDeclaration) -{ - d=(XMLNodeData*)malloc(sizeof(XMLNodeData)); - d->ref_count=1; +XMLNode::XMLNode(struct XMLNodeDataTag *p) { + d = p; + (p->ref_count)++; +} +XMLNode::XMLNode(XMLNodeData *pParent, XMLSTR lpszName, char isDeclaration) { + d = (XMLNodeData *)malloc(sizeof(XMLNodeData)); + d->ref_count = 1; - d->lpszName=NULL; - d->nChild= 0; - d->nText = 0; - d->nClear = 0; - d->nAttribute = 0; + d->lpszName = NULL; + d->nChild = 0; + d->nText = 0; + d->nClear = 0; + d->nAttribute = 0; - d->isDeclaration = isDeclaration; + d->isDeclaration = isDeclaration; - d->pParent = pParent; - d->pChild= NULL; - d->pText= NULL; - d->pClear= NULL; - d->pAttribute= NULL; - d->pOrder= NULL; + d->pParent = pParent; + d->pChild = NULL; + d->pText = NULL; + d->pClear = NULL; + d->pAttribute = NULL; + d->pOrder = NULL; - updateName_WOSD(lpszName); + updateName_WOSD(lpszName); } -XMLNode XMLNode::createXMLTopNode_WOSD(XMLSTR lpszName, char isDeclaration) { return XMLNode(NULL,lpszName,isDeclaration); } -XMLNode XMLNode::createXMLTopNode(XMLCSTR lpszName, char isDeclaration) { return XMLNode(NULL,stringDup(lpszName),isDeclaration); } +XMLNode XMLNode::createXMLTopNode_WOSD(XMLSTR lpszName, char isDeclaration) { + return XMLNode(NULL, lpszName, isDeclaration); +} +XMLNode XMLNode::createXMLTopNode(XMLCSTR lpszName, char isDeclaration) { + return XMLNode(NULL, stringDup(lpszName), isDeclaration); +} #define MEMORYINCREASE 50 -static inline void myFree(void *p) { if (p) free(p); } -static inline void *myRealloc(void *p, int newsize, int memInc, int sizeofElem) -{ - if (p==NULL) { if (memInc) return malloc(memInc*sizeofElem); return malloc(sizeofElem); } - if ((memInc==0)||((newsize%memInc)==0)) p=realloc(p,(newsize+memInc)*sizeofElem); -// if (!p) -// { -// printf("XMLParser Error: Not enough memory! Aborting...\n"); exit(220); -// } - return p; +static inline void myFree(void *p) { + if (p) free(p); +} +static inline void *myRealloc(void *p, int newsize, int memInc, + int sizeofElem) { + if (p == NULL) { + if (memInc) return malloc(memInc * sizeofElem); + return malloc(sizeofElem); + } + if ((memInc == 0) || ((newsize % memInc) == 0)) + p = realloc(p, (newsize + memInc) * sizeofElem); + // if (!p) + // { + // printf("XMLParser Error: Not enough memory! Aborting...\n"); + // exit(220); + // } + return p; } // private: -XMLElementPosition XMLNode::findPosition(XMLNodeData *d, int index, XMLElementType xxtype) -{ - if (index<0) return -1; - int i=0,j=(int)((index<<2)+xxtype),*o=d->pOrder; while (o[i]!=j) i++; return i; +XMLElementPosition XMLNode::findPosition(XMLNodeData *d, int index, + XMLElementType xxtype) { + if (index < 0) return -1; + int i = 0, j = (int)((index << 2) + xxtype), *o = d->pOrder; + while (o[i] != j) i++; + return i; } // private: // update "order" information when deleting a content of a XMLNode -int XMLNode::removeOrderElement(XMLNodeData *d, XMLElementType t, int index) -{ - int n=d->nChild+d->nText+d->nClear, *o=d->pOrder,i=findPosition(d,index,t); - memmove(o+i, o+i+1, (n-i)*sizeof(int)); - for (;ipOrder=(int)realloc(d->pOrder,n*sizeof(int)); - // but we skip reallocation because it's too time consuming. - // Anyway, at the end, it will be free'd completely at once. - return i; -} - -void *XMLNode::addToOrder(int memoryIncrease,int *_pos, int nc, void *p, int size, XMLElementType xtype) -{ - // in: *_pos is the position inside d->pOrder ("-1" means "EndOf") - // out: *_pos is the index inside p - p=myRealloc(p,(nc+1),memoryIncrease,size); - int n=d->nChild+d->nText+d->nClear; - d->pOrder=(int*)myRealloc(d->pOrder,n+1,memoryIncrease*3,sizeof(int)); - int pos=*_pos,*o=d->pOrder; - - if ((pos<0)||(pos>=n)) { *_pos=nc; o[n]=(int)((nc<<2)+xtype); return p; } +int XMLNode::removeOrderElement(XMLNodeData *d, XMLElementType t, int index) { + int n = d->nChild + d->nText + d->nClear, *o = d->pOrder, + i = findPosition(d, index, t); + memmove(o + i, o + i + 1, (n - i) * sizeof(int)); + for (; i < n; i++) + if ((o[i] & 3) == (int)t) o[i] -= 4; + // We should normally do: + // d->pOrder=(int)realloc(d->pOrder,n*sizeof(int)); + // but we skip reallocation because it's too time consuming. + // Anyway, at the end, it will be free'd completely at once. + return i; +} + +void *XMLNode::addToOrder(int memoryIncrease, int *_pos, int nc, void *p, + int size, XMLElementType xtype) { + // in: *_pos is the position inside d->pOrder ("-1" means "EndOf") + // out: *_pos is the index inside p + p = myRealloc(p, (nc + 1), memoryIncrease, size); + int n = d->nChild + d->nText + d->nClear; + d->pOrder = + (int *)myRealloc(d->pOrder, n + 1, memoryIncrease * 3, sizeof(int)); + int pos = *_pos, *o = d->pOrder; + + if ((pos < 0) || (pos >= n)) { + *_pos = nc; + o[n] = (int)((nc << 2) + xtype); + return p; + } - int i=pos; - memmove(o+i+1, o+i, (n-i)*sizeof(int)); + int i = pos; + memmove(o + i + 1, o + i, (n - i) * sizeof(int)); - while ((pos>2; - memmove(((char*)p)+(pos+1)*size,((char*)p)+pos*size,(nc-pos)*size); + *_pos = pos = o[pos] >> 2; + memmove(((char *)p) + (pos + 1) * size, ((char *)p) + pos * size, + (nc - pos) * size); - return p; + return p; } // Add a child node to the given element. -XMLNode XMLNode::addChild_priv(int memoryIncrease, XMLSTR lpszName, char isDeclaration, int pos) -{ - if (!lpszName) return emptyXMLNode; - d->pChild=(XMLNode*)addToOrder(memoryIncrease,&pos,d->nChild,d->pChild,sizeof(XMLNode),eNodeChild); - d->pChild[pos].d=NULL; - d->pChild[pos]=XMLNode(d,lpszName,isDeclaration); - d->nChild++; - return d->pChild[pos]; +XMLNode XMLNode::addChild_priv(int memoryIncrease, XMLSTR lpszName, + char isDeclaration, int pos) { + if (!lpszName) return emptyXMLNode; + d->pChild = (XMLNode *)addToOrder(memoryIncrease, &pos, d->nChild, d->pChild, + sizeof(XMLNode), eNodeChild); + d->pChild[pos].d = NULL; + d->pChild[pos] = XMLNode(d, lpszName, isDeclaration); + d->nChild++; + return d->pChild[pos]; } // Add an attribute to an element. -XMLAttribute *XMLNode::addAttribute_priv(int memoryIncrease,XMLSTR lpszName, XMLSTR lpszValuev) -{ - if (!lpszName) return &emptyXMLAttribute; - if (!d) { myFree(lpszName); myFree(lpszValuev); return &emptyXMLAttribute; } - int nc=d->nAttribute; - d->pAttribute=(XMLAttribute*)myRealloc(d->pAttribute,(nc+1),memoryIncrease,sizeof(XMLAttribute)); - XMLAttribute *pAttr=d->pAttribute+nc; - pAttr->lpszName = lpszName; - pAttr->lpszValue = lpszValuev; - d->nAttribute++; - return pAttr; +XMLAttribute *XMLNode::addAttribute_priv(int memoryIncrease, XMLSTR lpszName, + XMLSTR lpszValuev) { + if (!lpszName) return &emptyXMLAttribute; + if (!d) { + myFree(lpszName); + myFree(lpszValuev); + return &emptyXMLAttribute; + } + int nc = d->nAttribute; + d->pAttribute = (XMLAttribute *)myRealloc( + d->pAttribute, (nc + 1), memoryIncrease, sizeof(XMLAttribute)); + XMLAttribute *pAttr = d->pAttribute + nc; + pAttr->lpszName = lpszName; + pAttr->lpszValue = lpszValuev; + d->nAttribute++; + return pAttr; } // Add text to the element. -XMLCSTR XMLNode::addText_priv(int memoryIncrease, XMLSTR lpszValue, int pos) -{ - if (!lpszValue) return NULL; - if (!d) { myFree(lpszValue); return NULL; } - d->pText=(XMLCSTR*)addToOrder(memoryIncrease,&pos,d->nText,d->pText,sizeof(XMLSTR),eNodeText); - d->pText[pos]=lpszValue; - d->nText++; - return lpszValue; +XMLCSTR XMLNode::addText_priv(int memoryIncrease, XMLSTR lpszValue, int pos) { + if (!lpszValue) return NULL; + if (!d) { + myFree(lpszValue); + return NULL; + } + d->pText = (XMLCSTR *)addToOrder(memoryIncrease, &pos, d->nText, d->pText, + sizeof(XMLSTR), eNodeText); + d->pText[pos] = lpszValue; + d->nText++; + return lpszValue; } // Add clear (unformatted) text to the element. -XMLClear *XMLNode::addClear_priv(int memoryIncrease, XMLSTR lpszValue, XMLCSTR lpszOpen, XMLCSTR lpszClose, int pos) -{ - if (!lpszValue) return &emptyXMLClear; - if (!d) { myFree(lpszValue); return &emptyXMLClear; } - d->pClear=(XMLClear *)addToOrder(memoryIncrease,&pos,d->nClear,d->pClear,sizeof(XMLClear),eNodeClear); - XMLClear *pNewClear=d->pClear+pos; - pNewClear->lpszValue = lpszValue; - if (!lpszOpen) lpszOpen=XMLClearTags->lpszOpen; - if (!lpszClose) lpszClose=XMLClearTags->lpszClose; - pNewClear->lpszOpenTag = lpszOpen; - pNewClear->lpszCloseTag = lpszClose; - d->nClear++; - return pNewClear; +XMLClear *XMLNode::addClear_priv(int memoryIncrease, XMLSTR lpszValue, + XMLCSTR lpszOpen, XMLCSTR lpszClose, int pos) { + if (!lpszValue) return &emptyXMLClear; + if (!d) { + myFree(lpszValue); + return &emptyXMLClear; + } + d->pClear = (XMLClear *)addToOrder(memoryIncrease, &pos, d->nClear, d->pClear, + sizeof(XMLClear), eNodeClear); + XMLClear *pNewClear = d->pClear + pos; + pNewClear->lpszValue = lpszValue; + if (!lpszOpen) lpszOpen = XMLClearTags->lpszOpen; + if (!lpszClose) lpszClose = XMLClearTags->lpszClose; + pNewClear->lpszOpenTag = lpszOpen; + pNewClear->lpszCloseTag = lpszClose; + d->nClear++; + return pNewClear; } // private: // Parse a clear (unformatted) type node. -char XMLNode::parseClearTag(void *px, void *_pClear) -{ - XML *pXML=(XML *)px; - ALLXMLClearTag pClear=*((ALLXMLClearTag*)_pClear); - int cbTemp=0; - XMLCSTR lpszTemp=NULL; - XMLCSTR lpXML=&pXML->lpXML[pXML->nIndex]; - static XMLCSTR docTypeEnd=_CXML("]>"); - - // Find the closing tag - // Seems the ')) { lpszTemp=pCh; break; } +char XMLNode::parseClearTag(void *px, void *_pClear) { + XML *pXML = (XML *)px; + ALLXMLClearTag pClear = *((ALLXMLClearTag *)_pClear); + int cbTemp = 0; + XMLCSTR lpszTemp = NULL; + XMLCSTR lpXML = &pXML->lpXML[pXML->nIndex]; + static XMLCSTR docTypeEnd = _CXML("]>"); + + // Find the closing tag + // Seems the ')) { + lpszTemp = pCh; + break; + } #ifdef _XMLWIDECHAR - pCh++; + pCh++; #else - pCh+=XML_ByteTable[(unsigned char)(*pCh)]; + pCh += XML_ByteTable[(unsigned char)(*pCh)]; #endif - } - } else lpszTemp=xstrstr(lpXML, pClear.lpszClose); - - if (lpszTemp) - { - // Cache the size and increment the index - cbTemp = (int)(lpszTemp - lpXML); - - pXML->nIndex += cbTemp+(int)xstrlen(pClear.lpszClose); - - // Add the clear node to the current element - addClear_priv(MEMORYINCREASE,stringDup(lpXML,cbTemp), pClear.lpszOpen, pClear.lpszClose,-1); - return 0; } + } else + lpszTemp = xstrstr(lpXML, pClear.lpszClose); - // If we failed to find the end tag - pXML->error = eXMLErrorUnmatchedEndClearTag; - return 1; -} + if (lpszTemp) { + // Cache the size and increment the index + cbTemp = (int)(lpszTemp - lpXML); -void XMLNode::exactMemory(XMLNodeData *d) -{ - if (d->pOrder) d->pOrder=(int*)realloc(d->pOrder,(d->nChild+d->nText+d->nClear)*sizeof(int)); - if (d->pChild) d->pChild=(XMLNode*)realloc(d->pChild,d->nChild*sizeof(XMLNode)); - if (d->pAttribute) d->pAttribute=(XMLAttribute*)realloc(d->pAttribute,d->nAttribute*sizeof(XMLAttribute)); - if (d->pText) d->pText=(XMLCSTR*)realloc(d->pText,d->nText*sizeof(XMLSTR)); - if (d->pClear) d->pClear=(XMLClear *)realloc(d->pClear,d->nClear*sizeof(XMLClear)); -} + pXML->nIndex += cbTemp + (int)xstrlen(pClear.lpszClose); -char XMLNode::maybeAddTxT(void *pa, XMLCSTR tokenPStr) -{ - XML *pXML=(XML *)pa; - XMLCSTR lpszText=pXML->lpszText; - if (!lpszText) return 0; - if (dropWhiteSpace) while (XML_isSPACECHAR(*lpszText)&&(lpszText!=tokenPStr)) lpszText++; - int cbText = (int)(tokenPStr - lpszText); - if (!cbText) { pXML->lpszText=NULL; return 0; } - if (dropWhiteSpace) { cbText--; while ((cbText)&&XML_isSPACECHAR(lpszText[cbText])) cbText--; cbText++; } - if (!cbText) { pXML->lpszText=NULL; return 0; } - XMLSTR lpt=fromXMLString(lpszText,cbText,pXML); - if (!lpt) return 1; - pXML->lpszText=NULL; - if (removeCommentsInMiddleOfText && d->nText && d->nClear) - { - // if the previous insertion was a comment () AND - // if the previous previous insertion was a text then, delete the comment and append the text - int n=d->nChild+d->nText+d->nClear-1,*o=d->pOrder; - if (((o[n]&3)==eNodeClear)&&((o[n-1]&3)==eNodeText)) - { - int i=o[n]>>2; - if (d->pClear[i].lpszOpenTag==XMLClearTags[2].lpszOpen) - { - deleteClear(i); - i=o[n-1]>>2; - n=xstrlen(d->pText[i]); - int n2=xstrlen(lpt)+1; - d->pText[i]=(XMLSTR)realloc((void*)d->pText[i],(n+n2)*sizeof(XMLCHAR)); - if (!d->pText[i]) return 1; - memcpy((void*)(d->pText[i]+n),lpt,n2*sizeof(XMLCHAR)); - free(lpt); - return 0; - } - } - } - addText_priv(MEMORYINCREASE,lpt,-1); + // Add the clear node to the current element + addClear_priv(MEMORYINCREASE, stringDup(lpXML, cbTemp), pClear.lpszOpen, + pClear.lpszClose, -1); + return 0; + } + + // If we failed to find the end tag + pXML->error = eXMLErrorUnmatchedEndClearTag; + return 1; +} + +void XMLNode::exactMemory(XMLNodeData *d) { + if (d->pOrder) + d->pOrder = (int *)realloc( + d->pOrder, (d->nChild + d->nText + d->nClear) * sizeof(int)); + if (d->pChild) + d->pChild = (XMLNode *)realloc(d->pChild, d->nChild * sizeof(XMLNode)); + if (d->pAttribute) + d->pAttribute = (XMLAttribute *)realloc( + d->pAttribute, d->nAttribute * sizeof(XMLAttribute)); + if (d->pText) + d->pText = (XMLCSTR *)realloc(d->pText, d->nText * sizeof(XMLSTR)); + if (d->pClear) + d->pClear = (XMLClear *)realloc(d->pClear, d->nClear * sizeof(XMLClear)); +} + +char XMLNode::maybeAddTxT(void *pa, XMLCSTR tokenPStr) { + XML *pXML = (XML *)pa; + XMLCSTR lpszText = pXML->lpszText; + if (!lpszText) return 0; + if (dropWhiteSpace) + while (XML_isSPACECHAR(*lpszText) && (lpszText != tokenPStr)) lpszText++; + int cbText = (int)(tokenPStr - lpszText); + if (!cbText) { + pXML->lpszText = NULL; return 0; + } + if (dropWhiteSpace) { + cbText--; + while ((cbText) && XML_isSPACECHAR(lpszText[cbText])) cbText--; + cbText++; + } + if (!cbText) { + pXML->lpszText = NULL; + return 0; + } + XMLSTR lpt = fromXMLString(lpszText, cbText, pXML); + if (!lpt) return 1; + pXML->lpszText = NULL; + if (removeCommentsInMiddleOfText && d->nText && d->nClear) { + // if the previous insertion was a comment () AND + // if the previous previous insertion was a text then, delete the comment + // and append the text + int n = d->nChild + d->nText + d->nClear - 1, *o = d->pOrder; + if (((o[n] & 3) == eNodeClear) && ((o[n - 1] & 3) == eNodeText)) { + int i = o[n] >> 2; + if (d->pClear[i].lpszOpenTag == XMLClearTags[2].lpszOpen) { + deleteClear(i); + i = o[n - 1] >> 2; + n = xstrlen(d->pText[i]); + int n2 = xstrlen(lpt) + 1; + d->pText[i] = + (XMLSTR)realloc((void *)d->pText[i], (n + n2) * sizeof(XMLCHAR)); + if (!d->pText[i]) return 1; + memcpy((void *)(d->pText[i] + n), lpt, n2 * sizeof(XMLCHAR)); + free(lpt); + return 0; + } + } + } + addText_priv(MEMORYINCREASE, lpt, -1); + return 0; } // private: // Recursively parse an XML element. -int XMLNode::ParseXMLElement(void *pa) -{ - XML *pXML=(XML *)pa; - int cbToken; - enum XMLTokenTypeTag xtype; - NextToken token; - XMLCSTR lpszTemp=NULL; - int cbTemp=0; - char nDeclaration; - XMLNode pNew; - enum Status status; // inside or outside a tag - enum Attrib attrib = eAttribName; - - assert(pXML); - - // If this is the first call to the function - if (pXML->nFirst) - { - // Assume we are outside of a tag definition - pXML->nFirst = FALSE; - status = eOutsideTag; - } else - { - // If this is not the first call then we should only be called when inside a tag. - status = eInsideTag; - } - - // Iterate through the tokens in the document - for(;;) - { - // Obtain the next token - token = GetNextToken(pXML, &cbToken, &xtype); - - if (xtype != eTokenError) - { - // Check the current status - switch(status) - { - - // If we are outside of a tag definition - case eOutsideTag: - - // Check what type of token we obtained - switch(xtype) - { - // If we have found text or quoted text - case eTokenText: - case eTokenCloseTag: /* '>' */ - case eTokenShortHandClose: /* '/>' */ - case eTokenQuotedText: - case eTokenEquals: - break; - - // If we found a start tag '<' and declarations 'error = eXMLErrorMissingTagName; - return FALSE; - } - - // If we found a new element which is the same as this - // element then we need to pass this back to the caller.. +int XMLNode::ParseXMLElement(void *pa) { + XML *pXML = (XML *)pa; + int cbToken; + enum XMLTokenTypeTag xtype; + NextToken token; + XMLCSTR lpszTemp = NULL; + int cbTemp = 0; + char nDeclaration; + XMLNode pNew; + enum Status status; // inside or outside a tag + enum Attrib attrib = eAttribName; + + assert(pXML); + + // If this is the first call to the function + if (pXML->nFirst) { + // Assume we are outside of a tag definition + pXML->nFirst = FALSE; + status = eOutsideTag; + } else { + // If this is not the first call then we should only be called when inside a + // tag. + status = eInsideTag; + } + + // Iterate through the tokens in the document + for (;;) { + // Obtain the next token + token = GetNextToken(pXML, &cbToken, &xtype); + + if (xtype != eTokenError) { + // Check the current status + switch (status) { + // If we are outside of a tag definition + case eOutsideTag: + + // Check what type of token we obtained + switch (xtype) { + // If we have found text or quoted text + case eTokenText: + case eTokenCloseTag: /* '>' */ + case eTokenShortHandClose: /* '/>' */ + case eTokenQuotedText: + case eTokenEquals: + break; + + // If we found a start tag '<' and declarations 'error = eXMLErrorMissingTagName; + return FALSE; + } + + // If we found a new element which is the same as this + // element then we need to pass this back to the caller.. #ifdef APPROXIMATE_PARSING - if (d->lpszName && - myTagCompare(d->lpszName, token.pStr) == 0) - { - // Indicate to the caller that it needs to create a - // new element. - pXML->lpNewElement = token.pStr; - pXML->cbNewElement = cbToken; - return TRUE; - } else + if (d->lpszName && myTagCompare(d->lpszName, token.pStr) == 0) { + // Indicate to the caller that it needs to create a + // new element. + pXML->lpNewElement = token.pStr; + pXML->cbNewElement = cbToken; + return TRUE; + } else #endif - { - // If the name of the new element differs from the name of - // the current element we need to add the new element to - // the current one and recurse - pNew = addChild_priv(MEMORYINCREASE,stringDup(token.pStr,cbToken), nDeclaration,-1); - - while (!pNew.isEmpty()) - { - // Callself to process the new node. If we return - // FALSE this means we dont have any more - // processing to do... - - if (!pNew.ParseXMLElement(pXML)) return FALSE; - else - { - // If the call to recurse this function - // evented in a end tag specified in XML then - // we need to unwind the calls to this - // function until we find the appropriate node - // (the element name and end tag name must - // match) - if (pXML->cbEndTag) - { - // If we are back at the root node then we - // have an unmatched end tag - if (!d->lpszName) - { - pXML->error=eXMLErrorUnmatchedEndTag; - return FALSE; - } - - // If the end tag matches the name of this - // element then we only need to unwind - // once more... - - if (myTagCompare(d->lpszName, pXML->lpEndTag)==0) - { - pXML->cbEndTag = 0; - } - - return TRUE; - } else - if (pXML->cbNewElement) - { - // If the call indicated a new element is to - // be created on THIS element. - - // If the name of this element matches the - // name of the element we need to create - // then we need to return to the caller - // and let it process the element. - - if (myTagCompare(d->lpszName, pXML->lpNewElement)==0) - { - return TRUE; - } - - // Add the new element and recurse - pNew = addChild_priv(MEMORYINCREASE,stringDup(pXML->lpNewElement,pXML->cbNewElement),0,-1); - pXML->cbNewElement = 0; - } - else - { - // If we didn't have a new element to create - pNew = emptyXMLNode; - - } - } - } - } - break; + { + // If the name of the new element differs from the name of + // the current element we need to add the new element to + // the current one and recurse + pNew = addChild_priv(MEMORYINCREASE, + stringDup(token.pStr, cbToken), + nDeclaration, -1); + + while (!pNew.isEmpty()) { + // Callself to process the new node. If we return + // FALSE this means we dont have any more + // processing to do... + + if (!pNew.ParseXMLElement(pXML)) + return FALSE; + else { + // If the call to recurse this function + // evented in a end tag specified in XML then + // we need to unwind the calls to this + // function until we find the appropriate node + // (the element name and end tag name must + // match) + if (pXML->cbEndTag) { + // If we are back at the root node then we + // have an unmatched end tag + if (!d->lpszName) { + pXML->error = eXMLErrorUnmatchedEndTag; + return FALSE; + } - // If we found an end tag - case eTokenTagEnd: + // If the end tag matches the name of this + // element then we only need to unwind + // once more... - // If we have node text then add this to the element - if (maybeAddTxT(pXML,token.pStr)) return FALSE; + if (myTagCompare(d->lpszName, pXML->lpEndTag) == 0) { + pXML->cbEndTag = 0; + } - // Find the name of the end tag - token = GetNextToken(pXML, &cbTemp, &xtype); + return TRUE; + } else if (pXML->cbNewElement) { + // If the call indicated a new element is to + // be created on THIS element. - // The end tag should be text - if (xtype != eTokenText) - { - pXML->error = eXMLErrorMissingEndTagName; - return FALSE; - } - lpszTemp = token.pStr; + // If the name of this element matches the + // name of the element we need to create + // then we need to return to the caller + // and let it process the element. - // After the end tag we should find a closing tag - token = GetNextToken(pXML, &cbToken, &xtype); - if (xtype != eTokenCloseTag) - { - pXML->error = eXMLErrorMissingEndTagName; - return FALSE; + if (myTagCompare(d->lpszName, pXML->lpNewElement) == 0) { + return TRUE; + } + + // Add the new element and recurse + pNew = addChild_priv( + MEMORYINCREASE, + stringDup(pXML->lpNewElement, pXML->cbNewElement), 0, + -1); + pXML->cbNewElement = 0; + } else { + // If we didn't have a new element to create + pNew = emptyXMLNode; } - pXML->lpszText=pXML->lpXML+pXML->nIndex; - - // We need to return to the previous caller. If the name - // of the tag cannot be found we need to keep returning to - // caller until we find a match - if (myTagCompare(d->lpszName, lpszTemp) != 0) + } + } + } + break; + + // If we found an end tag + case eTokenTagEnd: + + // If we have node text then add this to the element + if (maybeAddTxT(pXML, token.pStr)) return FALSE; + + // Find the name of the end tag + token = GetNextToken(pXML, &cbTemp, &xtype); + + // The end tag should be text + if (xtype != eTokenText) { + pXML->error = eXMLErrorMissingEndTagName; + return FALSE; + } + lpszTemp = token.pStr; + + // After the end tag we should find a closing tag + token = GetNextToken(pXML, &cbToken, &xtype); + if (xtype != eTokenCloseTag) { + pXML->error = eXMLErrorMissingEndTagName; + return FALSE; + } + pXML->lpszText = pXML->lpXML + pXML->nIndex; + + // We need to return to the previous caller. If the name + // of the tag cannot be found we need to keep returning to + // caller until we find a match + if (myTagCompare(d->lpszName, lpszTemp) != 0) #ifdef STRICT_PARSING - { - pXML->error=eXMLErrorUnmatchedEndTag; - pXML->nIndexMissigEndTag=pXML->nIndex; - return FALSE; - } + { + pXML->error = eXMLErrorUnmatchedEndTag; + pXML->nIndexMissigEndTag = pXML->nIndex; + return FALSE; + } #else - { - pXML->error=eXMLErrorMissingEndTag; - pXML->nIndexMissigEndTag=pXML->nIndex; - pXML->lpEndTag = lpszTemp; - pXML->cbEndTag = cbTemp; - } + { + pXML->error = eXMLErrorMissingEndTag; + pXML->nIndexMissigEndTag = pXML->nIndex; + pXML->lpEndTag = lpszTemp; + pXML->cbEndTag = cbTemp; + } #endif - // Return to the caller + // Return to the caller + exactMemory(d); + return TRUE; + + // If we found a clear (unformatted) token + case eTokenClear: + // If we have node text then add this to the element + if (maybeAddTxT(pXML, token.pStr)) return FALSE; + if (parseClearTag(pXML, token.pClr)) return FALSE; + pXML->lpszText = pXML->lpXML + pXML->nIndex; + break; + + default: + break; + } + break; + + // If we are inside a tag definition we need to search for attributes + case eInsideTag: + + // Check what part of the attribute (name, equals, value) we + // are looking for. + switch (attrib) { + // If we are looking for a new attribute + case eAttribName: + + // Check what the current token type is + switch (xtype) { + // If the current type is text... + // Eg. 'attribute' + case eTokenText: + // Cache the token then indicate that we are next to + // look for the equals + lpszTemp = token.pStr; + cbTemp = cbToken; + attrib = eAttribEquals; + break; + + // If we found a closing tag... + // Eg. '>' + case eTokenCloseTag: + // We are now outside the tag + status = eOutsideTag; + pXML->lpszText = pXML->lpXML + pXML->nIndex; + break; + + // If we found a short hand '/>' closing tag then we can + // return to the caller + case eTokenShortHandClose: + exactMemory(d); + pXML->lpszText = pXML->lpXML + pXML->nIndex; + return TRUE; + + // Errors... + case eTokenQuotedText: /* '"SomeText"' */ + case eTokenTagStart: /* '<' */ + case eTokenTagEnd: /* 'error = eXMLErrorUnexpectedToken; + return FALSE; + default: + break; + } + break; + + // If we are looking for an equals + case eAttribEquals: + // Check what the current token type is + switch (xtype) { + // If the current type is text... + // Eg. 'Attribute AnotherAttribute' + case eTokenText: + // Add the unvalued attribute to the list + addAttribute_priv(MEMORYINCREASE, stringDup(lpszTemp, cbTemp), + NULL); + // Cache the token then indicate. We are next to + // look for the equals attribute + lpszTemp = token.pStr; + cbTemp = cbToken; + break; + + // If we found a closing tag 'Attribute >' or a short hand + // closing tag 'Attribute />' + case eTokenShortHandClose: + case eTokenCloseTag: + // If we are a declaration element 'lpszText = pXML->lpXML + pXML->nIndex; + + if (d->isDeclaration && + (lpszTemp[cbTemp - 1]) == _CXML('?')) { + cbTemp--; + if (d->pParent && d->pParent->pParent) + xtype = eTokenShortHandClose; + } + + if (cbTemp) { + // Add the unvalued attribute to the list + addAttribute_priv(MEMORYINCREASE, + stringDup(lpszTemp, cbTemp), NULL); + } + + // If this is the end of the tag then return to the caller + if (xtype == eTokenShortHandClose) { exactMemory(d); return TRUE; + } - // If we found a clear (unformatted) token - case eTokenClear: - // If we have node text then add this to the element - if (maybeAddTxT(pXML,token.pStr)) return FALSE; - if (parseClearTag(pXML, token.pClr)) return FALSE; - pXML->lpszText=pXML->lpXML+pXML->nIndex; - break; + // We are now outside the tag + status = eOutsideTag; + break; + // If we found the equals token... + // Eg. 'Attribute =' + case eTokenEquals: + // Indicate that we next need to search for the value + // for the attribute + attrib = eAttribValue; + break; + + // Errors... + case eTokenQuotedText: /* 'Attribute "InvalidAttr"'*/ + case eTokenTagStart: /* 'Attribute <' */ + case eTokenTagEnd: /* 'Attribute error = eXMLErrorUnexpectedToken; + return FALSE; default: - break; - } - break; - - // If we are inside a tag definition we need to search for attributes - case eInsideTag: - - // Check what part of the attribute (name, equals, value) we - // are looking for. - switch(attrib) - { - // If we are looking for a new attribute - case eAttribName: - - // Check what the current token type is - switch(xtype) - { - // If the current type is text... - // Eg. 'attribute' - case eTokenText: - // Cache the token then indicate that we are next to - // look for the equals - lpszTemp = token.pStr; - cbTemp = cbToken; - attrib = eAttribEquals; - break; - - // If we found a closing tag... - // Eg. '>' - case eTokenCloseTag: - // We are now outside the tag - status = eOutsideTag; - pXML->lpszText=pXML->lpXML+pXML->nIndex; - break; - - // If we found a short hand '/>' closing tag then we can - // return to the caller - case eTokenShortHandClose: - exactMemory(d); - pXML->lpszText=pXML->lpXML+pXML->nIndex; - return TRUE; - - // Errors... - case eTokenQuotedText: /* '"SomeText"' */ - case eTokenTagStart: /* '<' */ - case eTokenTagEnd: /* 'error = eXMLErrorUnexpectedToken; - return FALSE; - default: break; - } - break; - - // If we are looking for an equals - case eAttribEquals: - // Check what the current token type is - switch(xtype) - { - // If the current type is text... - // Eg. 'Attribute AnotherAttribute' - case eTokenText: - // Add the unvalued attribute to the list - addAttribute_priv(MEMORYINCREASE,stringDup(lpszTemp,cbTemp), NULL); - // Cache the token then indicate. We are next to - // look for the equals attribute - lpszTemp = token.pStr; - cbTemp = cbToken; - break; - - // If we found a closing tag 'Attribute >' or a short hand - // closing tag 'Attribute />' - case eTokenShortHandClose: - case eTokenCloseTag: - // If we are a declaration element 'lpszText=pXML->lpXML+pXML->nIndex; - - if (d->isDeclaration && - (lpszTemp[cbTemp-1]) == _CXML('?')) - { - cbTemp--; - if (d->pParent && d->pParent->pParent) xtype = eTokenShortHandClose; - } - - if (cbTemp) - { - // Add the unvalued attribute to the list - addAttribute_priv(MEMORYINCREASE,stringDup(lpszTemp,cbTemp), NULL); - } - - // If this is the end of the tag then return to the caller - if (xtype == eTokenShortHandClose) - { - exactMemory(d); - return TRUE; - } - - // We are now outside the tag - status = eOutsideTag; - break; - - // If we found the equals token... - // Eg. 'Attribute =' - case eTokenEquals: - // Indicate that we next need to search for the value - // for the attribute - attrib = eAttribValue; - break; - - // Errors... - case eTokenQuotedText: /* 'Attribute "InvalidAttr"'*/ - case eTokenTagStart: /* 'Attribute <' */ - case eTokenTagEnd: /* 'Attribute error = eXMLErrorUnexpectedToken; - return FALSE; - default: break; + break; + } + break; + + // If we are looking for an attribute value + case eAttribValue: + // Check what the current token type is + switch (xtype) { + // If the current type is text or quoted text... + // Eg. 'Attribute = "Value"' or 'Attribute = Value' or + // 'Attribute = 'Value''. + case eTokenText: + case eTokenQuotedText: + // If we are a declaration element 'isDeclaration && + (token.pStr[cbToken - 1]) == _CXML('?')) { + cbToken--; + } + + if (cbTemp) { + // Add the valued attribute to the list + if (xtype == eTokenQuotedText) { + token.pStr++; + cbToken -= 2; } - break; - - // If we are looking for an attribute value - case eAttribValue: - // Check what the current token type is - switch(xtype) - { - // If the current type is text or quoted text... - // Eg. 'Attribute = "Value"' or 'Attribute = Value' or - // 'Attribute = 'Value''. - case eTokenText: - case eTokenQuotedText: - // If we are a declaration element 'isDeclaration && - (token.pStr[cbToken-1]) == _CXML('?')) - { - cbToken--; - } - - if (cbTemp) - { - // Add the valued attribute to the list - if (xtype==eTokenQuotedText) { token.pStr++; cbToken-=2; } - XMLSTR attrVal=(XMLSTR)token.pStr; - if (attrVal) - { - attrVal=fromXMLString(attrVal,cbToken,pXML); - if (!attrVal) return FALSE; - } - addAttribute_priv(MEMORYINCREASE,stringDup(lpszTemp,cbTemp),attrVal); - } - - // Indicate we are searching for a new attribute - attrib = eAttribName; - break; - - // Errors... - case eTokenTagStart: /* 'Attr = <' */ - case eTokenTagEnd: /* 'Attr = ' */ - case eTokenShortHandClose: /* "Attr = />" */ - case eTokenEquals: /* 'Attr = =' */ - case eTokenDeclaration: /* 'Attr = error = eXMLErrorUnexpectedToken; - return FALSE; - break; - default: break; + XMLSTR attrVal = (XMLSTR)token.pStr; + if (attrVal) { + attrVal = fromXMLString(attrVal, cbToken, pXML); + if (!attrVal) return FALSE; } - } - } - } - // If we failed to obtain the next token - else - { - if ((!d->isDeclaration)&&(d->pParent)) - { + addAttribute_priv(MEMORYINCREASE, + stringDup(lpszTemp, cbTemp), attrVal); + } + + // Indicate we are searching for a new attribute + attrib = eAttribName; + break; + + // Errors... + case eTokenTagStart: /* 'Attr = <' */ + case eTokenTagEnd: /* 'Attr = ' */ + case eTokenShortHandClose: /* "Attr = />" */ + case eTokenEquals: /* 'Attr = =' */ + case eTokenDeclaration: /* 'Attr = error = eXMLErrorUnexpectedToken; + return FALSE; + break; + default: + break; + } + } + } + } + // If we failed to obtain the next token + else { + if ((!d->isDeclaration) && (d->pParent)) { #ifdef STRICT_PARSING - pXML->error=eXMLErrorUnmatchedEndTag; + pXML->error = eXMLErrorUnmatchedEndTag; #else - pXML->error=eXMLErrorMissingEndTag; + pXML->error = eXMLErrorMissingEndTag; #endif - pXML->nIndexMissigEndTag=pXML->nIndex; - } - maybeAddTxT(pXML,pXML->lpXML+pXML->nIndex); - return FALSE; - } + pXML->nIndexMissigEndTag = pXML->nIndex; + } + maybeAddTxT(pXML, pXML->lpXML + pXML->nIndex); + return FALSE; } + } } // Count the number of lines and columns in an XML string. -static void CountLinesAndColumns(XMLCSTR lpXML, int nUpto, XMLResults *pResults) -{ - XMLCHAR ch; - assert(lpXML); - assert(pResults); - - struct XML xml={ lpXML,lpXML, 0, 0, eXMLErrorNone, NULL, 0, NULL, 0, TRUE }; - - pResults->nLine = 1; - pResults->nColumn = 1; - while (xml.nIndexnColumn++; - else - { - pResults->nLine++; - pResults->nColumn=1; - } +static void CountLinesAndColumns(XMLCSTR lpXML, int nUpto, + XMLResults *pResults) { + XMLCHAR ch; + assert(lpXML); + assert(pResults); + + struct XML xml = {lpXML, lpXML, 0, 0, eXMLErrorNone, NULL, 0, NULL, 0, TRUE}; + + pResults->nLine = 1; + pResults->nColumn = 1; + while (xml.nIndex < nUpto) { + ch = getNextChar(&xml); + if (ch != _CXML('\n')) + pResults->nColumn++; + else { + pResults->nLine++; + pResults->nColumn = 1; } + } } // Parse XML and return the root element. -XMLNode XMLNode::parseString(XMLCSTR lpszXML, XMLCSTR tag, XMLResults *pResults) -{ - if (!lpszXML) - { - if (pResults) - { - pResults->error=eXMLErrorNoElements; - pResults->nLine=0; - pResults->nColumn=0; - } - return emptyXMLNode; +XMLNode XMLNode::parseString(XMLCSTR lpszXML, XMLCSTR tag, + XMLResults *pResults) { + if (!lpszXML) { + if (pResults) { + pResults->error = eXMLErrorNoElements; + pResults->nLine = 0; + pResults->nColumn = 0; } - - XMLNode xnode(NULL,NULL,FALSE); - struct XML xml={ lpszXML, lpszXML, 0, 0, eXMLErrorNone, NULL, 0, NULL, 0, TRUE }; - - // Create header element - xnode.ParseXMLElement(&xml); - enum XMLError error = xml.error; - if (!xnode.nChildNode()) error=eXMLErrorNoXMLTagFound; - if ((xnode.nChildNode()==1)&&(xnode.nElement()==1)) xnode=xnode.getChildNode(); // skip the empty node - - // If no error occurred - if ((error==eXMLErrorNone)||(error==eXMLErrorMissingEndTag)||(error==eXMLErrorNoXMLTagFound)) - { - XMLCSTR name=xnode.getName(); - if (tag&&(*tag)&&((!name)||(xstricmp(name,tag)))) - { - xnode=xnode.getChildNode(tag); - if (xnode.isEmpty()) - { - if (pResults) - { - pResults->error=eXMLErrorFirstTagNotFound; - pResults->nLine=0; - pResults->nColumn=0; - } - return emptyXMLNode; - } + return emptyXMLNode; + } + + XMLNode xnode(NULL, NULL, FALSE); + struct XML xml = {lpszXML, lpszXML, 0, 0, eXMLErrorNone, + NULL, 0, NULL, 0, TRUE}; + + // Create header element + xnode.ParseXMLElement(&xml); + enum XMLError error = xml.error; + if (!xnode.nChildNode()) error = eXMLErrorNoXMLTagFound; + if ((xnode.nChildNode() == 1) && (xnode.nElement() == 1)) + xnode = xnode.getChildNode(); // skip the empty node + + // If no error occurred + if ((error == eXMLErrorNone) || (error == eXMLErrorMissingEndTag) || + (error == eXMLErrorNoXMLTagFound)) { + XMLCSTR name = xnode.getName(); + if (tag && (*tag) && ((!name) || (xstricmp(name, tag)))) { + xnode = xnode.getChildNode(tag); + if (xnode.isEmpty()) { + if (pResults) { + pResults->error = eXMLErrorFirstTagNotFound; + pResults->nLine = 0; + pResults->nColumn = 0; } - } else - { - // Cleanup: this will destroy all the nodes - xnode = emptyXMLNode; + return emptyXMLNode; + } } - - - // If we have been given somewhere to place results - if (pResults) - { - pResults->error = error; - - // If we have an error - if (error!=eXMLErrorNone) - { - if (error==eXMLErrorMissingEndTag) xml.nIndex=xml.nIndexMissigEndTag; - // Find which line and column it starts on. - CountLinesAndColumns(xml.lpXML, xml.nIndex, pResults); - } + } else { + // Cleanup: this will destroy all the nodes + xnode = emptyXMLNode; + } + + // If we have been given somewhere to place results + if (pResults) { + pResults->error = error; + + // If we have an error + if (error != eXMLErrorNone) { + if (error == eXMLErrorMissingEndTag) xml.nIndex = xml.nIndexMissigEndTag; + // Find which line and column it starts on. + CountLinesAndColumns(xml.lpXML, xml.nIndex, pResults); } - return xnode; -} - -XMLNode XMLNode::parseFile(XMLCSTR filename, XMLCSTR tag, XMLResults *pResults) -{ - if (pResults) { pResults->nLine=0; pResults->nColumn=0; } - FILE *f=xfopen(filename,_CXML("rb")); - if (f==NULL) { if (pResults) pResults->error=eXMLErrorFileNotFound; return emptyXMLNode; } - fseek(f,0,SEEK_END); - int l=ftell(f),headerSz=0; - if (!l) { if (pResults) pResults->error=eXMLErrorEmpty; fclose(f); return emptyXMLNode; } - fseek(f,0,SEEK_SET); - unsigned char *buf=(unsigned char*)malloc(l+4); - l=fread(buf,1,l,f); + } + return xnode; +} + +XMLNode XMLNode::parseFile(XMLCSTR filename, XMLCSTR tag, + XMLResults *pResults) { + if (pResults) { + pResults->nLine = 0; + pResults->nColumn = 0; + } + FILE *f = xfopen(filename, _CXML("rb")); + if (f == NULL) { + if (pResults) pResults->error = eXMLErrorFileNotFound; + return emptyXMLNode; + } + fseek(f, 0, SEEK_END); + int l = ftell(f), headerSz = 0; + if (!l) { + if (pResults) pResults->error = eXMLErrorEmpty; fclose(f); - buf[l]=0;buf[l+1]=0;buf[l+2]=0;buf[l+3]=0; + return emptyXMLNode; + } + fseek(f, 0, SEEK_SET); + unsigned char *buf = (unsigned char *)malloc(l + 4); + l = fread(buf, 1, l, f); + fclose(f); + buf[l] = 0; + buf[l + 1] = 0; + buf[l + 2] = 0; + buf[l + 3] = 0; #ifdef _XMLWIDECHAR - if (guessWideCharChars) - { - if (!myIsTextWideChar(buf,l)) - { - XMLNode::XMLCharEncoding ce=XMLNode::char_encoding_legacy; - if ((buf[0]==0xef)&&(buf[1]==0xbb)&&(buf[2]==0xbf)) { headerSz=3; ce=XMLNode::char_encoding_UTF8; } - XMLSTR b2=myMultiByteToWideChar((const char*)(buf+headerSz),ce); - free(buf); buf=(unsigned char*)b2; headerSz=0; - } else - { - if ((buf[0]==0xef)&&(buf[1]==0xff)) headerSz=2; - if ((buf[0]==0xff)&&(buf[1]==0xfe)) headerSz=2; - } + if (guessWideCharChars) { + if (!myIsTextWideChar(buf, l)) { + XMLNode::XMLCharEncoding ce = XMLNode::char_encoding_legacy; + if ((buf[0] == 0xef) && (buf[1] == 0xbb) && (buf[2] == 0xbf)) { + headerSz = 3; + ce = XMLNode::char_encoding_UTF8; + } + XMLSTR b2 = myMultiByteToWideChar((const char *)(buf + headerSz), ce); + free(buf); + buf = (unsigned char *)b2; + headerSz = 0; + } else { + if ((buf[0] == 0xef) && (buf[1] == 0xff)) headerSz = 2; + if ((buf[0] == 0xff) && (buf[1] == 0xfe)) headerSz = 2; } + } #else - if (guessWideCharChars) - { - if (myIsTextWideChar(buf,l)) - { - if ((buf[0]==0xef)&&(buf[1]==0xff)) headerSz=2; - if ((buf[0]==0xff)&&(buf[1]==0xfe)) headerSz=2; - char *b2=myWideCharToMultiByte((const wchar_t*)(buf+headerSz)); - free(buf); buf=(unsigned char*)b2; headerSz=0; - } else - { - if ((buf[0]==0xef)&&(buf[1]==0xbb)&&(buf[2]==0xbf)) headerSz=3; - } + if (guessWideCharChars) { + if (myIsTextWideChar(buf, l)) { + if ((buf[0] == 0xef) && (buf[1] == 0xff)) headerSz = 2; + if ((buf[0] == 0xff) && (buf[1] == 0xfe)) headerSz = 2; + char *b2 = myWideCharToMultiByte((const wchar_t *)(buf + headerSz)); + free(buf); + buf = (unsigned char *)b2; + headerSz = 0; + } else { + if ((buf[0] == 0xef) && (buf[1] == 0xbb) && (buf[2] == 0xbf)) + headerSz = 3; } + } #endif - if (!buf) { if (pResults) pResults->error=eXMLErrorCharConversionError; return emptyXMLNode; } - XMLNode x=parseString((XMLSTR)(buf+headerSz),tag,pResults); - free(buf); - return x; + if (!buf) { + if (pResults) pResults->error = eXMLErrorCharConversionError; + return emptyXMLNode; + } + XMLNode x = parseString((XMLSTR)(buf + headerSz), tag, pResults); + free(buf); + return x; } -static inline void charmemset(XMLSTR dest,XMLCHAR c,int l) { while (l--) *(dest++)=c; } +static inline void charmemset(XMLSTR dest, XMLCHAR c, int l) { + while (l--) *(dest++) = c; +} // private: // Creates an user friendly XML string from a given element with // appropriate white space and carriage returns. // // This recurses through all subnodes then adds contents of the nodes to the // string. -int XMLNode::CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, int nFormat) -{ - int nResult = 0; - int cb=nFormat<0?0:nFormat; - int cbElement; - int nChildFormat=-1; - int nElementI=pEntry->nChild+pEntry->nText+pEntry->nClear; - int i,j; - if ((nFormat>=0)&&(nElementI==1)&&(pEntry->nText==1)&&(!pEntry->isDeclaration)) nFormat=-2; - - assert(pEntry); +int XMLNode::CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, + int nFormat) { + int nResult = 0; + int cb = nFormat < 0 ? 0 : nFormat; + int cbElement; + int nChildFormat = -1; + int nElementI = pEntry->nChild + pEntry->nText + pEntry->nClear; + int i, j; + if ((nFormat >= 0) && (nElementI == 1) && (pEntry->nText == 1) && + (!pEntry->isDeclaration)) + nFormat = -2; + + assert(pEntry); #define LENSTR(lpsz) (lpsz ? xstrlen(lpsz) : 0) - // If the element has no name then assume this is the head node. - cbElement = (int)LENSTR(pEntry->lpszName); - - if (cbElement) - { - // "isDeclaration) lpszMarker[nResult++]=_CXML('?'); - xstrcpy(&lpszMarker[nResult], pEntry->lpszName); - nResult+=cbElement; - lpszMarker[nResult++]=_CXML(' '); - - } else - { - nResult+=cbElement+2+cb; - if (pEntry->isDeclaration) nResult++; - } + // If the element has no name then assume this is the head node. + cbElement = (int)LENSTR(pEntry->lpszName); + + if (cbElement) { + // "isDeclaration) lpszMarker[nResult++] = _CXML('?'); + xstrcpy(&lpszMarker[nResult], pEntry->lpszName); + nResult += cbElement; + lpszMarker[nResult++] = _CXML(' '); + + } else { + nResult += cbElement + 2 + cb; + if (pEntry->isDeclaration) nResult++; + } - // Enumerate attributes and add them to the string - XMLAttribute *pAttr=pEntry->pAttribute; - for (i=0; inAttribute; i++) - { - // "Attrib - cb = (int)LENSTR(pAttr->lpszName); + // Enumerate attributes and add them to the string + XMLAttribute *pAttr = pEntry->pAttribute; + for (i = 0; i < pEntry->nAttribute; i++) { + // "Attrib + cb = (int)LENSTR(pAttr->lpszName); + if (cb) { + if (lpszMarker) xstrcpy(&lpszMarker[nResult], pAttr->lpszName); + nResult += cb; + // "Attrib=Value " + if (pAttr->lpszValue) { + cb = (int)ToXMLStringTool::lengthXMLString(pAttr->lpszValue); + if (lpszMarker) { + lpszMarker[nResult] = _CXML('='); + lpszMarker[nResult + 1] = _CXML('"'); if (cb) - { - if (lpszMarker) xstrcpy(&lpszMarker[nResult], pAttr->lpszName); - nResult += cb; - // "Attrib=Value " - if (pAttr->lpszValue) - { - cb=(int)ToXMLStringTool::lengthXMLString(pAttr->lpszValue); - if (lpszMarker) - { - lpszMarker[nResult]=_CXML('='); - lpszMarker[nResult+1]=_CXML('"'); - if (cb) ToXMLStringTool::toXMLUnSafe(&lpszMarker[nResult+2],pAttr->lpszValue); - lpszMarker[nResult+cb+2]=_CXML('"'); - } - nResult+=cb+3; - } - if (lpszMarker) lpszMarker[nResult] = _CXML(' '); - nResult++; - } - pAttr++; + ToXMLStringTool::toXMLUnSafe(&lpszMarker[nResult + 2], + pAttr->lpszValue); + lpszMarker[nResult + cb + 2] = _CXML('"'); + } + nResult += cb + 3; } - - if (pEntry->isDeclaration) - { - if (lpszMarker) - { - lpszMarker[nResult-1]=_CXML('?'); - lpszMarker[nResult]=_CXML('>'); - } - nResult++; - if (nFormat!=-1) - { - if (lpszMarker) lpszMarker[nResult]=_CXML('\n'); - nResult++; - } - } else - // If there are child nodes we need to terminate the start tag - if (nElementI) - { - if (lpszMarker) lpszMarker[nResult-1]=_CXML('>'); - if (nFormat>=0) - { - if (lpszMarker) lpszMarker[nResult]=_CXML('\n'); - nResult++; - } - } else nResult--; - } - - // Calculate the child format for when we recurse. This is used to - // determine the number of spaces used for prefixes. - if (nFormat!=-1) - { - if (cbElement&&(!pEntry->isDeclaration)) nChildFormat=nFormat+1; - else nChildFormat=nFormat; + if (lpszMarker) lpszMarker[nResult] = _CXML(' '); + nResult++; + } + pAttr++; } - // Enumerate through remaining children - for (i=0; ipOrder[i]; - switch((XMLElementType)(j&3)) - { - // Text nodes - case eNodeText: - { - // "Text" - XMLCSTR pChild=pEntry->pText[j>>2]; - cb = (int)ToXMLStringTool::lengthXMLString(pChild); - if (cb) - { - if (nFormat>=0) - { - if (lpszMarker) - { - charmemset(&lpszMarker[nResult],INDENTCHAR,nFormat+1); - ToXMLStringTool::toXMLUnSafe(&lpszMarker[nResult+nFormat+1],pChild); - lpszMarker[nResult+nFormat+1+cb]=_CXML('\n'); - } - nResult+=cb+nFormat+2; - } else - { - if (lpszMarker) ToXMLStringTool::toXMLUnSafe(&lpszMarker[nResult], pChild); - nResult += cb; - } - } - break; + if (pEntry->isDeclaration) { + if (lpszMarker) { + lpszMarker[nResult - 1] = _CXML('?'); + lpszMarker[nResult] = _CXML('>'); + } + nResult++; + if (nFormat != -1) { + if (lpszMarker) lpszMarker[nResult] = _CXML('\n'); + nResult++; + } + } else + // If there are child nodes we need to terminate the start tag + if (nElementI) { + if (lpszMarker) lpszMarker[nResult - 1] = _CXML('>'); + if (nFormat >= 0) { + if (lpszMarker) lpszMarker[nResult] = _CXML('\n'); + nResult++; + } + } else + nResult--; + } + + // Calculate the child format for when we recurse. This is used to + // determine the number of spaces used for prefixes. + if (nFormat != -1) { + if (cbElement && (!pEntry->isDeclaration)) + nChildFormat = nFormat + 1; + else + nChildFormat = nFormat; + } + + // Enumerate through remaining children + for (i = 0; i < nElementI; i++) { + j = pEntry->pOrder[i]; + switch ((XMLElementType)(j & 3)) { + // Text nodes + case eNodeText: { + // "Text" + XMLCSTR pChild = pEntry->pText[j >> 2]; + cb = (int)ToXMLStringTool::lengthXMLString(pChild); + if (cb) { + if (nFormat >= 0) { + if (lpszMarker) { + charmemset(&lpszMarker[nResult], INDENTCHAR, nFormat + 1); + ToXMLStringTool::toXMLUnSafe(&lpszMarker[nResult + nFormat + 1], + pChild); + lpszMarker[nResult + nFormat + 1 + cb] = _CXML('\n'); } + nResult += cb + nFormat + 2; + } else { + if (lpszMarker) + ToXMLStringTool::toXMLUnSafe(&lpszMarker[nResult], pChild); + nResult += cb; + } + } + break; + } + + // Clear type nodes + case eNodeClear: { + XMLClear *pChild = pEntry->pClear + (j >> 2); + // "OpenTag" + cb = (int)LENSTR(pChild->lpszOpenTag); + if (cb) { + if (nFormat != -1) { + if (lpszMarker) { + charmemset(&lpszMarker[nResult], INDENTCHAR, nFormat + 1); + xstrcpy(&lpszMarker[nResult + nFormat + 1], pChild->lpszOpenTag); + } + nResult += cb + nFormat + 1; + } else { + if (lpszMarker) xstrcpy(&lpszMarker[nResult], pChild->lpszOpenTag); + nResult += cb; + } + } - // Clear type nodes - case eNodeClear: - { - XMLClear *pChild=pEntry->pClear+(j>>2); - // "OpenTag" - cb = (int)LENSTR(pChild->lpszOpenTag); - if (cb) - { - if (nFormat!=-1) - { - if (lpszMarker) - { - charmemset(&lpszMarker[nResult], INDENTCHAR, nFormat+1); - xstrcpy(&lpszMarker[nResult+nFormat+1], pChild->lpszOpenTag); - } - nResult+=cb+nFormat+1; - } - else - { - if (lpszMarker)xstrcpy(&lpszMarker[nResult], pChild->lpszOpenTag); - nResult += cb; - } - } - - // "OpenTag Value" - cb = (int)LENSTR(pChild->lpszValue); - if (cb) - { - if (lpszMarker) xstrcpy(&lpszMarker[nResult], pChild->lpszValue); - nResult += cb; - } - - // "OpenTag Value CloseTag" - cb = (int)LENSTR(pChild->lpszCloseTag); - if (cb) - { - if (lpszMarker) xstrcpy(&lpszMarker[nResult], pChild->lpszCloseTag); - nResult += cb; - } + // "OpenTag Value" + cb = (int)LENSTR(pChild->lpszValue); + if (cb) { + if (lpszMarker) xstrcpy(&lpszMarker[nResult], pChild->lpszValue); + nResult += cb; + } - if (nFormat!=-1) - { - if (lpszMarker) lpszMarker[nResult] = _CXML('\n'); - nResult++; - } - break; - } + // "OpenTag Value CloseTag" + cb = (int)LENSTR(pChild->lpszCloseTag); + if (cb) { + if (lpszMarker) xstrcpy(&lpszMarker[nResult], pChild->lpszCloseTag); + nResult += cb; + } - // Element nodes - case eNodeChild: - { - // Recursively add child nodes - nResult += CreateXMLStringR(pEntry->pChild[j>>2].d, lpszMarker ? lpszMarker + nResult : 0, nChildFormat); - break; - } - default: break; + if (nFormat != -1) { + if (lpszMarker) lpszMarker[nResult] = _CXML('\n'); + nResult++; } + break; + } + + // Element nodes + case eNodeChild: { + // Recursively add child nodes + nResult += CreateXMLStringR(pEntry->pChild[j >> 2].d, + lpszMarker ? lpszMarker + nResult : 0, + nChildFormat); + break; + } + default: + break; } + } + + if ((cbElement) && (!pEntry->isDeclaration)) { + // If we have child entries we need to use long XML notation for + // closing the element - "blah blah blah" + if (nElementI) { + // "\0" + if (lpszMarker) { + if (nFormat >= 0) { + charmemset(&lpszMarker[nResult], INDENTCHAR, nFormat); + nResult += nFormat; + } - if ((cbElement)&&(!pEntry->isDeclaration)) - { - // If we have child entries we need to use long XML notation for - // closing the element - "blah blah blah" - if (nElementI) - { - // "\0" - if (lpszMarker) - { - if (nFormat >=0) - { - charmemset(&lpszMarker[nResult], INDENTCHAR,nFormat); - nResult+=nFormat; - } - - lpszMarker[nResult]=_CXML('<'); lpszMarker[nResult+1]=_CXML('/'); - nResult += 2; - xstrcpy(&lpszMarker[nResult], pEntry->lpszName); - nResult += cbElement; - - lpszMarker[nResult]=_CXML('>'); - if (nFormat == -1) nResult++; - else - { - lpszMarker[nResult+1]=_CXML('\n'); - nResult+=2; - } - } else - { - if (nFormat>=0) nResult+=cbElement+4+nFormat; - else if (nFormat==-1) nResult+=cbElement+3; - else nResult+=cbElement+4; - } - } else - { - // If there are no children we can use shorthand XML notation - - // "" - // "/>\0" - if (lpszMarker) - { - lpszMarker[nResult]=_CXML('/'); lpszMarker[nResult+1]=_CXML('>'); - if (nFormat != -1) lpszMarker[nResult+2]=_CXML('\n'); - } - nResult += nFormat == -1 ? 2 : 3; + lpszMarker[nResult] = _CXML('<'); + lpszMarker[nResult + 1] = _CXML('/'); + nResult += 2; + xstrcpy(&lpszMarker[nResult], pEntry->lpszName); + nResult += cbElement; + + lpszMarker[nResult] = _CXML('>'); + if (nFormat == -1) + nResult++; + else { + lpszMarker[nResult + 1] = _CXML('\n'); + nResult += 2; } + } else { + if (nFormat >= 0) + nResult += cbElement + 4 + nFormat; + else if (nFormat == -1) + nResult += cbElement + 3; + else + nResult += cbElement + 4; + } + } else { + // If there are no children we can use shorthand XML notation - + // "" + // "/>\0" + if (lpszMarker) { + lpszMarker[nResult] = _CXML('/'); + lpszMarker[nResult + 1] = _CXML('>'); + if (nFormat != -1) lpszMarker[nResult + 2] = _CXML('\n'); + } + nResult += nFormat == -1 ? 2 : 3; } + } - return nResult; + return nResult; } #undef LENSTR @@ -2084,638 +2351,832 @@ int XMLNode::CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, int nForma // NULL terminator. // @return XMLSTR - Allocated XML string, you must free // this with free(). -XMLSTR XMLNode::createXMLString(int nFormat, int *pnSize) const -{ - if (!d) { if (pnSize) *pnSize=0; return NULL; } - - XMLSTR lpszResult = NULL; - int cbStr; - - // Recursively Calculate the size of the XML string - if (!dropWhiteSpace) nFormat=0; - nFormat = nFormat ? 0 : -1; - cbStr = CreateXMLStringR(d, 0, nFormat); - // Alllocate memory for the XML string + the NULL terminator and - // create the recursively XML string. - lpszResult=(XMLSTR)malloc((cbStr+1)*sizeof(XMLCHAR)); - CreateXMLStringR(d, lpszResult, nFormat); - lpszResult[cbStr]=_CXML('\0'); - if (pnSize) *pnSize = cbStr; - return lpszResult; -} - -int XMLNode::detachFromParent(XMLNodeData *d) -{ - XMLNode *pa=d->pParent->pChild; - int i=0; - while (((void*)(pa[i].d))!=((void*)d)) i++; - d->pParent->nChild--; - if (d->pParent->nChild) memmove(pa+i,pa+i+1,(d->pParent->nChild-i)*sizeof(XMLNode)); - else { free(pa); d->pParent->pChild=NULL; } - return removeOrderElement(d->pParent,eNodeChild,i); -} - -XMLNode::~XMLNode() -{ - if (!d) return; +XMLSTR XMLNode::createXMLString(int nFormat, int *pnSize) const { + if (!d) { + if (pnSize) *pnSize = 0; + return NULL; + } + + XMLSTR lpszResult = NULL; + int cbStr; + + // Recursively Calculate the size of the XML string + if (!dropWhiteSpace) nFormat = 0; + nFormat = nFormat ? 0 : -1; + cbStr = CreateXMLStringR(d, 0, nFormat); + // Alllocate memory for the XML string + the NULL terminator and + // create the recursively XML string. + lpszResult = (XMLSTR)malloc((cbStr + 1) * sizeof(XMLCHAR)); + CreateXMLStringR(d, lpszResult, nFormat); + lpszResult[cbStr] = _CXML('\0'); + if (pnSize) *pnSize = cbStr; + return lpszResult; +} + +int XMLNode::detachFromParent(XMLNodeData *d) { + XMLNode *pa = d->pParent->pChild; + int i = 0; + while (((void *)(pa[i].d)) != ((void *)d)) i++; + d->pParent->nChild--; + if (d->pParent->nChild) + memmove(pa + i, pa + i + 1, (d->pParent->nChild - i) * sizeof(XMLNode)); + else { + free(pa); + d->pParent->pChild = NULL; + } + return removeOrderElement(d->pParent, eNodeChild, i); +} + +XMLNode::~XMLNode() { + if (!d) return; + d->ref_count--; + emptyTheNode(0); +} +void XMLNode::deleteNodeContent() { + if (!d) return; + if (d->pParent) { + detachFromParent(d); + d->pParent = NULL; d->ref_count--; - emptyTheNode(0); + } + emptyTheNode(1); } -void XMLNode::deleteNodeContent() -{ - if (!d) return; - if (d->pParent) { detachFromParent(d); d->pParent=NULL; d->ref_count--; } - emptyTheNode(1); -} -void XMLNode::emptyTheNode(char force) -{ - XMLNodeData *dd=d; // warning: must stay this way! - if ((dd->ref_count==0)||force) - { - if (d->pParent) detachFromParent(d); - int i; - XMLNode *pc; - for(i=0; inChild; i++) - { - pc=dd->pChild+i; - pc->d->pParent=NULL; - pc->d->ref_count--; - pc->emptyTheNode(force); - } - myFree(dd->pChild); - for(i=0; inText; i++) free((void*)dd->pText[i]); - myFree(dd->pText); - for(i=0; inClear; i++) free((void*)dd->pClear[i].lpszValue); - myFree(dd->pClear); - for(i=0; inAttribute; i++) - { - free((void*)dd->pAttribute[i].lpszName); - if (dd->pAttribute[i].lpszValue) free((void*)dd->pAttribute[i].lpszValue); - } - myFree(dd->pAttribute); - myFree(dd->pOrder); - myFree((void*)dd->lpszName); - dd->nChild=0; dd->nText=0; dd->nClear=0; dd->nAttribute=0; - dd->pChild=NULL; dd->pText=NULL; dd->pClear=NULL; dd->pAttribute=NULL; - dd->pOrder=NULL; dd->lpszName=NULL; dd->pParent=NULL; - } - if (dd->ref_count==0) - { - free(dd); - d=NULL; - } -} - -XMLNode& XMLNode::operator=( const XMLNode& A ) -{ - // shallow copy - if (this != &A) - { - if (d) { d->ref_count--; emptyTheNode(0); } - d=A.d; - if (d) (d->ref_count) ++ ; +void XMLNode::emptyTheNode(char force) { + XMLNodeData *dd = d; // warning: must stay this way! + if ((dd->ref_count == 0) || force) { + if (d->pParent) detachFromParent(d); + int i; + XMLNode *pc; + for (i = 0; i < dd->nChild; i++) { + pc = dd->pChild + i; + pc->d->pParent = NULL; + pc->d->ref_count--; + pc->emptyTheNode(force); } - return *this; -} - -XMLNode::XMLNode(const XMLNode &A) -{ - // shallow copy - d=A.d; - if (d) (d->ref_count)++ ; -} - -XMLNode XMLNode::deepCopy() const -{ - if (!d) return XMLNode::emptyXMLNode; - XMLNode x(NULL,stringDup(d->lpszName),d->isDeclaration); - XMLNodeData *p=x.d; - int n=d->nAttribute; - if (n) - { - p->nAttribute=n; p->pAttribute=(XMLAttribute*)malloc(n*sizeof(XMLAttribute)); - while (n--) - { - p->pAttribute[n].lpszName=stringDup(d->pAttribute[n].lpszName); - p->pAttribute[n].lpszValue=stringDup(d->pAttribute[n].lpszValue); - } + myFree(dd->pChild); + for (i = 0; i < dd->nText; i++) free((void *)dd->pText[i]); + myFree(dd->pText); + for (i = 0; i < dd->nClear; i++) free((void *)dd->pClear[i].lpszValue); + myFree(dd->pClear); + for (i = 0; i < dd->nAttribute; i++) { + free((void *)dd->pAttribute[i].lpszName); + if (dd->pAttribute[i].lpszValue) + free((void *)dd->pAttribute[i].lpszValue); } - if (d->pOrder) - { - n=(d->nChild+d->nText+d->nClear)*sizeof(int); p->pOrder=(int*)malloc(n); memcpy(p->pOrder,d->pOrder,n); + myFree(dd->pAttribute); + myFree(dd->pOrder); + myFree((void *)dd->lpszName); + dd->nChild = 0; + dd->nText = 0; + dd->nClear = 0; + dd->nAttribute = 0; + dd->pChild = NULL; + dd->pText = NULL; + dd->pClear = NULL; + dd->pAttribute = NULL; + dd->pOrder = NULL; + dd->lpszName = NULL; + dd->pParent = NULL; + } + if (dd->ref_count == 0) { + free(dd); + d = NULL; + } +} + +XMLNode &XMLNode::operator=(const XMLNode &A) { + // shallow copy + if (this != &A) { + if (d) { + d->ref_count--; + emptyTheNode(0); } - n=d->nText; - if (n) - { - p->nText=n; p->pText=(XMLCSTR*)malloc(n*sizeof(XMLCSTR)); - while(n--) p->pText[n]=stringDup(d->pText[n]); + d = A.d; + if (d) (d->ref_count)++; + } + return *this; +} + +XMLNode::XMLNode(const XMLNode &A) { + // shallow copy + d = A.d; + if (d) (d->ref_count)++; +} + +XMLNode XMLNode::deepCopy() const { + if (!d) return XMLNode::emptyXMLNode; + XMLNode x(NULL, stringDup(d->lpszName), d->isDeclaration); + XMLNodeData *p = x.d; + int n = d->nAttribute; + if (n) { + p->nAttribute = n; + p->pAttribute = (XMLAttribute *)malloc(n * sizeof(XMLAttribute)); + while (n--) { + p->pAttribute[n].lpszName = stringDup(d->pAttribute[n].lpszName); + p->pAttribute[n].lpszValue = stringDup(d->pAttribute[n].lpszValue); } - n=d->nClear; - if (n) - { - p->nClear=n; p->pClear=(XMLClear*)malloc(n*sizeof(XMLClear)); - while (n--) - { - p->pClear[n].lpszCloseTag=d->pClear[n].lpszCloseTag; - p->pClear[n].lpszOpenTag=d->pClear[n].lpszOpenTag; - p->pClear[n].lpszValue=stringDup(d->pClear[n].lpszValue); - } + } + if (d->pOrder) { + n = (d->nChild + d->nText + d->nClear) * sizeof(int); + p->pOrder = (int *)malloc(n); + memcpy(p->pOrder, d->pOrder, n); + } + n = d->nText; + if (n) { + p->nText = n; + p->pText = (XMLCSTR *)malloc(n * sizeof(XMLCSTR)); + while (n--) p->pText[n] = stringDup(d->pText[n]); + } + n = d->nClear; + if (n) { + p->nClear = n; + p->pClear = (XMLClear *)malloc(n * sizeof(XMLClear)); + while (n--) { + p->pClear[n].lpszCloseTag = d->pClear[n].lpszCloseTag; + p->pClear[n].lpszOpenTag = d->pClear[n].lpszOpenTag; + p->pClear[n].lpszValue = stringDup(d->pClear[n].lpszValue); } - n=d->nChild; - if (n) - { - p->nChild=n; p->pChild=(XMLNode*)malloc(n*sizeof(XMLNode)); - while (n--) - { - p->pChild[n].d=NULL; - p->pChild[n]=d->pChild[n].deepCopy(); - p->pChild[n].d->pParent=p; - } + } + n = d->nChild; + if (n) { + p->nChild = n; + p->pChild = (XMLNode *)malloc(n * sizeof(XMLNode)); + while (n--) { + p->pChild[n].d = NULL; + p->pChild[n] = d->pChild[n].deepCopy(); + p->pChild[n].d->pParent = p; } - return x; -} - -XMLNode XMLNode::addChild(XMLNode childNode, int pos) -{ - XMLNodeData *dc=childNode.d; - if ((!dc)||(!d)) return childNode; - if (!dc->lpszName) - { - // this is a root node: todo: correct fix - int j=pos; - while (dc->nChild) - { - addChild(dc->pChild[0],j); - if (pos>=0) j++; - } - return childNode; + } + return x; +} + +XMLNode XMLNode::addChild(XMLNode childNode, int pos) { + XMLNodeData *dc = childNode.d; + if ((!dc) || (!d)) return childNode; + if (!dc->lpszName) { + // this is a root node: todo: correct fix + int j = pos; + while (dc->nChild) { + addChild(dc->pChild[0], j); + if (pos >= 0) j++; } - if (dc->pParent) { if ((detachFromParent(dc)<=pos)&&(dc->pParent==d)) pos--; } else dc->ref_count++; - dc->pParent=d; -// int nc=d->nChild; -// d->pChild=(XMLNode*)myRealloc(d->pChild,(nc+1),memoryIncrease,sizeof(XMLNode)); - d->pChild=(XMLNode*)addToOrder(0,&pos,d->nChild,d->pChild,sizeof(XMLNode),eNodeChild); - d->pChild[pos].d=dc; - d->nChild++; return childNode; -} - -void XMLNode::deleteAttribute(int i) -{ - if ((!d)||(i<0)||(i>=d->nAttribute)) return; - d->nAttribute--; - XMLAttribute *p=d->pAttribute+i; - free((void*)p->lpszName); - if (p->lpszValue) free((void*)p->lpszValue); - if (d->nAttribute) memmove(p,p+1,(d->nAttribute-i)*sizeof(XMLAttribute)); else { free(p); d->pAttribute=NULL; } -} - -void XMLNode::deleteAttribute(XMLAttribute *a){ if (a) deleteAttribute(a->lpszName); } -void XMLNode::deleteAttribute(XMLCSTR lpszName) -{ - int j=0; - getAttribute(lpszName,&j); - if (j) deleteAttribute(j-1); -} - -XMLAttribute *XMLNode::updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName,int i) -{ - if (!d) { if (lpszNewValue) free(lpszNewValue); if (lpszNewName) free(lpszNewName); return NULL; } - if (i>=d->nAttribute) - { - if (lpszNewName) return addAttribute_WOSD(lpszNewName,lpszNewValue); - return NULL; - } - XMLAttribute *p=d->pAttribute+i; - if (p->lpszValue&&p->lpszValue!=lpszNewValue) free((void*)p->lpszValue); - p->lpszValue=lpszNewValue; - if (lpszNewName&&p->lpszName!=lpszNewName) { free((void*)p->lpszName); p->lpszName=lpszNewName; }; - return p; -} - -XMLAttribute *XMLNode::updateAttribute_WOSD(XMLAttribute *newAttribute, XMLAttribute *oldAttribute) -{ - if (oldAttribute) return updateAttribute_WOSD((XMLSTR)newAttribute->lpszValue,(XMLSTR)newAttribute->lpszName,oldAttribute->lpszName); - return addAttribute_WOSD((XMLSTR)newAttribute->lpszName,(XMLSTR)newAttribute->lpszValue); -} - -XMLAttribute *XMLNode::updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName,XMLCSTR lpszOldName) -{ - int j=0; - getAttribute(lpszOldName,&j); - if (j) return updateAttribute_WOSD(lpszNewValue,lpszNewName,j-1); + } + if (dc->pParent) { + if ((detachFromParent(dc) <= pos) && (dc->pParent == d)) pos--; + } else + dc->ref_count++; + dc->pParent = d; + // int nc=d->nChild; + // d->pChild=(XMLNode*)myRealloc(d->pChild,(nc+1),memoryIncrease,sizeof(XMLNode)); + d->pChild = (XMLNode *)addToOrder(0, &pos, d->nChild, d->pChild, + sizeof(XMLNode), eNodeChild); + d->pChild[pos].d = dc; + d->nChild++; + return childNode; +} + +void XMLNode::deleteAttribute(int i) { + if ((!d) || (i < 0) || (i >= d->nAttribute)) return; + d->nAttribute--; + XMLAttribute *p = d->pAttribute + i; + free((void *)p->lpszName); + if (p->lpszValue) free((void *)p->lpszValue); + if (d->nAttribute) + memmove(p, p + 1, (d->nAttribute - i) * sizeof(XMLAttribute)); + else { + free(p); + d->pAttribute = NULL; + } +} + +void XMLNode::deleteAttribute(XMLAttribute *a) { + if (a) deleteAttribute(a->lpszName); +} +void XMLNode::deleteAttribute(XMLCSTR lpszName) { + int j = 0; + getAttribute(lpszName, &j); + if (j) deleteAttribute(j - 1); +} + +XMLAttribute *XMLNode::updateAttribute_WOSD(XMLSTR lpszNewValue, + XMLSTR lpszNewName, int i) { + if (!d) { + if (lpszNewValue) free(lpszNewValue); + if (lpszNewName) free(lpszNewName); + return NULL; + } + if (i >= d->nAttribute) { + if (lpszNewName) return addAttribute_WOSD(lpszNewName, lpszNewValue); + return NULL; + } + XMLAttribute *p = d->pAttribute + i; + if (p->lpszValue && p->lpszValue != lpszNewValue) free((void *)p->lpszValue); + p->lpszValue = lpszNewValue; + if (lpszNewName && p->lpszName != lpszNewName) { + free((void *)p->lpszName); + p->lpszName = lpszNewName; + }; + return p; +} + +XMLAttribute *XMLNode::updateAttribute_WOSD(XMLAttribute *newAttribute, + XMLAttribute *oldAttribute) { + if (oldAttribute) + return updateAttribute_WOSD((XMLSTR)newAttribute->lpszValue, + (XMLSTR)newAttribute->lpszName, + oldAttribute->lpszName); + return addAttribute_WOSD((XMLSTR)newAttribute->lpszName, + (XMLSTR)newAttribute->lpszValue); +} + +XMLAttribute *XMLNode::updateAttribute_WOSD(XMLSTR lpszNewValue, + XMLSTR lpszNewName, + XMLCSTR lpszOldName) { + int j = 0; + getAttribute(lpszOldName, &j); + if (j) + return updateAttribute_WOSD(lpszNewValue, lpszNewName, j - 1); + else { + if (lpszNewName) + return addAttribute_WOSD(lpszNewName, lpszNewValue); else - { - if (lpszNewName) return addAttribute_WOSD(lpszNewName,lpszNewValue); - else return addAttribute_WOSD(stringDup(lpszOldName),lpszNewValue); - } + return addAttribute_WOSD(stringDup(lpszOldName), lpszNewValue); + } } -int XMLNode::indexText(XMLCSTR lpszValue) const -{ - if (!d) return -1; - int i,l=d->nText; - if (!lpszValue) { if (l) return 0; return -1; } - XMLCSTR *p=d->pText; - for (i=0; inText; + if (!lpszValue) { + if (l) return 0; return -1; -} - -void XMLNode::deleteText(int i) -{ - if ((!d)||(i<0)||(i>=d->nText)) return; - d->nText--; - XMLCSTR *p=d->pText+i; - free((void*)*p); - if (d->nText) memmove(p,p+1,(d->nText-i)*sizeof(XMLCSTR)); else { free(p); d->pText=NULL; } - removeOrderElement(d,eNodeText,i); -} - -void XMLNode::deleteText(XMLCSTR lpszValue) { deleteText(indexText(lpszValue)); } - -XMLCSTR XMLNode::updateText_WOSD(XMLSTR lpszNewValue, int i) -{ - if (!d) { if (lpszNewValue) free(lpszNewValue); return NULL; } - if (i>=d->nText) return addText_WOSD(lpszNewValue); - XMLCSTR *p=d->pText+i; - if (*p!=lpszNewValue) { free((void*)*p); *p=lpszNewValue; } - return lpszNewValue; -} - -XMLCSTR XMLNode::updateText_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue) -{ - if (!d) { if (lpszNewValue) free(lpszNewValue); return NULL; } - int i=indexText(lpszOldValue); - if (i>=0) return updateText_WOSD(lpszNewValue,i); - return addText_WOSD(lpszNewValue); -} - -void XMLNode::deleteClear(int i) -{ - if ((!d)||(i<0)||(i>=d->nClear)) return; - d->nClear--; - XMLClear *p=d->pClear+i; - free((void*)p->lpszValue); - if (d->nClear) memmove(p,p+1,(d->nClear-i)*sizeof(XMLClear)); else { free(p); d->pClear=NULL; } - removeOrderElement(d,eNodeClear,i); -} - -int XMLNode::indexClear(XMLCSTR lpszValue) const -{ - if (!d) return -1; - int i,l=d->nClear; - if (!lpszValue) { if (l) return 0; return -1; } - XMLClear *p=d->pClear; - for (i=0; ipText; + for (i = 0; i < l; i++) + if (lpszValue == p[i]) return i; + return -1; +} + +void XMLNode::deleteText(int i) { + if ((!d) || (i < 0) || (i >= d->nText)) return; + d->nText--; + XMLCSTR *p = d->pText + i; + free((void *)*p); + if (d->nText) + memmove(p, p + 1, (d->nText - i) * sizeof(XMLCSTR)); + else { + free(p); + d->pText = NULL; + } + removeOrderElement(d, eNodeText, i); +} + +void XMLNode::deleteText(XMLCSTR lpszValue) { + deleteText(indexText(lpszValue)); +} + +XMLCSTR XMLNode::updateText_WOSD(XMLSTR lpszNewValue, int i) { + if (!d) { + if (lpszNewValue) free(lpszNewValue); + return NULL; + } + if (i >= d->nText) return addText_WOSD(lpszNewValue); + XMLCSTR *p = d->pText + i; + if (*p != lpszNewValue) { + free((void *)*p); + *p = lpszNewValue; + } + return lpszNewValue; +} + +XMLCSTR XMLNode::updateText_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue) { + if (!d) { + if (lpszNewValue) free(lpszNewValue); + return NULL; + } + int i = indexText(lpszOldValue); + if (i >= 0) return updateText_WOSD(lpszNewValue, i); + return addText_WOSD(lpszNewValue); +} + +void XMLNode::deleteClear(int i) { + if ((!d) || (i < 0) || (i >= d->nClear)) return; + d->nClear--; + XMLClear *p = d->pClear + i; + free((void *)p->lpszValue); + if (d->nClear) + memmove(p, p + 1, (d->nClear - i) * sizeof(XMLClear)); + else { + free(p); + d->pClear = NULL; + } + removeOrderElement(d, eNodeClear, i); +} + +int XMLNode::indexClear(XMLCSTR lpszValue) const { + if (!d) return -1; + int i, l = d->nClear; + if (!lpszValue) { + if (l) return 0; return -1; + } + XMLClear *p = d->pClear; + for (i = 0; i < l; i++) + if (lpszValue == p[i].lpszValue) return i; + return -1; } -void XMLNode::deleteClear(XMLCSTR lpszValue) { deleteClear(indexClear(lpszValue)); } -void XMLNode::deleteClear(XMLClear *a) { if (a) deleteClear(a->lpszValue); } - -XMLClear *XMLNode::updateClear_WOSD(XMLSTR lpszNewContent, int i) -{ - if (!d) { if (lpszNewContent) free(lpszNewContent); return NULL; } - if (i>=d->nClear) return addClear_WOSD(lpszNewContent); - XMLClear *p=d->pClear+i; - if (lpszNewContent!=p->lpszValue) { free((void*)p->lpszValue); p->lpszValue=lpszNewContent; } - return p; +void XMLNode::deleteClear(XMLCSTR lpszValue) { + deleteClear(indexClear(lpszValue)); } - -XMLClear *XMLNode::updateClear_WOSD(XMLSTR lpszNewContent, XMLCSTR lpszOldValue) -{ - if (!d) { if (lpszNewContent) free(lpszNewContent); return NULL; } - int i=indexClear(lpszOldValue); - if (i>=0) return updateClear_WOSD(lpszNewContent,i); - return addClear_WOSD(lpszNewContent); +void XMLNode::deleteClear(XMLClear *a) { + if (a) deleteClear(a->lpszValue); } -XMLClear *XMLNode::updateClear_WOSD(XMLClear *newP,XMLClear *oldP) -{ - if (oldP) return updateClear_WOSD((XMLSTR)newP->lpszValue,(XMLSTR)oldP->lpszValue); +XMLClear *XMLNode::updateClear_WOSD(XMLSTR lpszNewContent, int i) { + if (!d) { + if (lpszNewContent) free(lpszNewContent); return NULL; -} - -int XMLNode::nChildNode(XMLCSTR name) const -{ - if (!d) return 0; - int i,j=0,n=d->nChild; - XMLNode *pc=d->pChild; - for (i=0; id->lpszName, name)==0) j++; - pc++; + } + if (i >= d->nClear) return addClear_WOSD(lpszNewContent); + XMLClear *p = d->pClear + i; + if (lpszNewContent != p->lpszValue) { + free((void *)p->lpszValue); + p->lpszValue = lpszNewContent; + } + return p; +} + +XMLClear *XMLNode::updateClear_WOSD(XMLSTR lpszNewContent, + XMLCSTR lpszOldValue) { + if (!d) { + if (lpszNewContent) free(lpszNewContent); + return NULL; + } + int i = indexClear(lpszOldValue); + if (i >= 0) return updateClear_WOSD(lpszNewContent, i); + return addClear_WOSD(lpszNewContent); +} + +XMLClear *XMLNode::updateClear_WOSD(XMLClear *newP, XMLClear *oldP) { + if (oldP) + return updateClear_WOSD((XMLSTR)newP->lpszValue, (XMLSTR)oldP->lpszValue); + return NULL; +} + +int XMLNode::nChildNode(XMLCSTR name) const { + if (!d) return 0; + int i, j = 0, n = d->nChild; + XMLNode *pc = d->pChild; + for (i = 0; i < n; i++) { + if (xstricmp(pc->d->lpszName, name) == 0) j++; + pc++; + } + return j; +} + +XMLNode XMLNode::getChildNode(XMLCSTR name, int *j) const { + if (!d) return emptyXMLNode; + int i = 0, n = d->nChild; + if (j) i = *j; + XMLNode *pc = d->pChild + i; + for (; i < n; i++) { + if (!xstricmp(pc->d->lpszName, name)) { + if (j) *j = i + 1; + return *pc; } - return j; -} - -XMLNode XMLNode::getChildNode(XMLCSTR name, int *j) const -{ - if (!d) return emptyXMLNode; - int i=0,n=d->nChild; - if (j) i=*j; - XMLNode *pc=d->pChild+i; - for (; id->lpszName, name)) - { - if (j) *j=i+1; - return *pc; - } - pc++; + pc++; + } + return emptyXMLNode; +} + +XMLNode XMLNode::getChildNode(XMLCSTR name, int j) const { + if (!d) return emptyXMLNode; + if (j >= 0) { + int i = 0; + while (j-- > 0) getChildNode(name, &i); + return getChildNode(name, &i); + } + int i = d->nChild; + while (i--) + if (!xstricmp(name, d->pChild[i].d->lpszName)) break; + if (i < 0) return emptyXMLNode; + return getChildNode(i); +} + +XMLNode XMLNode::getChildNodeByPath(XMLCSTR _path, char createMissing, + XMLCHAR sep) { + XMLSTR path = stringDup(_path); + XMLNode x = getChildNodeByPathNonConst(path, createMissing, sep); + if (path) free(path); + return x; +} + +XMLNode XMLNode::getChildNodeByPathNonConst(XMLSTR path, char createIfMissing, + XMLCHAR sep) { + if ((!path) || (!(*path))) return *this; + XMLNode xn, xbase = *this; + XMLCHAR *tend1, sepString[2]; + sepString[0] = sep; + sepString[1] = 0; + tend1 = xstrstr(path, sepString); + while (tend1) { + *tend1 = 0; + xn = xbase.getChildNode(path); + if (xn.isEmpty()) { + if (createIfMissing) + xn = xbase.addChild(path); + else { + *tend1 = sep; + return XMLNode::emptyXMLNode; + } } - return emptyXMLNode; -} - -XMLNode XMLNode::getChildNode(XMLCSTR name, int j) const -{ - if (!d) return emptyXMLNode; - if (j>=0) - { - int i=0; - while (j-->0) getChildNode(name,&i); - return getChildNode(name,&i); + *tend1 = sep; + xbase = xn; + path = tend1 + 1; + tend1 = xstrstr(path, sepString); + } + xn = xbase.getChildNode(path); + if (xn.isEmpty() && createIfMissing) xn = xbase.addChild(path); + return xn; +} + +XMLElementPosition XMLNode::positionOfText(int i) const { + if (i >= d->nText) i = d->nText - 1; + return findPosition(d, i, eNodeText); +} +XMLElementPosition XMLNode::positionOfClear(int i) const { + if (i >= d->nClear) i = d->nClear - 1; + return findPosition(d, i, eNodeClear); +} +XMLElementPosition XMLNode::positionOfChildNode(int i) const { + if (i >= d->nChild) i = d->nChild - 1; + return findPosition(d, i, eNodeChild); +} +XMLElementPosition XMLNode::positionOfText(XMLCSTR lpszValue) const { + return positionOfText(indexText(lpszValue)); +} +XMLElementPosition XMLNode::positionOfClear(XMLCSTR lpszValue) const { + return positionOfClear(indexClear(lpszValue)); +} +XMLElementPosition XMLNode::positionOfClear(XMLClear *a) const { + if (a) return positionOfClear(a->lpszValue); + return positionOfClear(); +} +XMLElementPosition XMLNode::positionOfChildNode(XMLNode x) const { + if ((!d) || (!x.d)) return -1; + XMLNodeData *dd = x.d; + XMLNode *pc = d->pChild; + int i = d->nChild; + while (i--) + if (pc[i].d == dd) return findPosition(d, i, eNodeChild); + return -1; +} +XMLElementPosition XMLNode::positionOfChildNode(XMLCSTR name, int count) const { + if (!name) return positionOfChildNode(count); + int j = 0; + do { + getChildNode(name, &j); + if (j < 0) return -1; + } while (count--); + return findPosition(d, j - 1, eNodeChild); +} + +XMLNode XMLNode::getChildNodeWithAttribute(XMLCSTR name, XMLCSTR attributeName, + XMLCSTR attributeValue, + int *k) const { + int i = 0, j; + if (k) i = *k; + XMLNode x; + XMLCSTR t; + do { + x = getChildNode(name, &i); + if (!x.isEmpty()) { + if (attributeValue) { + j = 0; + do { + t = x.getAttribute(attributeName, &j); + if (t && (xstricmp(attributeValue, t) == 0)) { + if (k) *k = i; + return x; + } + } while (t); + } else { + if (x.isAttributeSet(attributeName)) { + if (k) *k = i; + return x; + } + } } - int i=d->nChild; - while (i--) if (!xstricmp(name,d->pChild[i].d->lpszName)) break; - if (i<0) return emptyXMLNode; - return getChildNode(i); -} - -XMLNode XMLNode::getChildNodeByPath(XMLCSTR _path, char createMissing, XMLCHAR sep) -{ - XMLSTR path=stringDup(_path); - XMLNode x=getChildNodeByPathNonConst(path,createMissing,sep); - if (path) free(path); - return x; -} - -XMLNode XMLNode::getChildNodeByPathNonConst(XMLSTR path, char createIfMissing, XMLCHAR sep) -{ - if ((!path)||(!(*path))) return *this; - XMLNode xn,xbase=*this; - XMLCHAR *tend1,sepString[2]; sepString[0]=sep; sepString[1]=0; - tend1=xstrstr(path,sepString); - while(tend1) - { - *tend1=0; - xn=xbase.getChildNode(path); - if (xn.isEmpty()) - { - if (createIfMissing) xn=xbase.addChild(path); - else { *tend1=sep; return XMLNode::emptyXMLNode; } - } - *tend1=sep; - xbase=xn; - path=tend1+1; - tend1=xstrstr(path,sepString); - } - xn=xbase.getChildNode(path); - if (xn.isEmpty()&&createIfMissing) xn=xbase.addChild(path); - return xn; -} - -XMLElementPosition XMLNode::positionOfText (int i) const { if (i>=d->nText ) i=d->nText-1; return findPosition(d,i,eNodeText ); } -XMLElementPosition XMLNode::positionOfClear (int i) const { if (i>=d->nClear) i=d->nClear-1; return findPosition(d,i,eNodeClear); } -XMLElementPosition XMLNode::positionOfChildNode(int i) const { if (i>=d->nChild) i=d->nChild-1; return findPosition(d,i,eNodeChild); } -XMLElementPosition XMLNode::positionOfText (XMLCSTR lpszValue) const { return positionOfText (indexText (lpszValue)); } -XMLElementPosition XMLNode::positionOfClear(XMLCSTR lpszValue) const { return positionOfClear(indexClear(lpszValue)); } -XMLElementPosition XMLNode::positionOfClear(XMLClear *a) const { if (a) return positionOfClear(a->lpszValue); return positionOfClear(); } -XMLElementPosition XMLNode::positionOfChildNode(XMLNode x) const -{ - if ((!d)||(!x.d)) return -1; - XMLNodeData *dd=x.d; - XMLNode *pc=d->pChild; - int i=d->nChild; - while (i--) if (pc[i].d==dd) return findPosition(d,i,eNodeChild); - return -1; -} -XMLElementPosition XMLNode::positionOfChildNode(XMLCSTR name, int count) const -{ - if (!name) return positionOfChildNode(count); - int j=0; - do { getChildNode(name,&j); if (j<0) return -1; } while (count--); - return findPosition(d,j-1,eNodeChild); -} - -XMLNode XMLNode::getChildNodeWithAttribute(XMLCSTR name,XMLCSTR attributeName,XMLCSTR attributeValue, int *k) const -{ - int i=0,j; - if (k) i=*k; - XMLNode x; - XMLCSTR t; - do - { - x=getChildNode(name,&i); - if (!x.isEmpty()) - { - if (attributeValue) - { - j=0; - do - { - t=x.getAttribute(attributeName,&j); - if (t&&(xstricmp(attributeValue,t)==0)) { if (k) *k=i; return x; } - } while (t); - } else - { - if (x.isAttributeSet(attributeName)) { if (k) *k=i; return x; } - } - } - } while (!x.isEmpty()); - return emptyXMLNode; + } while (!x.isEmpty()); + return emptyXMLNode; } // Find an attribute on an node. -XMLCSTR XMLNode::getAttribute(XMLCSTR lpszAttrib, int *j) const -{ - if (!d) return NULL; - int i=0,n=d->nAttribute; - if (j) i=*j; - XMLAttribute *pAttr=d->pAttribute+i; - for (; ilpszName, lpszAttrib)==0) - { - if (j) *j=i+1; - return pAttr->lpszValue; - } - pAttr++; +XMLCSTR XMLNode::getAttribute(XMLCSTR lpszAttrib, int *j) const { + if (!d) return NULL; + int i = 0, n = d->nAttribute; + if (j) i = *j; + XMLAttribute *pAttr = d->pAttribute + i; + for (; i < n; i++) { + if (xstricmp(pAttr->lpszName, lpszAttrib) == 0) { + if (j) *j = i + 1; + return pAttr->lpszValue; } - return NULL; -} - -char XMLNode::isAttributeSet(XMLCSTR lpszAttrib) const -{ - if (!d) return FALSE; - int i,n=d->nAttribute; - XMLAttribute *pAttr=d->pAttribute; - for (i=0; ilpszName, lpszAttrib)==0) - { - return TRUE; - } - pAttr++; + pAttr++; + } + return NULL; +} + +char XMLNode::isAttributeSet(XMLCSTR lpszAttrib) const { + if (!d) return FALSE; + int i, n = d->nAttribute; + XMLAttribute *pAttr = d->pAttribute; + for (i = 0; i < n; i++) { + if (xstricmp(pAttr->lpszName, lpszAttrib) == 0) { + return TRUE; } - return FALSE; + pAttr++; + } + return FALSE; } -XMLCSTR XMLNode::getAttribute(XMLCSTR name, int j) const -{ - if (!d) return NULL; - int i=0; - while (j-->0) getAttribute(name,&i); - return getAttribute(name,&i); +XMLCSTR XMLNode::getAttribute(XMLCSTR name, int j) const { + if (!d) return NULL; + int i = 0; + while (j-- > 0) getAttribute(name, &i); + return getAttribute(name, &i); } -XMLNodeContents XMLNode::enumContents(int i) const -{ - XMLNodeContents c; - if (!d) { c.etype=eNodeNULL; return c; } - if (inAttribute) - { - c.etype=eNodeAttribute; - c.attrib=d->pAttribute[i]; - return c; - } - i-=d->nAttribute; - c.etype=(XMLElementType)(d->pOrder[i]&3); - i=(d->pOrder[i])>>2; - switch (c.etype) - { - case eNodeChild: c.child = d->pChild[i]; break; - case eNodeText: c.text = d->pText[i]; break; - case eNodeClear: c.clear = d->pClear[i]; break; - default: break; - } +XMLNodeContents XMLNode::enumContents(int i) const { + XMLNodeContents c; + if (!d) { + c.etype = eNodeNULL; return c; + } + if (i < d->nAttribute) { + c.etype = eNodeAttribute; + c.attrib = d->pAttribute[i]; + return c; + } + i -= d->nAttribute; + c.etype = (XMLElementType)(d->pOrder[i] & 3); + i = (d->pOrder[i]) >> 2; + switch (c.etype) { + case eNodeChild: + c.child = d->pChild[i]; + break; + case eNodeText: + c.text = d->pText[i]; + break; + case eNodeClear: + c.clear = d->pClear[i]; + break; + default: + break; + } + return c; +} + +XMLCSTR XMLNode::getName() const { + if (!d) return NULL; + return d->lpszName; +} +int XMLNode::nText() const { + if (!d) return 0; + return d->nText; +} +int XMLNode::nChildNode() const { + if (!d) return 0; + return d->nChild; +} +int XMLNode::nAttribute() const { + if (!d) return 0; + return d->nAttribute; +} +int XMLNode::nClear() const { + if (!d) return 0; + return d->nClear; +} +int XMLNode::nElement() const { + if (!d) return 0; + return d->nAttribute + d->nChild + d->nText + d->nClear; +} +XMLClear XMLNode::getClear(int i) const { + if ((!d) || (i >= d->nClear)) return emptyXMLClear; + return d->pClear[i]; +} +XMLAttribute XMLNode::getAttribute(int i) const { + if ((!d) || (i >= d->nAttribute)) return emptyXMLAttribute; + return d->pAttribute[i]; +} +XMLCSTR XMLNode::getAttributeName(int i) const { + if ((!d) || (i >= d->nAttribute)) return NULL; + return d->pAttribute[i].lpszName; +} +XMLCSTR XMLNode::getAttributeValue(int i) const { + if ((!d) || (i >= d->nAttribute)) return NULL; + return d->pAttribute[i].lpszValue; +} +XMLCSTR XMLNode::getText(int i) const { + if ((!d) || (i >= d->nText)) return NULL; + return d->pText[i]; +} +XMLNode XMLNode::getChildNode(int i) const { + if ((!d) || (i >= d->nChild)) return emptyXMLNode; + return d->pChild[i]; +} +XMLNode XMLNode::getParentNode() const { + if ((!d) || (!d->pParent)) return emptyXMLNode; + return XMLNode(d->pParent); +} +char XMLNode::isDeclaration() const { + if (!d) return 0; + return d->isDeclaration; +} +char XMLNode::isEmpty() const { return (d == NULL); } +XMLNode XMLNode::emptyNode() { return XMLNode::emptyXMLNode; } + +XMLNode XMLNode::addChild(XMLCSTR lpszName, char isDeclaration, + XMLElementPosition pos) { + return addChild_priv(0, stringDup(lpszName), isDeclaration, pos); +} +XMLNode XMLNode::addChild_WOSD(XMLSTR lpszName, char isDeclaration, + XMLElementPosition pos) { + return addChild_priv(0, lpszName, isDeclaration, pos); +} +XMLAttribute *XMLNode::addAttribute(XMLCSTR lpszName, XMLCSTR lpszValue) { + return addAttribute_priv(0, stringDup(lpszName), stringDup(lpszValue)); +} +XMLAttribute *XMLNode::addAttribute_WOSD(XMLSTR lpszName, XMLSTR lpszValuev) { + return addAttribute_priv(0, lpszName, lpszValuev); +} +XMLCSTR XMLNode::addText(XMLCSTR lpszValue, XMLElementPosition pos) { + return addText_priv(0, stringDup(lpszValue), pos); +} +XMLCSTR XMLNode::addText_WOSD(XMLSTR lpszValue, XMLElementPosition pos) { + return addText_priv(0, lpszValue, pos); +} +XMLClear *XMLNode::addClear(XMLCSTR lpszValue, XMLCSTR lpszOpen, + XMLCSTR lpszClose, XMLElementPosition pos) { + return addClear_priv(0, stringDup(lpszValue), lpszOpen, lpszClose, pos); +} +XMLClear *XMLNode::addClear_WOSD(XMLSTR lpszValue, XMLCSTR lpszOpen, + XMLCSTR lpszClose, XMLElementPosition pos) { + return addClear_priv(0, lpszValue, lpszOpen, lpszClose, pos); +} +XMLCSTR XMLNode::updateName(XMLCSTR lpszName) { + return updateName_WOSD(stringDup(lpszName)); +} +XMLAttribute *XMLNode::updateAttribute(XMLAttribute *newAttribute, + XMLAttribute *oldAttribute) { + return updateAttribute_WOSD(stringDup(newAttribute->lpszValue), + stringDup(newAttribute->lpszName), + oldAttribute->lpszName); +} +XMLAttribute *XMLNode::updateAttribute(XMLCSTR lpszNewValue, + XMLCSTR lpszNewName, int i) { + return updateAttribute_WOSD(stringDup(lpszNewValue), stringDup(lpszNewName), + i); +} +XMLAttribute *XMLNode::updateAttribute(XMLCSTR lpszNewValue, + XMLCSTR lpszNewName, + XMLCSTR lpszOldName) { + return updateAttribute_WOSD(stringDup(lpszNewValue), stringDup(lpszNewName), + lpszOldName); +} +XMLCSTR XMLNode::updateText(XMLCSTR lpszNewValue, int i) { + return updateText_WOSD(stringDup(lpszNewValue), i); +} +XMLCSTR XMLNode::updateText(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue) { + return updateText_WOSD(stringDup(lpszNewValue), lpszOldValue); +} +XMLClear *XMLNode::updateClear(XMLCSTR lpszNewContent, int i) { + return updateClear_WOSD(stringDup(lpszNewContent), i); +} +XMLClear *XMLNode::updateClear(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue) { + return updateClear_WOSD(stringDup(lpszNewValue), lpszOldValue); +} +XMLClear *XMLNode::updateClear(XMLClear *newP, XMLClear *oldP) { + return updateClear_WOSD(stringDup(newP->lpszValue), oldP->lpszValue); } -XMLCSTR XMLNode::getName() const { if (!d) return NULL; return d->lpszName; } -int XMLNode::nText() const { if (!d) return 0; return d->nText; } -int XMLNode::nChildNode() const { if (!d) return 0; return d->nChild; } -int XMLNode::nAttribute() const { if (!d) return 0; return d->nAttribute; } -int XMLNode::nClear() const { if (!d) return 0; return d->nClear; } -int XMLNode::nElement() const { if (!d) return 0; return d->nAttribute+d->nChild+d->nText+d->nClear; } -XMLClear XMLNode::getClear (int i) const { if ((!d)||(i>=d->nClear )) return emptyXMLClear; return d->pClear[i]; } -XMLAttribute XMLNode::getAttribute (int i) const { if ((!d)||(i>=d->nAttribute)) return emptyXMLAttribute; return d->pAttribute[i]; } -XMLCSTR XMLNode::getAttributeName (int i) const { if ((!d)||(i>=d->nAttribute)) return NULL; return d->pAttribute[i].lpszName; } -XMLCSTR XMLNode::getAttributeValue(int i) const { if ((!d)||(i>=d->nAttribute)) return NULL; return d->pAttribute[i].lpszValue; } -XMLCSTR XMLNode::getText (int i) const { if ((!d)||(i>=d->nText )) return NULL; return d->pText[i]; } -XMLNode XMLNode::getChildNode (int i) const { if ((!d)||(i>=d->nChild )) return emptyXMLNode; return d->pChild[i]; } -XMLNode XMLNode::getParentNode ( ) const { if ((!d)||(!d->pParent )) return emptyXMLNode; return XMLNode(d->pParent); } -char XMLNode::isDeclaration ( ) const { if (!d) return 0; return d->isDeclaration; } -char XMLNode::isEmpty ( ) const { return (d==NULL); } -XMLNode XMLNode::emptyNode ( ) { return XMLNode::emptyXMLNode; } - -XMLNode XMLNode::addChild(XMLCSTR lpszName, char isDeclaration, XMLElementPosition pos) - { return addChild_priv(0,stringDup(lpszName),isDeclaration,pos); } -XMLNode XMLNode::addChild_WOSD(XMLSTR lpszName, char isDeclaration, XMLElementPosition pos) - { return addChild_priv(0,lpszName,isDeclaration,pos); } -XMLAttribute *XMLNode::addAttribute(XMLCSTR lpszName, XMLCSTR lpszValue) - { return addAttribute_priv(0,stringDup(lpszName),stringDup(lpszValue)); } -XMLAttribute *XMLNode::addAttribute_WOSD(XMLSTR lpszName, XMLSTR lpszValuev) - { return addAttribute_priv(0,lpszName,lpszValuev); } -XMLCSTR XMLNode::addText(XMLCSTR lpszValue, XMLElementPosition pos) - { return addText_priv(0,stringDup(lpszValue),pos); } -XMLCSTR XMLNode::addText_WOSD(XMLSTR lpszValue, XMLElementPosition pos) - { return addText_priv(0,lpszValue,pos); } -XMLClear *XMLNode::addClear(XMLCSTR lpszValue, XMLCSTR lpszOpen, XMLCSTR lpszClose, XMLElementPosition pos) - { return addClear_priv(0,stringDup(lpszValue),lpszOpen,lpszClose,pos); } -XMLClear *XMLNode::addClear_WOSD(XMLSTR lpszValue, XMLCSTR lpszOpen, XMLCSTR lpszClose, XMLElementPosition pos) - { return addClear_priv(0,lpszValue,lpszOpen,lpszClose,pos); } -XMLCSTR XMLNode::updateName(XMLCSTR lpszName) - { return updateName_WOSD(stringDup(lpszName)); } -XMLAttribute *XMLNode::updateAttribute(XMLAttribute *newAttribute, XMLAttribute *oldAttribute) - { return updateAttribute_WOSD(stringDup(newAttribute->lpszValue),stringDup(newAttribute->lpszName),oldAttribute->lpszName); } -XMLAttribute *XMLNode::updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,int i) - { return updateAttribute_WOSD(stringDup(lpszNewValue),stringDup(lpszNewName),i); } -XMLAttribute *XMLNode::updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,XMLCSTR lpszOldName) - { return updateAttribute_WOSD(stringDup(lpszNewValue),stringDup(lpszNewName),lpszOldName); } -XMLCSTR XMLNode::updateText(XMLCSTR lpszNewValue, int i) - { return updateText_WOSD(stringDup(lpszNewValue),i); } -XMLCSTR XMLNode::updateText(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue) - { return updateText_WOSD(stringDup(lpszNewValue),lpszOldValue); } -XMLClear *XMLNode::updateClear(XMLCSTR lpszNewContent, int i) - { return updateClear_WOSD(stringDup(lpszNewContent),i); } -XMLClear *XMLNode::updateClear(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue) - { return updateClear_WOSD(stringDup(lpszNewValue),lpszOldValue); } -XMLClear *XMLNode::updateClear(XMLClear *newP,XMLClear *oldP) - { return updateClear_WOSD(stringDup(newP->lpszValue),oldP->lpszValue); } - -char XMLNode::setGlobalOptions(XMLCharEncoding _characterEncoding, char _guessWideCharChars, - char _dropWhiteSpace, char _removeCommentsInMiddleOfText) -{ - guessWideCharChars=_guessWideCharChars; dropWhiteSpace=_dropWhiteSpace; removeCommentsInMiddleOfText=_removeCommentsInMiddleOfText; +char XMLNode::setGlobalOptions(XMLCharEncoding _characterEncoding, + char _guessWideCharChars, char _dropWhiteSpace, + char _removeCommentsInMiddleOfText) { + guessWideCharChars = _guessWideCharChars; + dropWhiteSpace = _dropWhiteSpace; + removeCommentsInMiddleOfText = _removeCommentsInMiddleOfText; #ifdef _XMLWIDECHAR - if (_characterEncoding) characterEncoding=_characterEncoding; + if (_characterEncoding) characterEncoding = _characterEncoding; #else - switch(_characterEncoding) - { - case char_encoding_UTF8: characterEncoding=_characterEncoding; XML_ByteTable=XML_utf8ByteTable; break; - case char_encoding_legacy: characterEncoding=_characterEncoding; XML_ByteTable=XML_legacyByteTable; break; - case char_encoding_ShiftJIS: characterEncoding=_characterEncoding; XML_ByteTable=XML_sjisByteTable; break; - case char_encoding_GB2312: characterEncoding=_characterEncoding; XML_ByteTable=XML_gb2312ByteTable; break; + switch (_characterEncoding) { + case char_encoding_UTF8: + characterEncoding = _characterEncoding; + XML_ByteTable = XML_utf8ByteTable; + break; + case char_encoding_legacy: + characterEncoding = _characterEncoding; + XML_ByteTable = XML_legacyByteTable; + break; + case char_encoding_ShiftJIS: + characterEncoding = _characterEncoding; + XML_ByteTable = XML_sjisByteTable; + break; + case char_encoding_GB2312: + characterEncoding = _characterEncoding; + XML_ByteTable = XML_gb2312ByteTable; + break; case char_encoding_Big5: - case char_encoding_GBK: characterEncoding=_characterEncoding; XML_ByteTable=XML_gbk_big5_ByteTable; break; - default: return 1; - } + case char_encoding_GBK: + characterEncoding = _characterEncoding; + XML_ByteTable = XML_gbk_big5_ByteTable; + break; + default: + return 1; + } #endif - return 0; + return 0; } -XMLNode::XMLCharEncoding XMLNode::guessCharEncoding(void *buf,int l, char useXMLEncodingAttribute) -{ +XMLNode::XMLCharEncoding XMLNode::guessCharEncoding( + void *buf, int l, char useXMLEncodingAttribute) { #ifdef _XMLWIDECHAR - return (XMLCharEncoding)0; + return (XMLCharEncoding)0; #else - if (l<25) return (XMLCharEncoding)0; - if (guessWideCharChars&&(myIsTextWideChar(buf,l))) return (XMLCharEncoding)0; - unsigned char *b=(unsigned char*)buf; - if ((b[0]==0xef)&&(b[1]==0xbb)&&(b[2]==0xbf)) return char_encoding_UTF8; - - // Match utf-8 model ? - XMLCharEncoding bestGuess=char_encoding_UTF8; - int i=0; - while (i>2 ]; - *(curr++)=base64EncodeTable[(inbuf[0]<<4)&0x3F]; - *(curr++)=base64Fillchar; - *(curr++)=base64Fillchar; - } else if (eLen==2) - { - j=(inbuf[0]<<8)|inbuf[1]; - *(curr++)=base64EncodeTable[ j>>10 ]; - *(curr++)=base64EncodeTable[(j>> 4)&0x3f]; - *(curr++)=base64EncodeTable[(j<< 2)&0x3f]; - *(curr++)=base64Fillchar; +XMLParserBase64Tool::~XMLParserBase64Tool() { freeBuffer(); } + +void XMLParserBase64Tool::freeBuffer() { + if (buf) free(buf); + buf = NULL; + buflen = 0; +} + +int XMLParserBase64Tool::encodeLength(int inlen, char formatted) { + unsigned int i = ((inlen - 1) / 3 * 4 + 4 + 1); + if (formatted) i += inlen / 54; + return i; +} + +XMLSTR XMLParserBase64Tool::encode(unsigned char *inbuf, unsigned int inlen, + char formatted) { + int i = encodeLength(inlen, formatted), k = 17, eLen = inlen / 3, j; + alloc(i * sizeof(XMLCHAR)); + XMLSTR curr = (XMLSTR)buf; + for (i = 0; i < eLen; i++) { + // Copy next three bytes into lower 24 bits of int, paying attention to + // sign. + j = (inbuf[0] << 16) | (inbuf[1] << 8) | inbuf[2]; + inbuf += 3; + // Encode the int into four chars + *(curr++) = base64EncodeTable[j >> 18]; + *(curr++) = base64EncodeTable[(j >> 12) & 0x3f]; + *(curr++) = base64EncodeTable[(j >> 6) & 0x3f]; + *(curr++) = base64EncodeTable[(j)&0x3f]; + if (formatted) { + if (!k) { + *(curr++) = _CXML('\n'); + k = 18; + } + k--; } - *(curr++)=0; - return (XMLSTR)buf; -} - -unsigned int XMLParserBase64Tool::decodeSize(XMLCSTR data,XMLError *xe) -{ - if (xe) *xe=eXMLErrorNone; - int size=0; - unsigned char c; - //skip any extra characters (e.g. newlines or spaces) - while (*data) - { + } + eLen = inlen - eLen * 3; // 0 - 2. + if (eLen == 1) { + *(curr++) = base64EncodeTable[inbuf[0] >> 2]; + *(curr++) = base64EncodeTable[(inbuf[0] << 4) & 0x3F]; + *(curr++) = base64Fillchar; + *(curr++) = base64Fillchar; + } else if (eLen == 2) { + j = (inbuf[0] << 8) | inbuf[1]; + *(curr++) = base64EncodeTable[j >> 10]; + *(curr++) = base64EncodeTable[(j >> 4) & 0x3f]; + *(curr++) = base64EncodeTable[(j << 2) & 0x3f]; + *(curr++) = base64Fillchar; + } + *(curr++) = 0; + return (XMLSTR)buf; +} + +unsigned int XMLParserBase64Tool::decodeSize(XMLCSTR data, XMLError *xe) { + if (xe) *xe = eXMLErrorNone; + int size = 0; + unsigned char c; + // skip any extra characters (e.g. newlines or spaces) + while (*data) { #ifdef _XMLWIDECHAR - if (*data>255) { if (xe) *xe=eXMLErrorBase64DecodeIllegalCharacter; return 0; } + if (*data > 255) { + if (xe) *xe = eXMLErrorBase64DecodeIllegalCharacter; + return 0; + } #endif - c=base64DecodeTable[(unsigned char)(*data)]; - if (c<97) size++; - else if (c==98) { if (xe) *xe=eXMLErrorBase64DecodeIllegalCharacter; return 0; } - data++; + c = base64DecodeTable[(unsigned char)(*data)]; + if (c < 97) + size++; + else if (c == 98) { + if (xe) *xe = eXMLErrorBase64DecodeIllegalCharacter; + return 0; } - if (xe&&(size%4!=0)) *xe=eXMLErrorBase64DataSizeIsNotMultipleOf4; - if (size==0) return 0; - do { data--; size--; } while(*data==base64Fillchar); size++; - return (unsigned int)((size*3)/4); -} - -unsigned char XMLParserBase64Tool::decode(XMLCSTR data, unsigned char *buf, int len, XMLError *xe) -{ - if (xe) *xe=eXMLErrorNone; - int i=0,p=0; - unsigned char d,c; - for(;;) - { - + data++; + } + if (xe && (size % 4 != 0)) *xe = eXMLErrorBase64DataSizeIsNotMultipleOf4; + if (size == 0) return 0; + do { + data--; + size--; + } while (*data == base64Fillchar); + size++; + return (unsigned int)((size * 3) / 4); +} + +unsigned char XMLParserBase64Tool::decode(XMLCSTR data, unsigned char *buf, + int len, XMLError *xe) { + if (xe) *xe = eXMLErrorNone; + int i = 0, p = 0; + unsigned char d, c; + for (;;) { #ifdef _XMLWIDECHAR -#define BASE64DECODE_READ_NEXT_CHAR(c) \ - do { \ - if (data[i]>255){ c=98; break; } \ - c=base64DecodeTable[(unsigned char)data[i++]]; \ - }while (c==97); \ - if(c==98){ if(xe)*xe=eXMLErrorBase64DecodeIllegalCharacter; return 0; } +#define BASE64DECODE_READ_NEXT_CHAR(c) \ + do { \ + if (data[i] > 255) { \ + c = 98; \ + break; \ + } \ + c = base64DecodeTable[(unsigned char)data[i++]]; \ + } while (c == 97); \ + if (c == 98) { \ + if (xe) *xe = eXMLErrorBase64DecodeIllegalCharacter; \ + return 0; \ + } #else -#define BASE64DECODE_READ_NEXT_CHAR(c) \ - do { c=base64DecodeTable[(unsigned char)data[i++]]; }while (c==97); \ - if(c==98){ if(xe)*xe=eXMLErrorBase64DecodeIllegalCharacter; return 0; } +#define BASE64DECODE_READ_NEXT_CHAR(c) \ + do { \ + c = base64DecodeTable[(unsigned char)data[i++]]; \ + } while (c == 97); \ + if (c == 98) { \ + if (xe) *xe = eXMLErrorBase64DecodeIllegalCharacter; \ + return 0; \ + } #endif - BASE64DECODE_READ_NEXT_CHAR(c) - if (c==99) { return 2; } - if (c==96) - { - if (p==(int)len) return 2; - if (xe) *xe=eXMLErrorBase64DecodeTruncatedData; - return 1; - } + BASE64DECODE_READ_NEXT_CHAR(c) + if (c == 99) { + return 2; + } + if (c == 96) { + if (p == (int)len) return 2; + if (xe) *xe = eXMLErrorBase64DecodeTruncatedData; + return 1; + } - BASE64DECODE_READ_NEXT_CHAR(d) - if ((d==99)||(d==96)) { if (xe) *xe=eXMLErrorBase64DecodeTruncatedData; return 1; } - if (p==(int)len) { if (xe) *xe=eXMLErrorBase64DecodeBufferTooSmall; return 0; } - buf[p++]=(unsigned char)((c<<2)|((d>>4)&0x3)); - - BASE64DECODE_READ_NEXT_CHAR(c) - if (c==99) { if (xe) *xe=eXMLErrorBase64DecodeTruncatedData; return 1; } - if (p==(int)len) - { - if (c==96) return 2; - if (xe) *xe=eXMLErrorBase64DecodeBufferTooSmall; - return 0; - } - if (c==96) { if (xe) *xe=eXMLErrorBase64DecodeTruncatedData; return 1; } - buf[p++]=(unsigned char)(((d<<4)&0xf0)|((c>>2)&0xf)); - - BASE64DECODE_READ_NEXT_CHAR(d) - if (d==99 ) { if (xe) *xe=eXMLErrorBase64DecodeTruncatedData; return 1; } - if (p==(int)len) - { - if (d==96) return 2; - if (xe) *xe=eXMLErrorBase64DecodeBufferTooSmall; - return 0; - } - if (d==96) { if (xe) *xe=eXMLErrorBase64DecodeTruncatedData; return 1; } - buf[p++]=(unsigned char)(((c<<6)&0xc0)|d); + BASE64DECODE_READ_NEXT_CHAR(d) + if ((d == 99) || (d == 96)) { + if (xe) *xe = eXMLErrorBase64DecodeTruncatedData; + return 1; } -} -#undef BASE64DECODE_READ_NEXT_CHAR + if (p == (int)len) { + if (xe) *xe = eXMLErrorBase64DecodeBufferTooSmall; + return 0; + } + buf[p++] = (unsigned char)((c << 2) | ((d >> 4) & 0x3)); -void XMLParserBase64Tool::alloc(int newsize) -{ - if ((!buf)&&(newsize)) { buf=malloc(newsize); buflen=newsize; return; } - if (newsize>buflen) { buf=realloc(buf,newsize); buflen=newsize; } -} + BASE64DECODE_READ_NEXT_CHAR(c) + if (c == 99) { + if (xe) *xe = eXMLErrorBase64DecodeTruncatedData; + return 1; + } + if (p == (int)len) { + if (c == 96) return 2; + if (xe) *xe = eXMLErrorBase64DecodeBufferTooSmall; + return 0; + } + if (c == 96) { + if (xe) *xe = eXMLErrorBase64DecodeTruncatedData; + return 1; + } + buf[p++] = (unsigned char)(((d << 4) & 0xf0) | ((c >> 2) & 0xf)); -unsigned char *XMLParserBase64Tool::decode(XMLCSTR data, int *outlen, XMLError *xe) -{ - if (xe) *xe=eXMLErrorNone; - unsigned int len=decodeSize(data,xe); - if (outlen) *outlen=len; - if (!len) return NULL; - alloc(len+1); - if(!decode(data,(unsigned char*)buf,len,xe)){ return NULL; } - return (unsigned char*)buf; + BASE64DECODE_READ_NEXT_CHAR(d) + if (d == 99) { + if (xe) *xe = eXMLErrorBase64DecodeTruncatedData; + return 1; + } + if (p == (int)len) { + if (d == 96) return 2; + if (xe) *xe = eXMLErrorBase64DecodeBufferTooSmall; + return 0; + } + if (d == 96) { + if (xe) *xe = eXMLErrorBase64DecodeTruncatedData; + return 1; + } + buf[p++] = (unsigned char)(((c << 6) & 0xc0) | d); + } } +#undef BASE64DECODE_READ_NEXT_CHAR +void XMLParserBase64Tool::alloc(int newsize) { + if ((!buf) && (newsize)) { + buf = malloc(newsize); + buflen = newsize; + return; + } + if (newsize > buflen) { + buf = realloc(buf, newsize); + buflen = newsize; + } +} + +unsigned char *XMLParserBase64Tool::decode(XMLCSTR data, int *outlen, + XMLError *xe) { + if (xe) *xe = eXMLErrorNone; + unsigned int len = decodeSize(data, xe); + if (outlen) *outlen = len; + if (!len) return NULL; + alloc(len + 1); + if (!decode(data, (unsigned char *)buf, len, xe)) { + return NULL; + } + return (unsigned char *)buf; +} diff --git a/src/gpuwattch/xmlParser.h b/src/gpuwattch/xmlParser.h index 068b36f..71a1f57 100644 --- a/src/gpuwattch/xmlParser.h +++ b/src/gpuwattch/xmlParser.h @@ -9,18 +9,18 @@ * @version V2.41 * @author Frank Vanden Berghen * - * The following license terms for the "XMLParser library from Business-Insight" apply to projects - * that are in some way related to - * the "mcpat project", including applications - * using "mcpat project" and tools developed - * for enhancing "mcpat project". All other projects - * (not related to "mcpat project") have to use the "XMLParser library from Business-Insight" - * code under the Aladdin Free Public License (AFPL) - * See the file "AFPL-license.txt" for more informations about the AFPL license. - * (see http://www.artifex.com/downloads/doc/Public.htm for detailed AFPL terms) + * The following license terms for the "XMLParser library from Business-Insight" + *apply to projects that are in some way related to the "mcpat project", + *including applications using "mcpat project" and tools developed for enhancing + *"mcpat project". All other projects (not related to "mcpat project") have to + *use the "XMLParser library from Business-Insight" code under the Aladdin Free + *Public License (AFPL) See the file "AFPL-license.txt" for more informations + *about the AFPL license. (see http://www.artifex.com/downloads/doc/Public.htm + *for detailed AFPL terms) * - * Redistribution and use of the "XMLParser library from Business-Insight" in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * Redistribution and use of the "XMLParser library from Business-Insight" in + *source and binary forms, with or without modification, are permitted provided + *that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright @@ -46,71 +46,81 @@ * All rights reserved. * * \section tutorial First Tutorial - * You can follow a simple Tutorial to know the basics... + * You can follow a simple Tutorial to know + *the basics... * - * \section usage General usage: How to include the XMLParser library inside your project. + * \section usage General usage: How to include the XMLParser library inside + *your project. * - * The library is composed of two files: xmlParser.cpp and - * xmlParser.h. These are the ONLY 2 files that you need when - * using the library inside your own projects. + * The library is composed of two files: xmlParser.cpp and xmlParser.h. These are the ONLY 2 files that you + *need when using the library inside your own projects. * - * All the functions of the library are documented inside the comments of the file - * xmlParser.h. These comments can be transformed in - * full-fledged HTML documentation using the DOXYGEN software: simply type: "doxygen doxy.cfg" + * All the functions of the library are documented inside the comments of the + *file xmlParser.h. These comments can be + *transformed in full-fledged HTML documentation using the DOXYGEN software: + *simply type: "doxygen doxy.cfg" * - * By default, the XMLParser library uses (char*) for string representation.To use the (wchar_t*) - * version of the library, you need to define the "_UNICODE" preprocessor definition variable - * (this is usually done inside your project definition file) (This is done automatically for you - * when using Visual Studio). + * By default, the XMLParser library uses (char*) for string representation.To + *use the (wchar_t*) version of the library, you need to define the "_UNICODE" + *preprocessor definition variable (this is usually done inside your project + *definition file) (This is done automatically for you when using Visual + *Studio). * * \section example Advanced Tutorial and Many Examples of usage. * * Some very small introductory examples are described inside the Tutorial file * xmlParser.html * - * Some additional small examples are also inside the file xmlTest.cpp - * (for the "char*" version of the library) and inside the file - * xmlTestUnicode.cpp (for the "wchar_t*" - * version of the library). If you have a question, please review these additionnal examples - * before sending an e-mail to the author. + * Some additional small examples are also inside the file xmlTest.cpp (for the "char*" version of the + *library) and inside the file xmlTestUnicode.cpp (for the "wchar_t*" + * version of the library). If you have a question, please review these + *additionnal examples before sending an e-mail to the author. * * To build the examples: * - linux/unix: type "make" * - solaris: type "make -f makefile.solaris" * - windows: Visual Studio: double-click on xmlParser.dsw - * (under Visual Studio .NET, the .dsp and .dsw files will be automatically converted to .vcproj and .sln files) + * (under Visual Studio .NET, the .dsp and .dsw files will be automatically + *converted to .vcproj and .sln files) * * In order to build the examples you need some additional files: * - linux/unix: makefile * - solaris: makefile.solaris - * - windows: Visual Studio: *.dsp, xmlParser.dsw and also xmlParser.lib and xmlParser.dll + * - windows: Visual Studio: *.dsp, xmlParser.dsw and also xmlParser.lib and + *xmlParser.dll * * \section debugging Debugging with the XMLParser library * * \subsection debugwin Debugging under WINDOWS * - * Inside Visual C++, the "debug versions" of the memory allocation functions are - * very slow: Do not forget to compile in "release mode" to get maximum speed. - * When I had to debug a software that was using the XMLParser Library, it was usually - * a nightmare because the library was sooOOOoooo slow in debug mode (because of the - * slow memory allocations in Debug mode). To solve this - * problem, during all the debugging session, I am now using a very fast DLL version of the - * XMLParser Library (the DLL is compiled in release mode). Using the DLL version of - * the XMLParser Library allows me to have lightening XML parsing speed even in debug! - * Other than that, the DLL version is useless: In the release version of my tool, - * I always use the normal, ".cpp"-based, XMLParser Library (I simply include the - * xmlParser.cpp and - * xmlParser.h files into the project). + * Inside Visual C++, the "debug versions" of the memory allocation + *functions are very slow: Do not forget to compile in "release mode" to get + *maximum speed. When I had to debug a software that was using the XMLParser + *Library, it was usually a nightmare because the library was sooOOOoooo slow in + *debug mode (because of the slow memory allocations in Debug mode). To solve + *this problem, during all the debugging session, I am now using a very fast DLL + *version of the XMLParser Library (the DLL is compiled in release mode). Using + *the DLL version of the XMLParser Library allows me to have lightening XML + *parsing speed even in debug! Other than that, the DLL version is useless: In + *the release version of my tool, I always use the normal, ".cpp"-based, + *XMLParser Library (I simply include the xmlParser.cpp and xmlParser.h files into the project). * - * The file XMLNodeAutoexp.txt contains some - * "tweaks" that improve substancially the display of the content of the XMLNode objects - * inside the Visual Studio Debugger. Believe me, once you have seen inside the debugger - * the "smooth" display of the XMLNode objects, you cannot live without it anymore! + * The file XMLNodeAutoexp.txt + *contains some "tweaks" that improve substancially the display of the content + *of the XMLNode objects inside the Visual Studio Debugger. Believe me, once you + *have seen inside the debugger the "smooth" display of the XMLNode objects, you + *cannot live without it anymore! * * \subsection debuglinux Debugging under LINUX/UNIX * - * The speed of the debug version of the XMLParser library is tolerable so no extra - * work.has been done. + * The speed of the debug version of the XMLParser library is tolerable so + *no extra work.has been done. * ****************************************************************************/ @@ -120,16 +130,21 @@ #include #ifdef _UNICODE -// If you comment the next "define" line then the library will never "switch to" _UNICODE (wchar_t*) mode (16/32 bits per characters). -// This is useful when you get error messages like: -// 'XMLNode::openFileHelper' : cannot convert parameter 2 from 'const char [5]' to 'const wchar_t *' -// The _XMLWIDECHAR preprocessor variable force the XMLParser library into either utf16/32-mode (the proprocessor variable -// must be defined) or utf8-mode(the pre-processor variable must be undefined). +// If you comment the next "define" line then the library will never "switch to" +// _UNICODE (wchar_t*) mode (16/32 bits per characters). This is useful when you +// get error messages like: +// 'XMLNode::openFileHelper' : cannot convert parameter 2 from 'const char +// [5]' to 'const wchar_t *' +// The _XMLWIDECHAR preprocessor variable force the XMLParser library into +// either utf16/32-mode (the proprocessor variable must be defined) or +// utf8-mode(the pre-processor variable must be undefined). #define _XMLWIDECHAR #endif -#if defined(WIN32) || defined(UNDER_CE) || defined(_WIN32) || defined(WIN64) || defined(__BORLANDC__) -// comment the next line if you are under windows and the compiler is not Microsoft Visual Studio (6.0 or .NET) or Borland +#if defined(WIN32) || defined(UNDER_CE) || defined(_WIN32) || \ + defined(WIN64) || defined(__BORLANDC__) +// comment the next line if you are under windows and the compiler is not +// Microsoft Visual Studio (6.0 or .NET) or Borland #define _XMLWINDOWS #endif @@ -146,7 +161,8 @@ #define XMLDLLENTRY #endif -// uncomment the next line if you want no support for wchar_t* (no need for the or libraries anymore to compile) +// uncomment the next line if you want no support for wchar_t* (no need for the +// or libraries anymore to compile) //#define XML_NO_WIDE_CHAR #ifdef XML_NO_WIDE_CHAR @@ -159,604 +175,796 @@ #else #define XMLDLLENTRY #ifndef XML_NO_WIDE_CHAR -#include // to have 'wcsrtombs' for ANSI version - // to have 'mbsrtowcs' for WIDECHAR version +#include // to have 'wcsrtombs' for ANSI version + // to have 'mbsrtowcs' for WIDECHAR version #endif #endif // Some common types for char set portable code #ifdef _XMLWIDECHAR - #define _CXML(c) L ## c - #define XMLCSTR const wchar_t * - #define XMLSTR wchar_t * - #define XMLCHAR wchar_t +#define _CXML(c) L##c +#define XMLCSTR const wchar_t * +#define XMLSTR wchar_t * +#define XMLCHAR wchar_t #else - #define _CXML(c) c - #define XMLCSTR const char * - #define XMLSTR char * - #define XMLCHAR char +#define _CXML(c) c +#define XMLCSTR const char * +#define XMLSTR char * +#define XMLCHAR char #endif #ifndef FALSE - #define FALSE 0 +#define FALSE 0 #endif /* FALSE */ #ifndef TRUE - #define TRUE 1 +#define TRUE 1 #endif /* TRUE */ - /// Enumeration for XML parse errors. -typedef enum XMLError -{ - eXMLErrorNone = 0, - eXMLErrorMissingEndTag, - eXMLErrorNoXMLTagFound, - eXMLErrorEmpty, - eXMLErrorMissingTagName, - eXMLErrorMissingEndTagName, - eXMLErrorUnmatchedEndTag, - eXMLErrorUnmatchedEndClearTag, - eXMLErrorUnexpectedToken, - eXMLErrorNoElements, - eXMLErrorFileNotFound, - eXMLErrorFirstTagNotFound, - eXMLErrorUnknownCharacterEntity, - eXMLErrorCharacterCodeAbove255, - eXMLErrorCharConversionError, - eXMLErrorCannotOpenWriteFile, - eXMLErrorCannotWriteFile, - - eXMLErrorBase64DataSizeIsNotMultipleOf4, - eXMLErrorBase64DecodeIllegalCharacter, - eXMLErrorBase64DecodeTruncatedData, - eXMLErrorBase64DecodeBufferTooSmall +typedef enum XMLError { + eXMLErrorNone = 0, + eXMLErrorMissingEndTag, + eXMLErrorNoXMLTagFound, + eXMLErrorEmpty, + eXMLErrorMissingTagName, + eXMLErrorMissingEndTagName, + eXMLErrorUnmatchedEndTag, + eXMLErrorUnmatchedEndClearTag, + eXMLErrorUnexpectedToken, + eXMLErrorNoElements, + eXMLErrorFileNotFound, + eXMLErrorFirstTagNotFound, + eXMLErrorUnknownCharacterEntity, + eXMLErrorCharacterCodeAbove255, + eXMLErrorCharConversionError, + eXMLErrorCannotOpenWriteFile, + eXMLErrorCannotWriteFile, + + eXMLErrorBase64DataSizeIsNotMultipleOf4, + eXMLErrorBase64DecodeIllegalCharacter, + eXMLErrorBase64DecodeTruncatedData, + eXMLErrorBase64DecodeBufferTooSmall } XMLError; - -/// Enumeration used to manage type of data. Use in conjunction with structure XMLNodeContents -typedef enum XMLElementType -{ - eNodeChild=0, - eNodeAttribute=1, - eNodeText=2, - eNodeClear=3, - eNodeNULL=4 +/// Enumeration used to manage type of data. Use in conjunction with structure +/// XMLNodeContents +typedef enum XMLElementType { + eNodeChild = 0, + eNodeAttribute = 1, + eNodeText = 2, + eNodeClear = 3, + eNodeNULL = 4 } XMLElementType; /// Structure used to obtain error details if the parse fails. -typedef struct XMLResults -{ - enum XMLError error; - int nLine,nColumn; +typedef struct XMLResults { + enum XMLError error; + int nLine, nColumn; } XMLResults; /// Structure for XML clear (unformatted) node (usually comments) typedef struct XMLClear { - XMLCSTR lpszValue; XMLCSTR lpszOpenTag; XMLCSTR lpszCloseTag; + XMLCSTR lpszValue; + XMLCSTR lpszOpenTag; + XMLCSTR lpszCloseTag; } XMLClear; /// Structure for XML attribute. typedef struct XMLAttribute { - XMLCSTR lpszName; XMLCSTR lpszValue; + XMLCSTR lpszName; + XMLCSTR lpszValue; } XMLAttribute; /// XMLElementPosition are not interchangeable with simple indexes typedef int XMLElementPosition; struct XMLNodeContents; - + /** @defgroup XMLParserGeneral The XML parser */ /// Main Class representing a XML node /** * All operations are performed using this class. - * \note The constructors of the XMLNode class are protected, so use instead one of these four methods to get your first instance of XMLNode: - *
    - *
  • XMLNode::parseString
  • - *
  • XMLNode::parseFile
  • - *
  • XMLNode::openFileHelper
  • - *
  • XMLNode::createXMLTopNode (or XMLNode::createXMLTopNode_WOSD)
  • + * \note The constructors of the XMLNode class are protected, so use instead one + * of these four methods to get your first instance of XMLNode:
    • + * XMLNode::parseString
    • XMLNode::parseFile
    • + * XMLNode::openFileHelper
    • XMLNode::createXMLTopNode (or + * XMLNode::createXMLTopNode_WOSD)
    • *
    */ -typedef struct XMLDLLENTRY XMLNode -{ - private: - - struct XMLNodeDataTag; - - /// Constructors are protected, so use instead one of: XMLNode::parseString, XMLNode::parseFile, XMLNode::openFileHelper, XMLNode::createXMLTopNode - XMLNode(struct XMLNodeDataTag *pParent, XMLSTR lpszName, char isDeclaration); - /// Constructors are protected, so use instead one of: XMLNode::parseString, XMLNode::parseFile, XMLNode::openFileHelper, XMLNode::createXMLTopNode - XMLNode(struct XMLNodeDataTag *p); - - public: - static XMLCSTR getVersion();///< Return the XMLParser library version number - - /** @defgroup conversions Parsing XML files/strings to an XMLNode structure and Rendering XMLNode's to files/string. - * @ingroup XMLParserGeneral - * @{ */ - - /// Parse an XML string and return the root of a XMLNode tree representing the string. - static XMLNode parseString (XMLCSTR lpXMLString, XMLCSTR tag=NULL, XMLResults *pResults=NULL); - /**< The "parseString" function parse an XML string and return the root of a XMLNode tree. The "opposite" of this function is - * the function "createXMLString" that re-creates an XML string from an XMLNode tree. If the XML document is corrupted, the - * "parseString" method will initialize the "pResults" variable with some information that can be used to trace the error. - * If you still want to parse the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the - * beginning of the "xmlParser.cpp" file. - * - * @param lpXMLString the XML string to parse - * @param tag the name of the first tag inside the XML file. If the tag parameter is omitted, this function returns a node that represents the head of the xml document including the declaration term (). - * @param pResults a pointer to a XMLResults variable that will contain some information that can be used to trace the XML parsing error. You can have a user-friendly explanation of the parsing error with the "getError" function. - */ - - /// Parse an XML file and return the root of a XMLNode tree representing the file. - static XMLNode parseFile (XMLCSTR filename, XMLCSTR tag=NULL, XMLResults *pResults=NULL); - /**< The "parseFile" function parse an XML file and return the root of a XMLNode tree. The "opposite" of this function is - * the function "writeToFile" that re-creates an XML file from an XMLNode tree. If the XML document is corrupted, the - * "parseFile" method will initialize the "pResults" variable with some information that can be used to trace the error. - * If you still want to parse the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the - * beginning of the "xmlParser.cpp" file. - * - * @param filename the path to the XML file to parse - * @param tag the name of the first tag inside the XML file. If the tag parameter is omitted, this function returns a node that represents the head of the xml document including the declaration term (). - * @param pResults a pointer to a XMLResults variable that will contain some information that can be used to trace the XML parsing error. You can have a user-friendly explanation of the parsing error with the "getError" function. - */ - - /// Parse an XML file and return the root of a XMLNode tree representing the file. A very crude error checking is made. An attempt to guess the Char Encoding used in the file is made. - static XMLNode openFileHelper(XMLCSTR filename, XMLCSTR tag=NULL); - /**< The "openFileHelper" function reports to the screen all the warnings and errors that occurred during parsing of the XML file. - * This function also tries to guess char Encoding (UTF-8, ASCII or SHIT-JIS) based on the first 200 bytes of the file. Since each - * application has its own way to report and deal with errors, you should rather use the "parseFile" function to parse XML files - * and program yourself thereafter an "error reporting" tailored for your needs (instead of using the very crude "error reporting" - * mechanism included inside the "openFileHelper" function). - * - * If the XML document is corrupted, the "openFileHelper" method will: - * - display an error message on the console (or inside a messageBox for windows). - * - stop execution (exit). - * - * I strongly suggest that you write your own "openFileHelper" method tailored to your needs. If you still want to parse - * the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the beginning of the "xmlParser.cpp" file. - * - * @param filename the path of the XML file to parse. - * @param tag the name of the first tag inside the XML file. If the tag parameter is omitted, this function returns a node that represents the head of the xml document including the declaration term (). - */ - - static XMLCSTR getError(XMLError error); ///< this gives you a user-friendly explanation of the parsing error - - /// Create an XML string starting from the current XMLNode. - XMLSTR createXMLString(int nFormat=1, int *pnSize=NULL) const; - /**< The returned string should be free'd using the "freeXMLString" function. - * - * If nFormat==0, no formatting is required otherwise this returns an user friendly XML string from a given element - * with appropriate white spaces and carriage returns. if pnSize is given it returns the size in character of the string. */ - - /// Save the content of an xmlNode inside a file - XMLError writeToFile(XMLCSTR filename, - const char *encoding=NULL, - char nFormat=1) const; - /**< If nFormat==0, no formatting is required otherwise this returns an user friendly XML string from a given element with appropriate white spaces and carriage returns. - * If the global parameter "characterEncoding==encoding_UTF8", then the "encoding" parameter is ignored and always set to "utf-8". - * If the global parameter "characterEncoding==encoding_ShiftJIS", then the "encoding" parameter is ignored and always set to "SHIFT-JIS". - * If "_XMLWIDECHAR=1", then the "encoding" parameter is ignored and always set to "utf-16". - * If no "encoding" parameter is given the "ISO-8859-1" encoding is used. */ - /** @} */ - - /** @defgroup navigate Navigate the XMLNode structure - * @ingroup XMLParserGeneral - * @{ */ - XMLCSTR getName() const; ///< name of the node - XMLCSTR getText(int i=0) const; ///< return ith text field - int nText() const; ///< nbr of text field - XMLNode getParentNode() const; ///< return the parent node - XMLNode getChildNode(int i=0) const; ///< return ith child node - XMLNode getChildNode(XMLCSTR name, int i) const; ///< return ith child node with specific name (return an empty node if failing). If i==-1, this returns the last XMLNode with the given name. - XMLNode getChildNode(XMLCSTR name, int *i=NULL) const; ///< return next child node with specific name (return an empty node if failing) - XMLNode getChildNodeWithAttribute(XMLCSTR tagName, - XMLCSTR attributeName, - XMLCSTR attributeValue=NULL, - int *i=NULL) const; ///< return child node with specific name/attribute (return an empty node if failing) - XMLNode getChildNodeByPath(XMLCSTR path, char createNodeIfMissing=0, XMLCHAR sep='/'); - ///< return the first child node with specific path - XMLNode getChildNodeByPathNonConst(XMLSTR path, char createNodeIfMissing=0, XMLCHAR sep='/'); - ///< return the first child node with specific path. - - int nChildNode(XMLCSTR name) const; ///< return the number of child node with specific name - int nChildNode() const; ///< nbr of child node - XMLAttribute getAttribute(int i=0) const; ///< return ith attribute - XMLCSTR getAttributeName(int i=0) const; ///< return ith attribute name - XMLCSTR getAttributeValue(int i=0) const; ///< return ith attribute value - char isAttributeSet(XMLCSTR name) const; ///< test if an attribute with a specific name is given - XMLCSTR getAttribute(XMLCSTR name, int i) const; ///< return ith attribute content with specific name (return a NULL if failing) - XMLCSTR getAttribute(XMLCSTR name, int *i=NULL) const; ///< return next attribute content with specific name (return a NULL if failing) - int nAttribute() const; ///< nbr of attribute - XMLClear getClear(int i=0) const; ///< return ith clear field (comments) - int nClear() const; ///< nbr of clear field - XMLNodeContents enumContents(XMLElementPosition i) const; ///< enumerate all the different contents (attribute,child,text, clear) of the current XMLNode. The order is reflecting the order of the original file/string. NOTE: 0 <= i < nElement(); - int nElement() const; ///< nbr of different contents for current node - char isEmpty() const; ///< is this node Empty? - char isDeclaration() const; ///< is this node a declaration - XMLNode deepCopy() const; ///< deep copy (duplicate/clone) a XMLNode - static XMLNode emptyNode(); ///< return XMLNode::emptyXMLNode; - /** @} */ - - ~XMLNode(); - XMLNode(const XMLNode &A); ///< to allow shallow/fast copy: - XMLNode& operator=( const XMLNode& A ); ///< to allow shallow/fast copy: - - XMLNode(): d(NULL){}; - static XMLNode emptyXMLNode; - static XMLClear emptyXMLClear; - static XMLAttribute emptyXMLAttribute; - - /** @defgroup xmlModify Create or Update the XMLNode structure - * @ingroup XMLParserGeneral - * The functions in this group allows you to create from scratch (or update) a XMLNode structure. Start by creating your top - * node with the "createXMLTopNode" function and then add new nodes with the "addChild" function. The parameter 'pos' gives - * the position where the childNode, the text or the XMLClearTag will be inserted. The default value (pos=-1) inserts at the - * end. The value (pos=0) insert at the beginning (Insertion at the beginning is slower than at the end).
    - * - * REMARK: 0 <= pos < nChild()+nText()+nClear()
    - */ - - /** @defgroup creation Creating from scratch a XMLNode structure - * @ingroup xmlModify - * @{ */ - static XMLNode createXMLTopNode(XMLCSTR lpszName, char isDeclaration=FALSE); ///< Create the top node of an XMLNode structure - XMLNode addChild(XMLCSTR lpszName, char isDeclaration=FALSE, XMLElementPosition pos=-1); ///< Add a new child node - XMLNode addChild(XMLNode nodeToAdd, XMLElementPosition pos=-1); ///< If the "nodeToAdd" has some parents, it will be detached from it's parents before being attached to the current XMLNode - XMLAttribute *addAttribute(XMLCSTR lpszName, XMLCSTR lpszValuev); ///< Add a new attribute - XMLCSTR addText(XMLCSTR lpszValue, XMLElementPosition pos=-1); ///< Add a new text content - XMLClear *addClear(XMLCSTR lpszValue, XMLCSTR lpszOpen=NULL, XMLCSTR lpszClose=NULL, XMLElementPosition pos=-1); - /**< Add a new clear tag - * @param lpszOpen default value "" - */ - /** @} */ - - /** @defgroup xmlUpdate Updating Nodes - * @ingroup xmlModify - * Some update functions: - * @{ - */ - XMLCSTR updateName(XMLCSTR lpszName); ///< change node's name - XMLAttribute *updateAttribute(XMLAttribute *newAttribute, XMLAttribute *oldAttribute); ///< if the attribute to update is missing, a new one will be added - XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName=NULL,int i=0); ///< if the attribute to update is missing, a new one will be added - XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,XMLCSTR lpszOldName);///< set lpszNewName=NULL if you don't want to change the name of the attribute if the attribute to update is missing, a new one will be added - XMLCSTR updateText(XMLCSTR lpszNewValue, int i=0); ///< if the text to update is missing, a new one will be added - XMLCSTR updateText(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the text to update is missing, a new one will be added - XMLClear *updateClear(XMLCSTR lpszNewContent, int i=0); ///< if the clearTag to update is missing, a new one will be added - XMLClear *updateClear(XMLClear *newP,XMLClear *oldP); ///< if the clearTag to update is missing, a new one will be added - XMLClear *updateClear(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the clearTag to update is missing, a new one will be added - /** @} */ - - /** @defgroup xmlDelete Deleting Nodes or Attributes - * @ingroup xmlModify - * Some deletion functions: - * @{ - */ - /// The "deleteNodeContent" function forces the deletion of the content of this XMLNode and the subtree. - void deleteNodeContent(); - /**< \note The XMLNode instances that are referring to the part of the subtree that has been deleted CANNOT be used anymore!!. Unexpected results will occur if you continue using them. */ - void deleteAttribute(int i=0); ///< Delete the ith attribute of the current XMLNode - void deleteAttribute(XMLCSTR lpszName); ///< Delete the attribute with the given name (the "strcmp" function is used to find the right attribute) - void deleteAttribute(XMLAttribute *anAttribute); ///< Delete the attribute with the name "anAttribute->lpszName" (the "strcmp" function is used to find the right attribute) - void deleteText(int i=0); ///< Delete the Ith text content of the current XMLNode - void deleteText(XMLCSTR lpszValue); ///< Delete the text content "lpszValue" inside the current XMLNode (direct "pointer-to-pointer" comparison is used to find the right text) - void deleteClear(int i=0); ///< Delete the Ith clear tag inside the current XMLNode - void deleteClear(XMLCSTR lpszValue); ///< Delete the clear tag "lpszValue" inside the current XMLNode (direct "pointer-to-pointer" comparison is used to find the clear tag) - void deleteClear(XMLClear *p); ///< Delete the clear tag "p" inside the current XMLNode (direct "pointer-to-pointer" comparison on the lpszName of the clear tag is used to find the clear tag) - /** @} */ - - /** @defgroup xmlWOSD ???_WOSD functions. - * @ingroup xmlModify - * The strings given as parameters for the "add" and "update" methods that have a name with - * the postfix "_WOSD" (that means "WithOut String Duplication")(for example "addText_WOSD") - * will be free'd by the XMLNode class. For example, it means that this is incorrect: - * \code - * xNode.addText_WOSD("foo"); - * xNode.updateAttribute_WOSD("#newcolor" ,NULL,"color"); - * \endcode - * In opposition, this is correct: - * \code - * xNode.addText("foo"); - * xNode.addText_WOSD(stringDup("foo")); - * xNode.updateAttribute("#newcolor" ,NULL,"color"); - * xNode.updateAttribute_WOSD(stringDup("#newcolor"),NULL,"color"); - * \endcode - * Typically, you will never do: - * \code - * char *b=(char*)malloc(...); - * xNode.addText(b); - * free(b); - * \endcode - * ... but rather: - * \code - * char *b=(char*)malloc(...); - * xNode.addText_WOSD(b); - * \endcode - * ('free(b)' is performed by the XMLNode class) - * @{ */ - static XMLNode createXMLTopNode_WOSD(XMLSTR lpszName, char isDeclaration=FALSE); ///< Create the top node of an XMLNode structure - XMLNode addChild_WOSD(XMLSTR lpszName, char isDeclaration=FALSE, XMLElementPosition pos=-1); ///< Add a new child node - XMLAttribute *addAttribute_WOSD(XMLSTR lpszName, XMLSTR lpszValue); ///< Add a new attribute - XMLCSTR addText_WOSD(XMLSTR lpszValue, XMLElementPosition pos=-1); ///< Add a new text content - XMLClear *addClear_WOSD(XMLSTR lpszValue, XMLCSTR lpszOpen=NULL, XMLCSTR lpszClose=NULL, XMLElementPosition pos=-1); ///< Add a new clear Tag - - XMLCSTR updateName_WOSD(XMLSTR lpszName); ///< change node's name - XMLAttribute *updateAttribute_WOSD(XMLAttribute *newAttribute, XMLAttribute *oldAttribute); ///< if the attribute to update is missing, a new one will be added - XMLAttribute *updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName=NULL,int i=0); ///< if the attribute to update is missing, a new one will be added - XMLAttribute *updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName,XMLCSTR lpszOldName); ///< set lpszNewName=NULL if you don't want to change the name of the attribute if the attribute to update is missing, a new one will be added - XMLCSTR updateText_WOSD(XMLSTR lpszNewValue, int i=0); ///< if the text to update is missing, a new one will be added - XMLCSTR updateText_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the text to update is missing, a new one will be added - XMLClear *updateClear_WOSD(XMLSTR lpszNewContent, int i=0); ///< if the clearTag to update is missing, a new one will be added - XMLClear *updateClear_WOSD(XMLClear *newP,XMLClear *oldP); ///< if the clearTag to update is missing, a new one will be added - XMLClear *updateClear_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the clearTag to update is missing, a new one will be added - /** @} */ - - /** @defgroup xmlPosition Position helper functions (use in conjunction with the update&add functions - * @ingroup xmlModify - * These are some useful functions when you want to insert a childNode, a text or a XMLClearTag in the - * middle (at a specified position) of a XMLNode tree already constructed. The value returned by these - * methods is to be used as last parameter (parameter 'pos') of addChild, addText or addClear. - * @{ */ - XMLElementPosition positionOfText(int i=0) const; - XMLElementPosition positionOfText(XMLCSTR lpszValue) const; - XMLElementPosition positionOfClear(int i=0) const; - XMLElementPosition positionOfClear(XMLCSTR lpszValue) const; - XMLElementPosition positionOfClear(XMLClear *a) const; - XMLElementPosition positionOfChildNode(int i=0) const; - XMLElementPosition positionOfChildNode(XMLNode x) const; - XMLElementPosition positionOfChildNode(XMLCSTR name, int i=0) const; ///< return the position of the ith childNode with the specified name if (name==NULL) return the position of the ith childNode - /** @} */ - - /// Enumeration for XML character encoding. - typedef enum XMLCharEncoding - { - char_encoding_error=0, - char_encoding_UTF8=1, - char_encoding_legacy=2, - char_encoding_ShiftJIS=3, - char_encoding_GB2312=4, - char_encoding_Big5=5, - char_encoding_GBK=6 // this is actually the same as Big5 - } XMLCharEncoding; - - /** \addtogroup conversions - * @{ */ - - /// Sets the global options for the conversions - static char setGlobalOptions(XMLCharEncoding characterEncoding=XMLNode::char_encoding_UTF8, char guessWideCharChars=1, - char dropWhiteSpace=1, char removeCommentsInMiddleOfText=1); - /**< The "setGlobalOptions" function allows you to change four global parameters that affect string & file - * parsing. First of all, you most-probably will never have to change these 3 global parameters. - * - * @param guessWideCharChars If "guessWideCharChars"=1 and if this library is compiled in WideChar mode, then the - * XMLNode::parseFile and XMLNode::openFileHelper functions will test if the file contains ASCII - * characters. If this is the case, then the file will be loaded and converted in memory to - * WideChar before being parsed. If 0, no conversion will be performed. - * - * @param guessWideCharChars If "guessWideCharChars"=1 and if this library is compiled in ASCII/UTF8/char* mode, then the - * XMLNode::parseFile and XMLNode::openFileHelper functions will test if the file contains WideChar - * characters. If this is the case, then the file will be loaded and converted in memory to - * ASCII/UTF8/char* before being parsed. If 0, no conversion will be performed. - * - * @param characterEncoding This parameter is only meaningful when compiling in char* mode (multibyte character mode). - * In wchar_t* (wide char mode), this parameter is ignored. This parameter should be one of the - * three currently recognized encodings: XMLNode::encoding_UTF8, XMLNode::encoding_ascii, - * XMLNode::encoding_ShiftJIS. - * - * @param dropWhiteSpace In most situations, text fields containing only white spaces (and carriage returns) - * are useless. Even more, these "empty" text fields are annoying because they increase the - * complexity of the user's code for parsing. So, 99% of the time, it's better to drop - * the "empty" text fields. However The XML specification indicates that no white spaces - * should be lost when parsing the file. So to be perfectly XML-compliant, you should set - * dropWhiteSpace=0. A note of caution: if you set "dropWhiteSpace=0", the parser will be - * slower and your code will be more complex. - * - * @param removeCommentsInMiddleOfText To explain this parameter, let's consider this code: - * \code - * XMLNode x=XMLNode::parseString("foobarchu","a"); - * \endcode - * If removeCommentsInMiddleOfText=0, then we will have: - * \code - * x.getText(0) -> "foo" - * x.getText(1) -> "bar" - * x.getText(2) -> "chu" - * x.getClear(0) --> "" - * x.getClear(1) --> "" - * \endcode - * If removeCommentsInMiddleOfText=1, then we will have: - * \code - * x.getText(0) -> "foobar" - * x.getText(1) -> "chu" - * x.getClear(0) --> "" - * \endcode - * - * \return "0" when there are no errors. If you try to set an unrecognized encoding then the return value will be "1" to signal an error. - * - * \note Sometime, it's useful to set "guessWideCharChars=0" to disable any conversion - * because the test to detect the file-type (ASCII/UTF8/char* or WideChar) may fail (rarely). */ - - /// Guess the character encoding of the string (ascii, utf8 or shift-JIS) - static XMLCharEncoding guessCharEncoding(void *buffer, int bufLen, char useXMLEncodingAttribute=1); - /**< The "guessCharEncoding" function try to guess the character encoding. You most-probably will never - * have to use this function. It then returns the appropriate value of the global parameter - * "characterEncoding" described in the XMLNode::setGlobalOptions. The guess is based on the content of a buffer of length - * "bufLen" bytes that contains the first bytes (minimum 25 bytes; 200 bytes is a good value) of the - * file to be parsed. The XMLNode::openFileHelper function is using this function to automatically compute - * the value of the "characterEncoding" global parameter. There are several heuristics used to do the - * guess. One of the heuristic is based on the "encoding" attribute. The original XML specifications - * forbids to use this attribute to do the guess but you can still use it if you set - * "useXMLEncodingAttribute" to 1 (this is the default behavior and the behavior of most parsers). - * If an inconsistency in the encoding is detected, then the return value is "0". */ - /** @} */ - - private: - // these are functions and structures used internally by the XMLNode class (don't bother about them): - - typedef struct XMLNodeDataTag // to allow shallow copy and "intelligent/smart" pointers (automatic delete): - { - XMLCSTR lpszName; // Element name (=NULL if root) - int nChild, // Number of child nodes - nText, // Number of text fields - nClear, // Number of Clear fields (comments) - nAttribute; // Number of attributes - char isDeclaration; // Whether node is an XML declaration - '' - struct XMLNodeDataTag *pParent; // Pointer to parent element (=NULL if root) - XMLNode *pChild; // Array of child nodes - XMLCSTR *pText; // Array of text fields - XMLClear *pClear; // Array of clear fields - XMLAttribute *pAttribute; // Array of attributes - int *pOrder; // order of the child_nodes,text_fields,clear_fields - int ref_count; // for garbage collection (smart pointers) - } XMLNodeData; - XMLNodeData *d; - - char parseClearTag(void *px, void *pa); - char maybeAddTxT(void *pa, XMLCSTR tokenPStr); - int ParseXMLElement(void *pXML); - void *addToOrder(int memInc, int *_pos, int nc, void *p, int size, XMLElementType xtype); - int indexText(XMLCSTR lpszValue) const; - int indexClear(XMLCSTR lpszValue) const; - XMLNode addChild_priv(int,XMLSTR,char,int); - XMLAttribute *addAttribute_priv(int,XMLSTR,XMLSTR); - XMLCSTR addText_priv(int,XMLSTR,int); - XMLClear *addClear_priv(int,XMLSTR,XMLCSTR,XMLCSTR,int); - void emptyTheNode(char force); - static inline XMLElementPosition findPosition(XMLNodeData *d, int index, XMLElementType xtype); - static int CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, int nFormat); - static int removeOrderElement(XMLNodeData *d, XMLElementType t, int index); - static void exactMemory(XMLNodeData *d); - static int detachFromParent(XMLNodeData *d); +typedef struct XMLDLLENTRY XMLNode { + private: + struct XMLNodeDataTag; + + /// Constructors are protected, so use instead one of: XMLNode::parseString, + /// XMLNode::parseFile, XMLNode::openFileHelper, XMLNode::createXMLTopNode + XMLNode(struct XMLNodeDataTag *pParent, XMLSTR lpszName, char isDeclaration); + /// Constructors are protected, so use instead one of: XMLNode::parseString, + /// XMLNode::parseFile, XMLNode::openFileHelper, XMLNode::createXMLTopNode + XMLNode(struct XMLNodeDataTag *p); + + public: + static XMLCSTR getVersion(); ///< Return the XMLParser library version number + + /** @defgroup conversions Parsing XML files/strings to an XMLNode structure + * and Rendering XMLNode's to files/string. + * @ingroup XMLParserGeneral + * @{ */ + + /// Parse an XML string and return the root of a XMLNode tree representing the + /// string. + static XMLNode parseString(XMLCSTR lpXMLString, XMLCSTR tag = NULL, + XMLResults *pResults = NULL); + /**< The "parseString" function parse an XML string and return the root of a + * XMLNode tree. The "opposite" of this function is the function + * "createXMLString" that re-creates an XML string from an XMLNode tree. If + * the XML document is corrupted, the "parseString" method will initialize the + * "pResults" variable with some information that can be used to trace the + * error. If you still want to parse the file, you can use the + * APPROXIMATE_PARSING option as explained inside the note at the beginning of + * the "xmlParser.cpp" file. + * + * @param lpXMLString the XML string to parse + * @param tag the name of the first tag inside the XML file. If the tag + * parameter is omitted, this function returns a node that represents the head + * of the xml document including the declaration term (). + * @param pResults a pointer to a XMLResults variable that will contain some + * information that can be used to trace the XML parsing error. You can have a + * user-friendly explanation of the parsing error with the "getError" + * function. + */ + + /// Parse an XML file and return the root of a XMLNode tree representing the + /// file. + static XMLNode parseFile(XMLCSTR filename, XMLCSTR tag = NULL, + XMLResults *pResults = NULL); + /**< The "parseFile" function parse an XML file and return the root of a + * XMLNode tree. The "opposite" of this function is the function "writeToFile" + * that re-creates an XML file from an XMLNode tree. If the XML document is + * corrupted, the "parseFile" method will initialize the "pResults" variable + * with some information that can be used to trace the error. If you still + * want to parse the file, you can use the APPROXIMATE_PARSING option as + * explained inside the note at the beginning of the "xmlParser.cpp" file. + * + * @param filename the path to the XML file to parse + * @param tag the name of the first tag inside the XML file. If the tag + * parameter is omitted, this function returns a node that represents the head + * of the xml document including the declaration term (). + * @param pResults a pointer to a XMLResults variable that will contain some + * information that can be used to trace the XML parsing error. You can have a + * user-friendly explanation of the parsing error with the "getError" + * function. + */ + + /// Parse an XML file and return the root of a XMLNode tree representing the + /// file. A very crude error checking is made. An attempt to guess the Char + /// Encoding used in the file is made. + static XMLNode openFileHelper(XMLCSTR filename, XMLCSTR tag = NULL); + /**< The "openFileHelper" function reports to the screen all the warnings and + * errors that occurred during parsing of the XML file. This function also + * tries to guess char Encoding (UTF-8, ASCII or SHIT-JIS) based on the first + * 200 bytes of the file. Since each application has its own way to report and + * deal with errors, you should rather use the "parseFile" function to parse + * XML files and program yourself thereafter an "error reporting" tailored for + * your needs (instead of using the very crude "error reporting" mechanism + * included inside the "openFileHelper" function). + * + * If the XML document is corrupted, the "openFileHelper" method will: + * - display an error message on the console (or inside a messageBox + * for windows). + * - stop execution (exit). + * + * I strongly suggest that you write your own "openFileHelper" method tailored + * to your needs. If you still want to parse the file, you can use the + * APPROXIMATE_PARSING option as explained inside the note at the beginning of + * the "xmlParser.cpp" file. + * + * @param filename the path of the XML file to parse. + * @param tag the name of the first tag inside the XML file. If the tag + * parameter is omitted, this function returns a node that represents the head + * of the xml document including the declaration term (). + */ + + static XMLCSTR getError( + XMLError error); ///< this gives you a user-friendly explanation of the + ///< parsing error + + /// Create an XML string starting from the current XMLNode. + XMLSTR createXMLString(int nFormat = 1, int *pnSize = NULL) const; + /**< The returned string should be free'd using the "freeXMLString" function. + * + * If nFormat==0, no formatting is required otherwise this returns an user + * friendly XML string from a given element + * with appropriate white spaces and carriage returns. if pnSize is given it + * returns the size in character of the string. */ + + /// Save the content of an xmlNode inside a file + XMLError writeToFile(XMLCSTR filename, const char *encoding = NULL, + char nFormat = 1) const; + /**< If nFormat==0, no formatting is required otherwise this returns an user + * friendly XML string from a given element with appropriate white spaces and + * carriage returns. If the global parameter + * "characterEncoding==encoding_UTF8", then the "encoding" parameter is + * ignored and always set to "utf-8". If the global parameter + * "characterEncoding==encoding_ShiftJIS", then the "encoding" parameter is + * ignored and always set to "SHIFT-JIS". If "_XMLWIDECHAR=1", then the + * "encoding" parameter is ignored and always set to "utf-16". If no + * "encoding" parameter is given the "ISO-8859-1" encoding is used. */ + /** @} */ + + /** @defgroup navigate Navigate the XMLNode structure + * @ingroup XMLParserGeneral + * @{ */ + XMLCSTR getName() const; ///< name of the node + XMLCSTR getText(int i = 0) const; ///< return ith text field + int nText() const; ///< nbr of text field + XMLNode getParentNode() const; ///< return the parent node + XMLNode getChildNode(int i = 0) const; ///< return ith child node + XMLNode getChildNode(XMLCSTR name, int i) + const; ///< return ith child node with specific name (return an empty + ///< node if failing). If i==-1, this returns the last XMLNode + ///< with the given name. + XMLNode getChildNode(XMLCSTR name, int *i = NULL) + const; ///< return next child node with specific name (return an empty + ///< node if failing) + XMLNode getChildNodeWithAttribute( + XMLCSTR tagName, XMLCSTR attributeName, XMLCSTR attributeValue = NULL, + int *i = NULL) const; ///< return child node with specific name/attribute + ///< (return an empty node if failing) + XMLNode getChildNodeByPath(XMLCSTR path, char createNodeIfMissing = 0, + XMLCHAR sep = '/'); + ///< return the first child node with specific path + XMLNode getChildNodeByPathNonConst(XMLSTR path, char createNodeIfMissing = 0, + XMLCHAR sep = '/'); + ///< return the first child node with specific path. + + int nChildNode(XMLCSTR name) + const; ///< return the number of child node with specific name + int nChildNode() const; ///< nbr of child node + XMLAttribute getAttribute(int i = 0) const; ///< return ith attribute + XMLCSTR getAttributeName(int i = 0) const; ///< return ith attribute name + XMLCSTR getAttributeValue(int i = 0) const; ///< return ith attribute value + char isAttributeSet(XMLCSTR name) + const; ///< test if an attribute with a specific name is given + XMLCSTR getAttribute( + XMLCSTR name, int i) const; ///< return ith attribute content with + ///< specific name (return a NULL if failing) + XMLCSTR getAttribute(XMLCSTR name, int *i = NULL) + const; ///< return next attribute content with specific name (return a + ///< NULL if failing) + int nAttribute() const; ///< nbr of attribute + XMLClear getClear(int i = 0) const; ///< return ith clear field (comments) + int nClear() const; ///< nbr of clear field + XMLNodeContents enumContents(XMLElementPosition i) + const; ///< enumerate all the different contents (attribute,child,text, + ///< clear) of the current XMLNode. The order is reflecting the + ///< order of the original file/string. NOTE: 0 <= i < nElement(); + int nElement() const; ///< nbr of different contents for current node + char isEmpty() const; ///< is this node Empty? + char isDeclaration() const; ///< is this node a declaration + XMLNode deepCopy() const; ///< deep copy (duplicate/clone) a XMLNode + static XMLNode emptyNode(); ///< return XMLNode::emptyXMLNode; + /** @} */ + + ~XMLNode(); + XMLNode(const XMLNode &A); ///< to allow shallow/fast copy: + XMLNode &operator=(const XMLNode &A); ///< to allow shallow/fast copy: + + XMLNode() : d(NULL){}; + static XMLNode emptyXMLNode; + static XMLClear emptyXMLClear; + static XMLAttribute emptyXMLAttribute; + + /** @defgroup xmlModify Create or Update the XMLNode structure + * @ingroup XMLParserGeneral + * The functions in this group allows you to create from scratch (or update) + * a XMLNode structure. Start by creating your top node with the + * "createXMLTopNode" function and then add new nodes with the "addChild" + * function. The parameter 'pos' gives the position where the childNode, the + * text or the XMLClearTag will be inserted. The default value (pos=-1) + * inserts at the end. The value (pos=0) insert at the beginning (Insertion at + * the beginning is slower than at the end).
    + * + * REMARK: 0 <= pos < nChild()+nText()+nClear()
    + */ + + /** @defgroup creation Creating from scratch a XMLNode structure + * @ingroup xmlModify + * @{ */ + static XMLNode createXMLTopNode( + XMLCSTR lpszName, + char isDeclaration = + FALSE); ///< Create the top node of an XMLNode structure + XMLNode addChild(XMLCSTR lpszName, char isDeclaration = FALSE, + XMLElementPosition pos = -1); ///< Add a new child node + XMLNode addChild(XMLNode nodeToAdd, + XMLElementPosition pos = + -1); ///< If the "nodeToAdd" has some parents, it will + ///< be detached from it's parents before being + ///< attached to the current XMLNode + XMLAttribute *addAttribute(XMLCSTR lpszName, + XMLCSTR lpszValuev); ///< Add a new attribute + XMLCSTR addText(XMLCSTR lpszValue, + XMLElementPosition pos = -1); ///< Add a new text content + XMLClear *addClear(XMLCSTR lpszValue, XMLCSTR lpszOpen = NULL, + XMLCSTR lpszClose = NULL, XMLElementPosition pos = -1); + /**< Add a new clear tag + * @param lpszOpen default value "" + */ + /** @} */ + + /** @defgroup xmlUpdate Updating Nodes + * @ingroup xmlModify + * Some update functions: + * @{ + */ + XMLCSTR updateName(XMLCSTR lpszName); ///< change node's name + XMLAttribute *updateAttribute( + XMLAttribute *newAttribute, + XMLAttribute *oldAttribute); ///< if the attribute to update is missing, + ///< a new one will be added + XMLAttribute *updateAttribute( + XMLCSTR lpszNewValue, XMLCSTR lpszNewName = NULL, + int i = 0); ///< if the attribute to update is missing, a new one will be + ///< added + XMLAttribute *updateAttribute( + XMLCSTR lpszNewValue, XMLCSTR lpszNewName, + XMLCSTR + lpszOldName); ///< set lpszNewName=NULL if you don't want to change + ///< the name of the attribute if the attribute to + ///< update is missing, a new one will be added + XMLCSTR updateText(XMLCSTR lpszNewValue, + int i = 0); ///< if the text to update is missing, a new + ///< one will be added + XMLCSTR updateText( + XMLCSTR lpszNewValue, + XMLCSTR lpszOldValue); ///< if the text to update is missing, a new one + ///< will be added + XMLClear *updateClear(XMLCSTR lpszNewContent, + int i = 0); ///< if the clearTag to update is missing, + ///< a new one will be added + XMLClear *updateClear(XMLClear *newP, + XMLClear *oldP); ///< if the clearTag to update is + ///< missing, a new one will be added + XMLClear *updateClear( + XMLCSTR lpszNewValue, + XMLCSTR lpszOldValue); ///< if the clearTag to update is missing, a new + ///< one will be added + /** @} */ + + /** @defgroup xmlDelete Deleting Nodes or Attributes + * @ingroup xmlModify + * Some deletion functions: + * @{ + */ + /// The "deleteNodeContent" function forces the deletion of the content of + /// this XMLNode and the subtree. + void deleteNodeContent(); + /**< \note The XMLNode instances that are referring to the part of the subtree + * that has been deleted CANNOT be used anymore!!. Unexpected results will + * occur if you continue using them. */ + void deleteAttribute( + int i = 0); ///< Delete the ith attribute of the current XMLNode + void deleteAttribute( + XMLCSTR lpszName); ///< Delete the attribute with the given name (the + ///< "strcmp" function is used to find the right + ///< attribute) + void deleteAttribute( + XMLAttribute + *anAttribute); ///< Delete the attribute with the name + ///< "anAttribute->lpszName" (the "strcmp" function is + ///< used to find the right attribute) + void deleteText( + int i = 0); ///< Delete the Ith text content of the current XMLNode + void deleteText( + XMLCSTR lpszValue); ///< Delete the text content "lpszValue" inside the + ///< current XMLNode (direct "pointer-to-pointer" + ///< comparison is used to find the right text) + void deleteClear( + int i = 0); ///< Delete the Ith clear tag inside the current XMLNode + void deleteClear( + XMLCSTR lpszValue); ///< Delete the clear tag "lpszValue" inside the + ///< current XMLNode (direct "pointer-to-pointer" + ///< comparison is used to find the clear tag) + void deleteClear( + XMLClear + *p); ///< Delete the clear tag "p" inside the current XMLNode (direct + ///< "pointer-to-pointer" comparison on the lpszName of the + ///< clear tag is used to find the clear tag) + /** @} */ + + /** @defgroup xmlWOSD ???_WOSD functions. + * @ingroup xmlModify + * The strings given as parameters for the "add" and "update" methods that + * have a name with the postfix "_WOSD" (that means "WithOut String + * Duplication")(for example "addText_WOSD") will be free'd by the XMLNode + * class. For example, it means that this is incorrect: \code + * xNode.addText_WOSD("foo"); + * xNode.updateAttribute_WOSD("#newcolor" ,NULL,"color"); + * \endcode + * In opposition, this is correct: + * \code + * xNode.addText("foo"); + * xNode.addText_WOSD(stringDup("foo")); + * xNode.updateAttribute("#newcolor" ,NULL,"color"); + * xNode.updateAttribute_WOSD(stringDup("#newcolor"),NULL,"color"); + * \endcode + * Typically, you will never do: + * \code + * char *b=(char*)malloc(...); + * xNode.addText(b); + * free(b); + * \endcode + * ... but rather: + * \code + * char *b=(char*)malloc(...); + * xNode.addText_WOSD(b); + * \endcode + * ('free(b)' is performed by the XMLNode class) + * @{ */ + static XMLNode createXMLTopNode_WOSD( + XMLSTR lpszName, + char isDeclaration = + FALSE); ///< Create the top node of an XMLNode structure + XMLNode addChild_WOSD(XMLSTR lpszName, char isDeclaration = FALSE, + XMLElementPosition pos = -1); ///< Add a new child node + XMLAttribute *addAttribute_WOSD(XMLSTR lpszName, + XMLSTR lpszValue); ///< Add a new attribute + XMLCSTR addText_WOSD(XMLSTR lpszValue, XMLElementPosition pos = + -1); ///< Add a new text content + XMLClear *addClear_WOSD( + XMLSTR lpszValue, XMLCSTR lpszOpen = NULL, XMLCSTR lpszClose = NULL, + XMLElementPosition pos = -1); ///< Add a new clear Tag + + XMLCSTR updateName_WOSD(XMLSTR lpszName); ///< change node's name + XMLAttribute *updateAttribute_WOSD( + XMLAttribute *newAttribute, + XMLAttribute *oldAttribute); ///< if the attribute to update is missing, + ///< a new one will be added + XMLAttribute *updateAttribute_WOSD( + XMLSTR lpszNewValue, XMLSTR lpszNewName = NULL, + int i = 0); ///< if the attribute to update is missing, a new one will be + ///< added + XMLAttribute *updateAttribute_WOSD( + XMLSTR lpszNewValue, XMLSTR lpszNewName, + XMLCSTR + lpszOldName); ///< set lpszNewName=NULL if you don't want to change + ///< the name of the attribute if the attribute to + ///< update is missing, a new one will be added + XMLCSTR updateText_WOSD(XMLSTR lpszNewValue, + int i = 0); ///< if the text to update is missing, a + ///< new one will be added + XMLCSTR updateText_WOSD( + XMLSTR lpszNewValue, + XMLCSTR lpszOldValue); ///< if the text to update is missing, a new one + ///< will be added + XMLClear *updateClear_WOSD(XMLSTR lpszNewContent, + int i = 0); ///< if the clearTag to update is + ///< missing, a new one will be added + XMLClear *updateClear_WOSD( + XMLClear *newP, XMLClear *oldP); ///< if the clearTag to update is + ///< missing, a new one will be added + XMLClear *updateClear_WOSD( + XMLSTR lpszNewValue, + XMLCSTR lpszOldValue); ///< if the clearTag to update is missing, a new + ///< one will be added + /** @} */ + + /** @defgroup xmlPosition Position helper functions (use in conjunction with + * the update&add functions + * @ingroup xmlModify + * These are some useful functions when you want to insert a childNode, a text + * or a XMLClearTag in the middle (at a specified position) of a XMLNode tree + * already constructed. The value returned by these methods is to be used as + * last parameter (parameter 'pos') of addChild, addText or addClear. + * @{ */ + XMLElementPosition positionOfText(int i = 0) const; + XMLElementPosition positionOfText(XMLCSTR lpszValue) const; + XMLElementPosition positionOfClear(int i = 0) const; + XMLElementPosition positionOfClear(XMLCSTR lpszValue) const; + XMLElementPosition positionOfClear(XMLClear *a) const; + XMLElementPosition positionOfChildNode(int i = 0) const; + XMLElementPosition positionOfChildNode(XMLNode x) const; + XMLElementPosition positionOfChildNode(XMLCSTR name, int i = 0) + const; ///< return the position of the ith childNode with the specified + ///< name if (name==NULL) return the position of the ith childNode + /** @} */ + + /// Enumeration for XML character encoding. + typedef enum XMLCharEncoding { + char_encoding_error = 0, + char_encoding_UTF8 = 1, + char_encoding_legacy = 2, + char_encoding_ShiftJIS = 3, + char_encoding_GB2312 = 4, + char_encoding_Big5 = 5, + char_encoding_GBK = 6 // this is actually the same as Big5 + } XMLCharEncoding; + + /** \addtogroup conversions + * @{ */ + + /// Sets the global options for the conversions + static char setGlobalOptions( + XMLCharEncoding characterEncoding = XMLNode::char_encoding_UTF8, + char guessWideCharChars = 1, char dropWhiteSpace = 1, + char removeCommentsInMiddleOfText = 1); + /**< The "setGlobalOptions" function allows you to change four global + * parameters that affect string & file parsing. First of all, you + * most-probably will never have to change these 3 global parameters. + * + * @param guessWideCharChars If "guessWideCharChars"=1 and if this library is + * compiled in WideChar mode, then the XMLNode::parseFile and + * XMLNode::openFileHelper functions will test if the file contains ASCII + * characters. If this is the case, then the file will be loaded and + * converted in memory to WideChar before being parsed. If 0, no conversion + * will be performed. + * + * @param guessWideCharChars If "guessWideCharChars"=1 and if this library is + * compiled in ASCII/UTF8/char* mode, then the XMLNode::parseFile and + * XMLNode::openFileHelper functions will test if the file contains WideChar + * characters. If this is the case, then the file will be loaded and + * converted in memory to ASCII/UTF8/char* before being parsed. If 0, no + * conversion will be performed. + * + * @param characterEncoding This parameter is only meaningful when compiling + * in char* mode (multibyte character mode). In wchar_t* (wide char mode), + * this parameter is ignored. This parameter should be one of the three + * currently recognized encodings: XMLNode::encoding_UTF8, + * XMLNode::encoding_ascii, XMLNode::encoding_ShiftJIS. + * + * @param dropWhiteSpace In most situations, text fields containing only white + * spaces (and carriage returns) are useless. Even more, these "empty" text + * fields are annoying because they increase the complexity of the user's code + * for parsing. So, 99% of the time, it's better to drop the "empty" text + * fields. However The XML specification indicates that no white spaces should + * be lost when parsing the file. So to be perfectly XML-compliant, you should + * set dropWhiteSpace=0. A note of caution: if you set "dropWhiteSpace=0", the + * parser will be slower and your code will be more complex. + * + * @param removeCommentsInMiddleOfText To explain this parameter, let's + * consider this code: \code XMLNode x=XMLNode::parseString("foobarchu","a"); \endcode If + * removeCommentsInMiddleOfText=0, then we will have: \code x.getText(0) -> + * "foo" x.getText(1) -> "bar" x.getText(2) -> "chu" x.getClear(0) --> "" x.getClear(1) --> "" \endcode If + * removeCommentsInMiddleOfText=1, then we will have: \code x.getText(0) -> + * "foobar" x.getText(1) -> "chu" x.getClear(0) --> "" + * \endcode + * + * \return "0" when there are no errors. If you try to set an unrecognized + * encoding then the return value will be "1" to signal an error. + * + * \note Sometime, it's useful to set "guessWideCharChars=0" to disable any + * conversion because the test to detect the file-type (ASCII/UTF8/char* or + * WideChar) may fail (rarely). */ + + /// Guess the character encoding of the string (ascii, utf8 or shift-JIS) + static XMLCharEncoding guessCharEncoding(void *buffer, int bufLen, + char useXMLEncodingAttribute = 1); + /**< The "guessCharEncoding" function try to guess the character encoding. You + * most-probably will never have to use this function. It then returns the + * appropriate value of the global parameter "characterEncoding" described in + * the XMLNode::setGlobalOptions. The guess is based on the content of a + * buffer of length "bufLen" bytes that contains the first bytes (minimum 25 + * bytes; 200 bytes is a good value) of the file to be parsed. The + * XMLNode::openFileHelper function is using this function to automatically + * compute the value of the "characterEncoding" global parameter. There are + * several heuristics used to do the guess. One of the heuristic is based on + * the "encoding" attribute. The original XML specifications forbids to use + * this attribute to do the guess but you can still use it if you set + * "useXMLEncodingAttribute" to 1 (this is the default behavior and the + * behavior of most parsers). + * If an inconsistency in the encoding is detected, then the return value is + * "0". */ + /** @} */ + + private: + // these are functions and structures used internally by the XMLNode class + // (don't bother about them): + + typedef struct XMLNodeDataTag // to allow shallow copy and + // "intelligent/smart" pointers (automatic + // delete): + { + XMLCSTR lpszName; // Element name (=NULL if root) + int nChild, // Number of child nodes + nText, // Number of text fields + nClear, // Number of Clear fields (comments) + nAttribute; // Number of attributes + char isDeclaration; // Whether node is an XML declaration - '' + struct XMLNodeDataTag + *pParent; // Pointer to parent element (=NULL if root) + XMLNode *pChild; // Array of child nodes + XMLCSTR *pText; // Array of text fields + XMLClear *pClear; // Array of clear fields + XMLAttribute *pAttribute; // Array of attributes + int *pOrder; // order of the child_nodes,text_fields,clear_fields + int ref_count; // for garbage collection (smart pointers) + } XMLNodeData; + XMLNodeData *d; + + char parseClearTag(void *px, void *pa); + char maybeAddTxT(void *pa, XMLCSTR tokenPStr); + int ParseXMLElement(void *pXML); + void *addToOrder(int memInc, int *_pos, int nc, void *p, int size, + XMLElementType xtype); + int indexText(XMLCSTR lpszValue) const; + int indexClear(XMLCSTR lpszValue) const; + XMLNode addChild_priv(int, XMLSTR, char, int); + XMLAttribute *addAttribute_priv(int, XMLSTR, XMLSTR); + XMLCSTR addText_priv(int, XMLSTR, int); + XMLClear *addClear_priv(int, XMLSTR, XMLCSTR, XMLCSTR, int); + void emptyTheNode(char force); + static inline XMLElementPosition findPosition(XMLNodeData *d, int index, + XMLElementType xtype); + static int CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, + int nFormat); + static int removeOrderElement(XMLNodeData *d, XMLElementType t, int index); + static void exactMemory(XMLNodeData *d); + static int detachFromParent(XMLNodeData *d); } XMLNode; /// This structure is given by the function XMLNode::enumContents. -typedef struct XMLNodeContents -{ - /// This dictates what's the content of the XMLNodeContent - enum XMLElementType etype; - /**< should be an union to access the appropriate data. Compiler does not allow union of object with constructor... too bad. */ - XMLNode child; - XMLAttribute attrib; - XMLCSTR text; - XMLClear clear; +typedef struct XMLNodeContents { + /// This dictates what's the content of the XMLNodeContent + enum XMLElementType etype; + /**< should be an union to access the appropriate data. Compiler does not + * allow union of object with constructor... too bad. */ + XMLNode child; + XMLAttribute attrib; + XMLCSTR text; + XMLClear clear; } XMLNodeContents; -/** @defgroup StringAlloc String Allocation/Free functions - * @ingroup xmlModify - * @{ */ +/** @defgroup StringAlloc String Allocation/Free functions + * @ingroup xmlModify + * @{ */ /// Duplicate (copy in a new allocated buffer) the source string. -XMLDLLENTRY XMLSTR stringDup(XMLCSTR source, int cbData=-1); -/**< This is - * a very handy function when used with all the "XMLNode::*_WOSD" functions (\link xmlWOSD \endlink). - * @param cbData If !=0 then cbData is the number of chars to duplicate. New strings allocated with - * this function should be free'd using the "freeXMLString" function. */ - -/// to free the string allocated inside the "stringDup" function or the "createXMLString" function. -XMLDLLENTRY void freeXMLString(XMLSTR t); // {free(t);} -/** @} */ +XMLDLLENTRY XMLSTR stringDup(XMLCSTR source, int cbData = -1); +/**< This is + * a very handy function when used with all the "XMLNode::*_WOSD" functions + * (\link xmlWOSD \endlink). + * @param cbData If !=0 then cbData is the number of chars to duplicate. New + * strings allocated with this function should be free'd using the + * "freeXMLString" function. */ + +/// to free the string allocated inside the "stringDup" function or the +/// "createXMLString" function. +XMLDLLENTRY void freeXMLString(XMLSTR t); // {free(t);} +/** @} */ /** @defgroup atoX ato? like functions - * @ingroup XMLParserGeneral + * @ingroup XMLParserGeneral * The "xmlto?" functions are equivalents to the atoi, atol, atof functions. - * The only difference is: If the variable "xmlString" is NULL, than the return value - * is "defautValue". These 6 functions are only here as "convenience" functions for the - * user (they are not used inside the XMLparser). If you don't need them, you can - * delete them without any trouble. + * The only difference is: If the variable "xmlString" is NULL, than the return + * value is "defautValue". These 6 functions are only here as "convenience" + * functions for the user (they are not used inside the XMLparser). If you don't + * need them, you can delete them without any trouble. * * @{ */ -XMLDLLENTRY char xmltob(XMLCSTR xmlString,char defautValue=0); -XMLDLLENTRY int xmltoi(XMLCSTR xmlString,int defautValue=0); -XMLDLLENTRY long xmltol(XMLCSTR xmlString,long defautValue=0); -XMLDLLENTRY double xmltof(XMLCSTR xmlString,double defautValue=.0); -XMLDLLENTRY XMLCSTR xmltoa(XMLCSTR xmlString,XMLCSTR defautValue=_CXML("")); -XMLDLLENTRY XMLCHAR xmltoc(XMLCSTR xmlString,XMLCHAR defautValue=_CXML('\0')); +XMLDLLENTRY char xmltob(XMLCSTR xmlString, char defautValue = 0); +XMLDLLENTRY int xmltoi(XMLCSTR xmlString, int defautValue = 0); +XMLDLLENTRY long xmltol(XMLCSTR xmlString, long defautValue = 0); +XMLDLLENTRY double xmltof(XMLCSTR xmlString, double defautValue = .0); +XMLDLLENTRY XMLCSTR xmltoa(XMLCSTR xmlString, XMLCSTR defautValue = _CXML("")); +XMLDLLENTRY XMLCHAR xmltoc(XMLCSTR xmlString, + XMLCHAR defautValue = _CXML('\0')); /** @} */ -/** @defgroup ToXMLStringTool Helper class to create XML files using "printf", "fprintf", "cout",... functions. - * @ingroup XMLParserGeneral +/** @defgroup ToXMLStringTool Helper class to create XML files using "printf", + * "fprintf", "cout",... functions. + * @ingroup XMLParserGeneral * @{ */ -/// Helper class to create XML files using "printf", "fprintf", "cout",... functions. -/** The ToXMLStringTool class helps you creating XML files using "printf", "fprintf", "cout",... functions. - * The "ToXMLStringTool" class is processing strings so that all the characters +/// Helper class to create XML files using "printf", "fprintf", "cout",... +/// functions. +/** The ToXMLStringTool class helps you creating XML files using "printf", + * "fprintf", "cout",... functions. The "ToXMLStringTool" class is processing + * strings so that all the characters * &,",',<,> are replaced by their XML equivalent: * \verbatim &, ", ', <, > \endverbatim - * Using the "ToXMLStringTool class" and the "fprintf function" is THE most efficient - * way to produce VERY large XML documents VERY fast. - * \note If you are creating from scratch an XML file using the provided XMLNode class - * you must not use the "ToXMLStringTool" class (because the "XMLNode" class does the + * Using the "ToXMLStringTool class" and the "fprintf function" is THE most + * efficient way to produce VERY large XML documents VERY fast. \note If you are + * creating from scratch an XML file using the provided XMLNode class you must + * not use the "ToXMLStringTool" class (because the "XMLNode" class does the * processing job for you during rendering).*/ -typedef struct XMLDLLENTRY ToXMLStringTool -{ -public: - ToXMLStringTool(): buf(NULL),buflen(0){} - ~ToXMLStringTool(); - void freeBuffer();///