Skip to content

Commit ad850f3

Browse files
author
Matthias Koefferlein
committed
Merge branch 'lib-file' into bugfix/issue-2305
2 parents 87415f8 + aa36127 commit ad850f3

32 files changed

Lines changed: 682 additions & 155 deletions

src/db/db/dbCell.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -857,7 +857,7 @@ class DB_PUBLIC Cell
857857
void check_locked () const;
858858

859859
/**
860-
* @brief Tell, if this cell is a proxy cell
860+
* @brief Gets a value indicating if this cell is a proxy cell
861861
*
862862
* Proxy cells are such whose layout represents a snapshot of another entity.
863863
* Such cells can be PCell variants or library references for example.
@@ -867,6 +867,17 @@ class DB_PUBLIC Cell
867867
return false;
868868
}
869869

870+
/**
871+
* @brief Gets a value indicating that this cell is a replica that can be skipped
872+
*
873+
* This attribute is evaluated by file writers to skip cell replicas for
874+
* library cells that do not want to replicated.
875+
*/
876+
virtual bool can_skip_replica () const
877+
{
878+
return false;
879+
}
880+
870881
/**
871882
* @brief Sets the cell name
872883
*

src/db/db/dbCommonReader.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,11 @@ class CommonFormatDeclaration
692692
return false;
693693
}
694694

695+
virtual bool supports_context () const
696+
{
697+
return false;
698+
}
699+
695700
virtual tl::XMLElementBase *xml_reader_options_element () const
696701
{
697702
return new db::ReaderOptionsXMLElement<db::CommonReaderOptions> ("common",

src/db/db/dbLibrary.cc

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,17 @@
3333
namespace db
3434
{
3535

36-
Library::Library()
37-
: m_id (std::numeric_limits<lib_id_type>::max ()), m_layout (true)
36+
Library::Library ()
37+
: m_id (std::numeric_limits<lib_id_type>::max ()), m_layout (true), m_replicate (true)
3838
{
3939
m_layout.set_library (this);
4040
}
4141

42-
Library::Library(const Library &d)
43-
: gsi::ObjectBase (), tl::Object (), m_name (d.m_name), m_description (d.m_description), m_id (std::numeric_limits<lib_id_type>::max ()), m_layout (d.m_layout)
42+
Library::Library (const Library &d)
43+
: gsi::ObjectBase (), tl::Object (),
44+
m_name (d.m_name), m_description (d.m_description),
45+
m_id (std::numeric_limits<lib_id_type>::max ()), m_layout (d.m_layout),
46+
m_replicate (d.m_replicate)
4447
{
4548
m_layout.set_library (this);
4649
}
@@ -65,6 +68,12 @@ Library::for_technologies () const
6568
return ! m_technologies.empty ();
6669
}
6770

71+
void
72+
Library::set_technologies (const std::set<std::string> &t)
73+
{
74+
m_technologies = t;
75+
}
76+
6877
void
6978
Library::set_technology (const std::string &t)
7079
{
@@ -148,6 +157,12 @@ Library::is_retired (const db::cell_index_type library_cell_index) const
148157
return (i != m_refcount.end () && j != m_retired_count.end () && i->second == j->second);
149158
}
150159

160+
void
161+
Library::set_replicate (bool f)
162+
{
163+
m_replicate = f;
164+
}
165+
151166
void
152167
Library::rename (const std::string &name)
153168
{

src/db/db/dbLibrary.h

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,12 @@ class DB_PUBLIC Library
5353
/**
5454
* @brief The constructor
5555
*/
56-
Library();
56+
Library ();
5757

5858
/**
5959
* @brief Copy constructor
6060
*/
61-
Library(const Library &);
61+
Library (const Library &);
6262

6363
/**
6464
* @brief The destructor
@@ -138,6 +138,13 @@ class DB_PUBLIC Library
138138
*/
139139
bool for_technologies () const;
140140

141+
/**
142+
* @brief Sets the technology names this library is associated with
143+
*
144+
* This will reset the list of technologies to this set.
145+
*/
146+
void set_technologies (const std::set<std::string> &t);
147+
141148
/**
142149
* @brief Sets the technology name this library is associated with
143150
*
@@ -172,6 +179,27 @@ class DB_PUBLIC Library
172179
m_description = description;
173180
}
174181

182+
/**
183+
* @brief Sets a value indicating whether the library produces replicas
184+
*
185+
* If this value is true (the default), layout written will include the
186+
* actual layout of a library cell (replica). With this, it is possible
187+
* to regenerate the layout without actually having the library at the
188+
* cost of additional bytes in the file.
189+
*
190+
* Setting this flag to false avoids this replication, but a layout
191+
* cannot be regenerated without having this library.
192+
*/
193+
void set_replicate (bool f);
194+
195+
/**
196+
* @brief Gets a value indicating whether the library produces replicas
197+
*/
198+
bool replicate () const
199+
{
200+
return m_replicate;
201+
}
202+
175203
/**
176204
* @brief Getter for the library Id property
177205
*/
@@ -263,6 +291,7 @@ class DB_PUBLIC Library
263291
db::Layout m_layout;
264292
std::map<db::Layout *, int> m_referrers;
265293
std::map<db::cell_index_type, int> m_refcount, m_retired_count;
294+
bool m_replicate;
266295

267296
// no copying.
268297
Library &operator=(const Library &);

src/db/db/dbLibraryProxy.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,13 @@ LibraryProxy::update (db::ImportLayerMapping *layer_mapping)
249249
}
250250
}
251251

252+
bool
253+
LibraryProxy::can_skip_replica () const
254+
{
255+
const Library *lib = LibraryManager::instance ().lib (lib_id ());
256+
return lib && ! lib->replicate ();
257+
}
258+
252259
std::string
253260
LibraryProxy::get_basic_name () const
254261
{

src/db/db/dbLibraryProxy.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ class DB_PUBLIC LibraryProxy
9393
return true;
9494
}
9595

96+
/**
97+
* @brief Gets a value indicating that this cell is a replica that can be skipped
98+
*
99+
* This attribute is evaluated by file writers to skip cell replicas for
100+
* library cells that do not want to replicated.
101+
*/
102+
virtual bool can_skip_replica () const;
103+
96104
/**
97105
* @brief Gets the basic name
98106
*

src/db/db/dbSaveLayoutOptions.cc

Lines changed: 62 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ SaveLayoutOptions::operator= (const SaveLayoutOptions &d)
5656
m_format = d.m_format;
5757
m_layers = d.m_layers;
5858
m_cells = d.m_cells;
59-
m_implied_childred = d.m_implied_childred;
59+
m_implied_children = d.m_implied_children;
6060
m_all_layers = d.m_all_layers;
6161
m_all_cells = d.m_all_cells;
6262
m_dbu = d.m_dbu;
@@ -189,7 +189,7 @@ SaveLayoutOptions::add_cell (db::cell_index_type cell_index)
189189
{
190190
m_all_cells = false;
191191
m_cells.insert (cell_index);
192-
m_implied_childred.insert (cell_index);
192+
m_implied_children.insert (cell_index);
193193
}
194194

195195
void
@@ -204,15 +204,15 @@ SaveLayoutOptions::clear_cells ()
204204
{
205205
m_all_cells = false;
206206
m_cells.clear ();
207-
m_implied_childred.clear ();
207+
m_implied_children.clear ();
208208
}
209209

210210
void
211211
SaveLayoutOptions::select_all_cells ()
212212
{
213213
m_all_cells = true;
214214
m_cells.clear ();
215-
m_implied_childred.clear ();
215+
m_implied_children.clear ();
216216
}
217217

218218
void
@@ -340,21 +340,75 @@ SaveLayoutOptions::get_valid_layers (const db::Layout &layout, std::vector <std:
340340
}
341341
}
342342

343+
static void
344+
collect_called_cells_unskipped (db::cell_index_type ci, const db::Layout &layout, std::set<cell_index_type> &called)
345+
{
346+
const db::Cell &c = layout.cell (ci);
347+
if (c.can_skip_replica ()) {
348+
return;
349+
}
350+
351+
for (auto cc = c.begin_child_cells (); ! cc.at_end (); ++cc) {
352+
if (called.find (*cc) == called.end () && layout.is_valid_cell_index (*cc)) {
353+
called.insert (*cc);
354+
collect_called_cells_unskipped (*cc, layout, called);
355+
}
356+
}
357+
}
358+
343359
void
344360
SaveLayoutOptions::get_cells (const db::Layout &layout, std::set <db::cell_index_type> &cells, const std::vector <std::pair <unsigned int, db::LayerProperties> > &valid_layers, bool require_unique_names) const
345361
{
362+
bool has_context = m_write_context_info;
363+
for (tl::Registrar<db::StreamFormatDeclaration>::iterator fmt = tl::Registrar<db::StreamFormatDeclaration>::begin (); fmt != tl::Registrar<db::StreamFormatDeclaration>::end (); ++fmt) {
364+
if (fmt->format_name () == m_format) {
365+
if (! fmt->supports_context ()) {
366+
has_context = false;
367+
}
368+
break;
369+
}
370+
}
371+
346372
if (m_all_cells) {
347373

348-
for (db::Layout::const_iterator cell = layout.begin (); cell != layout.end (); ++cell) {
349-
cells.insert (cell->cell_index ());
374+
bool has_skipped_replica = false;
375+
376+
// check if we have skipped replicas
377+
if (has_context) {
378+
for (db::Layout::const_iterator cell = layout.begin (); cell != layout.end () && ! has_skipped_replica; ++cell) {
379+
has_skipped_replica = cell->can_skip_replica ();
380+
}
381+
}
382+
383+
// with skipped replicas start again and skip child cells of such cells
384+
// unless they are needed in other places.
385+
if (has_skipped_replica) {
386+
387+
for (db::Layout::const_iterator cell = layout.begin (); cell != layout.end (); ++cell) {
388+
if (cell->is_top ()) {
389+
cells.insert (cell->cell_index ());
390+
collect_called_cells_unskipped (cell->cell_index (), layout, cells);
391+
}
392+
}
393+
394+
} else {
395+
396+
for (db::Layout::const_iterator cell = layout.begin (); cell != layout.end () && ! has_skipped_replica; ++cell) {
397+
cells.insert (cell->cell_index ());
398+
}
399+
350400
}
351401

352402
} else {
353403

354404
for (std::set <db::cell_index_type>::const_iterator c = m_cells.begin (); c != m_cells.end (); ++c) {
355405
cells.insert (*c);
356-
if (m_implied_childred.find (*c) != m_implied_childred.end ()) {
357-
layout.cell (*c).collect_called_cells (cells);
406+
if (m_implied_children.find (*c) != m_implied_children.end ()) {
407+
if (has_context) {
408+
collect_called_cells_unskipped (*c, layout, cells);
409+
} else {
410+
layout.cell (*c).collect_called_cells (cells);
411+
}
358412
}
359413
}
360414

src/db/db/dbSaveLayoutOptions.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ class DB_PUBLIC SaveLayoutOptions
449449
std::string m_format;
450450
std::map<unsigned int, db::LayerProperties> m_layers;
451451
std::set<db::cell_index_type> m_cells;
452-
std::set<db::cell_index_type> m_implied_childred;
452+
std::set<db::cell_index_type> m_implied_children;
453453
bool m_all_layers;
454454
bool m_all_cells;
455455
double m_dbu;

src/db/db/dbStream.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@ class DB_PUBLIC StreamFormatDeclaration
109109
*/
110110
virtual bool can_write () const = 0;
111111

112+
/**
113+
* @brief Returns true, when the format supports a context (e.g. PCell parameters, Library references)
114+
*/
115+
virtual bool supports_context () const = 0;
116+
112117
/**
113118
* @brief Delivers the XMLElement object that represents the reader options within a technology XML tree
114119
*

src/db/db/gsiDeclDbLibrary.cc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,26 @@ LibraryClass<db::Library> decl_Library ("db", "LibraryBase",
266266
"\n"
267267
"This method has been introduced in version 0.30.5."
268268
) +
269+
gsi::method ("replicate=", &db::Library::set_replicate, gsi::arg ("flag"),
270+
"@brief Sets a value indicating whether the library produces replicas\n"
271+
"\n"
272+
"If this value is true (the default), layout written will include the\n"
273+
"actual layout of a library cell (replica). With this, it is possible\n"
274+
"to regenerate the layout without actually having the library at the\n"
275+
"cost of additional bytes in the file.\n"
276+
"\n"
277+
"Setting this flag to false avoids this replication, but a layout\n"
278+
"cannot be regenerated without having this library.\n"
279+
"\n"
280+
"This attribute has been introduced in version 0.30.8."
281+
) +
282+
gsi::method ("replicate", &db::Library::replicate,
283+
"@brief Gets a value indicating whether the library produces replicas\n"
284+
"\n"
285+
"See \\replicate= for a description of this attribute.\n"
286+
"\n"
287+
"This attribute has been introduced in version 0.30.8."
288+
) +
269289
gsi::method ("rename", &db::Library::rename, gsi::arg ("name"),
270290
"@brief Renames the library\n"
271291
"\n"

0 commit comments

Comments
 (0)