From af2bfce05171bf9159db6e412584eb19d6692ef6 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 23 Aug 2020 18:58:52 +0200 Subject: [PATCH] Tests and bug fixes for component maskshift implementation --- .../lefdef/db_plugin/dbDEFImporter.cc | 5 +- .../lefdef/db_plugin/dbLEFDEFImporter.cc | 120 ++++++++++++------ .../lefdef/db_plugin/dbLEFDEFImporter.h | 42 ++++-- .../lefdef/db_plugin/dbLEFImporter.cc | 4 +- .../lefdef/unit_tests/dbLEFDEFImportTests.cc | 8 ++ testdata/lefdef/masks-1/in_tech.lef | 10 +- testdata/lefdef/masks-2/au.oas.gz | Bin 0 -> 3217 bytes 7 files changed, 129 insertions(+), 60 deletions(-) create mode 100644 testdata/lefdef/masks-2/au.oas.gz diff --git a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc index e0950c063..4dc1d25ac 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc @@ -1313,7 +1313,7 @@ DEFImporter::read_components (db::Layout &layout, std::list ct = reader_state ()->macro_cell (model, layout, string2masks (maskshift), m->second, &m_lef_importer); + std::pair ct = reader_state ()->macro_cell (model, layout, m_component_maskshift, string2masks (maskshift), m->second, &m_lef_importer); 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)); @@ -1496,6 +1496,9 @@ DEFImporter::do_read (db::Layout &layout) m_component_maskshift.push_back (get ()); } + // because we treat the layers bottom first .. + std::reverse (m_component_maskshift.begin (), m_component_maskshift.end ()); + } else if (test ("COMPONENTS")) { get_long (); diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc index 58e5d128f..6ec7ae99b 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc @@ -122,8 +122,11 @@ RuleBasedViaGenerator::RuleBasedViaGenerator () { } void -RuleBasedViaGenerator::create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, const std::vector &masks, const LEFDEFNumberOfMasks *nm) +RuleBasedViaGenerator::create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, const std::vector *maskshift_layers, const std::vector &masks, const LEFDEFNumberOfMasks *nm) { + // will not be used with an external maskshift layer stack + tl_assert (maskshift_layers == 0); + unsigned int mask_bottom = mask (masks, 0), mask_cut = mask (masks, 1), mask_top = mask (masks, 2); if (mask_bottom == 0) { @@ -267,41 +270,61 @@ RuleBasedViaGenerator::create_cell (LEFDEFReaderState &reader, Layout &layout, d // GeometryBasedViaGenerator implementation GeometryBasedLayoutGenerator::GeometryBasedLayoutGenerator () - : LEFDEFLayoutGenerator () -{ } + : LEFDEFLayoutGenerator (), m_fixedmask (false) +{ + // .. nothing yet .. +} unsigned int -GeometryBasedLayoutGenerator::mask_for (const std::string &ln, unsigned int m, const std::vector &masks, const LEFDEFNumberOfMasks *nm) const +GeometryBasedLayoutGenerator::get_maskshift (const std::string &ln, const std::vector *msl, const std::vector &masks) { - for (std::vector::const_iterator l = m_maskshift_layers.begin (); l != m_maskshift_layers.end (); ++l) { - - if (! l->empty () && *l == ln) { - - unsigned int mm = mask (masks, (unsigned int) (l - m_maskshift_layers.begin ())); - - if (m == 0 || ! nm) { - m = mm; - } else if (mm > 0) { - m = (m + mm - 2) % nm->number_of_masks (ln) + 1; - } - - break; - - } - + if (! msl) { + msl = &m_maskshift_layers; } - return m; + for (std::vector::const_iterator l = msl->begin (); l != msl->end (); ++l) { + if (! l->empty () && *l == ln) { + return mask (masks, (unsigned int) (l - msl->begin ())); + } + } + + return 0; +} + +unsigned int +GeometryBasedLayoutGenerator::mask_for (const std::string &ln, unsigned int m, unsigned int mshift, const LEFDEFNumberOfMasks *nm) const +{ + // for FIXEDMASK we don't do any mask shifting + if (m_fixedmask || m == 0 || mshift == 0 || !nm) { + return m; + } else { + return (m + mshift - 2) % nm->number_of_masks (ln) + 1; + } +} + +unsigned int +GeometryBasedLayoutGenerator::combine_maskshifts (const std::string &ln, unsigned int mshift1, unsigned int mshift2, const LEFDEFNumberOfMasks *nm) const +{ + if (mshift1 == 0 || mshift2 == 0) { + return mshift1 + mshift2; + } else { + return (mshift1 + mshift2 - 2) % nm->number_of_masks (ln) + 1; + } } void -GeometryBasedLayoutGenerator::create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, const std::vector &masks, const LEFDEFNumberOfMasks *nm) +GeometryBasedLayoutGenerator::create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, const std::vector *ext_msl, const std::vector &masks, const LEFDEFNumberOfMasks *nm) { for (std::map >, db::Shapes>::const_iterator g = m_shapes.begin (); g != m_shapes.end (); ++g) { - std::pair dl = reader.open_layer (layout, g->first.first, g->first.second.first, mask_for (g->first.first, g->first.second.second, masks, nm)); + + unsigned int mshift = get_maskshift (g->first.first, ext_msl, masks); + unsigned int mask = mask_for (g->first.first, g->first.second.second, mshift, nm); + + std::pair dl = reader.open_layer (layout, g->first.first, g->first.second.first, mask); if (dl.first) { cell.shapes (dl.second).insert (g->second); } + } for (std::list::const_iterator v = m_vias.begin (); v != m_vias.end (); ++v) { @@ -314,10 +337,14 @@ GeometryBasedLayoutGenerator::create_cell (LEFDEFReaderState &reader, Layout &la std::vector msl = g->maskshift_layers (); msl.resize (3, std::string ()); + unsigned mshift_bottom = get_maskshift (msl [0], ext_msl, masks); + unsigned mshift_cut = get_maskshift (msl [1], ext_msl, masks); + unsigned mshift_top = get_maskshift (msl [2], ext_msl, masks); + db::Cell *vc = reader.via_cell (v->name, layout, - mask_for (msl [0], v->bottom_mask, masks, nm), - mask_for (msl [1], v->cut_mask, masks, nm), - mask_for (msl [2], v->top_mask, masks, nm), + combine_maskshifts (msl [0], v->bottom_mask, mshift_bottom, nm), + combine_maskshifts (msl [1], v->cut_mask, mshift_cut, nm), + combine_maskshifts (msl [2], v->top_mask, mshift_top, nm), nm); if (vc) { @@ -1292,7 +1319,7 @@ LEFDEFReaderState::via_cell (const std::string &vn, db::Layout &layout, unsigned masks.push_back (mask_cut); masks.push_back (mask_top); - vg->create_cell (*this, layout, *cell, masks, nm); + vg->create_cell (*this, layout, *cell, 0, masks, nm); } @@ -1326,9 +1353,22 @@ LEFDEFReaderState::macro_generator (const std::string &mn) } std::pair -LEFDEFReaderState::macro_cell (const std::string &mn, Layout &layout, const std::vector &masks, const MacroDesc ¯o_desc, const LEFDEFNumberOfMasks *nm) +LEFDEFReaderState::macro_cell (const std::string &mn, Layout &layout, const std::vector &maskshift_layers, const std::vector &masks, const MacroDesc ¯o_desc, const LEFDEFNumberOfMasks *nm) { - MacroKey mk (mn, masks); + std::map::const_iterator g = m_macro_generators.find (mn); + if (g == m_macro_generators.end ()) { + return std::make_pair ((db::Cell *) 0, db::Trans ()); + } + + LEFDEFLayoutGenerator *mg = g->second; + + MacroKey mk; + if (mg->is_fixedmask ()) { + mk = MacroKey (mn, std::vector ()); + } else { + mk = MacroKey (mn, masks); + } + std::map >::const_iterator i = m_macro_cells.find (mk); if (i != m_macro_cells.end ()) { tl_assert (! i->second.first || i->second.first->layout () == &layout); @@ -1338,13 +1378,6 @@ LEFDEFReaderState::macro_cell (const std::string &mn, Layout &layout, const std: db::Cell *cell = 0; db::Trans tr; - std::map::const_iterator g = m_macro_generators.find (mn); - if (g == m_macro_generators.end ()) { - return std::make_pair ((db::Cell *) 0, db::Trans ()); - } - - LEFDEFLayoutGenerator *mg = g->second; - if (! macro_desc.foreign_name.empty ()) { db::cell_index_type ci; @@ -1392,15 +1425,22 @@ LEFDEFReaderState::macro_cell (const std::string &mn, Layout &layout, const std: // actually implement the real cell std::string mask_suffix; - for (std::vector::const_iterator m = masks.begin (); m != masks.end (); ++m) { - mask_suffix += "_"; - mask_suffix += tl::to_string (*m); + if (! mg->is_fixedmask ()) { + for (std::vector::const_iterator m = masks.begin (); m != masks.end (); ++m) { + mask_suffix += "_"; + mask_suffix += tl::to_string (*m); + } } std::string cn = mn + mask_suffix; cell = &layout.cell (layout.add_cell (cn.c_str ())); - mg->create_cell (*this, layout, *cell, masks, nm); + + if (mg->is_fixedmask ()) { + mg->create_cell (*this, layout, *cell, 0, std::vector (), nm); + } else { + mg->create_cell (*this, layout, *cell, &maskshift_layers, masks, nm); + } } diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h index 97f2ecfd0..bbe4e5502 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h @@ -888,8 +888,9 @@ public: LEFDEFLayoutGenerator () { } virtual ~LEFDEFLayoutGenerator () { } - virtual void create_cell (LEFDEFReaderState &reader, db::Layout &layout, db::Cell &cell, const std::vector &masks, const LEFDEFNumberOfMasks *nm) = 0; + virtual void create_cell (LEFDEFReaderState &reader, db::Layout &layout, db::Cell &cell, const std::vector *maskshift_layers, const std::vector &masks, const LEFDEFNumberOfMasks *nm) = 0; virtual std::vector maskshift_layers () const = 0; + virtual bool is_fixedmask () const = 0; }; /** @@ -901,7 +902,7 @@ class DB_PLUGIN_PUBLIC RuleBasedViaGenerator public: RuleBasedViaGenerator (); - virtual void create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, const std::vector &masks, const LEFDEFNumberOfMasks *nm); + virtual void create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, const std::vector *maskshift_layers, const std::vector &masks, const LEFDEFNumberOfMasks *nm); virtual std::vector maskshift_layers () const { @@ -912,6 +913,11 @@ public: return msl; } + virtual bool is_fixedmask () const + { + return false; + } + void set_cutsize (const db::Vector &cutsize) { m_cutsize = cutsize; } void set_cutspacing (const db::Vector &cutspacing) { m_cutspacing = cutspacing; } void set_offset (const db::Point &offset) { m_offset = offset; } @@ -947,17 +953,11 @@ class DB_PLUGIN_PUBLIC GeometryBasedLayoutGenerator : public LEFDEFLayoutGenerator { public: - struct Via { - Via () : bottom_mask (0), cut_mask (0), top_mask (0) { } - std::string name; - unsigned int bottom_mask, cut_mask, top_mask; - db::Trans trans; - }; - GeometryBasedLayoutGenerator (); - virtual void create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, const std::vector &masks, const LEFDEFNumberOfMasks *num_cut_masks); + virtual void create_cell (LEFDEFReaderState &reader, Layout &layout, db::Cell &cell, const std::vector *maskshift_layers, const std::vector &masks, const LEFDEFNumberOfMasks *num_cut_masks); virtual std::vector maskshift_layers () const { return m_maskshift_layers; } + virtual bool is_fixedmask () const { return m_fixedmask; } void add_polygon (const std::string &ln, LayerPurpose purpose, const db::Polygon &poly, unsigned int mask, properties_id_type prop_id); void add_box (const std::string &ln, LayerPurpose purpose, const db::Box &box, unsigned int mask, properties_id_type prop_id); @@ -975,12 +975,27 @@ public: m_maskshift_layers[l] = s; } + void set_fixedmask (bool f) + { + m_fixedmask = f; + } + private: + struct Via { + Via () : bottom_mask (0), cut_mask (0), top_mask (0) { } + std::string name; + unsigned int bottom_mask, cut_mask, top_mask; + db::Trans trans; + }; + std::map >, db::Shapes> m_shapes; std::list m_vias; std::vector m_maskshift_layers; + bool m_fixedmask; - unsigned int mask_for (const std::string &ln, unsigned int m, const std::vector &masks, const LEFDEFNumberOfMasks *nm) const; + unsigned int get_maskshift (const std::string &ln, const std::vector *maskshift_layers, const std::vector &masks); + unsigned int mask_for (const std::string &ln, unsigned int m, unsigned int mshift, const LEFDEFNumberOfMasks *nm) const; + unsigned int combine_maskshifts (const std::string &ln, unsigned int mshift1, unsigned int mshift2, const LEFDEFNumberOfMasks *nm) const; }; /** @@ -1058,7 +1073,7 @@ public: /** * @brief Gets the macro cell for the given macro name or 0 if no such maco is registered */ - std::pair macro_cell (const std::string &mn, Layout &layout, const std::vector &masks, const MacroDesc ¯o_desc, const LEFDEFNumberOfMasks *nm); + std::pair macro_cell (const std::string &mn, Layout &layout, const std::vector &maskshift_layers, const std::vector &masks, const MacroDesc ¯o_desc, const LEFDEFNumberOfMasks *nm); /** * @brief Gets the macro generator for a given macro name or 0 if there is no such generator @@ -1114,6 +1129,9 @@ private: */ struct MacroKey { + MacroKey () + { } + MacroKey (const std::string &n, const std::vector &m) : name (n), masks (m) { } diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc index d4721a7ee..c1a6caa1c 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc @@ -939,7 +939,7 @@ LEFImporter::read_macro (Layout &layout) } else if (test ("FIXEDMASK")) { - // we do actually expect FIXEDMASK to be the case always. + mg->set_fixedmask (true); expect (";"); } else { @@ -1068,7 +1068,7 @@ void LEFImporter::finish_lef (db::Layout &layout) { for (std::map::const_iterator m = m_macros.begin (); m != m_macros.end (); ++m) { - reader_state ()->macro_cell (m->first, layout, std::vector (), m->second, this); + reader_state ()->macro_cell (m->first, layout, std::vector (), std::vector (), m->second, this); } } diff --git a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc index 2e1390bd8..e082869a8 100644 --- a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc +++ b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc @@ -541,6 +541,14 @@ TEST(114_lef_skips_end_library) run_test (_this, "lef-skips-end-library", "lef:in.lef+def:in.def", "au.oas", opt, false); } +TEST(115_componentmaskshift) +{ + db::LEFDEFReaderOptions options = default_options (); + options.set_map_file ("in.map"); + + run_test (_this, "masks-2", "lef:in_tech.lef+lef:in.lef+def:in.def", "au.oas.gz", options, false); +} + TEST(200_lefdef_plugin) { db::Layout ly; diff --git a/testdata/lefdef/masks-1/in_tech.lef b/testdata/lefdef/masks-1/in_tech.lef index 4d7c3fc47..b85d99283 100644 --- a/testdata/lefdef/masks-1/in_tech.lef +++ b/testdata/lefdef/masks-1/in_tech.lef @@ -1,25 +1,25 @@ LAYER M0PO TYPE MASTERSLICE ; WIDTH 0.02 ; - MASKS 2 ; + MASK 2 ; END M0PO LAYER VIA0 TYPE CUT ; - MASKS 2 ; + MASK 2 ; END VIA0 LAYER M1 TYPE MASTERSLICE ; WIDTH 0.024 ; - MASKS 2 ; + MASK 2 ; END M1 LAYER VIA1 TYPE CUT ; - MASKS 2 ; + MASK 2 ; END VIA1 LAYER M2 TYPE MASTERSLICE ; WIDTH 0.03 ; - MASKS 2 ; + MASK 2 ; END M2 VIA square diff --git a/testdata/lefdef/masks-2/au.oas.gz b/testdata/lefdef/masks-2/au.oas.gz new file mode 100644 index 0000000000000000000000000000000000000000..4f2623eabd324d2091876e892aae4768c35662ba GIT binary patch literal 3217 zcmd^9J#QOF5WT(G6Di&u$+ONd5YUwnqzcWu(r^kTIx7Syk`U>9H3vZ^0V5IR*f3zj zO$;HO4OsA>&`)rmCU&LB4TCf;U8+=>*`3|JJ(5Y`lsN(<-Y5 zbw^>1LDKFxA1aRhw61bZQ@SXlDLF;O5 zl#d6){Hv_j3o3{E_ow%MnpEned}n)<5BCPcY;XMix_5ANcs~IhhuY!(!yog*{euTb z(EO&ml|TIX(f)%;-oZ}_wSs}5P-4W^rc%4ebf9TvBzd}!m0(sbg4t1#2T{>M zP64Rf0!+BJB*C+=f4EW-QU@!*4EAXZM=+IxTr`clGHTqL0Hg@6cu4Ksx2_ypE} zc`o@2FqOv|WMZNOdM$b)rv>ywgqF{MJ}*;vC!|Vw4CwI^V>DzX0Q##%1tq&7F9E$3 z%@~BSR5|NOXDwu6DR|^81qq^asd3hm&X%wh7YWi?Eg%A&O{KG*bk_Wr=aQG6bXG?2 zUL!IwQ9?RPL4xRPYCG#mXBR1SO;XBPPddB67!BFzk+UQ!DA^5p=}Bi(8&Jzio;8j&V8hm}T@UzHSop#nFDjZ_~DM)>ym!UsSmrDpne7Vy3t>U3?q~+C*c`H&!7{FQ z2Ukt2swq)Ug2sAi==ed-Yr~BVS%%BWH{GTAYnnO?#Oknrl7YB;;<3_#o+Oi zC-F0gpSfXJhJG2YBYex0`q+iAYKUW)#)4TxW@;%sjgQd@seq*%*D%iU51^Z&-z+o)@18zNM8wp;G_?0*N)!j(EH!Q42^TrAI&P%vb z%60!C^~BSeK{O9PF0&TR{g2D6L}%;bO{@R(NE!a#Q@i=cn=Y=(0KImzzHOP-!+X7M#X{ Vy