mirror of https://github.com/KLayout/klayout.git
Added a configuration option for providing macro substitution layouts (not through UI, only scripting so far)
This commit is contained in:
parent
9a4cd629fc
commit
a6e750b088
|
|
@ -517,6 +517,7 @@ LEFDEFReaderOptions &LEFDEFReaderOptions::operator= (const LEFDEFReaderOptions &
|
|||
m_macro_resolution_mode = d.m_macro_resolution_mode;
|
||||
m_lef_files = d.m_lef_files;
|
||||
m_read_lef_with_def = d.m_read_lef_with_def;
|
||||
set_macro_layouts (d.macro_layouts ());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -1358,6 +1359,20 @@ LEFDEFReaderState::macro_generator (const std::string &mn)
|
|||
}
|
||||
}
|
||||
|
||||
db::cell_index_type
|
||||
LEFDEFReaderState::foreign_cell (Layout &layout, const std::string &name)
|
||||
{
|
||||
std::map<std::string, db::cell_index_type>::const_iterator c = m_foreign_cells.find (name);
|
||||
if (c != m_foreign_cells.end ()) {
|
||||
return c->second;
|
||||
} else {
|
||||
db::cell_index_type ci = layout.add_cell (name.c_str ());
|
||||
layout.cell (ci).set_ghost_cell (true);
|
||||
m_foreign_cells.insert (std::make_pair (name, ci));
|
||||
return ci;
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<db::Cell *, db::Trans>
|
||||
LEFDEFReaderState::macro_cell (const std::string &mn, Layout &layout, const std::vector<std::string> &maskshift_layers, const std::vector<unsigned int> &masks, const MacroDesc ¯o_desc, const LEFDEFNumberOfMasks *nm)
|
||||
{
|
||||
|
|
@ -1386,15 +1401,7 @@ LEFDEFReaderState::macro_cell (const std::string &mn, Layout &layout, const std:
|
|||
|
||||
if (! macro_desc.foreign_name.empty ()) {
|
||||
|
||||
db::cell_index_type ci;
|
||||
std::pair<bool, db::cell_index_type> c = layout.cell_by_name (macro_desc.foreign_name.c_str ());
|
||||
if (c.first) {
|
||||
ci = c.second;
|
||||
} else {
|
||||
ci = layout.add_cell (macro_desc.foreign_name.c_str ());
|
||||
layout.cell (ci).set_ghost_cell (true);
|
||||
}
|
||||
|
||||
db::cell_index_type ci = foreign_cell (layout, macro_desc.foreign_name);
|
||||
db::Cell *foreign_cell = &layout.cell (ci);
|
||||
|
||||
if (macro_desc.foreign_name != mn) {
|
||||
|
|
@ -1415,15 +1422,7 @@ LEFDEFReaderState::macro_cell (const std::string &mn, Layout &layout, const std:
|
|||
|
||||
// create a ghost cell always
|
||||
|
||||
db::cell_index_type ci;
|
||||
std::pair<bool, db::cell_index_type> c = layout.cell_by_name (mn.c_str ());
|
||||
if (c.first) {
|
||||
ci = c.second;
|
||||
} else {
|
||||
ci = layout.add_cell (mn.c_str ());
|
||||
layout.cell (ci).set_ghost_cell (true);
|
||||
}
|
||||
|
||||
db::cell_index_type ci = foreign_cell (layout, mn);
|
||||
cell = &layout.cell (ci);
|
||||
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -791,6 +791,24 @@ public:
|
|||
m_macro_resolution_mode = m;
|
||||
}
|
||||
|
||||
void set_macro_layouts (const std::vector<db::Layout *> &layouts)
|
||||
{
|
||||
for (std::vector<db::Layout *>::const_iterator l = layouts.begin (); l != layouts.end (); ++l) {
|
||||
m_macro_layouts.push_back (*l);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<db::Layout *> macro_layouts () const
|
||||
{
|
||||
std::vector<db::Layout *> res;
|
||||
for (tl::weak_collection<db::Layout>::const_iterator m = m_macro_layouts.begin (); m != m_macro_layouts.end (); ++m) {
|
||||
if (m.operator-> ()) {
|
||||
res.push_back (const_cast<db::Layout *> (m.operator-> ()));
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_read_all_layers;
|
||||
db::LayerMap m_layer_map;
|
||||
|
|
@ -847,6 +865,7 @@ private:
|
|||
unsigned int m_macro_resolution_mode;
|
||||
bool m_read_lef_with_def;
|
||||
std::vector<std::string> m_lef_files;
|
||||
tl::weak_collection<db::Layout> m_macro_layouts;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1088,6 +1107,14 @@ public:
|
|||
return mp_tech_comp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets a map of foreign cells vs. name
|
||||
*/
|
||||
const std::map<std::string, db::cell_index_type> &foreign_cells () const
|
||||
{
|
||||
return m_foreign_cells;
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief A key for the via cache
|
||||
|
|
@ -1171,9 +1198,11 @@ private:
|
|||
std::map<std::string, LEFDEFLayoutGenerator *> m_via_generators;
|
||||
std::map<MacroKey, std::pair<db::Cell *, db::Trans> > m_macro_cells;
|
||||
std::map<std::string, LEFDEFLayoutGenerator *> m_macro_generators;
|
||||
std::map<std::string, db::cell_index_type> m_foreign_cells;
|
||||
|
||||
std::pair <bool, unsigned int> open_layer_uncached (db::Layout &layout, const std::string &name, LayerPurpose purpose, unsigned int mask);
|
||||
void map_layer_explicit (const std::string &n, LayerPurpose purpose, const LayerProperties &lp, unsigned int layer, unsigned int mask);
|
||||
db::cell_index_type foreign_cell(Layout &layout, const std::string &name);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "dbLEFDEFImporter.h"
|
||||
#include "dbLayoutUtils.h"
|
||||
#include "dbTechnology.h"
|
||||
#include "dbCellMapping.h"
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
|
@ -192,6 +193,35 @@ private:
|
|||
tl::log << tl::to_string (tr ("Reading")) << " " << m_stream.source ();
|
||||
importer.read (m_stream, layout, state);
|
||||
|
||||
// Resolve unresolved COMPONENT cells
|
||||
|
||||
std::map<std::string, db::cell_index_type> foreign_cells = state.foreign_cells ();
|
||||
db::cell_index_type seen = std::numeric_limits<db::cell_index_type>::max ();
|
||||
|
||||
std::vector<db::Layout *> macro_layouts = lefdef_options->macro_layouts ();
|
||||
for (std::vector<db::Layout *>::const_iterator m = macro_layouts.begin (); m != macro_layouts.end (); ++m) {
|
||||
|
||||
std::vector<db::cell_index_type> target_cells, source_cells;
|
||||
|
||||
// collect the cells to pull in
|
||||
for (std::map<std::string, db::cell_index_type>::iterator f = foreign_cells.begin (); f != foreign_cells.end (); ++f) {
|
||||
if (f->second != seen) {
|
||||
std::pair<bool, db::cell_index_type> cp = (*m)->cell_by_name (f->first.c_str ());
|
||||
if (cp.first) {
|
||||
target_cells.push_back (f->second);
|
||||
source_cells.push_back (cp.second);
|
||||
layout.cell (f->second).set_ghost_cell (false);
|
||||
f->second = seen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
db::CellMapping cm;
|
||||
cm.create_multi_mapping_full (layout, target_cells, **m, source_cells);
|
||||
layout.copy_tree_shapes (**m, cm);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
state.finish (layout);
|
||||
|
|
|
|||
|
|
@ -775,11 +775,14 @@ gsi::Class<db::LEFDEFReaderOptions> decl_lefdef_config ("db", "LEFDEFReaderConfi
|
|||
"are three modes available:\n"
|
||||
"\n"
|
||||
"@ul\n"
|
||||
" @li 0: propduce LEF geometry unless a FOREIGN cell is specified (default) @/li\n"
|
||||
" @li 0: produce LEF geometry unless a FOREIGN cell is specified (default) @/li\n"
|
||||
" @li 1: produce LEF geometry always and ignore FOREIGN @/li\n"
|
||||
" @li 2: produce a placeholder cell always (even if FOREIGN isn't given) @/li\n"
|
||||
" @li 2: Never produce LEF geometry @/li\n"
|
||||
"@/ul\n"
|
||||
"\n"
|
||||
"If substitution layouts are specified with \\macro_layouts, these are used to provide "
|
||||
"macro layouts in case no LEF geometry is taken.\n"
|
||||
"\n"
|
||||
"This property has been added in version 0.27.\n"
|
||||
) +
|
||||
gsi::method ("macro_resolution_mode=", &db::LEFDEFReaderOptions::set_macro_resolution_mode, gsi::arg ("mode"),
|
||||
|
|
@ -788,6 +791,25 @@ gsi::Class<db::LEFDEFReaderOptions> decl_lefdef_config ("db", "LEFDEFReaderConfi
|
|||
"\n"
|
||||
"This property has been added in version 0.27.\n"
|
||||
) +
|
||||
gsi::method ("macro_layouts", &db::LEFDEFReaderOptions::macro_layouts,
|
||||
"@brief Gets the layout objects used for resolving LEF macros in the DEF reader.\n"
|
||||
"The DEF reader can either use LEF geometry or use a separate source of layouts for the "
|
||||
"LEF macros. The \\macro_resolution_mode controls whether to use LEF geometry. If LEF geometry is not "
|
||||
"used, the DEF reader will look up macro cells from the \\macro_layouts and pull cell layouts from there.\n"
|
||||
"\n"
|
||||
"The LEF cells are looked up by name from the macro layouts in the order these are given in this array.\n"
|
||||
"\n"
|
||||
"This property has been added in version 0.27.\n"
|
||||
) +
|
||||
gsi::method ("macro_layouts=", &db::LEFDEFReaderOptions::set_macro_layouts,
|
||||
"@brief Sets the layout objects used for resolving LEF macros in the DEF reader.\n"
|
||||
"See \\macro_layouts for more details about this property.\n"
|
||||
"\n"
|
||||
"Layout objects specified in the array for this property are not owned by the \\LEFDEFReaderConfiguration object. "
|
||||
"Be sure to keep some other reference to these Layout objects if you are storing away the LEF/DEF reader configuration object.\n"
|
||||
"\n"
|
||||
"This property has been added in version 0.27.\n"
|
||||
) +
|
||||
gsi::method ("lef_files", &db::LEFDEFReaderOptions::lef_files,
|
||||
"@brief Gets the list technology LEF files to additionally import\n"
|
||||
"Returns a list of path names for technology LEF files to read in addition to the primary file. "
|
||||
|
|
|
|||
Loading…
Reference in New Issue