Added a configuration option for providing macro substitution layouts (not through UI, only scripting so far)

This commit is contained in:
Matthias Koefferlein 2020-08-30 01:37:14 +02:00
parent 9a4cd629fc
commit a6e750b088
4 changed files with 100 additions and 20 deletions

View File

@ -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 &macro_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 {

View File

@ -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);
};
/**

View File

@ -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);

View File

@ -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. "