From 7a37a6b7ed98bae7363518320dd8b71b07a6a429 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 21 Jul 2021 18:31:51 +0200 Subject: [PATCH 1/2] Implemented extent(cell_filter) for DRC, added Layout#cells with name filter --- src/db/db/dbOriginalLayerRegion.cc | 6 +++ src/db/db/gsiDeclDbLayout.cc | 25 ++++++++++ src/drc/drc/built-in-macros/_drc_engine.rb | 29 ++++++------ src/drc/drc/built-in-macros/_drc_source.rb | 51 +++++++++++++++++---- src/drc/unit_tests/drcSimpleTests.cc | 9 ++++ testdata/drc/drcSimpleTests_52.drc | 14 ++++++ testdata/drc/drcSimpleTests_52.gds | Bin 0 -> 13222 bytes testdata/drc/drcSimpleTests_53.drc | 16 +++++++ testdata/drc/drcSimpleTests_53.gds | Bin 0 -> 13222 bytes testdata/drc/drcSimpleTests_au52.gds | Bin 0 -> 2464 bytes testdata/drc/drcSimpleTests_au53.gds | Bin 0 -> 2150 bytes testdata/ruby/dbLayoutTest.rb | 18 ++++++++ 12 files changed, 146 insertions(+), 22 deletions(-) create mode 100644 testdata/drc/drcSimpleTests_52.drc create mode 100644 testdata/drc/drcSimpleTests_52.gds create mode 100644 testdata/drc/drcSimpleTests_53.drc create mode 100644 testdata/drc/drcSimpleTests_53.gds create mode 100644 testdata/drc/drcSimpleTests_au52.gds create mode 100644 testdata/drc/drcSimpleTests_au53.gds diff --git a/src/db/db/dbOriginalLayerRegion.cc b/src/db/db/dbOriginalLayerRegion.cc index 2671686ac..6df7a711f 100644 --- a/src/db/db/dbOriginalLayerRegion.cc +++ b/src/db/db/dbOriginalLayerRegion.cc @@ -379,6 +379,12 @@ OriginalLayerRegion::init () void OriginalLayerRegion::insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const { + // explicitly update the layout if the source is equal to the target + // (needed because we lock the layout below and no update would happen) + if (layout == m_iter.layout ()) { + layout->update (); + } + db::Shapes &sh = layout->cell (into_cell).shapes (into_layer); // NOTE: if the source (r) is from the same layout than the shapes live in, we better diff --git a/src/db/db/gsiDeclDbLayout.cc b/src/db/db/gsiDeclDbLayout.cc index 9ff2f70b3..edf3363cd 100644 --- a/src/db/db/gsiDeclDbLayout.cc +++ b/src/db/db/gsiDeclDbLayout.cc @@ -41,6 +41,7 @@ #include "dbCellMapping.h" #include "dbTechnology.h" #include "tlStream.h" +#include "tlGlobPattern.h" namespace gsi { @@ -708,6 +709,22 @@ static db::Cell *cell_from_name (db::Layout *ly, const std::string &name) } } +static std::vector cells_from_name (db::Layout *layout, const std::string &filter) +{ + tl::GlobPattern gp (filter); + + std::vector result; + db::Layout::top_down_iterator td = layout->begin_top_down (); + while (td != layout->end_top_down ()) { + if (gp.match (layout->cell_name (*td))) { + result.push_back (&layout->cell (*td)); + } + ++td; + } + + return result; +} + static std::vector top_cells (db::Layout *layout) { std::vector tc; @@ -1488,6 +1505,14 @@ Class decl_Layout ("db", "Layout", "\n" "@return The number of cells (the maximum cell index)\n" ) + + gsi::method_ext ("cells", &cells_from_name, gsi::arg ("name_filter"), + "@brief Gets the cell objects for a given name filter\n" + "\n" + "@param name_filter The cell name filter (glob pattern)\n" + "@return A list of \\Cell object of the cells matching the pattern\n" + "\n" + "This method has been introduced in version 0.27.3.\n" + ) + gsi::method_ext ("cell", &cell_from_name, gsi::arg ("name"), "@brief Gets a cell object from the cell name\n" "\n" diff --git a/src/drc/drc/built-in-macros/_drc_engine.rb b/src/drc/drc/built-in-macros/_drc_engine.rb index 6359bff21..f5fc0e9cf 100644 --- a/src/drc/drc/built-in-macros/_drc_engine.rb +++ b/src/drc/drc/built-in-macros/_drc_engine.rb @@ -1484,13 +1484,14 @@ module DRC # %DRC% # @name extent - # @brief Creates a new layer with the bounding box of the default source + # @brief Creates a new layer with the bounding box of the default source or cell bounding boxes # @synopsis extent + # @synopsis extent(cell_filter) # See \Source#extent for a description of that function. - def extent + def extent(cell_filter = nil) self._context("extent") do - layout.extent + layout.extent(cell_filter) end end @@ -1615,6 +1616,8 @@ CODE # # shapes now will be taken from the given rectangle and clipped to it # l1 = input(1, 0) # @/code + # + # To remove the clip condition, call "clip" without any arguments. def clip(*args) self._context("clip") do @@ -2638,16 +2641,6 @@ CODE end end - private - - def _make_string(v) - if v.class.respond_to?(:from_s) - v.class.to_s + "::from_s(" + v.to_s.inspect + ")" - else - v.inspect - end - end - def _input(layout, cell_index, layers, sel, box, clip, overlapping, shape_flags, global_trans, cls) if layers.empty? && ! @deep @@ -2714,6 +2707,16 @@ CODE end + private + + def _make_string(v) + if v.class.respond_to?(:from_s) + v.class.to_s + "::from_s(" + v.to_s.inspect + ")" + else + v.inspect + end + end + def _layout(name) @layout_sources[name].layout end diff --git a/src/drc/drc/built-in-macros/_drc_source.rb b/src/drc/drc/built-in-macros/_drc_source.rb index 538ecf968..600630949 100644 --- a/src/drc/drc/built-in-macros/_drc_source.rb +++ b/src/drc/drc/built-in-macros/_drc_source.rb @@ -101,7 +101,9 @@ module DRC @engine._context(method) do box = nil - if args.size == 1 + if args.size == 0 + # unclip + elsif args.size == 1 box = args[0] box.is_a?(RBA::DBox) || raise("Method requires a box specification") elsif args.size == 2 @@ -112,7 +114,7 @@ module DRC else raise("Invalid number of arguments (1, 2 or 4 expected)") end - @box = RBA::Box::from_dbox(box * (1.0 / @layout.dbu)) + @box = box && RBA::Box::from_dbox(box * (1.0 / @layout.dbu)) self @@ -311,24 +313,55 @@ CODE # %DRC% # @name extent - # @brief Returns a layer with the bounding box of the selected layout + # @brief Returns a layer with the bounding box of the selected layout or cells # @synopsis source.extent + # @synopsis source.extent(cell_filter) + # + # Without an argument, the extent method returns a layer with the bounding box + # of the top cell. With a cell filter argument, the method returns a layer + # with the bounding boxes of the selected cells. The cell filter is a glob + # pattern. + # # The extent function is useful to invert a layer: # # @code # inverse_1 = extent.sized(100.0) - input(1, 0) # @/code + # + # The following example returns the bounding boxes of all cells whose + # names start with "A": + # + # @code + # a_cells = extent("A*") + # @/code - def extent + def extent(cell_filter = nil) + @engine._context("extent") do - layer = input - if @box - layer.insert(RBA::DBox::from_ibox(@box) * @layout.dbu) - else - layer.insert((RBA::DBox::from_ibox(@cell.bbox) * @layout.dbu).transformed(@global_trans)) + + if cell_filter + cell_filter.is_a?(String) || raise("Invalid cell filter argument - must be a string") end + + if cell_filter + tmp = @layout_var.insert_layer(RBA::LayerInfo::new) + @tmp_layers << tmp + @layout_var.cells(cell_filter).each do |cell| + cell.shapes(tmp).insert(cell.bbox) + end + layer = DRCLayer::new(@engine, @engine._cmd(@engine, :_input, @layout_var, @cell.cell_index, [tmp], @sel, @box, @clip, @overlapping, RBA::Shapes::SAll, @global_trans, RBA::Region)) + else + layer = input + layer.insert((RBA::DBox::from_ibox(@cell.bbox) * @layout.dbu).transformed(@global_trans)) + if @box + layer.data &= RBA::Region::new(@box) + end + end + layer + end + end # %DRC% diff --git a/src/drc/unit_tests/drcSimpleTests.cc b/src/drc/unit_tests/drcSimpleTests.cc index ad98a0644..5bcba5fa3 100644 --- a/src/drc/unit_tests/drcSimpleTests.cc +++ b/src/drc/unit_tests/drcSimpleTests.cc @@ -1303,3 +1303,12 @@ TEST(51_epInternalAngle) run_test (_this, "51", false); } +TEST(52_cellWiseExtent) +{ + run_test (_this, "52", false); +} + +TEST(53_cellWiseExtentWithClip) +{ + run_test (_this, "53", false); +} diff --git a/testdata/drc/drcSimpleTests_52.drc b/testdata/drc/drcSimpleTests_52.drc new file mode 100644 index 000000000..91d043f52 --- /dev/null +++ b/testdata/drc/drcSimpleTests_52.drc @@ -0,0 +1,14 @@ + +source $drc_test_source +target $drc_test_target + +extent.output(2000) +extent("PMOS*").output(2001) +extent("NMOS*").output(2002) + +deep + +extent.output(2100) +extent("PMOS*").output(2101) +extent("NMOS*").output(2102) + diff --git a/testdata/drc/drcSimpleTests_52.gds b/testdata/drc/drcSimpleTests_52.gds new file mode 100644 index 0000000000000000000000000000000000000000..e498a3028b17e8ab4fd943ac4a072f9af288f866 GIT binary patch literal 13222 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 literal 0 HcmV?d00001 diff --git a/testdata/ruby/dbLayoutTest.rb b/testdata/ruby/dbLayoutTest.rb index db993a61f..4d08991c3 100644 --- a/testdata/ruby/dbLayoutTest.rb +++ b/testdata/ruby/dbLayoutTest.rb @@ -79,6 +79,7 @@ class DBLayout_TestClass < TestBase assert_equal( ly.cell_name(ci), "new_cell" ) assert_equal( ly.cell_by_name("new_cell"), ci ) + assert_equal( ly.cells("A*"), [] ) assert_equal( ly.cell("new_cell").name, "new_cell" ) assert_equal( ly.cell("x").inspect, "nil" ) @@ -1175,6 +1176,23 @@ class DBLayout_TestClass < TestBase end + # Layout#cells + def test_15 + + g = RBA::Layout::new + c1 = g.create_cell("B1") + c2 = g.create_cell("B2") + c0 = g.create_cell("A") + c0.insert(RBA::CellInstArray::new(c1.cell_index, RBA::Trans::new)) + c0.insert(RBA::CellInstArray::new(c2.cell_index, RBA::Trans::new)) + + assert_equal(g.cells("B*").collect(&:name).join(","), "B1,B2") + assert_equal(g.cells("*").collect(&:name).join(","), "A,B1,B2") + assert_equal(g.cells("A").collect(&:name).join(","), "A") + assert_equal(g.cells("X").collect(&:name).join(","), "") + + end + end load("test_epilogue.rb") From 99bb98127f7efed40b4a42628375a69e470f2556 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 21 Jul 2021 18:51:34 +0200 Subject: [PATCH 2/2] Updated doc. --- src/lay/lay/doc/about/drc_ref_global.xml | 5 ++++- src/lay/lay/doc/about/drc_ref_source.xml | 15 ++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/lay/lay/doc/about/drc_ref_global.xml b/src/lay/lay/doc/about/drc_ref_global.xml index 917ada706..96c622861 100644 --- a/src/lay/lay/doc/about/drc_ref_global.xml +++ b/src/lay/lay/doc/about/drc_ref_global.xml @@ -306,6 +306,8 @@ clip(0.mm, 0.mm, 0.5.mm, 0.6.mm) # shapes now will be taken from the given rectangle and clipped to it l1 = input(1, 0) +

+To remove the clip condition, call "clip" without any arguments.

"connect" - Specifies a connection between two layers

@@ -619,11 +621,12 @@ actual edges from the first input (see
separation for

Similar to log, but the message is printed formatted as an error

-

"extent" - Creates a new layer with the bounding box of the default source

+

"extent" - Creates a new layer with the bounding box of the default source or cell bounding boxes

Usage:

  • extent
  • +
  • extent(cell_filter)

See Source#extent for a description of that function. diff --git a/src/lay/lay/doc/about/drc_ref_source.xml b/src/lay/lay/doc/about/drc_ref_source.xml index 05525f41e..20a46bee9 100644 --- a/src/lay/lay/doc/about/drc_ref_source.xml +++ b/src/lay/lay/doc/about/drc_ref_source.xml @@ -96,18 +96,31 @@ Use the global version of "edges" without a source object to address the default

This method has been introduced in version 0.27.

-

"extent" - Returns a layer with the bounding box of the selected layout

+

"extent" - Returns a layer with the bounding box of the selected layout or cells

Usage:

  • source.extent
  • +
  • source.extent(cell_filter)

+Without an argument, the extent method returns a layer with the bounding box +of the top cell. With a cell filter argument, the method returns a layer +with the bounding boxes of the selected cells. The cell filter is a glob +pattern. +

The extent function is useful to invert a layer:

 inverse_1 = extent.sized(100.0) - input(1, 0)
 
+

+The following example returns the bounding boxes of all cells whose +names start with "A": +

+

+a_cells = extent("A*")
+

"global_transform" - Gets or sets a global transformation