summaryrefslogtreecommitdiff
path: root/ext/dsent/model/electrical/MultiplexerCrossbar.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ext/dsent/model/electrical/MultiplexerCrossbar.cc')
-rw-r--r--ext/dsent/model/electrical/MultiplexerCrossbar.cc214
1 files changed, 214 insertions, 0 deletions
diff --git a/ext/dsent/model/electrical/MultiplexerCrossbar.cc b/ext/dsent/model/electrical/MultiplexerCrossbar.cc
new file mode 100644
index 000000000..7400d5ed2
--- /dev/null
+++ b/ext/dsent/model/electrical/MultiplexerCrossbar.cc
@@ -0,0 +1,214 @@
+#include "model/electrical/MultiplexerCrossbar.h"
+
+#include <vector>
+#include <cmath>
+
+#include "model/PortInfo.h"
+#include "model/EventInfo.h"
+#include "model/TransitionInfo.h"
+#include "model/timing_graph/ElectricalNet.h"
+#include "model/electrical/Multiplexer.h"
+
+namespace DSENT
+{
+ using std::ceil;
+ using std::vector;
+
+ MultiplexerCrossbar::MultiplexerCrossbar(const String& instance_name_, const TechModel* tech_model_)
+ : ElectricalModel(instance_name_, tech_model_)
+ {
+ initParameters();
+ initProperties();
+ }
+
+ MultiplexerCrossbar::~MultiplexerCrossbar()
+ {}
+
+ void MultiplexerCrossbar::initParameters()
+ {
+ addParameterName("NumberInputs");
+ addParameterName("NumberOutputs");
+ addParameterName("NumberBits");
+ addParameterName("BitDuplicate", "TRUE");
+ return;
+ }
+
+ void MultiplexerCrossbar::initProperties()
+ {
+ return;
+ }
+
+ MultiplexerCrossbar* MultiplexerCrossbar::clone() const
+ {
+ // TODO
+ return NULL;
+ }
+
+ void MultiplexerCrossbar::constructModel()
+ {
+ // Get Parameters
+ unsigned int number_inputs = getParameter("NumberInputs").toUInt();
+ unsigned int number_outputs = getParameter("NumberOutputs").toUInt();
+ unsigned int number_bits = getParameter("NumberBits").toUInt();
+ bool bit_duplicate = getParameter("BitDuplicate").toBool();
+
+ ASSERT(number_inputs > 0, "[Error] " + getInstanceName() + " -> Number of inputs must be > 0!");
+ ASSERT(number_outputs > 0, "[Error] " + getInstanceName() + " -> Number of outputs must be > 0!");
+ ASSERT(number_bits > 0, "[Error] " + getInstanceName() + " -> Number of bits must be > 0!");
+
+ unsigned int number_selects = (unsigned int)ceil(log2((double)number_inputs));
+ getGenProperties()->set("NumberSelectsPerPort", number_selects);
+
+ // Construct electrical ports and nets
+ // Create input ports
+ for(unsigned int i = 0; i < number_inputs; ++i)
+ {
+ createInputPort("In" + (String)i, makeNetIndex(0, number_bits-1));
+ }
+ // Create select signals
+ for(unsigned int i = 0; i < number_outputs; ++i)
+ {
+ for(unsigned int j = 0; j < number_selects; ++j)
+ {
+ createInputPort(String::format("Sel%d_%d", i, j));
+ }
+ }
+ // Create output ports
+ for(unsigned int i = 0; i < number_outputs; ++i)
+ {
+ createOutputPort("Out" + (String)i, makeNetIndex(0, number_bits-1));
+ }
+
+ // Create energy, power, and area results
+ addAreaResult(new AtomicResult("CrossbarWire"));
+ addAreaResult(new AtomicResult("CrossbarFill"));
+ createElectricalResults();
+ getEventInfo("Idle")->setStaticTransitionInfos();
+ createElectricalEventResult("Multicast0");
+ getEventInfo("Multicast0")->setStaticTransitionInfos();
+ for(unsigned int i = 1; i <= number_outputs; ++i)
+ {
+ createElectricalEventResult("Multicast" + (String)i);
+ EventInfo* event_info = getEventInfo("Multicast" + (String)i);
+ // Assuming that In0 is sending to Out0, Out1, ..., Outi
+ // and other input ports are static
+ for(unsigned int j = 1; j < number_inputs; ++j)
+ {
+ event_info->setStaticTransitionInfo("In" + (String)j);
+ }
+ for(unsigned int j = i; j < number_outputs; ++j)
+ {
+ for(unsigned int k = 0; k < number_selects; ++k)
+ {
+ event_info->setStaticTransitionInfo(String::format("Sel%d_%d", j, k));
+ }
+ }
+ }
+ createElectricalEventResult("Crossbar");
+
+ // Initiate multiplexers
+ vector<String> mux_names(number_outputs, "");
+ vector<Multiplexer*> muxs(number_outputs, NULL);
+ for(unsigned int i = 0; i < number_outputs; ++i)
+ {
+ mux_names[i] = "Mux" + (String)i;
+ muxs[i] = new Multiplexer(mux_names[i], getTechModel());
+ muxs[i]->setParameter("NumberInputs", number_inputs);
+ muxs[i]->setParameter("NumberBits", number_bits);
+ muxs[i]->setParameter("BitDuplicate", bit_duplicate);
+ muxs[i]->construct();
+ }
+
+ // Connect inputs and outputs to multiplexers
+ for(unsigned int i = 0; i < number_outputs; ++i)
+ {
+ // Connect inputs
+ for(unsigned int j = 0; j < number_inputs; ++j)
+ {
+ portConnect(muxs[i], "In" + (String)j, "In" + (String)j, makeNetIndex(0, number_bits-1));
+ }
+
+ // Connect select signals
+ for(unsigned int j = 0; j < number_selects; ++j)
+ {
+ portConnect(muxs[i], "Sel" + (String)j, String::format("Sel%d_%d", i, j));
+ }
+
+ // Connect outputs
+ portConnect(muxs[i], "Out", "Out" + (String)i, makeNetIndex(0, number_bits-1));
+ }
+
+ // Add area, power, and event results for each mux
+ for(unsigned int i = 0; i < number_outputs; ++i)
+ {
+ addSubInstances(muxs[i], 1.0);
+ addElectricalSubResults(muxs[i], 1.0);
+ for(unsigned int j = 0; j <= number_outputs; ++j)
+ {
+ getEventResult("Multicast" + (String)j)->addSubResult(muxs[i]->getEventResult("Mux"), mux_names[i], 1.0);
+ }
+ getEventResult("Crossbar")->addSubResult(muxs[i]->getEventResult("Mux"), mux_names[i], 1.0);
+ }
+
+ // Estimate wiring area
+ const String& crossbar_wire_layer = "Intermediate";
+ addElectricalWireSubResult(crossbar_wire_layer, getAreaResult("CrossbarWire"), "Self", 1.0);
+ double wire_width = getTechModel()->get("Wire->" + crossbar_wire_layer + "->MinWidth").toDouble();
+ double wire_spacing = getTechModel()->get("Wire->" + crossbar_wire_layer + "->MinSpacing").toDouble();
+ double wire_pitch = wire_width + wire_spacing;
+ double wire_area = (number_bits * number_inputs * wire_pitch) * (number_bits * number_outputs * wire_pitch);
+ getAreaResult("CrossbarWire")->setValue(wire_area);
+
+ // Add filler area
+ getAreaResult("Active")->addSubResult(getAreaResult("CrossbarFill"), "Self", 1.0);
+ return;
+ }
+
+ void MultiplexerCrossbar::updateModel()
+ {
+ // Update all sub instances
+ Model::updateModel();
+
+ // Update filler area
+ // Total Active area = max(stdcell active area, wiring area);
+ double wire_area = getAreaResult("CrossbarWire")->calculateSum();
+ double active_area = getAreaResult("Active")->calculateSum();
+ double fill_area = 0.0;
+ if(active_area < wire_area)
+ {
+ fill_area = wire_area - active_area;
+ }
+ getAreaResult("CrossbarFill")->setValue(fill_area);
+ return;
+ }
+
+ void MultiplexerCrossbar::propagateTransitionInfo()
+ {
+ // The only thing can be updated are the input probabilities
+ const unsigned int number_inputs = getParameter("NumberInputs").toUInt();
+ const unsigned int number_outputs = getParameter("NumberOutputs").toUInt();
+
+ const unsigned int number_selects = getGenProperties()->get("NumberSelectsPerPort").toUInt();
+
+ for(unsigned int i = 0; i < number_outputs; ++i)
+ {
+ ElectricalModel* muxi = (ElectricalModel*)getSubInstance("Mux" + (String)i);
+ for(unsigned int j = 0; j < number_inputs; ++j)
+ {
+ propagatePortTransitionInfo(muxi, "In" + (String)j, "In" + (String)j);
+ }
+ for(unsigned int j = 0; j < number_selects; ++j)
+ {
+ propagatePortTransitionInfo(muxi, "Sel" + (String)j, String::format("Sel%d_%d", i, j));
+ }
+ muxi->use();
+
+ // Set output probability
+ propagatePortTransitionInfo("Out" + (String)i, muxi, "Out");
+ }
+
+ return;
+ }
+
+} // namespace DSENT
+