diff --git a/src/laybasic/laybasic/layLayoutView.cc b/src/laybasic/laybasic/layLayoutView.cc index 44d534acf..91d0fe807 100644 --- a/src/laybasic/laybasic/layLayoutView.cc +++ b/src/laybasic/laybasic/layLayoutView.cc @@ -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); diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc index 61223bb34..5a8261f98 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc @@ -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, 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); diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h index 22858f048..ddeb8e036 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h @@ -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 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); }; /** diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFPlugin.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFPlugin.cc index 2bd4466ae..e69af924e 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFPlugin.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFPlugin.cc @@ -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 (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::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::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; diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc index cb78db7a9..02f482670 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc @@ -352,10 +352,12 @@ LEFImporter::read_geometries (db::Layout &layout, db::Cell &cell, LayerPurpose p if (iterate) { std::vector ti = get_iteration (layout); - for (std::vector::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::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]))); } diff --git a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc index 2d1f235f6..efd68ffa1 100644 --- a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc +++ b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc @@ -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;