SeparableAllocator.cc revision 10447
110447Snilay@cs.wisc.edu#include "model/electrical/SeparableAllocator.h"
210447Snilay@cs.wisc.edu
310447Snilay@cs.wisc.edu#include "model/ModelGen.h"
410447Snilay@cs.wisc.edu#include "model/timing_graph/ElectricalNet.h"
510447Snilay@cs.wisc.edu
610447Snilay@cs.wisc.edunamespace DSENT
710447Snilay@cs.wisc.edu{
810447Snilay@cs.wisc.edu    SeparableAllocator::SeparableAllocator(const String& instance_name_, const TechModel* tech_model_)
910447Snilay@cs.wisc.edu        : ElectricalModel(instance_name_, tech_model_)
1010447Snilay@cs.wisc.edu    {
1110447Snilay@cs.wisc.edu        initParameters();
1210447Snilay@cs.wisc.edu        initProperties();
1310447Snilay@cs.wisc.edu    }
1410447Snilay@cs.wisc.edu
1510447Snilay@cs.wisc.edu    SeparableAllocator::~SeparableAllocator()
1610447Snilay@cs.wisc.edu    {}
1710447Snilay@cs.wisc.edu
1810447Snilay@cs.wisc.edu    void SeparableAllocator::initParameters()
1910447Snilay@cs.wisc.edu    {
2010447Snilay@cs.wisc.edu        addParameterName("NumberRequesters");
2110447Snilay@cs.wisc.edu        addParameterName("NumberResources");
2210447Snilay@cs.wisc.edu        addParameterName("IsRequesterFirst", true);
2310447Snilay@cs.wisc.edu        addParameterName("Stage1->ArbiterModel");
2410447Snilay@cs.wisc.edu        addParameterName("Stage2->ArbiterModel");
2510447Snilay@cs.wisc.edu        return;
2610447Snilay@cs.wisc.edu    }
2710447Snilay@cs.wisc.edu
2810447Snilay@cs.wisc.edu    void SeparableAllocator::initProperties()
2910447Snilay@cs.wisc.edu    {
3010447Snilay@cs.wisc.edu        addPropertyName("P(Request)");
3110447Snilay@cs.wisc.edu        addPropertyName("Act(Request)");
3210447Snilay@cs.wisc.edu        addPropertyName("P(CK)");
3310447Snilay@cs.wisc.edu        addPropertyName("Act(CK)");
3410447Snilay@cs.wisc.edu        return;
3510447Snilay@cs.wisc.edu    }
3610447Snilay@cs.wisc.edu
3710447Snilay@cs.wisc.edu    SeparableAllocator* SeparableAllocator::clone() const
3810447Snilay@cs.wisc.edu    {
3910447Snilay@cs.wisc.edu        // TODO
4010447Snilay@cs.wisc.edu        return NULL;
4110447Snilay@cs.wisc.edu    }
4210447Snilay@cs.wisc.edu
4310447Snilay@cs.wisc.edu    void SeparableAllocator::constructModel()
4410447Snilay@cs.wisc.edu    {
4510447Snilay@cs.wisc.edu        // Get parameters
4610447Snilay@cs.wisc.edu        unsigned int number_requesters = getParameter("NumberRequesters").toUInt();
4710447Snilay@cs.wisc.edu        unsigned int number_resources = getParameter("NumberResources").toUInt();
4810447Snilay@cs.wisc.edu        bool is_requester_first = getParameter("IsRequesterFirst").toBool();
4910447Snilay@cs.wisc.edu        const String& stage1_arbiter_model = getParameter("Stage1->ArbiterModel");
5010447Snilay@cs.wisc.edu        const String& stage2_arbiter_model = getParameter("Stage2->ArbiterModel");
5110447Snilay@cs.wisc.edu
5210447Snilay@cs.wisc.edu        ASSERT(number_requesters > 0, "[Error] " + getInstanceName() +
5310447Snilay@cs.wisc.edu                " -> Number of requesters must be > 0!");
5410447Snilay@cs.wisc.edu        ASSERT(number_resources > 0, "[Error] " + getInstanceName() +
5510447Snilay@cs.wisc.edu                " -> Number of resources must be > 0!");
5610447Snilay@cs.wisc.edu
5710447Snilay@cs.wisc.edu        // Create area, power, and event results
5810447Snilay@cs.wisc.edu        createElectricalResults();
5910447Snilay@cs.wisc.edu        addEventResult(new Result("Allocate"));
6010447Snilay@cs.wisc.edu
6110447Snilay@cs.wisc.edu        // Create ports
6210447Snilay@cs.wisc.edu        createInputPort("CK");
6310447Snilay@cs.wisc.edu        for(unsigned int i = 0; i < number_requesters; ++i)
6410447Snilay@cs.wisc.edu        {
6510447Snilay@cs.wisc.edu            createInputPort("Request" + (String)i, makeNetIndex(0, number_resources-1));
6610447Snilay@cs.wisc.edu            createOutputPort("Grant" + (String)i, makeNetIndex(0, number_resources-1));
6710447Snilay@cs.wisc.edu        }
6810447Snilay@cs.wisc.edu
6910447Snilay@cs.wisc.edu        // If is_requester_first is set, requests from the same requester will be arbitrate
7010447Snilay@cs.wisc.edu        // on stage 1
7110447Snilay@cs.wisc.edu        if(is_requester_first)
7210447Snilay@cs.wisc.edu        {
7310447Snilay@cs.wisc.edu            // Init stage 1 arbiters
7410447Snilay@cs.wisc.edu            for(unsigned int i = 0; i < number_requesters; ++i)
7510447Snilay@cs.wisc.edu            {
7610447Snilay@cs.wisc.edu                ElectricalModel* arb = (ElectricalModel*)ModelGen::createModel(stage1_arbiter_model, "Stage1Arb" + (String)i, getTechModel());
7710447Snilay@cs.wisc.edu                arb->setParameter("NumberRequests", number_resources);
7810447Snilay@cs.wisc.edu                arb->construct();
7910447Snilay@cs.wisc.edu
8010447Snilay@cs.wisc.edu                addSubInstances(arb, 1.0);
8110447Snilay@cs.wisc.edu                addElectricalSubResults(arb, 1.0);
8210447Snilay@cs.wisc.edu
8310447Snilay@cs.wisc.edu                getEventResult("Allocate")->addSubResult(arb->getEventResult("Arbitrate"), arb->getInstanceName(), 1.0);
8410447Snilay@cs.wisc.edu
8510447Snilay@cs.wisc.edu                createNet("Stage1Arb_In" + (String)i, makeNetIndex(0, number_resources-1));
8610447Snilay@cs.wisc.edu                createNet("Stage1Arb_Out" + (String)i, makeNetIndex(0, number_resources-1));
8710447Snilay@cs.wisc.edu
8810447Snilay@cs.wisc.edu                portConnect(arb, "CK", "CK");
8910447Snilay@cs.wisc.edu                assign("Stage1Arb_In" + (String)i, "Request" + (String)i);
9010447Snilay@cs.wisc.edu                for(unsigned int j = 0; j < number_resources; ++j)
9110447Snilay@cs.wisc.edu                {
9210447Snilay@cs.wisc.edu                    portConnect(arb, "Request" + (String)j, "Stage1Arb_In" + (String)i, makeNetIndex(j));
9310447Snilay@cs.wisc.edu                    portConnect(arb, "Grant" + (String)j, "Stage1Arb_Out" + (String)i, makeNetIndex(j));
9410447Snilay@cs.wisc.edu                }
9510447Snilay@cs.wisc.edu            }
9610447Snilay@cs.wisc.edu
9710447Snilay@cs.wisc.edu            // Init stage 2 arbiters
9810447Snilay@cs.wisc.edu            for(unsigned int i = 0; i < number_resources; ++i)
9910447Snilay@cs.wisc.edu            {
10010447Snilay@cs.wisc.edu                ElectricalModel* arb = (ElectricalModel*)ModelGen::createModel(stage2_arbiter_model, "Stage2Arb" + (String)i, getTechModel());
10110447Snilay@cs.wisc.edu                arb->setParameter("NumberRequests", number_requesters);
10210447Snilay@cs.wisc.edu                arb->construct();
10310447Snilay@cs.wisc.edu
10410447Snilay@cs.wisc.edu                addSubInstances(arb, 1.0);
10510447Snilay@cs.wisc.edu                addElectricalSubResults(arb, 1.0);
10610447Snilay@cs.wisc.edu
10710447Snilay@cs.wisc.edu                getEventResult("Allocate")->addSubResult(arb->getEventResult("Arbitrate"), arb->getInstanceName(), 1.0);
10810447Snilay@cs.wisc.edu
10910447Snilay@cs.wisc.edu                createNet("Stage2Arb_In" + (String)i, makeNetIndex(0, number_requesters-1));
11010447Snilay@cs.wisc.edu                createNet("Stage2Arb_Out" + (String)i, makeNetIndex(0, number_requesters-1));
11110447Snilay@cs.wisc.edu
11210447Snilay@cs.wisc.edu                portConnect(arb, "CK", "CK");
11310447Snilay@cs.wisc.edu                for(unsigned int j = 0; j < number_requesters; ++j)
11410447Snilay@cs.wisc.edu                {
11510447Snilay@cs.wisc.edu                    assign("Stage2Arb_In" + (String)i, makeNetIndex(j), "Stage1Arb_Out" + (String)j, makeNetIndex(i));
11610447Snilay@cs.wisc.edu                    portConnect(arb, "Request" + (String)j, "Stage2Arb_In" + (String)i, makeNetIndex(j));
11710447Snilay@cs.wisc.edu                    portConnect(arb, "Grant" + (String)j, "Stage2Arb_Out" + (String)i, makeNetIndex(j));
11810447Snilay@cs.wisc.edu                    assign("Grant" + (String)j, makeNetIndex(i), "Stage2Arb_Out" + (String)i, makeNetIndex(j));
11910447Snilay@cs.wisc.edu                }
12010447Snilay@cs.wisc.edu            }
12110447Snilay@cs.wisc.edu        }
12210447Snilay@cs.wisc.edu        else
12310447Snilay@cs.wisc.edu        {
12410447Snilay@cs.wisc.edu            // Init stage 1 arbiters
12510447Snilay@cs.wisc.edu            for(unsigned int i = 0; i < number_resources; ++i)
12610447Snilay@cs.wisc.edu            {
12710447Snilay@cs.wisc.edu                ElectricalModel* arb = (ElectricalModel*)ModelGen::createModel(stage1_arbiter_model, "Stage1Arb" + (String)i, getTechModel());
12810447Snilay@cs.wisc.edu                arb->setParameter("NumberRequests", number_requesters);
12910447Snilay@cs.wisc.edu                arb->construct();
13010447Snilay@cs.wisc.edu
13110447Snilay@cs.wisc.edu                addSubInstances(arb, 1.0);
13210447Snilay@cs.wisc.edu                addElectricalSubResults(arb, 1.0);
13310447Snilay@cs.wisc.edu
13410447Snilay@cs.wisc.edu                getEventResult("Allocate")->addSubResult(arb->getEventResult("Arbitrate"), arb->getInstanceName(), 1.0);
13510447Snilay@cs.wisc.edu
13610447Snilay@cs.wisc.edu                createNet("Stage1Arb_In" + (String)i, makeNetIndex(0, number_requesters-1));
13710447Snilay@cs.wisc.edu                createNet("Stage1Arb_Out" + (String)i, makeNetIndex(0, number_requesters-1));
13810447Snilay@cs.wisc.edu
13910447Snilay@cs.wisc.edu                portConnect(arb, "CK", "CK");
14010447Snilay@cs.wisc.edu                for(unsigned int j = 0; j < number_requesters; ++j)
14110447Snilay@cs.wisc.edu                {
14210447Snilay@cs.wisc.edu                    assign("Stage1Arb_In" + (String)i, makeNetIndex(j), "Request" + (String)j, makeNetIndex(i));
14310447Snilay@cs.wisc.edu                    portConnect(arb, "Request" + (String)j, "Stage1Arb_In" + (String)i, makeNetIndex(j));
14410447Snilay@cs.wisc.edu                    portConnect(arb, "Grant" + (String)j, "Stage1Arb_Out" + (String)i, makeNetIndex(j));
14510447Snilay@cs.wisc.edu                }
14610447Snilay@cs.wisc.edu            }
14710447Snilay@cs.wisc.edu
14810447Snilay@cs.wisc.edu            // Init stage 2 arbiters
14910447Snilay@cs.wisc.edu            for(unsigned int i = 0; i < number_requesters; ++i)
15010447Snilay@cs.wisc.edu            {
15110447Snilay@cs.wisc.edu                ElectricalModel* arb = (ElectricalModel*)ModelGen::createModel(stage2_arbiter_model, "Stage2Arb" + (String)i, getTechModel());
15210447Snilay@cs.wisc.edu                arb->setParameter("NumberRequests", number_requesters);
15310447Snilay@cs.wisc.edu                arb->construct();
15410447Snilay@cs.wisc.edu
15510447Snilay@cs.wisc.edu                addSubInstances(arb, 1.0);
15610447Snilay@cs.wisc.edu                addElectricalSubResults(arb, 1.0);
15710447Snilay@cs.wisc.edu
15810447Snilay@cs.wisc.edu                getEventResult("Allocate")->addSubResult(arb->getEventResult("Arbitrate"), arb->getInstanceName(), 1.0);
15910447Snilay@cs.wisc.edu
16010447Snilay@cs.wisc.edu                createNet("Stage2Arb_In" + (String)i, makeNetIndex(0, number_resources-1));
16110447Snilay@cs.wisc.edu                createNet("Stage2Arb_Out" + (String)i, makeNetIndex(0, number_resources-1));
16210447Snilay@cs.wisc.edu
16310447Snilay@cs.wisc.edu                portConnect(arb, "CK", "CK");
16410447Snilay@cs.wisc.edu                for(unsigned int j = 0; j < number_resources; ++j)
16510447Snilay@cs.wisc.edu                {
16610447Snilay@cs.wisc.edu                    assign("Stage2Arb_In" + (String)i, makeNetIndex(j), "Stage1Arb_Out" + (String)j, makeNetIndex(i));
16710447Snilay@cs.wisc.edu                    portConnect(arb, "Request" + (String)j, "Stage2Arb_In", makeNetIndex(j));
16810447Snilay@cs.wisc.edu                    portConnect(arb, "Grant" + (String)j, "Stage2Arb_Out", makeNetIndex(j));
16910447Snilay@cs.wisc.edu                }
17010447Snilay@cs.wisc.edu                assign("Grant" + (String)i, "Stage2Arb_Out" + (String)i);
17110447Snilay@cs.wisc.edu            }
17210447Snilay@cs.wisc.edu        }
17310447Snilay@cs.wisc.edu        return;
17410447Snilay@cs.wisc.edu    }
17510447Snilay@cs.wisc.edu
17610447Snilay@cs.wisc.edu    void SeparableAllocator::updateModel()
17710447Snilay@cs.wisc.edu    {
17810447Snilay@cs.wisc.edu        // Get parameters
17910447Snilay@cs.wisc.edu        unsigned int number_requesters = getParameter("NumberRequesters").toUInt();
18010447Snilay@cs.wisc.edu        unsigned int number_resources = getParameter("NumberResources").toUInt();
18110447Snilay@cs.wisc.edu        bool is_requester_first = getParameter("IsRequesterFirst").toBool();
18210447Snilay@cs.wisc.edu
18310447Snilay@cs.wisc.edu        // Get probabilities from inputs
18410447Snilay@cs.wisc.edu        const String& P_request = getProperty("P(Request)");
18510447Snilay@cs.wisc.edu        const String& act_request = getProperty("Act(Request)");
18610447Snilay@cs.wisc.edu        const String& P_CK = getProperty("P(CK)");
18710447Snilay@cs.wisc.edu        const String& act_CK = getProperty("Act(CK)");
18810447Snilay@cs.wisc.edu
18910447Snilay@cs.wisc.edu        const vector<double>& P_request_vector = LibUtil::castStringVector<double>(P_request.split("[,]"));
19010447Snilay@cs.wisc.edu        const vector<double>& act_request_vector = LibUtil::castStringVector<double>(act_request.split("[,]"));
19110447Snilay@cs.wisc.edu
19210447Snilay@cs.wisc.edu        ASSERT(P_request_vector.size() == (number_requesters * number_resources), "[Error] " + getInstanceName() +
19310447Snilay@cs.wisc.edu                " -> Expecting " + (String)(number_requesters * number_resources) +
19410447Snilay@cs.wisc.edu                " request probabilities, but got " + P_request);
19510447Snilay@cs.wisc.edu        ASSERT(act_request_vector.size() == (number_requesters * number_resources), "[Error] " + getInstanceName() +
19610447Snilay@cs.wisc.edu                " -> Expecting " + (String)(number_requesters * number_resources) +
19710447Snilay@cs.wisc.edu                " request actvities multiplier, but got " + act_request);
19810447Snilay@cs.wisc.edu
19910447Snilay@cs.wisc.edu        vector<double> P_int_request_vector(number_requesters * number_resources, 0.0);
20010447Snilay@cs.wisc.edu        vector<double> act_int_request_vector(number_requesters * number_resources, 0.0);
20110447Snilay@cs.wisc.edu        vector<double> P_out_request_vector(number_requesters * number_resources, 0.0);
20210447Snilay@cs.wisc.edu        vector<double> act_out_request_vector(number_requesters * number_resources, 0.0);
20310447Snilay@cs.wisc.edu        if(is_requester_first)
20410447Snilay@cs.wisc.edu        {
20510447Snilay@cs.wisc.edu            // Update stage1 arbiter
20610447Snilay@cs.wisc.edu            for(unsigned int i = 0; i < number_requesters; ++i)
20710447Snilay@cs.wisc.edu            {
20810447Snilay@cs.wisc.edu                vector<double> P_arb_request_vector(number_resources, 0.0);
20910447Snilay@cs.wisc.edu                vector<double> act_arb_request_vector(number_resources, 0.0);
21010447Snilay@cs.wisc.edu                for(unsigned int j = 0; j < number_resources; ++j)
21110447Snilay@cs.wisc.edu                {
21210447Snilay@cs.wisc.edu                    P_arb_request_vector[j] = P_request_vector[i * number_resources + j];
21310447Snilay@cs.wisc.edu                    act_arb_request_vector[j] = act_request_vector[i * number_resources + j];
21410447Snilay@cs.wisc.edu                }
21510447Snilay@cs.wisc.edu
21610447Snilay@cs.wisc.edu                Model* arb = getSubInstance("Stage1Arb" + (String)i);
21710447Snilay@cs.wisc.edu                arb->setProperty("P(Request)", LibUtil::vectorToString(P_arb_request_vector));
21810447Snilay@cs.wisc.edu                arb->setProperty("Act(Request)", LibUtil::vectorToString(act_arb_request_vector));
21910447Snilay@cs.wisc.edu                arb->setProperty("P(CK)", P_CK);
22010447Snilay@cs.wisc.edu                arb->setProperty("Act(CK)", act_CK);
22110447Snilay@cs.wisc.edu                arb->update();
22210447Snilay@cs.wisc.edu
22310447Snilay@cs.wisc.edu                const vector<double>& P_arb_out_request_vector = LibUtil::castStringVector<double>(arb->getGenProperties()->get("P(Grant)").split("[,]"));
22410447Snilay@cs.wisc.edu                const vector<double>& act_arb_out_request_vector = LibUtil::castStringVector<double>(arb->getGenProperties()->get("Act(Grant)").split("[,]"));
22510447Snilay@cs.wisc.edu                for(unsigned int j = 0; j < number_resources; ++j)
22610447Snilay@cs.wisc.edu                {
22710447Snilay@cs.wisc.edu                    P_int_request_vector[i * number_resources + j] = P_arb_out_request_vector[j];
22810447Snilay@cs.wisc.edu                    act_int_request_vector[i * number_resources + j] = act_arb_out_request_vector[j];
22910447Snilay@cs.wisc.edu                }
23010447Snilay@cs.wisc.edu            }
23110447Snilay@cs.wisc.edu            // Update stage2 arbiter
23210447Snilay@cs.wisc.edu            for(unsigned int i = 0; i < number_resources; ++i)
23310447Snilay@cs.wisc.edu            {
23410447Snilay@cs.wisc.edu                vector<double> P_arb_request_vector(number_requesters, 0.0);
23510447Snilay@cs.wisc.edu                vector<double> act_arb_request_vector(number_requesters, 0.0);
23610447Snilay@cs.wisc.edu                for(unsigned int j = 0; j < number_requesters; ++j)
23710447Snilay@cs.wisc.edu                {
23810447Snilay@cs.wisc.edu                    P_arb_request_vector[j] = P_int_request_vector[j * number_resources + i];
23910447Snilay@cs.wisc.edu                    act_arb_request_vector[j] = act_int_request_vector[j * number_resources + i];
24010447Snilay@cs.wisc.edu                }
24110447Snilay@cs.wisc.edu
24210447Snilay@cs.wisc.edu                Model* arb = getSubInstance("Stage2Arb" + (String)i);
24310447Snilay@cs.wisc.edu                arb->setProperty("P(Request)", LibUtil::vectorToString(P_arb_request_vector));
24410447Snilay@cs.wisc.edu                arb->setProperty("Act(Request)", LibUtil::vectorToString(act_arb_request_vector));
24510447Snilay@cs.wisc.edu                arb->setProperty("P(CK)", P_CK);
24610447Snilay@cs.wisc.edu                arb->setProperty("Act(CK)", act_CK);
24710447Snilay@cs.wisc.edu                arb->update();
24810447Snilay@cs.wisc.edu
24910447Snilay@cs.wisc.edu                const vector<double>& P_arb_out_request_vector = LibUtil::castStringVector<double>(arb->getGenProperties()->get("P(Grant)").split("[,]"));
25010447Snilay@cs.wisc.edu                const vector<double>& act_arb_out_request_vector = LibUtil::castStringVector<double>(arb->getGenProperties()->get("Act(Grant)").split("[,]"));
25110447Snilay@cs.wisc.edu                for(unsigned int j = 0; j < number_requesters; ++j)
25210447Snilay@cs.wisc.edu                {
25310447Snilay@cs.wisc.edu                    P_out_request_vector[j * number_resources + i] = P_arb_out_request_vector[j];
25410447Snilay@cs.wisc.edu                    act_out_request_vector[j * number_resources + i] = act_arb_out_request_vector[j];
25510447Snilay@cs.wisc.edu                }
25610447Snilay@cs.wisc.edu            }
25710447Snilay@cs.wisc.edu        }
25810447Snilay@cs.wisc.edu        else
25910447Snilay@cs.wisc.edu        {
26010447Snilay@cs.wisc.edu
26110447Snilay@cs.wisc.edu        }
26210447Snilay@cs.wisc.edu
26310447Snilay@cs.wisc.edu        // Update output probabilities
26410447Snilay@cs.wisc.edu        getGenProperties()->set("P(Grant)", LibUtil::vectorToString(P_out_request_vector));
26510447Snilay@cs.wisc.edu        getGenProperties()->set("Act(Grant)", LibUtil::vectorToString(act_out_request_vector));
26610447Snilay@cs.wisc.edu
26710447Snilay@cs.wisc.edu        return;
26810447Snilay@cs.wisc.edu    }
26910447Snilay@cs.wisc.edu} // namespace DSENT
27010447Snilay@cs.wisc.edu
271