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