MultiplexerCrossbar.cc revision 10447:a465576671d4
1#include "model/electrical/MultiplexerCrossbar.h" 2 3#include <vector> 4#include <cmath> 5 6#include "model/PortInfo.h" 7#include "model/EventInfo.h" 8#include "model/TransitionInfo.h" 9#include "model/timing_graph/ElectricalNet.h" 10#include "model/electrical/Multiplexer.h" 11 12namespace DSENT 13{ 14 using std::ceil; 15 using std::vector; 16 17 MultiplexerCrossbar::MultiplexerCrossbar(const String& instance_name_, const TechModel* tech_model_) 18 : ElectricalModel(instance_name_, tech_model_) 19 { 20 initParameters(); 21 initProperties(); 22 } 23 24 MultiplexerCrossbar::~MultiplexerCrossbar() 25 {} 26 27 void MultiplexerCrossbar::initParameters() 28 { 29 addParameterName("NumberInputs"); 30 addParameterName("NumberOutputs"); 31 addParameterName("NumberBits"); 32 addParameterName("BitDuplicate", "TRUE"); 33 return; 34 } 35 36 void MultiplexerCrossbar::initProperties() 37 { 38 return; 39 } 40 41 MultiplexerCrossbar* MultiplexerCrossbar::clone() const 42 { 43 // TODO 44 return NULL; 45 } 46 47 void MultiplexerCrossbar::constructModel() 48 { 49 // Get Parameters 50 unsigned int number_inputs = getParameter("NumberInputs").toUInt(); 51 unsigned int number_outputs = getParameter("NumberOutputs").toUInt(); 52 unsigned int number_bits = getParameter("NumberBits").toUInt(); 53 bool bit_duplicate = getParameter("BitDuplicate").toBool(); 54 55 ASSERT(number_inputs > 0, "[Error] " + getInstanceName() + " -> Number of inputs must be > 0!"); 56 ASSERT(number_outputs > 0, "[Error] " + getInstanceName() + " -> Number of outputs must be > 0!"); 57 ASSERT(number_bits > 0, "[Error] " + getInstanceName() + " -> Number of bits must be > 0!"); 58 59 unsigned int number_selects = (unsigned int)ceil(log2((double)number_inputs)); 60 getGenProperties()->set("NumberSelectsPerPort", number_selects); 61 62 // Construct electrical ports and nets 63 // Create input ports 64 for(unsigned int i = 0; i < number_inputs; ++i) 65 { 66 createInputPort("In" + (String)i, makeNetIndex(0, number_bits-1)); 67 } 68 // Create select signals 69 for(unsigned int i = 0; i < number_outputs; ++i) 70 { 71 for(unsigned int j = 0; j < number_selects; ++j) 72 { 73 createInputPort(String::format("Sel%d_%d", i, j)); 74 } 75 } 76 // Create output ports 77 for(unsigned int i = 0; i < number_outputs; ++i) 78 { 79 createOutputPort("Out" + (String)i, makeNetIndex(0, number_bits-1)); 80 } 81 82 // Create energy, power, and area results 83 addAreaResult(new AtomicResult("CrossbarWire")); 84 addAreaResult(new AtomicResult("CrossbarFill")); 85 createElectricalResults(); 86 getEventInfo("Idle")->setStaticTransitionInfos(); 87 createElectricalEventResult("Multicast0"); 88 getEventInfo("Multicast0")->setStaticTransitionInfos(); 89 for(unsigned int i = 1; i <= number_outputs; ++i) 90 { 91 createElectricalEventResult("Multicast" + (String)i); 92 EventInfo* event_info = getEventInfo("Multicast" + (String)i); 93 // Assuming that In0 is sending to Out0, Out1, ..., Outi 94 // and other input ports are static 95 for(unsigned int j = 1; j < number_inputs; ++j) 96 { 97 event_info->setStaticTransitionInfo("In" + (String)j); 98 } 99 for(unsigned int j = i; j < number_outputs; ++j) 100 { 101 for(unsigned int k = 0; k < number_selects; ++k) 102 { 103 event_info->setStaticTransitionInfo(String::format("Sel%d_%d", j, k)); 104 } 105 } 106 } 107 createElectricalEventResult("Crossbar"); 108 109 // Initiate multiplexers 110 vector<String> mux_names(number_outputs, ""); 111 vector<Multiplexer*> muxs(number_outputs, NULL); 112 for(unsigned int i = 0; i < number_outputs; ++i) 113 { 114 mux_names[i] = "Mux" + (String)i; 115 muxs[i] = new Multiplexer(mux_names[i], getTechModel()); 116 muxs[i]->setParameter("NumberInputs", number_inputs); 117 muxs[i]->setParameter("NumberBits", number_bits); 118 muxs[i]->setParameter("BitDuplicate", bit_duplicate); 119 muxs[i]->construct(); 120 } 121 122 // Connect inputs and outputs to multiplexers 123 for(unsigned int i = 0; i < number_outputs; ++i) 124 { 125 // Connect inputs 126 for(unsigned int j = 0; j < number_inputs; ++j) 127 { 128 portConnect(muxs[i], "In" + (String)j, "In" + (String)j, makeNetIndex(0, number_bits-1)); 129 } 130 131 // Connect select signals 132 for(unsigned int j = 0; j < number_selects; ++j) 133 { 134 portConnect(muxs[i], "Sel" + (String)j, String::format("Sel%d_%d", i, j)); 135 } 136 137 // Connect outputs 138 portConnect(muxs[i], "Out", "Out" + (String)i, makeNetIndex(0, number_bits-1)); 139 } 140 141 // Add area, power, and event results for each mux 142 for(unsigned int i = 0; i < number_outputs; ++i) 143 { 144 addSubInstances(muxs[i], 1.0); 145 addElectricalSubResults(muxs[i], 1.0); 146 for(unsigned int j = 0; j <= number_outputs; ++j) 147 { 148 getEventResult("Multicast" + (String)j)->addSubResult(muxs[i]->getEventResult("Mux"), mux_names[i], 1.0); 149 } 150 getEventResult("Crossbar")->addSubResult(muxs[i]->getEventResult("Mux"), mux_names[i], 1.0); 151 } 152 153 // Estimate wiring area 154 const String& crossbar_wire_layer = "Intermediate"; 155 addElectricalWireSubResult(crossbar_wire_layer, getAreaResult("CrossbarWire"), "Self", 1.0); 156 double wire_width = getTechModel()->get("Wire->" + crossbar_wire_layer + "->MinWidth").toDouble(); 157 double wire_spacing = getTechModel()->get("Wire->" + crossbar_wire_layer + "->MinSpacing").toDouble(); 158 double wire_pitch = wire_width + wire_spacing; 159 double wire_area = (number_bits * number_inputs * wire_pitch) * (number_bits * number_outputs * wire_pitch); 160 getAreaResult("CrossbarWire")->setValue(wire_area); 161 162 // Add filler area 163 getAreaResult("Active")->addSubResult(getAreaResult("CrossbarFill"), "Self", 1.0); 164 return; 165 } 166 167 void MultiplexerCrossbar::updateModel() 168 { 169 // Update all sub instances 170 Model::updateModel(); 171 172 // Update filler area 173 // Total Active area = max(stdcell active area, wiring area); 174 double wire_area = getAreaResult("CrossbarWire")->calculateSum(); 175 double active_area = getAreaResult("Active")->calculateSum(); 176 double fill_area = 0.0; 177 if(active_area < wire_area) 178 { 179 fill_area = wire_area - active_area; 180 } 181 getAreaResult("CrossbarFill")->setValue(fill_area); 182 return; 183 } 184 185 void MultiplexerCrossbar::propagateTransitionInfo() 186 { 187 // The only thing can be updated are the input probabilities 188 const unsigned int number_inputs = getParameter("NumberInputs").toUInt(); 189 const unsigned int number_outputs = getParameter("NumberOutputs").toUInt(); 190 191 const unsigned int number_selects = getGenProperties()->get("NumberSelectsPerPort").toUInt(); 192 193 for(unsigned int i = 0; i < number_outputs; ++i) 194 { 195 ElectricalModel* muxi = (ElectricalModel*)getSubInstance("Mux" + (String)i); 196 for(unsigned int j = 0; j < number_inputs; ++j) 197 { 198 propagatePortTransitionInfo(muxi, "In" + (String)j, "In" + (String)j); 199 } 200 for(unsigned int j = 0; j < number_selects; ++j) 201 { 202 propagatePortTransitionInfo(muxi, "Sel" + (String)j, String::format("Sel%d_%d", i, j)); 203 } 204 muxi->use(); 205 206 // Set output probability 207 propagatePortTransitionInfo("Out" + (String)i, muxi, "Out"); 208 } 209 210 return; 211 } 212 213} // namespace DSENT 214 215