SeparableAllocator.cc revision 10447:a465576671d4
1#include "model/electrical/SeparableAllocator.h" 2 3#include "model/ModelGen.h" 4#include "model/timing_graph/ElectricalNet.h" 5 6namespace DSENT 7{ 8 SeparableAllocator::SeparableAllocator(const String& instance_name_, const TechModel* tech_model_) 9 : ElectricalModel(instance_name_, tech_model_) 10 { 11 initParameters(); 12 initProperties(); 13 } 14 15 SeparableAllocator::~SeparableAllocator() 16 {} 17 18 void SeparableAllocator::initParameters() 19 { 20 addParameterName("NumberRequesters"); 21 addParameterName("NumberResources"); 22 addParameterName("IsRequesterFirst", true); 23 addParameterName("Stage1->ArbiterModel"); 24 addParameterName("Stage2->ArbiterModel"); 25 return; 26 } 27 28 void SeparableAllocator::initProperties() 29 { 30 addPropertyName("P(Request)"); 31 addPropertyName("Act(Request)"); 32 addPropertyName("P(CK)"); 33 addPropertyName("Act(CK)"); 34 return; 35 } 36 37 SeparableAllocator* SeparableAllocator::clone() const 38 { 39 // TODO 40 return NULL; 41 } 42 43 void SeparableAllocator::constructModel() 44 { 45 // Get parameters 46 unsigned int number_requesters = getParameter("NumberRequesters").toUInt(); 47 unsigned int number_resources = getParameter("NumberResources").toUInt(); 48 bool is_requester_first = getParameter("IsRequesterFirst").toBool(); 49 const String& stage1_arbiter_model = getParameter("Stage1->ArbiterModel"); 50 const String& stage2_arbiter_model = getParameter("Stage2->ArbiterModel"); 51 52 ASSERT(number_requesters > 0, "[Error] " + getInstanceName() + 53 " -> Number of requesters must be > 0!"); 54 ASSERT(number_resources > 0, "[Error] " + getInstanceName() + 55 " -> Number of resources must be > 0!"); 56 57 // Create area, power, and event results 58 createElectricalResults(); 59 addEventResult(new Result("Allocate")); 60 61 // Create ports 62 createInputPort("CK"); 63 for(unsigned int i = 0; i < number_requesters; ++i) 64 { 65 createInputPort("Request" + (String)i, makeNetIndex(0, number_resources-1)); 66 createOutputPort("Grant" + (String)i, makeNetIndex(0, number_resources-1)); 67 } 68 69 // If is_requester_first is set, requests from the same requester will be arbitrate 70 // on stage 1 71 if(is_requester_first) 72 { 73 // Init stage 1 arbiters 74 for(unsigned int i = 0; i < number_requesters; ++i) 75 { 76 ElectricalModel* arb = (ElectricalModel*)ModelGen::createModel(stage1_arbiter_model, "Stage1Arb" + (String)i, getTechModel()); 77 arb->setParameter("NumberRequests", number_resources); 78 arb->construct(); 79 80 addSubInstances(arb, 1.0); 81 addElectricalSubResults(arb, 1.0); 82 83 getEventResult("Allocate")->addSubResult(arb->getEventResult("Arbitrate"), arb->getInstanceName(), 1.0); 84 85 createNet("Stage1Arb_In" + (String)i, makeNetIndex(0, number_resources-1)); 86 createNet("Stage1Arb_Out" + (String)i, makeNetIndex(0, number_resources-1)); 87 88 portConnect(arb, "CK", "CK"); 89 assign("Stage1Arb_In" + (String)i, "Request" + (String)i); 90 for(unsigned int j = 0; j < number_resources; ++j) 91 { 92 portConnect(arb, "Request" + (String)j, "Stage1Arb_In" + (String)i, makeNetIndex(j)); 93 portConnect(arb, "Grant" + (String)j, "Stage1Arb_Out" + (String)i, makeNetIndex(j)); 94 } 95 } 96 97 // Init stage 2 arbiters 98 for(unsigned int i = 0; i < number_resources; ++i) 99 { 100 ElectricalModel* arb = (ElectricalModel*)ModelGen::createModel(stage2_arbiter_model, "Stage2Arb" + (String)i, getTechModel()); 101 arb->setParameter("NumberRequests", number_requesters); 102 arb->construct(); 103 104 addSubInstances(arb, 1.0); 105 addElectricalSubResults(arb, 1.0); 106 107 getEventResult("Allocate")->addSubResult(arb->getEventResult("Arbitrate"), arb->getInstanceName(), 1.0); 108 109 createNet("Stage2Arb_In" + (String)i, makeNetIndex(0, number_requesters-1)); 110 createNet("Stage2Arb_Out" + (String)i, makeNetIndex(0, number_requesters-1)); 111 112 portConnect(arb, "CK", "CK"); 113 for(unsigned int j = 0; j < number_requesters; ++j) 114 { 115 assign("Stage2Arb_In" + (String)i, makeNetIndex(j), "Stage1Arb_Out" + (String)j, makeNetIndex(i)); 116 portConnect(arb, "Request" + (String)j, "Stage2Arb_In" + (String)i, makeNetIndex(j)); 117 portConnect(arb, "Grant" + (String)j, "Stage2Arb_Out" + (String)i, makeNetIndex(j)); 118 assign("Grant" + (String)j, makeNetIndex(i), "Stage2Arb_Out" + (String)i, makeNetIndex(j)); 119 } 120 } 121 } 122 else 123 { 124 // Init stage 1 arbiters 125 for(unsigned int i = 0; i < number_resources; ++i) 126 { 127 ElectricalModel* arb = (ElectricalModel*)ModelGen::createModel(stage1_arbiter_model, "Stage1Arb" + (String)i, getTechModel()); 128 arb->setParameter("NumberRequests", number_requesters); 129 arb->construct(); 130 131 addSubInstances(arb, 1.0); 132 addElectricalSubResults(arb, 1.0); 133 134 getEventResult("Allocate")->addSubResult(arb->getEventResult("Arbitrate"), arb->getInstanceName(), 1.0); 135 136 createNet("Stage1Arb_In" + (String)i, makeNetIndex(0, number_requesters-1)); 137 createNet("Stage1Arb_Out" + (String)i, makeNetIndex(0, number_requesters-1)); 138 139 portConnect(arb, "CK", "CK"); 140 for(unsigned int j = 0; j < number_requesters; ++j) 141 { 142 assign("Stage1Arb_In" + (String)i, makeNetIndex(j), "Request" + (String)j, makeNetIndex(i)); 143 portConnect(arb, "Request" + (String)j, "Stage1Arb_In" + (String)i, makeNetIndex(j)); 144 portConnect(arb, "Grant" + (String)j, "Stage1Arb_Out" + (String)i, makeNetIndex(j)); 145 } 146 } 147 148 // Init stage 2 arbiters 149 for(unsigned int i = 0; i < number_requesters; ++i) 150 { 151 ElectricalModel* arb = (ElectricalModel*)ModelGen::createModel(stage2_arbiter_model, "Stage2Arb" + (String)i, getTechModel()); 152 arb->setParameter("NumberRequests", number_requesters); 153 arb->construct(); 154 155 addSubInstances(arb, 1.0); 156 addElectricalSubResults(arb, 1.0); 157 158 getEventResult("Allocate")->addSubResult(arb->getEventResult("Arbitrate"), arb->getInstanceName(), 1.0); 159 160 createNet("Stage2Arb_In" + (String)i, makeNetIndex(0, number_resources-1)); 161 createNet("Stage2Arb_Out" + (String)i, makeNetIndex(0, number_resources-1)); 162 163 portConnect(arb, "CK", "CK"); 164 for(unsigned int j = 0; j < number_resources; ++j) 165 { 166 assign("Stage2Arb_In" + (String)i, makeNetIndex(j), "Stage1Arb_Out" + (String)j, makeNetIndex(i)); 167 portConnect(arb, "Request" + (String)j, "Stage2Arb_In", makeNetIndex(j)); 168 portConnect(arb, "Grant" + (String)j, "Stage2Arb_Out", makeNetIndex(j)); 169 } 170 assign("Grant" + (String)i, "Stage2Arb_Out" + (String)i); 171 } 172 } 173 return; 174 } 175 176 void SeparableAllocator::updateModel() 177 { 178 // Get parameters 179 unsigned int number_requesters = getParameter("NumberRequesters").toUInt(); 180 unsigned int number_resources = getParameter("NumberResources").toUInt(); 181 bool is_requester_first = getParameter("IsRequesterFirst").toBool(); 182 183 // Get probabilities from inputs 184 const String& P_request = getProperty("P(Request)"); 185 const String& act_request = getProperty("Act(Request)"); 186 const String& P_CK = getProperty("P(CK)"); 187 const String& act_CK = getProperty("Act(CK)"); 188 189 const vector<double>& P_request_vector = LibUtil::castStringVector<double>(P_request.split("[,]")); 190 const vector<double>& act_request_vector = LibUtil::castStringVector<double>(act_request.split("[,]")); 191 192 ASSERT(P_request_vector.size() == (number_requesters * number_resources), "[Error] " + getInstanceName() + 193 " -> Expecting " + (String)(number_requesters * number_resources) + 194 " request probabilities, but got " + P_request); 195 ASSERT(act_request_vector.size() == (number_requesters * number_resources), "[Error] " + getInstanceName() + 196 " -> Expecting " + (String)(number_requesters * number_resources) + 197 " request actvities multiplier, but got " + act_request); 198 199 vector<double> P_int_request_vector(number_requesters * number_resources, 0.0); 200 vector<double> act_int_request_vector(number_requesters * number_resources, 0.0); 201 vector<double> P_out_request_vector(number_requesters * number_resources, 0.0); 202 vector<double> act_out_request_vector(number_requesters * number_resources, 0.0); 203 if(is_requester_first) 204 { 205 // Update stage1 arbiter 206 for(unsigned int i = 0; i < number_requesters; ++i) 207 { 208 vector<double> P_arb_request_vector(number_resources, 0.0); 209 vector<double> act_arb_request_vector(number_resources, 0.0); 210 for(unsigned int j = 0; j < number_resources; ++j) 211 { 212 P_arb_request_vector[j] = P_request_vector[i * number_resources + j]; 213 act_arb_request_vector[j] = act_request_vector[i * number_resources + j]; 214 } 215 216 Model* arb = getSubInstance("Stage1Arb" + (String)i); 217 arb->setProperty("P(Request)", LibUtil::vectorToString(P_arb_request_vector)); 218 arb->setProperty("Act(Request)", LibUtil::vectorToString(act_arb_request_vector)); 219 arb->setProperty("P(CK)", P_CK); 220 arb->setProperty("Act(CK)", act_CK); 221 arb->update(); 222 223 const vector<double>& P_arb_out_request_vector = LibUtil::castStringVector<double>(arb->getGenProperties()->get("P(Grant)").split("[,]")); 224 const vector<double>& act_arb_out_request_vector = LibUtil::castStringVector<double>(arb->getGenProperties()->get("Act(Grant)").split("[,]")); 225 for(unsigned int j = 0; j < number_resources; ++j) 226 { 227 P_int_request_vector[i * number_resources + j] = P_arb_out_request_vector[j]; 228 act_int_request_vector[i * number_resources + j] = act_arb_out_request_vector[j]; 229 } 230 } 231 // Update stage2 arbiter 232 for(unsigned int i = 0; i < number_resources; ++i) 233 { 234 vector<double> P_arb_request_vector(number_requesters, 0.0); 235 vector<double> act_arb_request_vector(number_requesters, 0.0); 236 for(unsigned int j = 0; j < number_requesters; ++j) 237 { 238 P_arb_request_vector[j] = P_int_request_vector[j * number_resources + i]; 239 act_arb_request_vector[j] = act_int_request_vector[j * number_resources + i]; 240 } 241 242 Model* arb = getSubInstance("Stage2Arb" + (String)i); 243 arb->setProperty("P(Request)", LibUtil::vectorToString(P_arb_request_vector)); 244 arb->setProperty("Act(Request)", LibUtil::vectorToString(act_arb_request_vector)); 245 arb->setProperty("P(CK)", P_CK); 246 arb->setProperty("Act(CK)", act_CK); 247 arb->update(); 248 249 const vector<double>& P_arb_out_request_vector = LibUtil::castStringVector<double>(arb->getGenProperties()->get("P(Grant)").split("[,]")); 250 const vector<double>& act_arb_out_request_vector = LibUtil::castStringVector<double>(arb->getGenProperties()->get("Act(Grant)").split("[,]")); 251 for(unsigned int j = 0; j < number_requesters; ++j) 252 { 253 P_out_request_vector[j * number_resources + i] = P_arb_out_request_vector[j]; 254 act_out_request_vector[j * number_resources + i] = act_arb_out_request_vector[j]; 255 } 256 } 257 } 258 else 259 { 260 261 } 262 263 // Update output probabilities 264 getGenProperties()->set("P(Grant)", LibUtil::vectorToString(P_out_request_vector)); 265 getGenProperties()->set("Act(Grant)", LibUtil::vectorToString(act_out_request_vector)); 266 267 return; 268 } 269} // namespace DSENT 270 271