Cluster *Cluster::create(const char *clusterName, GMemorySystem *ms, GProcessor *gproc) { // Note: Clusters do NOT share functional units. This breaks the cluster // principle. If someone were interested in doing that, the UnitMap sould be // cleared (unitMap.clear()) by the PendingWindow instead of buildCluster. If // the objective is to share the FUs even between Cores, UnitMap must be // declared static in that class (what a mess!) unitMap.clear(); // Constraints SescConf->isCharPtr(clusterName,"recycleAt"); SescConf->isInList(clusterName,"recycleAt","Execute","Retire","Issue"); //NM added Issue const char *recycleAt = SescConf->getCharPtr(clusterName,"recycleAt"); SescConf->isLong(clusterName,"winSize"); SescConf->isBetween(clusterName,"winSize",1,262144); Cluster *cluster; if( strcasecmp(recycleAt,"retire") == 0) { cluster = new RetiredCluster(clusterName, gproc); }else if( strcasecmp(recycleAt,"issue") == 0) { //NM added issue cluster = new IssuedCluster(clusterName, gproc); }else{ I( strcasecmp(recycleAt,"execute") == 0); cluster = new ExecutedCluster(clusterName, gproc); } char strtmp[128]; sprintf(strtmp,"%s_energy",clusterName); GStatsEnergyCGBase *ecgbase = new GStatsEnergyCGBase(strtmp,gproc->getId()); cluster->buildUnit(clusterName,ms,cluster,iALU,ecgbase); cluster->buildUnit(clusterName,ms,cluster,iMult,ecgbase); cluster->buildUnit(clusterName,ms,cluster,iDiv,ecgbase); cluster->buildUnit(clusterName,ms,cluster,iBJ,ecgbase); cluster->buildUnit(clusterName,ms,cluster,iLoad,ecgbase); cluster->buildUnit(clusterName,ms,cluster,iStore,ecgbase); cluster->buildUnit(clusterName,ms,cluster,fpALU,ecgbase); cluster->buildUnit(clusterName,ms,cluster,fpMult,ecgbase); cluster->buildUnit(clusterName,ms,cluster,fpDiv,ecgbase); // Do not leave useless garbage unitMap.clear(); return cluster; }
Cluster *Cluster::create(const char *clusterName, GMemorySystem *ms, GProcessor *gproc) { // Note: Clusters do NOT share functional units. This breaks the cluster // principle. If someone were interested in doing that, the UnitMap sould be // cleared (unitMap.clear()) by the PendingWindow instead of buildCluster. If // the objective is to share the FUs even between Cores, UnitMap must be // declared static in that class (what a mess!) unitMap.clear(); // Constraints SescConf->isCharPtr(clusterName,"recycleAt"); SescConf->isInList(clusterName,"recycleAt","Executing","Execute","Retire"); const char *recycleAt = SescConf->getCharPtr(clusterName,"recycleAt"); SescConf->isInt(clusterName,"winSize"); SescConf->isBetween(clusterName,"winSize",1,262144); Cluster *cluster; if( strcasecmp(recycleAt,"retire") == 0) { cluster = new RetiredCluster(clusterName, gproc); }else if( strcasecmp(recycleAt,"executing") == 0) { cluster = new ExecutingCluster(clusterName, gproc); }else{ I( strcasecmp(recycleAt,"execute") == 0); cluster = new ExecutedCluster(clusterName, gproc); } cluster->regPool = SescConf->getInt(clusterName, "nRegs"); SescConf->isInt(clusterName , "nRegs"); SescConf->isBetween(clusterName , "nRegs", 16, 262144); for(int32_t t = 0; t < iMAX; t++) { cluster->buildUnit(clusterName,ms,cluster,static_cast<InstOpcode>(t)); } // Do not leave useless garbage unitMap.clear(); return cluster; }
void Cluster::buildUnit(const char *clusterName ,GMemorySystem *ms ,Cluster *cluster ,InstOpcode type) { const char *unitType = Instruction::opcode2Name(type); char utUnit[1024]; char utLat[1024]; sprintf(utUnit,"%sUnit",unitType); sprintf(utLat,"%sLat",unitType); if( !SescConf->checkCharPtr(clusterName,utUnit) ) return; const char *unitName = SescConf->getCharPtr(clusterName,utUnit); TimeDelta_t lat = SescConf->getInt(clusterName,utLat); PortGeneric *gen; SescConf->isBetween(clusterName,utLat,0,1024); UnitMapType::const_iterator it = unitMap.find(unitName); if( it != unitMap.end() ) { gen = it->second.gen; }else{ UnitEntry e; e.num = SescConf->getInt(unitName,"Num"); SescConf->isLT(unitName,"Num",1024); e.occ = SescConf->getInt(unitName,"occ"); SescConf->isBetween(unitName,"occ",0,1024); char name[1024]; sprintf(name,"%s(%d)", unitName, (int)gproc->getId()); e.gen = PortGeneric::create(name,e.num,e.occ); unitMap[unitName] = e; gen = e.gen; } Resource *r=0; char name[100]; sprintf(name, "Cluster(%d)", (int)gproc->getId()); bool scooreMemory=false; if (SescConf->checkBool("cpusimu", "scooreMemory",gproc->getId())) scooreMemory=SescConf->getBool("cpusimu", "scooreMemory",gproc->getId()); bool noMemSpec = SescConf->getBool("cpusimu", "noMemSpec",gproc->getId()); switch(type) { case iOpInvalid: case iRALU: r = new FURALU(cluster, gen, lat, scooreMemory, gproc->getId()); break ; case iAALU: case iCALU_FPMULT: case iCALU_FPDIV: case iCALU_FPALU: case iCALU_MULT: case iCALU_DIV: r = new FUGeneric(cluster, gen, lat); break ; case iFUZE: //ESESC_FUZE FIXME: IANLEE1521 r = new FUFuze(cluster, gen, lat); //r = new FUGeneric(cluster, gen, lat); break; case iBALU_LBRANCH: case iBALU_LJUMP: case iBALU_LCALL: case iBALU_RBRANCH: case iBALU_RJUMP: case iBALU_RCALL: case iBALU_RET: { int32_t MaxBranches = SescConf->getInt("cpusimu", "maxBranches", gproc->getId()); if( MaxBranches == 0 ) MaxBranches = INT_MAX; r = new FUBranch(cluster, gen, lat, MaxBranches); } break; case iLALU_LD: { if(scooreMemory){ r = new FUSCOORELoad(cluster, gen, gproc->getSS(), lat, ms, gproc->getId(), "scooreld"); }else{ TimeDelta_t ldstdelay=SescConf->getInt("cpusimu", "stForwardDelay",gproc->getId()); SescConf->isInt("cpusimu", "maxLoads",gproc->getId()); SescConf->isBetween("cpusimu", "maxLoads", 0, 256*1024, gproc->getId()); int32_t maxLoads=SescConf->getInt("cpusimu", "maxLoads",gproc->getId()); if( maxLoads == 0 ) maxLoads = 256*1024; if(noMemSpec){ r = new FULoad_noMemSpec(cluster, gen, ldstdelay, lat, ms, maxLoads, gproc->getId(), "nonspecld"); }else{ r = new FULoad(cluster, gen, gproc->getLSQ(), gproc->getSS(), ldstdelay, lat, ms, maxLoads, gproc->getId(), "specld"); } } } break; case iSALU_LL: case iSALU_SC: case iSALU_ST: case iSALU_ADDR: { if(scooreMemory){ r = new FUSCOOREStore(cluster, gen, gproc->getSS(), lat, ms, gproc->getId(), "scoorest"); }else{ SescConf->isInt("cpusimu", "maxStores",gproc->getId()); SescConf->isBetween("cpusimu", "maxStores", 0, 256*1024, gproc->getId()); int32_t maxStores=SescConf->getInt("cpusimu", "maxStores",gproc->getId()); if( maxStores == 0 ) maxStores = 256*1024; if(noMemSpec){ r = new FUStore_noMemSpec(cluster, gen, lat, ms, maxStores, gproc->getId(), Instruction::opcode2Name(type)); }else{ r = new FUStore(cluster, gen, gproc->getLSQ(), gproc->getSS(), lat, ms, maxStores, gproc->getId(), Instruction::opcode2Name(type)); } } } break; default: I(0); MSG("Unknown unit type [%d] [%s]",type,Instruction::opcode2Name(type)); } I(r); I(res[type] == 0); res[type] = r; }
void Cluster::buildUnit(const char *clusterName ,GMemorySystem *ms ,Cluster *cluster ,InstType type ,GStatsEnergyCGBase *ecgbase ) { const char *unitType = Instruction::opcode2Name(type); char utUnit[1024]; char utLat[1024]; sprintf(utUnit,"%sUnit",unitType); sprintf(utLat,"%sLat",unitType); if( !SescConf->checkCharPtr(clusterName,utUnit) ) return; const char *unitName = SescConf->getCharPtr(clusterName,utUnit); TimeDelta_t lat = SescConf->getInt(clusterName,utLat); PortGeneric *gen; SescConf->isBetween(clusterName,utLat,0,1024); UnitMapType::const_iterator it = unitMap.find(unitName); if( it != unitMap.end() ) { gen = it->second.gen; }else{ UnitEntry e; e.num = SescConf->getInt(unitName,"Num"); SescConf->isLT(unitName,"Num",1024); e.occ = SescConf->getInt(unitName,"occ"); SescConf->isBetween(unitName,"occ",0,1024); char name[1024]; sprintf(name,"%s(%d)", unitName, (int)gproc->getId()); e.gen = PortGeneric::create(name,e.num,e.occ); unitMap[unitName] = e; gen = e.gen; } Resource *r=0; GStatsEnergyCG *eng; char *strtmp=0; char name[100]; sprintf(name, "Cluster(%d)", (int)gproc->getId()); switch(type) { case iOpInvalid: case iALU: strtmp = strdup("iALUEnergy"); case iMult: if(!strtmp) strtmp = strdup("iMultEnergy"); case iDiv: if(!strtmp) strtmp = strdup("iDivEnergy"); eng = new GStatsEnergyCG(static_cast<const char*>(strtmp) ,name ,gproc->getId() ,ExecPower ,EnergyMgr::get("iALUEnergy",gproc->getId()) ,ecgbase); r = new FUGeneric(cluster, gen, lat, eng); break; case fpALU: strtmp = strdup("fpALUEnergy"); case fpMult: if(!strtmp) strtmp=strdup("fpMultEnergy"); case fpDiv: if(!strtmp) strtmp=strdup("fpDivEnergy"); eng = new GStatsEnergyCG(static_cast<const char*>(strtmp) ,name ,gproc->getId() ,ExecPower ,EnergyMgr::get("fpALUEnergy", gproc->getId()) ,ecgbase); r = new FUGeneric(cluster, gen, lat, eng); break ; case iBJ: { int MaxBranches = SescConf->getInt("cpucore", "maxBranches", gproc->getId()); if( MaxBranches == 0 ) MaxBranches = INT_MAX; r = new FUBranch(cluster, gen, lat, MaxBranches); } break; case iLoad: { TimeDelta_t ldstdelay=SescConf->getInt("cpucore", "stForwardDelay",gproc->getId()); SescConf->isInt("cpucore", "maxLoads",gproc->getId()); SescConf->isBetween("cpucore", "maxLoads", 0, 256*1024, gproc->getId()); int maxLoads=SescConf->getInt("cpucore", "maxLoads",gproc->getId()); if( maxLoads == 0 ) maxLoads = 256*1024; r = new FULoad(cluster, gen, lat, ldstdelay, ms, maxLoads, gproc->getId()); } break; case iStore: { SescConf->isInt("cpucore", "maxStores",gproc->getId()); SescConf->isBetween("cpucore", "maxStores", 0, 256*1024, gproc->getId()); int maxStores=SescConf->getInt("cpucore", "maxStores",gproc->getId()); if( maxStores == 0 ) maxStores = 256*1024; r = new FUStore(cluster, gen, lat, ms, maxStores, gproc->getId()); // Those resources go together with the store unit (TODO: LD/ST unit // should go to the same cluster) if(res[iFence]==0) { res[iFence] = new FUMemory(cluster, ms, gproc->getId()); I(res[iEvent]==0); res[iEvent] = new FUEvent(cluster); } } break; default: I(0); MSG("Unknown unit type [%d] [%s]",type,Instruction::opcode2Name(type)); } I(r); I(res[type] == 0); res[type] = r; }