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/std_cells/BUF.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/CellMacros.h"
31 #include "model/timing_graph/ElectricalNet.h"
32 #include "model/timing_graph/ElectricalDriver.h"
33 #include "model/timing_graph/ElectricalLoad.h"
34 #include "model/timing_graph/ElectricalDelay.h"
40 BUF::BUF(const String
& instance_name_
, const TechModel
* tech_model_
)
41 : StdCell(instance_name_
, tech_model_
)
49 void BUF::initProperties()
54 void BUF::constructModel()
57 createOutputPort("Y");
60 createDelay("A_to_Y_delay");
61 createDriver("Y_Ron", true);
63 ElectricalLoad
* a_cap
= getLoad("A_Cap");
64 ElectricalDelay
* a_to_y_delay
= getDelay("A_to_Y_delay");
65 ElectricalDriver
* y_ron
= getDriver("Y_Ron");
67 getNet("A")->addDownstreamNode(a_cap
);
68 a_cap
->addDownstreamNode(a_to_y_delay
);
69 a_to_y_delay
->addDownstreamNode(y_ron
);
70 y_ron
->addDownstreamNode(getNet("Y"));
73 // Create NDD Power result
74 createElectricalAtomicResults();
75 // Create OR Event Energy Result
76 createElectricalEventAtomicResult("BUF");
78 getEventInfo("Idle")->setStaticTransitionInfos();
83 void BUF::updateModel()
86 double drive_strength
= getDrivingStrength();
87 Map
<double>* cache
= getTechModel()->getStdCellLib()->getStdCellCache();
89 // Standard cell cache string
90 const String
& cell_name
= "BUF_X" + (String
) drive_strength
;
92 // Get timing parameters
93 getLoad("A_Cap")->setLoadCap(cache
->get(cell_name
+ "->Cap->A"));
94 getDelay("A_to_Y_delay")->setDelay(cache
->get(cell_name
+ "->Delay->A_to_Y"));
95 getDriver("Y_Ron")->setOutputRes(cache
->get(cell_name
+ "->DriveRes->Y"));
98 getAreaResult("Active")->setValue(cache
->get(cell_name
+ "->ActiveArea"));
99 getAreaResult("Metal1Wire")->setValue(cache
->get(cell_name
+ "->ActiveArea"));
104 void BUF::evaluateModel()
112 double drive_strength
= getDrivingStrength();
113 Map
<double>* cache
= getTechModel()->getStdCellLib()->getStdCellCache();
115 // Stadard cell cache string
116 const String
& cell_name
= "BUF_X" + (String
) drive_strength
;
118 // Propagate the transition info and get the 0->1 transtion count
119 propagateTransitionInfo();
120 double P_A
= getInputPort("A")->getTransitionInfo().getProbability1();
121 double Y_num_trans_01
= getOutputPort("Y")->getTransitionInfo().getNumberTransitions01();
125 leakage
+= cache
->get(cell_name
+ "->Leakage->!A") * (1 - P_A
);
126 leakage
+= cache
->get(cell_name
+ "->Leakage->A") * P_A
;
127 getNddPowerResult("Leakage")->setValue(leakage
);
130 double vdd
= getTechModel()->get("Vdd");
133 double y_b_cap
= cache
->get(cell_name
+ "->Cap->Y_b");
134 double y_cap
= cache
->get(cell_name
+ "->Cap->Y");
135 double y_load_cap
= getNet("Y")->getTotalDownstreamCap();
137 // Calculate BUFEvent energy
138 double energy_per_trans_01
= (y_b_cap
+ y_cap
+ y_load_cap
) * vdd
* vdd
;
139 getEventResult("BUF")->setValue(energy_per_trans_01
* Y_num_trans_01
);
144 void BUF::propagateTransitionInfo()
146 // Get input signal transition info
147 const TransitionInfo
& trans_A
= getInputPort("A")->getTransitionInfo();
149 getOutputPort("Y")->setTransitionInfo(trans_A
);
153 // Creates the standard cell, characterizes and abstracts away the details
154 void BUF::cacheStdCell(StdCellLib
* cell_lib_
, double drive_strength_
)
157 double gate_pitch
= cell_lib_
->getTechModel()->get("Gate->PitchContacted");
158 Map
<double>* cache
= cell_lib_
->getStdCellCache();
160 // Stadard cell cache string
161 const String
& cell_name
= "BUF_X" + (String
) drive_strength_
;
163 Log::printLine("=== " + cell_name
+ " ===");
165 // Now actually build the full standard cell model
166 createInputPort("A");
167 createOutputPort("Y");
172 CellMacros::addInverter(this, "INV0", false, true, "A", "Y_b");
173 CellMacros::addInverter(this, "INV1", false, true, "Y_b", "Y");
176 CellMacros::updateInverter(this, "INV0", drive_strength_
* 0.367);
177 CellMacros::updateInverter(this, "INV1", drive_strength_
* 1.0);
181 area
+= gate_pitch
* getTotalHeight() * 1;
182 area
+= gate_pitch
* getTotalHeight() * getGenProperties()->get("INV0_GatePitches").toDouble();
183 area
+= gate_pitch
* getTotalHeight() * getGenProperties()->get("INV1_GatePitches").toDouble();
184 cache
->set(cell_name
+ "->ActiveArea", area
);
185 Log::printLine(cell_name
+ "->ActiveArea=" + (String
)area
);
187 // --------------------------------------------------------------------
188 // Leakage Model Calculation
189 // --------------------------------------------------------------------
190 // Cache leakage power results (for every single signal combination)
191 double leakage_0
= 0.0; // !A
192 double leakage_1
= 0.0; // A
194 leakage_0
+= getGenProperties()->get("INV0_LeakagePower_0").toDouble();
195 leakage_0
+= getGenProperties()->get("INV1_LeakagePower_1").toDouble();
197 leakage_1
+= getGenProperties()->get("INV0_LeakagePower_1").toDouble();
198 leakage_1
+= getGenProperties()->get("INV1_LeakagePower_0").toDouble();
200 cache
->set(cell_name
+ "->Leakage->!A", leakage_0
);
201 cache
->set(cell_name
+ "->Leakage->A", leakage_1
);
202 Log::printLine(cell_name
+ "->Leakage->!A=" + (String
) leakage_0
);
203 Log::printLine(cell_name
+ "->Leakage->A=" + (String
) leakage_1
);
204 // --------------------------------------------------------------------
206 // --------------------------------------------------------------------
207 // Get Node Capacitances
208 // --------------------------------------------------------------------
209 double a_cap
= getNet("A")->getTotalDownstreamCap();
210 double y_b_cap
= getNet("Y_b")->getTotalDownstreamCap();
211 double y_cap
= getNet("Y")->getTotalDownstreamCap();
213 cache
->set(cell_name
+ "->Cap->A", a_cap
);
214 cache
->set(cell_name
+ "->Cap->Y_b", y_b_cap
);
215 cache
->set(cell_name
+ "->Cap->Y", y_cap
);
216 Log::printLine(cell_name
+ "->Cap->A_Cap=" + (String
) a_cap
);
217 Log::printLine(cell_name
+ "->Cap->Y_b_Cap=" + (String
) y_b_cap
);
218 Log::printLine(cell_name
+ "->Cap->Y_Cap=" + (String
) y_cap
);
219 // --------------------------------------------------------------------
221 // --------------------------------------------------------------------
222 // Build Internal Delay Model
223 // --------------------------------------------------------------------
224 double y_ron
= getDriver("INV1_RonZN")->getOutputRes();
225 double a_to_y_delay
= getDriver("INV0_RonZN")->calculateDelay() +
226 getDriver("INV1_RonZN")->calculateDelay();
228 cache
->set(cell_name
+ "->DriveRes->Y", y_ron
);
229 cache
->set(cell_name
+ "->Delay->A_to_Y", a_to_y_delay
);
230 Log::printLine(cell_name
+ "->DriveRes->Y=" + (String
) y_ron
);
231 Log::printLine(cell_name
+ "->Delay->A_to_Y=" + (String
) a_to_y_delay
);
232 // --------------------------------------------------------------------