110448Snilay@cs.wisc.edu/* Copyright (c) 2012 Massachusetts Institute of Technology
210448Snilay@cs.wisc.edu *
310448Snilay@cs.wisc.edu * Permission is hereby granted, free of charge, to any person obtaining a copy
410448Snilay@cs.wisc.edu * of this software and associated documentation files (the "Software"), to deal
510448Snilay@cs.wisc.edu * in the Software without restriction, including without limitation the rights
610448Snilay@cs.wisc.edu * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
710448Snilay@cs.wisc.edu * copies of the Software, and to permit persons to whom the Software is
810448Snilay@cs.wisc.edu * furnished to do so, subject to the following conditions:
910448Snilay@cs.wisc.edu *
1010448Snilay@cs.wisc.edu * The above copyright notice and this permission notice shall be included in
1110448Snilay@cs.wisc.edu * all copies or substantial portions of the Software.
1210448Snilay@cs.wisc.edu *
1310448Snilay@cs.wisc.edu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1410448Snilay@cs.wisc.edu * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1510448Snilay@cs.wisc.edu * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1610448Snilay@cs.wisc.edu * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1710448Snilay@cs.wisc.edu * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1810448Snilay@cs.wisc.edu * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1910448Snilay@cs.wisc.edu * THE SOFTWARE.
2010448Snilay@cs.wisc.edu */
2110448Snilay@cs.wisc.edu
2210447Snilay@cs.wisc.edu#include "model/electrical/router/RouterSwitchAllocator.h"
2310447Snilay@cs.wisc.edu
2410447Snilay@cs.wisc.edu#include "model/PortInfo.h"
2510447Snilay@cs.wisc.edu#include "model/EventInfo.h"
2610447Snilay@cs.wisc.edu#include "model/TransitionInfo.h"
2710447Snilay@cs.wisc.edu#include "model/ModelGen.h"
2810447Snilay@cs.wisc.edu#include "model/std_cells/StdCell.h"
2910447Snilay@cs.wisc.edu#include "model/std_cells/StdCellLib.h"
3010447Snilay@cs.wisc.edu
3110447Snilay@cs.wisc.edunamespace DSENT
3210447Snilay@cs.wisc.edu{
3310447Snilay@cs.wisc.edu    RouterSwitchAllocator::RouterSwitchAllocator(const String& instance_name_, const TechModel* tech_model_)
3410447Snilay@cs.wisc.edu        : ElectricalModel(instance_name_, tech_model_)
3510447Snilay@cs.wisc.edu    {
3610447Snilay@cs.wisc.edu        initParameters();
3710447Snilay@cs.wisc.edu        initProperties();
3810447Snilay@cs.wisc.edu    }
3910447Snilay@cs.wisc.edu
4010447Snilay@cs.wisc.edu    RouterSwitchAllocator::~RouterSwitchAllocator()
4110447Snilay@cs.wisc.edu    {}
4210447Snilay@cs.wisc.edu
4310447Snilay@cs.wisc.edu    void RouterSwitchAllocator::initParameters()
4410447Snilay@cs.wisc.edu    {
4510447Snilay@cs.wisc.edu        addParameterName("NumberInputPorts");
4610447Snilay@cs.wisc.edu        addParameterName("NumberOutputPorts");
4710447Snilay@cs.wisc.edu        addParameterName("TotalNumberVirtualChannels");
4810447Snilay@cs.wisc.edu        addParameterName("ArbiterModel");
4910447Snilay@cs.wisc.edu        return;
5010447Snilay@cs.wisc.edu    }
5110447Snilay@cs.wisc.edu
5210447Snilay@cs.wisc.edu    void RouterSwitchAllocator::initProperties()
5310447Snilay@cs.wisc.edu    {}
5410447Snilay@cs.wisc.edu
5510447Snilay@cs.wisc.edu    RouterSwitchAllocator* RouterSwitchAllocator::clone() const
5610447Snilay@cs.wisc.edu    {
5710447Snilay@cs.wisc.edu        // TODO
5810447Snilay@cs.wisc.edu        return NULL;
5910447Snilay@cs.wisc.edu    }
6010447Snilay@cs.wisc.edu
6110447Snilay@cs.wisc.edu    void RouterSwitchAllocator::constructModel()
6210447Snilay@cs.wisc.edu    {
6310447Snilay@cs.wisc.edu        // Get parameters
6410447Snilay@cs.wisc.edu        unsigned int number_input_ports = getParameter("NumberInputPorts").toUInt();
6510447Snilay@cs.wisc.edu        unsigned int number_output_ports = getParameter("NumberOutputPorts").toUInt();
6610447Snilay@cs.wisc.edu        unsigned int total_number_vcs = getParameter("TotalNumberVirtualChannels").toUInt();
6710447Snilay@cs.wisc.edu        const String& arb_model = getParameter("ArbiterModel");
6810447Snilay@cs.wisc.edu
6910447Snilay@cs.wisc.edu        ASSERT(number_input_ports > 0, "[Error] " + getInstanceName() +
7010447Snilay@cs.wisc.edu                " -> Number of input ports must be > 0!");
7110447Snilay@cs.wisc.edu        ASSERT(number_output_ports > 0, "[Error] " + getInstanceName() +
7210447Snilay@cs.wisc.edu                " -> Number of output ports must be > 0!");
7310447Snilay@cs.wisc.edu        ASSERT(total_number_vcs > 0, "[Error] " + getInstanceName() +
7410447Snilay@cs.wisc.edu                " -> Total number of virtual channels must be > 0!");
7510447Snilay@cs.wisc.edu
7610447Snilay@cs.wisc.edu        unsigned int stage1_number_requests = total_number_vcs;
7710447Snilay@cs.wisc.edu        unsigned int number_stage1_arbiters = number_input_ports;
7810447Snilay@cs.wisc.edu        unsigned int stage2_number_requests = number_input_ports;
7910447Snilay@cs.wisc.edu        unsigned int number_stage2_arbiters = number_output_ports;
8010447Snilay@cs.wisc.edu
8110447Snilay@cs.wisc.edu        getGenProperties()->set("NumberStage1Arbiters", number_stage1_arbiters);
8210447Snilay@cs.wisc.edu        getGenProperties()->set("Stage1->NumberRequests", stage1_number_requests);
8310447Snilay@cs.wisc.edu        getGenProperties()->set("NumberStage2Arbiters", number_stage2_arbiters);
8410447Snilay@cs.wisc.edu        getGenProperties()->set("Stage2->NumberRequests", stage2_number_requests);
8510447Snilay@cs.wisc.edu
8610447Snilay@cs.wisc.edu        // Create ports
8710447Snilay@cs.wisc.edu        createInputPort("CK");
8810447Snilay@cs.wisc.edu        for(unsigned int i = 0; i < number_stage1_arbiters; ++i)
8910447Snilay@cs.wisc.edu        {
9010447Snilay@cs.wisc.edu            for(unsigned int j = 0; j < stage1_number_requests; ++j)
9110447Snilay@cs.wisc.edu            {
9210447Snilay@cs.wisc.edu                createInputPort(String::format("Stage1Arb%d->Request%d", i, j));
9310447Snilay@cs.wisc.edu                createInputPort(String::format("Stage1Arb%d->Grant%d", i, j));
9410447Snilay@cs.wisc.edu            }
9510447Snilay@cs.wisc.edu        }
9610447Snilay@cs.wisc.edu        for(unsigned int i = 0; i < number_stage2_arbiters; ++i)
9710447Snilay@cs.wisc.edu        {
9810447Snilay@cs.wisc.edu            for(unsigned int j = 0; j < stage2_number_requests; ++j)
9910447Snilay@cs.wisc.edu            {
10010447Snilay@cs.wisc.edu                createInputPort(String::format("Stage2Arb%d->Request%d", i, j));
10110447Snilay@cs.wisc.edu                createInputPort(String::format("Stage2Arb%d->Grant%d", i, j));
10210447Snilay@cs.wisc.edu            }
10310447Snilay@cs.wisc.edu        }
10410447Snilay@cs.wisc.edu
10510447Snilay@cs.wisc.edu        // Create area, power, and event results
10610447Snilay@cs.wisc.edu        createElectricalResults();
10710447Snilay@cs.wisc.edu        getEventInfo("Idle")->setStaticTransitionInfos();
10810447Snilay@cs.wisc.edu        getEventInfo("Idle")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0));
10910447Snilay@cs.wisc.edu
11010447Snilay@cs.wisc.edu        createElectricalEventResult("ArbitrateStage1");
11110447Snilay@cs.wisc.edu        getEventInfo("ArbitrateStage1")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0));
11210447Snilay@cs.wisc.edu        createElectricalEventResult("ArbitrateStage2");
11310447Snilay@cs.wisc.edu        getEventInfo("ArbitrateStage2")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0));
11410447Snilay@cs.wisc.edu
11510447Snilay@cs.wisc.edu        // Init Stage1 arbiter
11610447Snilay@cs.wisc.edu        vector<String> stage1_arb_dff_names(stage1_number_requests, "");
11710447Snilay@cs.wisc.edu        vector<StdCell*> stage1_arb_dffs(stage1_number_requests, NULL);
11810447Snilay@cs.wisc.edu        for(unsigned int i = 0; i < stage1_number_requests; ++i)
11910447Snilay@cs.wisc.edu        {
12010447Snilay@cs.wisc.edu            stage1_arb_dff_names[i] = "Stage1ArbDFF" + (String)i;
12110447Snilay@cs.wisc.edu            stage1_arb_dffs[i] = getTechModel()->getStdCellLib()->createStdCell("DFFQ", stage1_arb_dff_names[i]);
12210447Snilay@cs.wisc.edu            stage1_arb_dffs[i]->construct();
12310447Snilay@cs.wisc.edu        }
12410447Snilay@cs.wisc.edu        const String& stage1_arb_name = "Stage1Arb";
12510447Snilay@cs.wisc.edu        ElectricalModel* stage1_arb = (ElectricalModel*)ModelGen::createModel(arb_model, stage1_arb_name, getTechModel());
12610447Snilay@cs.wisc.edu        stage1_arb->setParameter("NumberRequests", stage1_number_requests);
12710447Snilay@cs.wisc.edu        stage1_arb->construct();
12810447Snilay@cs.wisc.edu
12910447Snilay@cs.wisc.edu        // Init stage2 arbiter
13010447Snilay@cs.wisc.edu        vector<String> stage2_arb_dff_names(stage2_number_requests, "");
13110447Snilay@cs.wisc.edu        vector<StdCell*> stage2_arb_dffs(stage2_number_requests, NULL);
13210447Snilay@cs.wisc.edu        for(unsigned int i = 0; i < stage2_number_requests; ++i)
13310447Snilay@cs.wisc.edu        {
13410447Snilay@cs.wisc.edu            stage2_arb_dff_names[i] = "Stage2ArbDFF" + (String)i;
13510447Snilay@cs.wisc.edu            stage2_arb_dffs[i] = getTechModel()->getStdCellLib()->createStdCell("DFFQ", stage2_arb_dff_names[i]);
13610447Snilay@cs.wisc.edu            stage2_arb_dffs[i]->construct();
13710447Snilay@cs.wisc.edu        }
13810447Snilay@cs.wisc.edu        const String& stage2_arb_name = "Stage2Arb";
13910447Snilay@cs.wisc.edu        ElectricalModel* stage2_arb = (ElectricalModel*)ModelGen::createModel(arb_model, stage2_arb_name, getTechModel());
14010447Snilay@cs.wisc.edu        stage2_arb->setParameter("NumberRequests", stage2_number_requests);
14110447Snilay@cs.wisc.edu        stage2_arb->construct();
14210447Snilay@cs.wisc.edu
14310447Snilay@cs.wisc.edu        // Connect ports
14410447Snilay@cs.wisc.edu        for(unsigned int i = 0; i < stage1_number_requests; ++i)
14510447Snilay@cs.wisc.edu        {
14610447Snilay@cs.wisc.edu            const String& dff_in_name = "Stage1Arb_DFF_In" + (String)i;
14710447Snilay@cs.wisc.edu            const String& req_name = "Stage1Arb->Request" + (String)i;
14810447Snilay@cs.wisc.edu            const String& grant_name = "Stage1Arb->Grant" + (String)i;
14910447Snilay@cs.wisc.edu            createNet(dff_in_name);
15010447Snilay@cs.wisc.edu            createNet(req_name);
15110447Snilay@cs.wisc.edu            createNet(grant_name);
15210447Snilay@cs.wisc.edu            portConnect(stage1_arb_dffs[i], "D", dff_in_name);
15310447Snilay@cs.wisc.edu            portConnect(stage1_arb_dffs[i], "CK", "CK");
15410447Snilay@cs.wisc.edu            portConnect(stage1_arb_dffs[i], "Q", req_name);
15510447Snilay@cs.wisc.edu            portConnect(stage1_arb, "Request" + (String)i, req_name);
15610447Snilay@cs.wisc.edu            portConnect(stage1_arb, "Grant" + (String)i, grant_name);
15710447Snilay@cs.wisc.edu            for(unsigned int j = 0; j < number_stage1_arbiters; ++j)
15810447Snilay@cs.wisc.edu            {
15910447Snilay@cs.wisc.edu                assignVirtualFanin(dff_in_name, String::format("Stage1Arb%d->Request%d", j, i));
16010447Snilay@cs.wisc.edu                assignVirtualFanout(String::format("Stage1Arb%d->Grant%d", j, i), grant_name);
16110447Snilay@cs.wisc.edu            }
16210447Snilay@cs.wisc.edu        }
16310447Snilay@cs.wisc.edu        for(unsigned int i = 0; i < stage2_number_requests; ++i)
16410447Snilay@cs.wisc.edu        {
16510447Snilay@cs.wisc.edu            const String& dff_in_name = "Stage2Arb_DFF_In" + (String)i;
16610447Snilay@cs.wisc.edu            const String& req_name = "Stage2Arb->Request" + (String)i;
16710447Snilay@cs.wisc.edu            const String& grant_name = "Stage2Arb->Grant" + (String)i;
16810447Snilay@cs.wisc.edu            createNet(dff_in_name);
16910447Snilay@cs.wisc.edu            createNet(req_name);
17010447Snilay@cs.wisc.edu            createNet(grant_name);
17110447Snilay@cs.wisc.edu            portConnect(stage2_arb_dffs[i], "D", dff_in_name);
17210447Snilay@cs.wisc.edu            portConnect(stage2_arb_dffs[i], "CK", "CK");
17310447Snilay@cs.wisc.edu            portConnect(stage2_arb_dffs[i], "Q", req_name);
17410447Snilay@cs.wisc.edu            portConnect(stage2_arb, "Request" + (String)i, req_name);
17510447Snilay@cs.wisc.edu            portConnect(stage2_arb, "Grant" + (String)i, grant_name);
17610447Snilay@cs.wisc.edu            for(unsigned int j = 0; j < number_stage2_arbiters; ++j)
17710447Snilay@cs.wisc.edu            {
17810447Snilay@cs.wisc.edu                assignVirtualFanin(dff_in_name, String::format("Stage2Arb%d->Request%d", j, i));
17910447Snilay@cs.wisc.edu                assignVirtualFanout(String::format("Stage2Arb%d->Grant%d", j, i), grant_name);
18010447Snilay@cs.wisc.edu            }
18110447Snilay@cs.wisc.edu        }
18210447Snilay@cs.wisc.edu
18310447Snilay@cs.wisc.edu        // Add sub components
18410447Snilay@cs.wisc.edu        for(unsigned int i = 0; i < stage1_number_requests; ++i)
18510447Snilay@cs.wisc.edu        {
18610447Snilay@cs.wisc.edu            addSubInstances(stage1_arb_dffs[i], 1.0);
18710447Snilay@cs.wisc.edu            addElectricalSubResults(stage1_arb_dffs[i], 1.0);
18810447Snilay@cs.wisc.edu        }
18910447Snilay@cs.wisc.edu        addSubInstances(stage1_arb, number_stage1_arbiters);
19010447Snilay@cs.wisc.edu        addElectricalSubResults(stage1_arb, number_stage1_arbiters);
19110447Snilay@cs.wisc.edu        for(unsigned int i = 0; i < stage2_number_requests; ++i)
19210447Snilay@cs.wisc.edu        {
19310447Snilay@cs.wisc.edu            addSubInstances(stage2_arb_dffs[i], 1.0);
19410447Snilay@cs.wisc.edu            addElectricalSubResults(stage2_arb_dffs[i], 1.0);
19510447Snilay@cs.wisc.edu        }
19610447Snilay@cs.wisc.edu        addSubInstances(stage2_arb, number_stage2_arbiters);
19710447Snilay@cs.wisc.edu        addElectricalSubResults(stage2_arb, number_stage2_arbiters);
19810447Snilay@cs.wisc.edu
19910447Snilay@cs.wisc.edu        // Update stage1 arb arbitrate
20010447Snilay@cs.wisc.edu        getEventResult("ArbitrateStage1")->addSubResult(stage1_arb->getEventResult("Arbitrate"), stage1_arb_name, 1.0);
20110447Snilay@cs.wisc.edu
20210447Snilay@cs.wisc.edu        // Update stage2 arb arbitrate
20310447Snilay@cs.wisc.edu        getEventResult("ArbitrateStage2")->addSubResult(stage2_arb->getEventResult("Arbitrate"), stage2_arb_name, 1.0);
20410447Snilay@cs.wisc.edu        return;
20510447Snilay@cs.wisc.edu    }
20610447Snilay@cs.wisc.edu
20710447Snilay@cs.wisc.edu    void RouterSwitchAllocator::propagateTransitionInfo()
20810447Snilay@cs.wisc.edu    {
20910447Snilay@cs.wisc.edu        ElectricalModel* stage1_arb = (ElectricalModel*)getSubInstance("Stage1Arb");
21010447Snilay@cs.wisc.edu        stage1_arb->applyTransitionInfo("Arbitrate");
21110447Snilay@cs.wisc.edu        stage1_arb->use();
21210447Snilay@cs.wisc.edu
21310447Snilay@cs.wisc.edu        ElectricalModel* stage2_arb = (ElectricalModel*)getSubInstance("Stage2Arb");
21410447Snilay@cs.wisc.edu        stage2_arb->applyTransitionInfo("Arbitrate");
21510447Snilay@cs.wisc.edu        stage2_arb->use();
21610447Snilay@cs.wisc.edu
21710447Snilay@cs.wisc.edu        return;
21810447Snilay@cs.wisc.edu    }
21910447Snilay@cs.wisc.edu} // namespace DSENT
22010447Snilay@cs.wisc.edu
221