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/StdCellLib.h"
26 #include "model/std_cells/StdCell.h"
27 #include "model/std_cells/INV.h"
28 #include "model/ModelGen.h"
34 StdCellLib::StdCellLib(TechModel
* tech_model_
)
35 : m_tech_model_(tech_model_
)
37 m_std_cell_cache_
= new Map
<double>();
38 ASSERT((m_tech_model_
!= NULL
), "[Error] StdCellLib -> tech_model is NULL");
42 StdCellLib::~StdCellLib()
44 delete m_std_cell_cache_
;
47 const TechModel
* StdCellLib::getTechModel() const
52 StdCell
* StdCellLib::createStdCell(const String
& std_cell_name_
, const String
& instance_name_
) const
54 // Create the standard cell
55 StdCell
* created_cell
= ModelGen::createStdCell(std_cell_name_
, instance_name_
, getTechModel());
56 // Grab the variants of each standard cell
57 String driving_strength_str
= getTechModel()->get("StdCell->AvailableSizes");
58 // Set library properties for the standard cell
59 created_cell
->setPToNRatio(getPToNRatio());
60 created_cell
->setActiveHeight(getActiveHeight());
61 created_cell
->setTotalHeight(getTotalHeight());
62 created_cell
->setAvailableDrivingStrengths(driving_strength_str
);
66 // Get PMOS to NMOS ratio
67 double StdCellLib::getPToNRatio() const
69 return m_p_to_n_ratio_
;
72 void StdCellLib::setPToNRatio(double p_to_n_ratio_
)
74 m_p_to_n_ratio_
= p_to_n_ratio_
;
77 // Get height of the standard cell taken by active transistors
78 double StdCellLib::getActiveHeight() const
80 return m_active_height_
;
83 void StdCellLib::setActiveHeight(double active_height_
)
85 m_active_height_
= active_height_
;
88 // Get total height of the standard cell including overheads
89 double StdCellLib::getTotalHeight() const
91 return m_total_height_
;
94 void StdCellLib::setTotalHeight(double total_height_
)
96 m_total_height_
= total_height_
;
99 void StdCellLib::createLib()
101 Log::printLine("Standard cell library creation for tech model " + getTechModel()->get("Name"));
103 // Get technology parameters
104 double nmos_eff_res
= getTechModel()->get("Nmos->EffResWidth");
105 double pmos_eff_res
= getTechModel()->get("Pmos->EffResWidth");
106 double gate_min_width
= getTechModel()->get("Gate->MinWidth");
108 // Create standard cell common parameters
109 double pn_ratio
= pmos_eff_res
/ nmos_eff_res
;
110 double nmos_unit_width
= gate_min_width
;
111 double pmos_unit_width
= gate_min_width
* pn_ratio
;
113 // Derive the height of each cell in the standard cell library, as well as the max Nmos and Pmos widths
114 double std_cell_total_height
= getTechModel()->get("StdCell->Tracks").toDouble() *
115 (getTechModel()->get("Wire->Metal1->MinWidth").toDouble() + getTechModel()->get("Wire->Metal1->MinSpacing").toDouble());
116 double std_cell_active_height
= std_cell_total_height
/ getTechModel()->get("StdCell->HeightOverheadFactor").toDouble();
118 Log::printLine("Standard cell P-to-N ratio (Beta) = " + (String
) pn_ratio
);
119 Log::printLine("Standard cell NMOS unit width = " + (String
) nmos_unit_width
);
120 Log::printLine("Standard cell PMOS unit width = " + (String
) pmos_unit_width
);
121 Log::printLine("Standard cell active height = " + (String
) std_cell_active_height
);
122 Log::printLine("Standard cell total height = " + (String
) std_cell_total_height
);
124 setPToNRatio(pn_ratio
);
125 setActiveHeight(std_cell_active_height
);
126 setTotalHeight(std_cell_total_height
);
128 const vector
<String
>& cell_sizes
= getTechModel()->get("StdCell->AvailableSizes").split("[,]");
129 // Create cached standard cells
130 for (unsigned int i
= 0; i
< cell_sizes
.size(); ++i
)
132 StdCell
* inv
= createStdCell("INV", "CachedINV");
133 inv
->cacheStdCell(this, cell_sizes
[i
].toDouble());
136 StdCell
* nand2
= createStdCell("NAND2", "CachedNAND2");
137 nand2
->cacheStdCell(this, cell_sizes
[i
].toDouble());
140 StdCell
* nor2
= createStdCell("NOR2", "CachedNOR2");
141 nor2
->cacheStdCell(this, cell_sizes
[i
].toDouble());
144 StdCell
* mux2
= createStdCell("MUX2", "CachedMUX2");
145 mux2
->cacheStdCell(this, cell_sizes
[i
].toDouble());
148 StdCell
* xor2
= createStdCell("XOR2", "CachedXOR2");
149 xor2
->cacheStdCell(this, cell_sizes
[i
].toDouble());
152 StdCell
* addf
= createStdCell("ADDF", "CachedADDF");
153 addf
->cacheStdCell(this, cell_sizes
[i
].toDouble());
156 StdCell
* dffq
= createStdCell("DFFQ", "CachedDFFQ");
157 dffq
->cacheStdCell(this, cell_sizes
[i
].toDouble());
160 StdCell
* latq
= createStdCell("LATQ", "CachedLATQ");
161 latq
->cacheStdCell(this, cell_sizes
[i
].toDouble());
164 StdCell
* or2
= createStdCell("OR2", "CachedOR2");
165 or2
->cacheStdCell(this, cell_sizes
[i
].toDouble());
168 StdCell
* and2
= createStdCell("AND2", "CachedAND2");
169 and2
->cacheStdCell(this, cell_sizes
[i
].toDouble());
173 Log::printLine("Standard cell library creation - End");
177 StdCellLib
* StdCellLib::clone() const
179 StdCellLib
* new_lib
= new StdCellLib(m_tech_model_
);
183 const String
StdCellLib::genDrivingStrengthString(const vector
<double>& driving_strength_
) const
185 String ret_str
= "[";
186 for(int i
= 0; i
< (int)driving_strength_
.size() - 1; ++i
)
188 ret_str
+= String(driving_strength_
[i
]) + ", ";
190 ret_str
+= String(driving_strength_
[driving_strength_
.size() - 1]);
195 Map
<double>* StdCellLib::getStdCellCache() const
197 return m_std_cell_cache_
;