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