summaryrefslogtreecommitdiff
path: root/ext/dsent/model/electrical/router/RouterSwitchAllocator.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ext/dsent/model/electrical/router/RouterSwitchAllocator.cc')
-rw-r--r--ext/dsent/model/electrical/router/RouterSwitchAllocator.cc199
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
+