From e8ed7b1d1b5bef31e9874f679a5797c2e00d06f1 Mon Sep 17 00:00:00 2001 From: Nilay Vaish Date: Sat, 11 Oct 2014 15:02:23 -0500 Subject: 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. --- ext/dsent/model/electrical/MultiplexerCrossbar.cc | 214 ++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 ext/dsent/model/electrical/MultiplexerCrossbar.cc (limited to 'ext/dsent/model/electrical/MultiplexerCrossbar.cc') 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 +#include + +#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 mux_names(number_outputs, ""); + vector 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 + -- cgit v1.2.3