sim, kvm: make KvmVM a System parameter
[gem5.git] / ext / dsent / model / electrical / MatrixArbiter.cc
1 /* Copyright (c) 2012 Massachusetts Institute of Technology
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to deal
5 * in the Software without restriction, including without limitation the rights
6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 * copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 * THE SOFTWARE.
20 */
21
22 #include "model/electrical/MatrixArbiter.h"
23
24 #include <cmath>
25 #include <vector>
26
27 #include "model/PortInfo.h"
28 #include "model/EventInfo.h"
29 #include "model/TransitionInfo.h"
30 #include "model/ModelGen.h"
31 #include "model/std_cells/StdCell.h"
32 #include "model/std_cells/StdCellLib.h"
33
34 namespace DSENT
35 {
36 using std::abs;
37 using std::vector;
38
39 MatrixArbiter::MatrixArbiter(const String& instance_name_, const TechModel* tech_model_)
40 : ElectricalModel(instance_name_, tech_model_)
41 {
42 initParameters();
43 initProperties();
44 }
45
46 MatrixArbiter::~MatrixArbiter()
47 {}
48
49 void MatrixArbiter::initParameters()
50 {
51 addParameterName("NumberRequests");
52 return;
53 }
54
55 void MatrixArbiter::initProperties()
56 {
57 return;
58 }
59
60 MatrixArbiter* MatrixArbiter::clone() const
61 {
62 // TODO
63 return NULL;
64 }
65
66 void MatrixArbiter::constructModel()
67 {
68 // Get parameters
69 unsigned int number_requests = getParameter("NumberRequests").toUInt();
70
71 ASSERT(number_requests > 0, "[Error] " + getInstanceName() +
72 " -> Number of requests must be > 0!");
73
74 // Connect ports
75 createInputPort("CK");
76 for(unsigned int i = 0; i < number_requests; ++i)
77 {
78 createInputPort("Request" + (String)i);
79 createOutputPort("Grant" + (String)i);
80 }
81
82 // Create area, power, event results
83 createElectricalResults();
84 getEventInfo("Idle")->setStaticTransitionInfos();
85 getEventInfo("Idle")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0));
86 // for(unsigned int i = 0; i <= number_requests; ++i)
87 // {
88 // // Create arbitrate event with i requests
89 // createElectricalEventResult("Arbitrate" + (String)i);
90 // EventInfo* event_info = getEventInfo("Arbitrate" + (String)i);
91 // event_info->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0));
92 //
93 // for(unsigned int j = 0; j < i; ++j)
94 // {
95 // event_info->setTransitionInfo("Request" + (String)j, TransitionInfo(0.0, 0.0, 1.0));
96 // }
97 // for(unsigned int j = i; j < number_requests; ++j)
98 // {
99 // event_info->setTransitionInfo("Request" + (String)j, TransitionInfo(1.0, 0.0, 0.0));
100 //
101 // }
102 // //double P_0 = (double)(number_requests - i) / (double)(number_requests);
103 // //double P_1 = (double)(i) / (double)(number_requests);
104 // //TransitionInfo trans(P_0 * P_0, P_0 * P_1, P_1 * P_1);
105 //
106 // //for(unsigned int j = 0; j < number_requests; ++j)
107 // //{
108 // // event_info->setTransitionInfo("Request" + (String)j, trans);
109 // //}
110 // }
111 createElectricalEventResult("Arbitrate");
112 getEventInfo("Arbitrate")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0));
113 for(unsigned int i = 0; i < number_requests; ++i)
114 {
115 getEventInfo("Arbitrate")->setTransitionInfo("Request" + (String)i, TransitionInfo(0.25, 0.25, 0.25));
116 }
117
118 if(number_requests == 1)
119 {
120 assign("Grant0", "Request0");
121 }
122 else
123 {
124 // Init components
125 vector<String> g_inv_names(number_requests, "");
126 vector<StdCell*> g_invs(number_requests, NULL);
127 vector<String> g_and2_names(number_requests, "");
128 vector<StdCell*> g_and2s(number_requests, NULL);
129 for(unsigned int i = 0; i < number_requests; ++i)
130 {
131 g_inv_names[i] = "G_INV" + (String)i;
132 g_and2_names[i] = "G_AND2" + (String)i;
133 g_invs[i] = getTechModel()->getStdCellLib()->createStdCell("INV", g_inv_names[i]);
134 g_invs[i]->construct();
135 g_and2s[i] = getTechModel()->getStdCellLib()->createStdCell("AND2", g_and2_names[i]);
136 g_and2s[i]->construct();
137 }
138
139 unsigned int number_states = (number_requests - 1) * number_requests / 2;
140
141 vector<String> w_or2_names(number_states, "");
142 vector<StdCell*> w_or2s(number_states, NULL);
143 vector<String> w_and2_names(number_states, "");
144 vector<StdCell*> w_and2s(number_states, NULL);
145 vector<String> w_inv_names(number_states, "");
146 vector<StdCell*> w_invs(number_states, NULL);
147 vector<String> w_dff_names(number_states, "");
148 vector<StdCell*> w_dffs(number_states, NULL);
149 vector<String> dis_and2_names(number_states * 2, "");
150 vector<StdCell*> dis_and2s(number_states * 2, NULL);
151 vector<String> dis_inv_names(number_states, "");
152 vector<StdCell*> dis_invs(number_states, NULL);
153 unsigned int state_count = 0;
154 for(unsigned int i = 0; i < number_requests; ++i)
155 {
156 for(unsigned int j = i + 1; j < number_requests; ++j)
157 {
158 w_or2_names[state_count] = String::format("W_OR2_%d_%d", i, j);
159 w_and2_names[state_count] = String::format("W_AND2_%d_%d", i, j);
160 w_inv_names[state_count] = String::format("W_INV_%d_%d", i, j);
161 w_dff_names[state_count] = String::format("W_DFF_%d_%d", i, j);
162 w_or2s[state_count] = getTechModel()->getStdCellLib()->createStdCell("OR2", w_or2_names[state_count]);
163 w_or2s[state_count]->construct();
164 w_and2s[state_count] = getTechModel()->getStdCellLib()->createStdCell("AND2", w_and2_names[state_count]);
165 w_and2s[state_count]->construct();
166 w_invs[state_count] = getTechModel()->getStdCellLib()->createStdCell("INV", w_inv_names[state_count]);
167 w_invs[state_count]->construct();
168 w_dffs[state_count] = getTechModel()->getStdCellLib()->createStdCell("DFFQ", w_dff_names[state_count]);
169 w_dffs[state_count]->construct();
170
171 dis_inv_names[state_count] = String::format("Dis_INV_%d_%d", i, j);
172 dis_and2_names[state_count] = String::format("Dis_AND2_%d_%d", i, j);
173 dis_and2_names[state_count + number_states] = String::format("Dis_AND2_%d_%d", j, i);
174 dis_invs[state_count] = getTechModel()->getStdCellLib()->createStdCell("INV", dis_inv_names[state_count]);
175 dis_invs[state_count]->construct();
176 dis_and2s[state_count] = getTechModel()->getStdCellLib()->createStdCell("AND2", dis_and2_names[state_count]);
177 dis_and2s[state_count]->construct();
178 dis_and2s[state_count + number_states] = getTechModel()->getStdCellLib()->createStdCell("AND2", dis_and2_names[state_count + number_states]);
179 dis_and2s[state_count + number_states]->construct();
180 state_count++;
181 }
182 }
183
184 vector<String> dis_or_names(number_requests, "");
185 vector<ElectricalModel*> dis_ors(number_requests, NULL);
186 for(unsigned int i = 0; i < number_requests; ++i)
187 {
188 dis_or_names[i] = "Dis_OR" + (String)i;
189 dis_ors[i] = (ElectricalModel*)ModelGen::createModel("OR", dis_or_names[i], getTechModel());
190 dis_ors[i]->setParameter("NumberInputs", number_requests-1);
191 dis_ors[i]->setParameter("NumberBits", 1);
192 dis_ors[i]->construct();
193 }
194
195 state_count = 0;
196 for(unsigned int i = 0; i < number_requests; ++i)
197 {
198 createNet("Dis_OR_Out" + (String)i);
199 createNet("G_INV_Out" + (String)i);
200 portConnect(g_invs[i], "A", "Dis_OR_Out" + (String)i);
201 portConnect(g_invs[i], "Y", "G_INV_Out" + (String)i);
202 portConnect(g_and2s[i], "A", "Request" + (String)i);
203 portConnect(g_and2s[i], "B", "G_INV_Out" + (String)i);
204 portConnect(g_and2s[i], "Y", "Grant" + (String)i);
205
206 for(unsigned int j = i + 1; j < number_requests; ++j)
207 {
208 createNet(String::format("W_INV_Out_%d_%d", i, j));
209 createNet(String::format("W_OR2_Out_%d_%d", i, j));
210 createNet(String::format("W_AND2_Out_%d_%d", i, j));
211 createNet(String::format("W_DFF_Out_%d_%d", i, j));
212 portConnect(w_invs[state_count], "A", "Grant" + (String)i);
213 portConnect(w_invs[state_count], "Y", String::format("W_INV_Out_%d_%d", i, j));
214 portConnect(w_or2s[state_count], "A", String::format("W_DFF_Out_%d_%d", i, j));
215 portConnect(w_or2s[state_count], "B", "Grant" + (String)j);
216 portConnect(w_or2s[state_count], "Y", String::format("W_OR2_Out_%d_%d", i, j));
217 portConnect(w_and2s[state_count], "A", String::format("W_OR2_Out_%d_%d", i, j));
218 portConnect(w_and2s[state_count], "B", String::format("W_INV_Out_%d_%d", i, j));
219 portConnect(w_and2s[state_count], "Y", String::format("W_AND2_Out_%d_%d", i, j));
220 portConnect(w_dffs[state_count], "D", String::format("W_AND2_Out_%d_%d", i, j));
221 portConnect(w_dffs[state_count], "CK", "CK");
222 portConnect(w_dffs[state_count], "Q", String::format("W_DFF_Out_%d_%d", i, j));
223
224 createNet(String::format("Dis_AND2_Out_%d_%d", i, j));
225 createNet(String::format("Dis_AND2_Out_%d_%d", j, i));
226 createNet(String::format("Dis_INV_Out_%d_%d", j, i));
227 portConnect(dis_and2s[state_count], "A", "Request" + (String)i);
228 portConnect(dis_and2s[state_count], "B", String::format("W_DFF_Out_%d_%d", i, j));
229 portConnect(dis_and2s[state_count], "Y", String::format("Dis_AND2_Out_%d_%d", i, j));
230
231 portConnect(dis_invs[state_count], "A", String::format("W_DFF_Out_%d_%d", i, j));
232 portConnect(dis_invs[state_count], "Y", String::format("Dis_INV_Out_%d_%d", j, i));
233 portConnect(dis_and2s[state_count + number_states], "A", "Request" + (String)j);
234 portConnect(dis_and2s[state_count + number_states], "B", String::format("Dis_INV_Out_%d_%d", j, i));
235 portConnect(dis_and2s[state_count + number_states], "Y", String::format("Dis_AND2_Out_%d_%d", j, i));
236
237 state_count++;
238 }
239 }
240 for(unsigned int i = 0; i < number_requests; ++i)
241 {
242 unsigned int k = 0;
243 for(unsigned int j = 0; j < number_requests; ++j)
244 {
245 if(i != j)
246 {
247 portConnect(dis_ors[i], "In" + (String)k, String::format("Dis_AND2_Out_%d_%d", j, i));
248 k++;
249 }
250 }
251 portConnect(dis_ors[i], "Out", "Dis_OR_Out" + (String)i);
252 }
253
254 // Add instances
255 for(unsigned int i = 0; i < number_requests; ++i)
256 {
257 addSubInstances(g_invs[i], 1.0);
258 addElectricalSubResults(g_invs[i], 1.0);
259 addSubInstances(g_and2s[i], 1.0);
260 addElectricalSubResults(g_and2s[i], 1.0);
261 addSubInstances(dis_ors[i], 1.0);
262 addElectricalSubResults(dis_ors[i], 1.0);
263 }
264 for(unsigned int i = 0; i < number_states; ++i)
265 {
266 addSubInstances(w_or2s[i], 1.0);
267 addElectricalSubResults(w_or2s[i], 1.0);
268 addSubInstances(w_and2s[i], 1.0);
269 addElectricalSubResults(w_and2s[i], 1.0);
270 addSubInstances(w_invs[i], 1.0);
271 addElectricalSubResults(w_invs[i], 1.0);
272 addSubInstances(w_dffs[i], 1.0);
273 addElectricalSubResults(w_dffs[i], 1.0);
274 addSubInstances(dis_and2s[i], 1.0);
275 addElectricalSubResults(dis_and2s[i], 1.0);
276 addSubInstances(dis_and2s[i + number_states], 1.0);
277 addElectricalSubResults(dis_and2s[i + number_states], 1.0);
278 addSubInstances(dis_invs[i], 1.0);
279 addElectricalSubResults(dis_invs[i], 1.0);
280 }
281
282 // Update event
283 //for(unsigned int i = 0; i <= number_requests; ++i)
284 //{
285 //Result* arb_event = getEventResult("Arbitrate" + (String)i);
286 Result* arb_event = getEventResult("Arbitrate");
287 for(unsigned int j = 0; j < number_requests; ++j)
288 {
289 arb_event->addSubResult(g_invs[j]->getEventResult("INV"), g_inv_names[j], 1.0);
290 arb_event->addSubResult(g_and2s[j]->getEventResult("AND2"), g_and2_names[j], 1.0);
291 arb_event->addSubResult(dis_ors[j]->getEventResult("OR"), dis_or_names[j], 1.0);
292 }
293 for(unsigned int j = 0; j < number_states; ++j)
294 {
295 arb_event->addSubResult(w_or2s[j]->getEventResult("OR2"), w_or2_names[j], 1.0);
296 arb_event->addSubResult(w_and2s[j]->getEventResult("AND2"), w_and2_names[j], 1.0);
297 arb_event->addSubResult(w_invs[j]->getEventResult("INV"), w_inv_names[j], 1.0);
298 arb_event->addSubResult(w_dffs[j]->getEventResult("DFFD"), w_dff_names[j], 1.0);
299 arb_event->addSubResult(w_dffs[j]->getEventResult("DFFQ"), w_dff_names[j], 1.0);
300 arb_event->addSubResult(w_dffs[j]->getEventResult("CK"), w_dff_names[j], 1.0);
301 arb_event->addSubResult(dis_and2s[j]->getEventResult("AND2"), dis_and2_names[j], 1.0);
302 arb_event->addSubResult(dis_and2s[j + number_states]->getEventResult("AND2"), dis_and2_names[j + number_states], 1.0);
303 arb_event->addSubResult(dis_invs[j]->getEventResult("INV"), dis_inv_names[j], 1.0);
304 }
305 //}
306 }
307 return;
308 }
309
310 void MatrixArbiter::propagateTransitionInfo()
311 {
312 // Get parameters
313 unsigned int number_requests = getParameter("NumberRequests").toUInt();
314
315 if(number_requests == 1)
316 {
317 propagatePortTransitionInfo("Grant0", "Request0");
318 }
319 else
320 {
321 unsigned int number_states = (number_requests - 1) * number_requests / 2;
322
323 vector<ElectricalModel*> g_and2s(number_requests, NULL);
324 vector<ElectricalModel*> g_invs(number_requests, NULL);
325 vector<ElectricalModel*> w_invs(number_states, NULL);
326 vector<ElectricalModel*> w_or2s(number_states, NULL);
327 vector<ElectricalModel*> w_and2s(number_states, NULL);
328 vector<ElectricalModel*> w_dffs(number_states, NULL);
329 vector<ElectricalModel*> dis_invs(number_states, NULL);
330 vector<ElectricalModel*> dis_and2s(number_requests * number_requests, NULL);
331 vector<ElectricalModel*> dis_ors(number_requests, NULL);
332 for(unsigned int i = 0; i < number_requests; ++i)
333 {
334 g_and2s[i] = (ElectricalModel*)getSubInstance("G_AND2" + (String)i);
335 g_invs[i] = (ElectricalModel*)getSubInstance("G_INV" + (String)i);
336 dis_ors[i] = (ElectricalModel*)getSubInstance("Dis_OR" + (String)i);
337 }
338 unsigned int state_count = 0;
339 for(unsigned int i = 0; i < number_requests; ++i)
340 {
341 for(unsigned int j = i + 1; j < number_requests; ++j)
342 {
343 w_invs[state_count] = (ElectricalModel*)getSubInstance(String::format("W_INV_%d_%d", i, j));
344 w_or2s[state_count] = (ElectricalModel*)getSubInstance(String::format("W_OR2_%d_%d", i, j));
345 w_and2s[state_count] = (ElectricalModel*)getSubInstance(String::format("W_AND2_%d_%d", i, j));
346 w_dffs[state_count] = (ElectricalModel*)getSubInstance(String::format("W_DFF_%d_%d", i, j));
347 dis_invs[state_count] = (ElectricalModel*)getSubInstance(String::format("Dis_INV_%d_%d", i, j));
348 dis_and2s[i * number_requests + j] = (ElectricalModel*)getSubInstance(String::format("Dis_AND2_%d_%d", i, j));
349 dis_and2s[j * number_requests + i] = (ElectricalModel*)getSubInstance(String::format("Dis_AND2_%d_%d", j, i));
350
351 w_dffs[state_count]->getInputPort("D")->setTransitionInfo(TransitionInfo(0.5, 0.0, 0.5));
352 propagatePortTransitionInfo(w_dffs[state_count], "CK", "CK");
353 w_dffs[state_count]->use();
354
355 state_count++;
356 }
357 }
358
359 unsigned int iteration = 1;
360 unsigned int max_number_iterations = 10;
361 //vector<TransitionInfo> trans_vector(number_states, TransitionInfo(0.0, 0.0, 1.0));
362 //vector<double> total_P_vector(number_states, 0.0);
363 while(iteration < max_number_iterations)
364 {
365 // for(unsigned int i = 0; i < number_states; ++i)
366 // {
367 // w_dffs[i]->getInputPort("D")->setTransitionInfo(trans_vector[i]);
368 // propagatePortTransitionInfo(w_dffs[i], "CK", "CK");
369 // w_dffs[i]->use();
370 // }
371 state_count = 0;
372 for(unsigned int i = 0; i < number_requests; ++i)
373 {
374 for(unsigned int j = i + 1; j < number_requests; ++j)
375 {
376 propagatePortTransitionInfo(dis_and2s[i * number_requests + j], "A", "Request" + (String)i);
377 propagatePortTransitionInfo(dis_and2s[i * number_requests + j], "B", w_dffs[state_count], "Q");
378 dis_and2s[i * number_requests + j]->use();
379 propagatePortTransitionInfo(dis_invs[state_count], "A", w_dffs[state_count], "Q");
380 dis_invs[state_count]->use();
381 propagatePortTransitionInfo(dis_and2s[j * number_requests + i], "A", "Request" + (String)j);
382 propagatePortTransitionInfo(dis_and2s[j * number_requests + i], "B", dis_invs[state_count], "Y");
383 dis_and2s[j * number_requests + i]->use();
384
385 state_count++;
386 }
387 }
388 for(unsigned int i = 0; i < number_requests; ++i)
389 {
390 unsigned int k = 0;
391 for(unsigned int j = 0; j < number_requests; ++j)
392 {
393 if(i != j)
394 {
395 propagatePortTransitionInfo(dis_ors[i], "In" + (String)k, dis_and2s[j * number_requests + i], "Y");
396 k++;
397 }
398 }
399 dis_ors[i]->use();
400 }
401 for(unsigned int i = 0; i < number_requests; ++i)
402 {
403 propagatePortTransitionInfo(g_invs[i], "A", dis_ors[i], "Out");
404 g_invs[i]->use();
405 propagatePortTransitionInfo(g_and2s[i], "A", "Request" + (String)i);
406 propagatePortTransitionInfo(g_and2s[i], "B", g_invs[i], "Y");
407 g_and2s[i]->use();
408 }
409 state_count = 0;
410 for(unsigned int i = 0; i < number_requests; ++i)
411 {
412 for(unsigned int j = i + 1; j < number_requests; ++j)
413 {
414 propagatePortTransitionInfo(w_invs[state_count], "A", g_and2s[i], "Y");
415 w_invs[state_count]->use();
416 propagatePortTransitionInfo(w_or2s[state_count], "A", w_dffs[state_count], "Q");
417 propagatePortTransitionInfo(w_or2s[state_count], "B", g_and2s[j], "Y");
418 w_or2s[state_count]->use();
419 propagatePortTransitionInfo(w_and2s[state_count], "A", w_or2s[state_count], "Y");
420 propagatePortTransitionInfo(w_and2s[state_count], "B", w_invs[state_count], "Y");
421 w_and2s[state_count]->use();
422 propagatePortTransitionInfo(w_dffs[state_count], "D", w_and2s[state_count], "Y");
423 propagatePortTransitionInfo(w_dffs[state_count], "CK", "CK");
424 w_dffs[state_count]->use();
425 state_count++;
426 }
427 }
428
429 // for(unsigned int i = 0; i < number_states; ++i)
430 // {
431 // const TransitionInfo& new_trans = w_dffs[i]->getOutputPort("Q")->getTransitionInfo();
432 // total_P_vector[i] += new_trans.getProbability1();
433 // trans_vector[i] = TransitionInfo((1.0 - total_P_vector[i] / iteration) * (1.0 - total_P_vector[i] / iteration),
434 // (1.0 - total_P_vector[i] / iteration) * (total_P_vector[i] / iteration),
435 // (total_P_vector[i] / iteration) * (total_P_vector[i] / iteration));
436 // }
437 //
438 // for(unsigned int i = 0; i < number_requests; ++i)
439 // {
440 // g_and2s[i]->getOutputPort("Y")->getTransitionInfo().print(cout);
441 // }
442 // cout << endl;
443 iteration++;
444 }
445
446 for(unsigned int i = 0; i < number_requests; ++i)
447 {
448 propagatePortTransitionInfo("Grant" + (String)i, g_and2s[i], "Y");
449 }
450 }
451
452 return;
453 }
454 } // namespace DSENT
455