diff --git a/src/laybasic/laybasic/layLayerProperties.cc b/src/laybasic/laybasic/layLayerProperties.cc index 53a4e88be..e150fa401 100644 --- a/src/laybasic/laybasic/layLayerProperties.cc +++ b/src/laybasic/laybasic/layLayerProperties.cc @@ -1839,10 +1839,15 @@ LayerPropertiesList::load (tl::XMLSource &stream, std::vector > std::string inst_name = get (); std::string model = get (); - db::Cell *cell = m_lef_importer.macro_by_name (model); + std::pair ct = m_lef_importer.macro_by_name (model); while (test ("+")) { @@ -1158,8 +1158,8 @@ DEFImporter::read_components (std::list > db::FTrans ft = get_orient (false /*mandatory*/); db::Vector d = pt - m_lef_importer.macro_bbox_by_name (model).transformed (ft).lower_left (); - if (cell) { - db::CellInstArray inst (db::CellInst (cell->cell_index ()), db::Trans (ft.rot (), d)); + if (ct.first) { + db::CellInstArray inst (db::CellInst (ct.first->cell_index ()), db::Trans (ft.rot (), d) * ct.second); instances.push_back (std::make_pair (inst_name, inst)); } else { warn (tl::to_string (tr ("Macro not found in LEF file: ")) + model); diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc index 090fdfae8..1f8d4b942 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc @@ -105,14 +105,14 @@ LEFImporter::layer_width (const std::string &layer, const std::string &nondefaul } } -db::Cell * +std::pair LEFImporter::macro_by_name (const std::string &name) const { - std::map::const_iterator m = m_macros_by_name.find (name); + std::map >::const_iterator m = m_macros_by_name.find (name); if (m != m_macros_by_name.end ()) { return m->second; } else { - return 0; + return std::make_pair ((db::Cell *) 0, db::Trans ()); } } @@ -726,9 +726,9 @@ LEFImporter::read_macro (Layout &layout) std::string mn = get (); set_cellname (mn); - db::Cell &cell = layout.cell (layout.add_cell (mn.c_str ())); - - m_macros_by_name.insert (std::make_pair (mn, &cell)); + db::Cell &cell = layout.cell (layout.add_cell ()); + db::Cell *foreign_cell = 0; + db::Trans foreign_trans; db::Point origin; db::Vector size; @@ -811,13 +811,12 @@ LEFImporter::read_macro (Layout &layout) } else if (test ("FOREIGN")) { - std::string cn = get (); - - if (cn == mn) { - // rename out macro placeholder cell so we don't create a recursive hierarchy - layout.rename_cell (cell.cell_index (), ("LEF_" + mn).c_str ()); + if (foreign_cell) { + error ("Duplicate FOREIGN definition"); } + std::string cn = get (); + db::cell_index_type ci; std::pair c = layout.cell_by_name (cn.c_str ()); if (c.first) { @@ -836,7 +835,8 @@ LEFImporter::read_macro (Layout &layout) expect (";"); - cell.insert (db::CellInstArray (db::CellInst (ci), (db::Trans (origin - db::Point ()) * db::Trans (ft)).inverted ())); + foreign_cell = &layout.cell (ci); + foreign_trans = (db::Trans (origin - db::Point ()) * db::Trans (ft)).inverted (); } else if (test ("OBS")) { @@ -851,9 +851,26 @@ LEFImporter::read_macro (Layout &layout) } - std::pair dl = open_layer (layout, std::string (), Outline); - if (dl.first) { - cell.shapes (dl.second).insert (db::Box (-origin, -origin + size)); + if (! foreign_cell) { + + // actually implement the real cell + + layout.rename_cell (cell.cell_index (), mn.c_str ()); + + std::pair dl = open_layer (layout, std::string (), Outline); + if (dl.first) { + cell.shapes (dl.second).insert (db::Box (-origin, -origin + size)); + } + + m_macros_by_name.insert (std::make_pair (mn, std::make_pair (&cell, db::Trans ()))); + + } else { + + // use FOREIGN cell instead of new one + + layout.delete_cell (cell.cell_index ()); + m_macros_by_name.insert (std::make_pair (mn, std::make_pair (foreign_cell, foreign_trans))); + } m_macro_bboxes_by_name.insert (std::make_pair (mn, db::Box (-origin, -origin + size))); diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h index f52133996..859ceef54 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h @@ -63,7 +63,7 @@ public: * Returns 0 if the name is not a valid macro name. Otherwise it returns the pointer * to the corresponding db::Cell object. */ - db::Cell *macro_by_name (const std::string ¯o_name) const; + std::pair macro_by_name (const std::string ¯o_name) const; /** * @brief Get the cell bbox for the given macro name @@ -125,7 +125,7 @@ private: std::map > m_default_widths; std::map m_default_ext; std::map > m_min_widths; - std::map m_macros_by_name; + std::map > m_macros_by_name; std::map m_macro_bboxes_by_name; std::map m_vias; std::set m_routing_layers, m_cut_layers; diff --git a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc index cdd6bf28c..30090da2b 100644 --- a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc +++ b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc @@ -334,15 +334,18 @@ TEST(108_scanchain) TEST(109_foreigncell) { - run_test (_this, "foreigncell", "gds:foreign.gds+lef:in_tech.lef+lef:in.lef", "au.oas.gz", default_options (), false); + run_test (_this, "foreigncell", "gds:foreign.gds+lef:in_tech.lef+lef:in.lef+def:in.def", "au.oas.gz", default_options (), false); +} +TEST(110_lefpins) +{ db::LEFDEFReaderOptions options = default_options (); options.set_produce_lef_pins (false); - run_test (_this, "foreigncell", "gds:foreign.gds+lef:in_tech.lef+lef:in.lef", "au_no_lefpins.oas.gz", options, false); + run_test (_this, "lefpins", "lef:in_tech.lef+lef:in.lef+def:in.def", "au_no_lefpins.oas.gz", options, false); options.set_produce_lef_pins (true); options.set_lef_pins_datatype (10); options.set_lef_pins_suffix (".LEFPIN"); - run_test (_this, "foreigncell", "gds:foreign.gds+lef:in_tech.lef+lef:in.lef", "au_lefpins_mapped.oas.gz", options, false); + run_test (_this, "lefpins", "lef:in_tech.lef+lef:in.lef+def:in.def", "au_lefpins_mapped.oas.gz", options, false); } diff --git a/testdata/lefdef/foreigncell/au.oas.gz b/testdata/lefdef/foreigncell/au.oas.gz index a46321b03..fec13c35b 100644 Binary files a/testdata/lefdef/foreigncell/au.oas.gz and b/testdata/lefdef/foreigncell/au.oas.gz differ diff --git a/testdata/lefdef/foreigncell/au_lefpins_mapped.oas.gz b/testdata/lefdef/foreigncell/au_lefpins_mapped.oas.gz deleted file mode 100644 index 7416d50b6..000000000 Binary files a/testdata/lefdef/foreigncell/au_lefpins_mapped.oas.gz and /dev/null differ diff --git a/testdata/lefdef/foreigncell/au_no_lefpins.oas.gz b/testdata/lefdef/foreigncell/au_no_lefpins.oas.gz deleted file mode 100644 index f0e21a209..000000000 Binary files a/testdata/lefdef/foreigncell/au_no_lefpins.oas.gz and /dev/null differ diff --git a/testdata/lefdef/foreigncell/foreign.gds b/testdata/lefdef/foreigncell/foreign.gds index d8558194e..dce50b5e8 100644 Binary files a/testdata/lefdef/foreigncell/foreign.gds and b/testdata/lefdef/foreigncell/foreign.gds differ diff --git a/testdata/lefdef/foreigncell/in.def b/testdata/lefdef/foreigncell/in.def new file mode 100644 index 000000000..04045ef5f --- /dev/null +++ b/testdata/lefdef/foreigncell/in.def @@ -0,0 +1,17 @@ + +VERSION 5.8 ; +DIVIDERCHAR "/" ; +BUSBITCHARS "[]" ; +DESIGN foreigncells ; +UNITS DISTANCE MICRONS 1000 ; + +DIEAREA ( 0 0 ) ( 1000 2000 ) ; + +COMPONENTS 3 ; + - macro1 macro1 + PLACED ( 0 0 ) N ; + - macro2 macro2 + PLACED ( 0 500 ) N ; + - macro3 macro3 + PLACED ( 0 1000 ) N ; +END COMPONENTS + +END DESIGN + diff --git a/testdata/lefdef/lefpins/au_lefpins_mapped.oas.gz b/testdata/lefdef/lefpins/au_lefpins_mapped.oas.gz new file mode 100644 index 000000000..80c578b58 Binary files /dev/null and b/testdata/lefdef/lefpins/au_lefpins_mapped.oas.gz differ diff --git a/testdata/lefdef/lefpins/au_no_lefpins.oas.gz b/testdata/lefdef/lefpins/au_no_lefpins.oas.gz new file mode 100644 index 000000000..099aeed88 Binary files /dev/null and b/testdata/lefdef/lefpins/au_no_lefpins.oas.gz differ diff --git a/testdata/lefdef/lefpins/in.def b/testdata/lefdef/lefpins/in.def new file mode 100644 index 000000000..58d6e328b --- /dev/null +++ b/testdata/lefdef/lefpins/in.def @@ -0,0 +1,15 @@ + +VERSION 5.8 ; +DIVIDERCHAR "/" ; +BUSBITCHARS "[]" ; +DESIGN foreigncells ; +UNITS DISTANCE MICRONS 1000 ; + +DIEAREA ( 0 0 ) ( 1000 2000 ) ; + +COMPONENTS 3 ; + - macro1 macro1 + PLACED ( 0 0 ) N ; +END COMPONENTS + +END DESIGN + diff --git a/testdata/lefdef/lefpins/in.lef b/testdata/lefdef/lefpins/in.lef new file mode 100644 index 000000000..e2751e688 --- /dev/null +++ b/testdata/lefdef/lefpins/in.lef @@ -0,0 +1,15 @@ +MACRO macro1 + CLASS CORE ; + ORIGIN 0.000 0.000 ; + SIZE 0.384 BY 0.480 ; + PIN Z + PORT + LAYER M1 ; + RECT 0.306 0.357 0.318 0.403 ; + RECT 0.318 0.115 0.352 0.403 ; + VIA 0.336 0.167 square ; + VIA 0.336 0.351 square ; + END + END Z +END macro1 + diff --git a/testdata/lefdef/lefpins/in_tech.lef b/testdata/lefdef/lefpins/in_tech.lef new file mode 100644 index 000000000..eb0e75b0b --- /dev/null +++ b/testdata/lefdef/lefpins/in_tech.lef @@ -0,0 +1,36 @@ +LAYER OD + TYPE IMPLANT ; +END OD +LAYER VTS_N + TYPE IMPLANT ; +END VTS_N +LAYER VTS_P + TYPE IMPLANT ; +END VTS_P +LAYER M0OD + TYPE IMPLANT ; +END M0OD +LAYER M0PO + TYPE MASTERSLICE ; +END M0PO +LAYER VIA0 + TYPE CUT ; +END VIA0 +LAYER M1 + TYPE MASTERSLICE ; +END M1 +LAYER VIA1 + TYPE CUT ; +END VIA1 +LAYER M2 + TYPE MASTERSLICE ; +END M2 + +VIA square + LAYER M0PO ; + RECT -0.006 -0.006 0.006 0.006 ; + LAYER VIA0 ; + RECT -0.006 -0.006 0.006 0.006 ; + LAYER M1 ; + RECT -0.006 -0.006 0.006 0.006 ; +END square