LEF/DEF reader

More consistently ignore the settings from the "Rule based layer mapping".
So if a map file is given, the map file statements shall not be overridden
by rules from the rule-based mapping tab.
This commit is contained in:
Matthias Koefferlein 2020-06-13 15:39:41 +02:00
parent 5992a9b509
commit d462a442a8
6 changed files with 76 additions and 87 deletions

View File

@ -4739,7 +4739,9 @@ LayoutView::active_library_changed (int /*index*/)
void
LayoutView::cellview_changed (unsigned int index)
{
mp_hierarchy_panel->do_update_content (index);
if (mp_hierarchy_panel) {
mp_hierarchy_panel->do_update_content (index);
}
cellview_changed_event (index);

View File

@ -23,6 +23,7 @@
#include "dbLEFDEFImporter.h"
#include "dbLayoutUtils.h"
#include "dbTechnology.h"
#include "tlStream.h"
#include "tlProgress.h"
@ -33,6 +34,39 @@
namespace db
{
// -----------------------------------------------------------------------------------
// Path resolution utility
std::string correct_path (const std::string &fn, const db::Layout &layout, const std::string &base_path)
{
if (! tl::is_absolute (fn)) {
// if a technology is given and the file can be found in the technology's base path, take it
// from there.
std::string tn = layout.meta_info_value ("technology");
const db::Technology *tech = 0;
if (! tn.empty ()) {
tech = db::Technologies::instance ()->technology_by_name (tn);
}
if (tech && ! tech->base_path ().empty ()) {
std::string new_fn = tl::combine_path (tech->base_path (), fn);
if (tl::file_exists (new_fn)) {
return new_fn;
}
}
if (! base_path.empty ()) {
return tl::combine_path (base_path, fn);
} else {
return fn;
}
} else {
return fn;
}
}
// -----------------------------------------------------------------------------------
// LEFDEFTechnologyComponent implementation
@ -157,15 +191,24 @@ LEFDEFReaderOptions::format_name () const
// -----------------------------------------------------------------------------------
// LEFDEFLayerDelegate implementation
LEFDEFReaderState::LEFDEFReaderState (const LEFDEFReaderOptions *tc, db::Layout &layout)
: m_create_layers (true), m_has_explicit_layer_mapping (false), m_laynum (1), mp_tech_comp (tc)
LEFDEFReaderState::LEFDEFReaderState (const LEFDEFReaderOptions *tc, db::Layout &layout, const std::string &base_path)
: m_create_layers (true), m_laynum (1), mp_tech_comp (tc)
{
if (tc) {
m_layer_map = tc->layer_map ();
m_create_layers = tc->read_all_layers ();
}
m_has_explicit_layer_mapping = ! tc->map_file ().empty ();
if (m_has_explicit_layer_mapping) {
m_layer_map.prepare (layout);
read_map_file (correct_path (tc->map_file (), layout, base_path), layout);
} else {
if (tc) {
m_layer_map = tc->layer_map ();
m_create_layers = tc->read_all_layers ();
}
m_layer_map.prepare (layout);
}
}
void
@ -175,18 +218,10 @@ LEFDEFReaderState::register_layer (const std::string &ln)
++m_laynum;
}
void
LEFDEFReaderState::set_explicit_layer_mapping (bool f)
{
m_has_explicit_layer_mapping = f;
if (! f) {
m_layers.clear ();
}
}
void
LEFDEFReaderState::map_layer_explicit (const std::string &n, LayerPurpose purpose, const db::LayerProperties &lp, unsigned int layer)
{
tl_assert (m_has_explicit_layer_mapping);
m_layers [std::make_pair (n, purpose)] = std::make_pair (true, layer);
m_layer_map.map (lp, layer);
}
@ -194,6 +229,8 @@ LEFDEFReaderState::map_layer_explicit (const std::string &n, LayerPurpose purpos
void
LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout)
{
tl_assert (m_has_explicit_layer_mapping);
tl::log << tl::to_string (tr ("Reading LEF/DEF map file")) << " " << path;
tl::InputFile file (path);
@ -299,8 +336,6 @@ LEFDEFReaderState::read_map_file (const std::string &path, db::Layout &layout)
}
set_explicit_layer_mapping (true);
db::DirectLayerMapping lm (&layout);
for (std::map<std::pair<std::string, LayerPurpose>, db::LayerProperties>::const_iterator i = layer_map.begin (); i != layer_map.end (); ++i) {
map_layer_explicit (i->first.first, i->first.second, i->second, lm.map_layer (i->second).second);

View File

@ -43,6 +43,12 @@ namespace tl
namespace db
{
/**
* @brief Correct a path relative to the stream and technology
*/
DB_PLUGIN_PUBLIC
std::string correct_path (const std::string &fn, const db::Layout &layout, const std::string &base_path);
/**
* @brief Generic base class of DXF reader exceptions
*/
@ -619,34 +625,15 @@ public:
/**
* @brief Constructor
*/
LEFDEFReaderState (const LEFDEFReaderOptions *tc, db::Layout &layout);
LEFDEFReaderState (const LEFDEFReaderOptions *tc, db::Layout &layout, const std::string &base_path = std::string ());
/**
* @brief Provides an explicit layer mapping
* This method is used when reading the layer map file.
*/
void map_layer_explicit (const std::string &n, LayerPurpose purpose, const LayerProperties &lp, unsigned int layer);
/**
* @brief Provides an explicit layer mapping
* If this flag is set, the layer mapping specified in the reader options are ignored.
*/
void set_explicit_layer_mapping (bool f);
/**
* @brief Reads a map file
* @brief Reads the given map file
*
* Usually this file is read by the constructor. This method is provided for test purposes.
*/
void read_map_file (const std::string &path, db::Layout &layout);
/**
* @brief Sets the layer map
*/
virtual void set_layer_map (const db::LayerMap &lm, bool create_layers)
{
m_layer_map = lm;
m_create_layers = create_layers;
}
/**
* @brief Gets the layer map
*/
@ -655,14 +642,6 @@ public:
return m_layer_map;
}
/**
* @brief Gets the layer map (non-const version)
*/
db::LayerMap &layer_map ()
{
return m_layer_map;
}
/**
* @brief Create a new layer or return the index of the given layer
*/
@ -708,6 +687,7 @@ private:
const LEFDEFReaderOptions *mp_tech_comp;
std::pair <bool, unsigned int> open_layer_uncached (db::Layout &layout, const std::string &name, LayerPurpose purpose);
void map_layer_explicit (const std::string &n, LayerPurpose purpose, const LayerProperties &lp, unsigned int layer);
};
/**

View File

@ -109,32 +109,6 @@ private:
tl::InputStream &m_stream;
db::LayerMap m_layer_map;
std::string correct_path (const std::string &fn, const db::Layout &layout)
{
if (! tl::is_absolute (fn)) {
// if a technology is given and the file can be found in the technology's base path, take it
// from there.
std::string tn = layout.meta_info_value ("technology");
const db::Technology *tech = 0;
if (! tn.empty ()) {
tech = db::Technologies::instance ()->technology_by_name (tn);
}
if (tech && ! tech->base_path ().empty ()) {
std::string new_fn = tl::combine_path (tech->base_path (), fn);
if (tl::file_exists (new_fn)) {
return new_fn;
}
}
return tl::combine_path (tl::dirname (m_stream.absolute_path ()), fn);
} else {
return fn;
}
}
const db::LayerMap &read_lefdef (db::Layout &layout, const db::LoadLayoutOptions &options, bool import_lef)
{
const db::LEFDEFReaderOptions *lefdef_options = dynamic_cast<const db::LEFDEFReaderOptions *> (options.get_options (format ()));
@ -143,11 +117,7 @@ private:
lefdef_options = &default_options;
}
db::LEFDEFReaderState state (lefdef_options, layout);
if (! lefdef_options->map_file ().empty ()) {
state.read_map_file (correct_path (lefdef_options->map_file (), layout), layout);
}
db::LEFDEFReaderState state (lefdef_options, layout, tl::dirname (m_stream.absolute_path ()));
layout.dbu (lefdef_options->dbu ());
@ -159,7 +129,7 @@ private:
for (std::vector<std::string>::const_iterator l = lefdef_options->begin_lef_files (); l != lefdef_options->end_lef_files (); ++l) {
std::string lp = correct_path (*l, layout);
std::string lp = correct_path (*l, layout, tl::dirname (m_stream.absolute_path ()));
tl::InputStream lef_stream (lp);
tl::log << tl::to_string (tr ("Reading")) << " " << lp;
@ -178,7 +148,7 @@ private:
for (std::vector<std::string>::const_iterator l = lefdef_options->begin_lef_files (); l != lefdef_options->end_lef_files (); ++l) {
std::string lp = correct_path (*l, layout);
std::string lp = correct_path (*l, layout, tl::dirname (m_stream.absolute_path ()));
tl::InputStream lef_stream (lp);
tl::log << tl::to_string (tr ("Reading")) << " " << lp;

View File

@ -352,10 +352,12 @@ LEFImporter::read_geometries (db::Layout &layout, db::Cell &cell, LayerPurpose p
if (iterate) {
std::vector<db::Trans> ti = get_iteration (layout);
for (std::vector<db::Trans>::const_iterator t = ti.begin (); t != ti.end (); ++t) {
cell.insert (db::CellInstArray (db::CellInst (vc->cell_index ()), *t * db::Trans (points [0])));
if (vc) {
for (std::vector<db::Trans>::const_iterator t = ti.begin (); t != ti.end (); ++t) {
cell.insert (db::CellInstArray (db::CellInst (vc->cell_index ()), *t * db::Trans (points [0])));
}
}
} else {
} else if (vc) {
cell.insert (db::CellInstArray (db::CellInst (vc->cell_index ()), db::Trans (points [0])));
}

View File

@ -61,7 +61,7 @@ static void run_test (tl::TestBase *_this, const char *lef_dir, const char *file
tl::Extractor ex (filename);
db::LEFDEFReaderState ld (&options, layout);
db::LEFDEFReaderState ld (&options, layout, fn_path);
db::DEFImporter imp;