diff options
author | Nilay Vaish <nilay@cs.wisc.edu> | 2014-10-11 15:02:23 -0500 |
---|---|---|
committer | Nilay Vaish <nilay@cs.wisc.edu> | 2014-10-11 15:02:23 -0500 |
commit | e8ed7b1d1b5bef31e9874f679a5797c2e00d06f1 (patch) | |
tree | 421c9c50377aa664958685914f5504c4c019e21f /ext/dsent/model/electrical/router/RouterSwitchAllocator.cc | |
parent | a098fad174d8559037602b248b8e6f7f46bfebbb (diff) | |
download | gem5-e8ed7b1d1b5bef31e9874f679a5797c2e00d06f1.tar.xz |
ext: add the source code for DSENT
This patch adds a tool called DSENT to the ext/ directory. DSENT
is a tool that models power and area for on-chip networks. The next
patch adds a script for using the tool.
Diffstat (limited to 'ext/dsent/model/electrical/router/RouterSwitchAllocator.cc')
-rw-r--r-- | ext/dsent/model/electrical/router/RouterSwitchAllocator.cc | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/ext/dsent/model/electrical/router/RouterSwitchAllocator.cc b/ext/dsent/model/electrical/router/RouterSwitchAllocator.cc new file mode 100644 index 000000000..92e5431b1 --- /dev/null +++ b/ext/dsent/model/electrical/router/RouterSwitchAllocator.cc @@ -0,0 +1,199 @@ +#include "model/electrical/router/RouterSwitchAllocator.h" + +#include "model/PortInfo.h" +#include "model/EventInfo.h" +#include "model/TransitionInfo.h" +#include "model/ModelGen.h" +#include "model/std_cells/StdCell.h" +#include "model/std_cells/StdCellLib.h" + +namespace DSENT +{ + RouterSwitchAllocator::RouterSwitchAllocator(const String& instance_name_, const TechModel* tech_model_) + : ElectricalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + RouterSwitchAllocator::~RouterSwitchAllocator() + {} + + void RouterSwitchAllocator::initParameters() + { + addParameterName("NumberInputPorts"); + addParameterName("NumberOutputPorts"); + addParameterName("TotalNumberVirtualChannels"); + addParameterName("ArbiterModel"); + return; + } + + void RouterSwitchAllocator::initProperties() + {} + + RouterSwitchAllocator* RouterSwitchAllocator::clone() const + { + // TODO + return NULL; + } + + void RouterSwitchAllocator::constructModel() + { + // Get parameters + unsigned int number_input_ports = getParameter("NumberInputPorts").toUInt(); + unsigned int number_output_ports = getParameter("NumberOutputPorts").toUInt(); + unsigned int total_number_vcs = getParameter("TotalNumberVirtualChannels").toUInt(); + const String& arb_model = getParameter("ArbiterModel"); + + ASSERT(number_input_ports > 0, "[Error] " + getInstanceName() + + " -> Number of input ports must be > 0!"); + ASSERT(number_output_ports > 0, "[Error] " + getInstanceName() + + " -> Number of output ports must be > 0!"); + ASSERT(total_number_vcs > 0, "[Error] " + getInstanceName() + + " -> Total number of virtual channels must be > 0!"); + + unsigned int stage1_number_requests = total_number_vcs; + unsigned int number_stage1_arbiters = number_input_ports; + unsigned int stage2_number_requests = number_input_ports; + unsigned int number_stage2_arbiters = number_output_ports; + + getGenProperties()->set("NumberStage1Arbiters", number_stage1_arbiters); + getGenProperties()->set("Stage1->NumberRequests", stage1_number_requests); + getGenProperties()->set("NumberStage2Arbiters", number_stage2_arbiters); + getGenProperties()->set("Stage2->NumberRequests", stage2_number_requests); + + // Create ports + createInputPort("CK"); + for(unsigned int i = 0; i < number_stage1_arbiters; ++i) + { + for(unsigned int j = 0; j < stage1_number_requests; ++j) + { + createInputPort(String::format("Stage1Arb%d->Request%d", i, j)); + createInputPort(String::format("Stage1Arb%d->Grant%d", i, j)); + } + } + for(unsigned int i = 0; i < number_stage2_arbiters; ++i) + { + for(unsigned int j = 0; j < stage2_number_requests; ++j) + { + createInputPort(String::format("Stage2Arb%d->Request%d", i, j)); + createInputPort(String::format("Stage2Arb%d->Grant%d", i, j)); + } + } + + // Create area, power, and event results + createElectricalResults(); + getEventInfo("Idle")->setStaticTransitionInfos(); + getEventInfo("Idle")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); + + createElectricalEventResult("ArbitrateStage1"); + getEventInfo("ArbitrateStage1")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); + createElectricalEventResult("ArbitrateStage2"); + getEventInfo("ArbitrateStage2")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); + + // Init Stage1 arbiter + vector<String> stage1_arb_dff_names(stage1_number_requests, ""); + vector<StdCell*> stage1_arb_dffs(stage1_number_requests, NULL); + for(unsigned int i = 0; i < stage1_number_requests; ++i) + { + stage1_arb_dff_names[i] = "Stage1ArbDFF" + (String)i; + stage1_arb_dffs[i] = getTechModel()->getStdCellLib()->createStdCell("DFFQ", stage1_arb_dff_names[i]); + stage1_arb_dffs[i]->construct(); + } + const String& stage1_arb_name = "Stage1Arb"; + ElectricalModel* stage1_arb = (ElectricalModel*)ModelGen::createModel(arb_model, stage1_arb_name, getTechModel()); + stage1_arb->setParameter("NumberRequests", stage1_number_requests); + stage1_arb->construct(); + + // Init stage2 arbiter + vector<String> stage2_arb_dff_names(stage2_number_requests, ""); + vector<StdCell*> stage2_arb_dffs(stage2_number_requests, NULL); + for(unsigned int i = 0; i < stage2_number_requests; ++i) + { + stage2_arb_dff_names[i] = "Stage2ArbDFF" + (String)i; + stage2_arb_dffs[i] = getTechModel()->getStdCellLib()->createStdCell("DFFQ", stage2_arb_dff_names[i]); + stage2_arb_dffs[i]->construct(); + } + const String& stage2_arb_name = "Stage2Arb"; + ElectricalModel* stage2_arb = (ElectricalModel*)ModelGen::createModel(arb_model, stage2_arb_name, getTechModel()); + stage2_arb->setParameter("NumberRequests", stage2_number_requests); + stage2_arb->construct(); + + // Connect ports + for(unsigned int i = 0; i < stage1_number_requests; ++i) + { + const String& dff_in_name = "Stage1Arb_DFF_In" + (String)i; + const String& req_name = "Stage1Arb->Request" + (String)i; + const String& grant_name = "Stage1Arb->Grant" + (String)i; + createNet(dff_in_name); + createNet(req_name); + createNet(grant_name); + portConnect(stage1_arb_dffs[i], "D", dff_in_name); + portConnect(stage1_arb_dffs[i], "CK", "CK"); + portConnect(stage1_arb_dffs[i], "Q", req_name); + portConnect(stage1_arb, "Request" + (String)i, req_name); + portConnect(stage1_arb, "Grant" + (String)i, grant_name); + for(unsigned int j = 0; j < number_stage1_arbiters; ++j) + { + assignVirtualFanin(dff_in_name, String::format("Stage1Arb%d->Request%d", j, i)); + assignVirtualFanout(String::format("Stage1Arb%d->Grant%d", j, i), grant_name); + } + } + for(unsigned int i = 0; i < stage2_number_requests; ++i) + { + const String& dff_in_name = "Stage2Arb_DFF_In" + (String)i; + const String& req_name = "Stage2Arb->Request" + (String)i; + const String& grant_name = "Stage2Arb->Grant" + (String)i; + createNet(dff_in_name); + createNet(req_name); + createNet(grant_name); + portConnect(stage2_arb_dffs[i], "D", dff_in_name); + portConnect(stage2_arb_dffs[i], "CK", "CK"); + portConnect(stage2_arb_dffs[i], "Q", req_name); + portConnect(stage2_arb, "Request" + (String)i, req_name); + portConnect(stage2_arb, "Grant" + (String)i, grant_name); + for(unsigned int j = 0; j < number_stage2_arbiters; ++j) + { + assignVirtualFanin(dff_in_name, String::format("Stage2Arb%d->Request%d", j, i)); + assignVirtualFanout(String::format("Stage2Arb%d->Grant%d", j, i), grant_name); + } + } + + // Add sub components + for(unsigned int i = 0; i < stage1_number_requests; ++i) + { + addSubInstances(stage1_arb_dffs[i], 1.0); + addElectricalSubResults(stage1_arb_dffs[i], 1.0); + } + addSubInstances(stage1_arb, number_stage1_arbiters); + addElectricalSubResults(stage1_arb, number_stage1_arbiters); + for(unsigned int i = 0; i < stage2_number_requests; ++i) + { + addSubInstances(stage2_arb_dffs[i], 1.0); + addElectricalSubResults(stage2_arb_dffs[i], 1.0); + } + addSubInstances(stage2_arb, number_stage2_arbiters); + addElectricalSubResults(stage2_arb, number_stage2_arbiters); + + // Update stage1 arb arbitrate + getEventResult("ArbitrateStage1")->addSubResult(stage1_arb->getEventResult("Arbitrate"), stage1_arb_name, 1.0); + + // Update stage2 arb arbitrate + getEventResult("ArbitrateStage2")->addSubResult(stage2_arb->getEventResult("Arbitrate"), stage2_arb_name, 1.0); + return; + } + + void RouterSwitchAllocator::propagateTransitionInfo() + { + ElectricalModel* stage1_arb = (ElectricalModel*)getSubInstance("Stage1Arb"); + stage1_arb->applyTransitionInfo("Arbitrate"); + stage1_arb->use(); + + ElectricalModel* stage2_arb = (ElectricalModel*)getSubInstance("Stage2Arb"); + stage2_arb->applyTransitionInfo("Arbitrate"); + stage2_arb->use(); + + return; + } +} // namespace DSENT + |