1 /* Copyright (c) 2012 Massachusetts Institute of Technology
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to deal
5 * in the Software without restriction, including without limitation the rights
6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 * copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 #include "model/electrical/MultiplexerCrossbar.h"
27 #include "model/PortInfo.h"
28 #include "model/EventInfo.h"
29 #include "model/TransitionInfo.h"
30 #include "model/timing_graph/ElectricalNet.h"
31 #include "model/electrical/Multiplexer.h"
38 MultiplexerCrossbar::MultiplexerCrossbar(const String
& instance_name_
, const TechModel
* tech_model_
)
39 : ElectricalModel(instance_name_
, tech_model_
)
45 MultiplexerCrossbar::~MultiplexerCrossbar()
48 void MultiplexerCrossbar::initParameters()
50 addParameterName("NumberInputs");
51 addParameterName("NumberOutputs");
52 addParameterName("NumberBits");
53 addParameterName("BitDuplicate", "TRUE");
57 void MultiplexerCrossbar::initProperties()
62 MultiplexerCrossbar
* MultiplexerCrossbar::clone() const
68 void MultiplexerCrossbar::constructModel()
71 unsigned int number_inputs
= getParameter("NumberInputs").toUInt();
72 unsigned int number_outputs
= getParameter("NumberOutputs").toUInt();
73 unsigned int number_bits
= getParameter("NumberBits").toUInt();
74 bool bit_duplicate
= getParameter("BitDuplicate").toBool();
76 ASSERT(number_inputs
> 0, "[Error] " + getInstanceName() + " -> Number of inputs must be > 0!");
77 ASSERT(number_outputs
> 0, "[Error] " + getInstanceName() + " -> Number of outputs must be > 0!");
78 ASSERT(number_bits
> 0, "[Error] " + getInstanceName() + " -> Number of bits must be > 0!");
80 unsigned int number_selects
= (unsigned int)ceil(log2((double)number_inputs
));
81 getGenProperties()->set("NumberSelectsPerPort", number_selects
);
83 // Construct electrical ports and nets
85 for(unsigned int i
= 0; i
< number_inputs
; ++i
)
87 createInputPort("In" + (String
)i
, makeNetIndex(0, number_bits
-1));
89 // Create select signals
90 for(unsigned int i
= 0; i
< number_outputs
; ++i
)
92 for(unsigned int j
= 0; j
< number_selects
; ++j
)
94 createInputPort(String::format("Sel%d_%d", i
, j
));
97 // Create output ports
98 for(unsigned int i
= 0; i
< number_outputs
; ++i
)
100 createOutputPort("Out" + (String
)i
, makeNetIndex(0, number_bits
-1));
103 // Create energy, power, and area results
104 addAreaResult(new AtomicResult("CrossbarWire"));
105 addAreaResult(new AtomicResult("CrossbarFill"));
106 createElectricalResults();
107 getEventInfo("Idle")->setStaticTransitionInfos();
108 createElectricalEventResult("Multicast0");
109 getEventInfo("Multicast0")->setStaticTransitionInfos();
110 for(unsigned int i
= 1; i
<= number_outputs
; ++i
)
112 createElectricalEventResult("Multicast" + (String
)i
);
113 EventInfo
* event_info
= getEventInfo("Multicast" + (String
)i
);
114 // Assuming that In0 is sending to Out0, Out1, ..., Outi
115 // and other input ports are static
116 for(unsigned int j
= 1; j
< number_inputs
; ++j
)
118 event_info
->setStaticTransitionInfo("In" + (String
)j
);
120 for(unsigned int j
= i
; j
< number_outputs
; ++j
)
122 for(unsigned int k
= 0; k
< number_selects
; ++k
)
124 event_info
->setStaticTransitionInfo(String::format("Sel%d_%d", j
, k
));
128 createElectricalEventResult("Crossbar");
130 // Initiate multiplexers
131 vector
<String
> mux_names(number_outputs
, "");
132 vector
<Multiplexer
*> muxs(number_outputs
, NULL
);
133 for(unsigned int i
= 0; i
< number_outputs
; ++i
)
135 mux_names
[i
] = "Mux" + (String
)i
;
136 muxs
[i
] = new Multiplexer(mux_names
[i
], getTechModel());
137 muxs
[i
]->setParameter("NumberInputs", number_inputs
);
138 muxs
[i
]->setParameter("NumberBits", number_bits
);
139 muxs
[i
]->setParameter("BitDuplicate", bit_duplicate
);
140 muxs
[i
]->construct();
143 // Connect inputs and outputs to multiplexers
144 for(unsigned int i
= 0; i
< number_outputs
; ++i
)
147 for(unsigned int j
= 0; j
< number_inputs
; ++j
)
149 portConnect(muxs
[i
], "In" + (String
)j
, "In" + (String
)j
, makeNetIndex(0, number_bits
-1));
152 // Connect select signals
153 for(unsigned int j
= 0; j
< number_selects
; ++j
)
155 portConnect(muxs
[i
], "Sel" + (String
)j
, String::format("Sel%d_%d", i
, j
));
159 portConnect(muxs
[i
], "Out", "Out" + (String
)i
, makeNetIndex(0, number_bits
-1));
162 // Add area, power, and event results for each mux
163 for(unsigned int i
= 0; i
< number_outputs
; ++i
)
165 addSubInstances(muxs
[i
], 1.0);
166 addElectricalSubResults(muxs
[i
], 1.0);
167 for(unsigned int j
= 0; j
<= number_outputs
; ++j
)
169 getEventResult("Multicast" + (String
)j
)->addSubResult(muxs
[i
]->getEventResult("Mux"), mux_names
[i
], 1.0);
171 getEventResult("Crossbar")->addSubResult(muxs
[i
]->getEventResult("Mux"), mux_names
[i
], 1.0);
174 // Estimate wiring area
175 const String
& crossbar_wire_layer
= "Intermediate";
176 addElectricalWireSubResult(crossbar_wire_layer
, getAreaResult("CrossbarWire"), "Self", 1.0);
177 double wire_width
= getTechModel()->get("Wire->" + crossbar_wire_layer
+ "->MinWidth").toDouble();
178 double wire_spacing
= getTechModel()->get("Wire->" + crossbar_wire_layer
+ "->MinSpacing").toDouble();
179 double wire_pitch
= wire_width
+ wire_spacing
;
180 double wire_area
= (number_bits
* number_inputs
* wire_pitch
) * (number_bits
* number_outputs
* wire_pitch
);
181 getAreaResult("CrossbarWire")->setValue(wire_area
);
184 getAreaResult("Active")->addSubResult(getAreaResult("CrossbarFill"), "Self", 1.0);
188 void MultiplexerCrossbar::updateModel()
190 // Update all sub instances
191 Model::updateModel();
193 // Update filler area
194 // Total Active area = max(stdcell active area, wiring area);
195 double wire_area
= getAreaResult("CrossbarWire")->calculateSum();
196 double active_area
= getAreaResult("Active")->calculateSum();
197 double fill_area
= 0.0;
198 if(active_area
< wire_area
)
200 fill_area
= wire_area
- active_area
;
202 getAreaResult("CrossbarFill")->setValue(fill_area
);
206 void MultiplexerCrossbar::propagateTransitionInfo()
208 // The only thing can be updated are the input probabilities
209 const unsigned int number_inputs
= getParameter("NumberInputs").toUInt();
210 const unsigned int number_outputs
= getParameter("NumberOutputs").toUInt();
212 const unsigned int number_selects
= getGenProperties()->get("NumberSelectsPerPort").toUInt();
214 for(unsigned int i
= 0; i
< number_outputs
; ++i
)
216 ElectricalModel
* muxi
= (ElectricalModel
*)getSubInstance("Mux" + (String
)i
);
217 for(unsigned int j
= 0; j
< number_inputs
; ++j
)
219 propagatePortTransitionInfo(muxi
, "In" + (String
)j
, "In" + (String
)j
);
221 for(unsigned int j
= 0; j
< number_selects
; ++j
)
223 propagatePortTransitionInfo(muxi
, "Sel" + (String
)j
, String::format("Sel%d_%d", i
, j
));
227 // Set output probability
228 propagatePortTransitionInfo("Out" + (String
)i
, muxi
, "Out");