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/OR.h"
26 #include "model/PortInfo.h"
27 #include "model/TransitionInfo.h"
28 #include "model/EventInfo.h"
29 #include "model/std_cells/StdCellLib.h"
30 #include "model/std_cells/StdCell.h"
31 #include "model/timing_graph/ElectricalNet.h"
38 OR::OR(const String
& instance_name_
, const TechModel
* tech_model_
)
39 : ElectricalModel(instance_name_
, tech_model_
)
48 void OR::initParameters()
50 addParameterName("NumberInputs");
51 addParameterName("NumberBits");
52 addParameterName("BitDuplicate", "TRUE");
56 void OR::initProperties()
67 void OR::constructModel()
70 unsigned int number_inputs
= getParameter("NumberInputs").toUInt();
71 unsigned int number_bits
= getParameter("NumberBits").toUInt();
72 bool bit_duplicate
= getParameter("BitDuplicate").toBool();
74 ASSERT(number_inputs
> 0, "[Error] " + getInstanceName() +
75 " -> Number of inputs must be > 0!");
76 ASSERT(number_bits
> 0, "[Error] " + getInstanceName() +
77 " -> Number of bits must be > 0!");
81 for(unsigned int i
= 0; i
< number_inputs
; ++i
)
83 createInputPort("In" + (String
)i
, makeNetIndex(0, number_bits
-1));
85 createOutputPort("Out", makeNetIndex(0, number_bits
-1));
87 // Number of inputs on the 0 side
88 unsigned int or0_number_inputs
= (unsigned int)ceil((double)number_inputs
/ 2.0);
89 // Number of inputs on the 1 side
90 unsigned int or1_number_inputs
= (unsigned int)floor((double)number_inputs
/ 2.0);
92 // Create area, power, and event results
93 createElectricalResults();
94 createElectricalEventResult("OR");
96 getEventInfo("Idle")->setStaticTransitionInfos();
98 //Depending on whether we want to create a 1-bit instance and have it multiplied
99 //up by number of bits or actually instantiate number_bits of 1-bit instances.
100 //Recursively instantiates smaller ors
101 if(bit_duplicate
|| number_bits
== 1)
103 // If it is just a 1-input or, just connect output to input
104 if(number_inputs
== 1)
106 assign("Out", "In0");
110 // If it is more than 1 input, instantiate two sub ors (OR_way0 and OR_way1)
111 // and create a final OR2 to OR them
112 const String
& or0_name
= "OR_way0";
113 const String
& or1_name
= "OR_way1";
114 const String
& orf_name
= "OR2_i" + (String
)number_inputs
;
116 OR
* or0
= new OR(or0_name
, getTechModel());
117 or0
->setParameter("NumberInputs", or0_number_inputs
);
118 or0
->setParameter("NumberBits", 1);
119 or0
->setParameter("BitDuplicate", "TRUE");
122 OR
* or1
= new OR(or1_name
, getTechModel());
123 or1
->setParameter("NumberInputs", or1_number_inputs
);
124 or1
->setParameter("NumberBits", 1);
125 or1
->setParameter("BitDuplicate", "TRUE");
128 StdCell
* orf
= getTechModel()->getStdCellLib()->createStdCell("OR2", orf_name
);
131 // Create outputs of way0 and way1 ors with final or
132 createNet("way0_Out");
133 createNet("way1_Out");
134 portConnect(or0
, "Out", "way0_Out");
135 portConnect(or1
, "Out", "way1_Out");
136 portConnect(orf
, "A", "way0_Out");
137 portConnect(orf
, "B", "way1_Out");
139 // Connect inputs to the sub ors.
140 for(unsigned int i
= 0; i
< or0_number_inputs
; ++i
)
142 createNet("way0_In" + (String
)i
);
143 portConnect(or0
, "In" + (String
)i
, "way0_In" + (String
)i
);
144 assignVirtualFanin("way0_In" + (String
)i
, "In" + (String
)i
);
146 for(unsigned int i
= 0; i
< or1_number_inputs
; ++i
)
148 createNet("way1_In" + (String
)i
);
149 portConnect(or1
, "In" + (String
)i
, "way1_In" + (String
)i
);
150 assignVirtualFanin("way1_In" + (String
)i
, "In" + (String
)(i
+ or0_number_inputs
));
154 createNet("OR2_Out");
155 portConnect(orf
, "Y", "OR2_Out");
156 assignVirtualFanout("Out", "OR2_Out");
158 addSubInstances(or0
, number_bits
);
159 addElectricalSubResults(or0
, number_bits
);
160 addSubInstances(or1
, number_bits
);
161 addElectricalSubResults(or1
, number_bits
);
162 addSubInstances(orf
, number_bits
);
163 addElectricalSubResults(orf
, number_bits
);
165 Result
* or_event
= getEventResult("OR");
166 or_event
->addSubResult(or0
->getEventResult("OR"), or0_name
, number_bits
);
167 or_event
->addSubResult(or1
->getEventResult("OR"), or1_name
, number_bits
);
168 or_event
->addSubResult(orf
->getEventResult("OR2"), orf_name
, number_bits
);
174 // Init a bunch of 1-bit ors
175 Result
* or_event
= getEventResult("OR");
176 for(unsigned int n
= 0; n
< number_bits
; ++n
)
178 const String
& or_name
= "OR_bit" + (String
)n
;
180 OR
* ors
= new OR(or_name
, getTechModel());
181 ors
->setParameter("NumberInputs", number_inputs
);
182 ors
->setParameter("NumberBits", 1);
183 ors
->setParameter("BitDuplicate", "TRUE");
186 for(unsigned int i
= 0; i
< number_inputs
; ++i
)
188 portConnect(ors
, "In" + (String
)i
, "In" + (String
)i
, makeNetIndex(n
));
190 portConnect(ors
, "Out", "Out", makeNetIndex(n
));
192 addSubInstances(ors
, 1.0);
193 addElectricalSubResults(ors
, 1.0);
194 or_event
->addSubResult(ors
->getEventResult("OR"), or_name
, 1.0);
200 void OR::propagateTransitionInfo()
203 unsigned int number_inputs
= getParameter("NumberInputs").toUInt();
204 unsigned int number_bits
= getParameter("NumberBits").toUInt();
205 bool bit_duplicate
= getParameter("BitDuplicate").toBool();
207 // Number of inputs on 0 side
208 unsigned int or0_number_inputs
= (unsigned int)ceil((double)number_inputs
/ 2.0);
209 unsigned int or1_number_inputs
= (unsigned int)floor((double)number_inputs
/ 2.0);
211 if(bit_duplicate
|| number_bits
== 1)
213 if(number_inputs
== 1)
215 propagatePortTransitionInfo("Out", "In0");
219 ElectricalModel
* or0
= (ElectricalModel
*)getSubInstance("OR_way0");
220 for(unsigned int i
= 0; i
< or0_number_inputs
; ++i
)
222 propagatePortTransitionInfo(or0
, "In" + (String
)i
, "In" + (String
)i
);
226 ElectricalModel
* or1
= (ElectricalModel
*)getSubInstance("OR_way1");
227 for(unsigned int i
= 0; i
< or1_number_inputs
; ++i
)
229 propagatePortTransitionInfo(or1
, "In" + (String
)i
, "In" + (String
)i
);
233 ElectricalModel
* orf
= (ElectricalModel
*)getSubInstance("OR2_i" + (String
)number_inputs
);
234 propagatePortTransitionInfo(orf
, "A", or0
, "Out");
235 propagatePortTransitionInfo(orf
, "B", or1
, "Out");
238 // Set output probability
239 propagatePortTransitionInfo("Out", orf
, "Y");
244 for(unsigned int n
= 0; n
< number_bits
; ++n
)
246 ElectricalModel
* or_bit
= (ElectricalModel
*)getSubInstance("OR_bit" + (String
)n
);
247 for(unsigned int i
= 0; i
< number_inputs
; ++i
)
249 propagatePortTransitionInfo(or_bit
, "In" + (String
)i
, "In" + (String
)i
);
254 ElectricalModel
* or_bit
= (ElectricalModel
*)getSubInstance("OR_bit0");
255 propagatePortTransitionInfo("Out", or_bit
, "Out");