1 /* Copyright (c) 2012 Massachusetts Institute of Technology
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:
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
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
22 #include "model/electrical/MatrixArbiter.h"
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"
39 MatrixArbiter::MatrixArbiter(const String
& instance_name_
, const TechModel
* tech_model_
)
40 : ElectricalModel(instance_name_
, tech_model_
)
46 MatrixArbiter::~MatrixArbiter()
49 void MatrixArbiter::initParameters()
51 addParameterName("NumberRequests");
55 void MatrixArbiter::initProperties()
60 MatrixArbiter
* MatrixArbiter::clone() const
66 void MatrixArbiter::constructModel()
69 unsigned int number_requests
= getParameter("NumberRequests").toUInt();
71 ASSERT(number_requests
> 0, "[Error] " + getInstanceName() +
72 " -> Number of requests must be > 0!");
75 createInputPort("CK");
76 for(unsigned int i
= 0; i
< number_requests
; ++i
)
78 createInputPort("Request" + (String
)i
);
79 createOutputPort("Grant" + (String
)i
);
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)
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));
93 // for(unsigned int j = 0; j < i; ++j)
95 // event_info->setTransitionInfo("Request" + (String)j, TransitionInfo(0.0, 0.0, 1.0));
97 // for(unsigned int j = i; j < number_requests; ++j)
99 // event_info->setTransitionInfo("Request" + (String)j, TransitionInfo(1.0, 0.0, 0.0));
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);
106 // //for(unsigned int j = 0; j < number_requests; ++j)
108 // // event_info->setTransitionInfo("Request" + (String)j, trans);
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
)
115 getEventInfo("Arbitrate")->setTransitionInfo("Request" + (String
)i
, TransitionInfo(0.25, 0.25, 0.25));
118 if(number_requests
== 1)
120 assign("Grant0", "Request0");
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
)
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();
139 unsigned int number_states
= (number_requests
- 1) * number_requests
/ 2;
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
)
156 for(unsigned int j
= i
+ 1; j
< number_requests
; ++j
)
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();
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();
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
)
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();
196 for(unsigned int i
= 0; i
< number_requests
; ++i
)
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
);
206 for(unsigned int j
= i
+ 1; j
< number_requests
; ++j
)
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
));
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
));
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
));
240 for(unsigned int i
= 0; i
< number_requests
; ++i
)
243 for(unsigned int j
= 0; j
< number_requests
; ++j
)
247 portConnect(dis_ors
[i
], "In" + (String
)k
, String::format("Dis_AND2_Out_%d_%d", j
, i
));
251 portConnect(dis_ors
[i
], "Out", "Dis_OR_Out" + (String
)i
);
255 for(unsigned int i
= 0; i
< number_requests
; ++i
)
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);
264 for(unsigned int i
= 0; i
< number_states
; ++i
)
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);
283 //for(unsigned int i = 0; i <= number_requests; ++i)
285 //Result* arb_event = getEventResult("Arbitrate" + (String)i);
286 Result
* arb_event
= getEventResult("Arbitrate");
287 for(unsigned int j
= 0; j
< number_requests
; ++j
)
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);
293 for(unsigned int j
= 0; j
< number_states
; ++j
)
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);
310 void MatrixArbiter::propagateTransitionInfo()
313 unsigned int number_requests
= getParameter("NumberRequests").toUInt();
315 if(number_requests
== 1)
317 propagatePortTransitionInfo("Grant0", "Request0");
321 unsigned int number_states
= (number_requests
- 1) * number_requests
/ 2;
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
)
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
);
338 unsigned int state_count
= 0;
339 for(unsigned int i
= 0; i
< number_requests
; ++i
)
341 for(unsigned int j
= i
+ 1; j
< number_requests
; ++j
)
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
));
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();
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
)
365 // for(unsigned int i = 0; i < number_states; ++i)
367 // w_dffs[i]->getInputPort("D")->setTransitionInfo(trans_vector[i]);
368 // propagatePortTransitionInfo(w_dffs[i], "CK", "CK");
372 for(unsigned int i
= 0; i
< number_requests
; ++i
)
374 for(unsigned int j
= i
+ 1; j
< number_requests
; ++j
)
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();
388 for(unsigned int i
= 0; i
< number_requests
; ++i
)
391 for(unsigned int j
= 0; j
< number_requests
; ++j
)
395 propagatePortTransitionInfo(dis_ors
[i
], "In" + (String
)k
, dis_and2s
[j
* number_requests
+ i
], "Y");
401 for(unsigned int i
= 0; i
< number_requests
; ++i
)
403 propagatePortTransitionInfo(g_invs
[i
], "A", dis_ors
[i
], "Out");
405 propagatePortTransitionInfo(g_and2s
[i
], "A", "Request" + (String
)i
);
406 propagatePortTransitionInfo(g_and2s
[i
], "B", g_invs
[i
], "Y");
410 for(unsigned int i
= 0; i
< number_requests
; ++i
)
412 for(unsigned int j
= i
+ 1; j
< number_requests
; ++j
)
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();
429 // for(unsigned int i = 0; i < number_states; ++i)
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));
438 // for(unsigned int i = 0; i < number_requests; ++i)
440 // g_and2s[i]->getOutputPort("Y")->getTransitionInfo().print(cout);
446 for(unsigned int i
= 0; i
< number_requests
; ++i
)
448 propagatePortTransitionInfo("Grant" + (String
)i
, g_and2s
[i
], "Y");