# encoding: UTF-8 # KLayout Layout Viewer # Copyright (C) 2006-2024 Matthias Koefferlein # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA if !$:.member?(File::dirname($0)) $:.push(File::dirname($0)) end load("test_prologue.rb") class DBLayout_TestClass < TestBase def collect(s, l) # check native iteration here too .. res2 = [] s.each do |s| r = "[#{s.inst_cell.name}]" r += (s.trans * s.inst_trans).to_s res2.push(r) end res = [] s.reset while !s.at_end? r = "[#{s.inst_cell.name}]" r += (s.trans * s.inst_trans).to_s res.push(r) s.next end assert_equal(res, res2) return res.join("/") end def dcollect(s, l) res = [] while !s.at_end? r = "[#{s.inst_cell.name}]" r += (s.dtrans * s.inst_dtrans).to_s res.push(r) s.next end return res.join("/") end def test_1 # Recursive instance iterator tests l = RBA::Layout.new l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) l.insert_layer_at(1, RBA::LayerInfo.new(2, 0)) c0 = l.cell(l.add_cell("c0")) c1 = l.cell(l.add_cell("c1")) c2 = l.cell(l.add_cell("c2")) c3 = l.cell(l.add_cell("c3")) b = RBA::Box.new(0, 100, 1000, 1200) c0.shapes(0).insert(b) c1.shapes(0).insert(b) c2.shapes(0).insert(b) c3.shapes(0).insert(b) bb = RBA::Box.new(1, 101, 1001, 1201) c3.shapes(1).insert(bb) tt = RBA::Trans.new c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) i1 = c0.begin_instances_rec_touching(RBA::Box.new(0, 0, 100, 100)) i1copy = i1.dup assert_equal(i1copy.overlapping?, false) assert_equal(collect(i1, l), "[c1]r0 *1 0,0/[c2]r0 *1 100,-100") i1.reset assert_equal(dcollect(i1, l), "[c1]r0 *1 0,0/[c2]r0 *1 0.1,-0.1") assert_equal(collect(i1copy, l), "[c1]r0 *1 0,0/[c2]r0 *1 100,-100") i1 = c0.begin_instances_rec_touching(RBA::DBox.new(0, 0, 0.100, 0.100)) assert_equal(collect(i1, l), "[c1]r0 *1 0,0/[c2]r0 *1 100,-100") i1o = c0.begin_instances_rec_overlapping(RBA::Box.new(0, 0, 100, 100)); assert_equal(collect(i1o, l), ""); i1o = c0.begin_instances_rec_overlapping(RBA::DBox.new(0, 0, 0.100, 0.100)); assert_equal(collect(i1o, l), ""); i1copy.overlapping = true assert_equal(i1copy.overlapping?, true) assert_equal(collect(i1copy, l), ""); i1o = c0.begin_instances_rec_overlapping(RBA::Box.new(0, 0, 100, 101)); assert_equal(collect(i1o, l), "[c1]r0 *1 0,0"); i1o = c0.begin_instances_rec_overlapping(RBA::DBox.new(0, 0, 0.100, 0.101)); assert_equal(collect(i1o, l), "[c1]r0 *1 0,0"); i1copy.region = RBA::Box.new(0, 0, 100, 101) assert_equal(i1copy.region.to_s, "(0,0;100,101)") assert_equal(collect(i1copy, l), "[c1]r0 *1 0,0"); i1copy.region = RBA::Region::new(RBA::Box.new(0, 0, 100, 101)) assert_equal(i1copy.region.to_s, "(0,0;100,101)") assert_equal(collect(i1copy, l), "[c1]r0 *1 0,0"); i1copy.region = RBA::Box.new(-1000, -1000, 1100, 1101) i1copy.confine_region(RBA::Box.new(0, 0, 100, 101)) assert_equal(i1copy.region.to_s, "(0,0;100,101)") assert_equal(collect(i1copy, l), "[c1]r0 *1 0,0"); i1copy.region = RBA::Box.new(-1000, -1000, 1100, 1101) i1copy.confine_region(RBA::Region::new(RBA::Box.new(0, 0, 100, 101))) assert_equal(i1copy.region.to_s, "(0,0;100,101)") assert_equal(collect(i1copy, l), "[c1]r0 *1 0,0"); i1o = c0.begin_instances_rec_overlapping(RBA::Box.new(0, 0, 101, 101)); assert_equal(collect(i1o, l), "[c1]r0 *1 0,0/[c2]r0 *1 100,-100"); i1o = c0.begin_instances_rec_overlapping(RBA::Box.new(0, 0, 101, 101)); assert_equal(collect(i1o, l), "[c1]r0 *1 0,0/[c2]r0 *1 100,-100"); i2 = c0.begin_instances_rec_touching(RBA::Box.new(-100, 0, 100, 100)); assert_equal(collect(i2, l), "[c1]r0 *1 0,0/[c2]r0 *1 100,-100/[c3]r90 *1 0,0"); i2o = c0.begin_instances_rec_overlapping(RBA::Box.new(-100, 0, 100, 100)); assert_equal(collect(i2o, l), ""); i2o = c0.begin_instances_rec_overlapping(RBA::Box.new(-101, 0, 101, 101)); assert_equal(collect(i2o, l), "[c1]r0 *1 0,0/[c2]r0 *1 100,-100/[c3]r90 *1 0,0"); i4 = c0.begin_instances_rec_touching(RBA::Box.new(-100, 0, 2000, 100)); i4_copy = c0.begin_instances_rec_touching(RBA::Box.new(-100, 0, 2000, 100)); i4.max_depth = 0; assert_equal(collect(i4, l), "[c1]r0 *1 0,0/[c2]r0 *1 100,-100/[c3]r90 *1 0,0"); assert_equal(i4 == i4, true); assert_equal(i4 != i4, false); assert_equal(i4 == i4_copy, false); assert_equal(i4 != i4_copy, true); i4 = i4_copy.dup assert_equal(i4 == i4_copy, true); assert_equal(i4 != i4_copy, false); i4.max_depth = 1; assert_equal(i4.max_depth, 1) assert_equal(collect(i4, l), "[c1]r0 *1 0,0/[c3]r0 *1 1200,-100/[c2]r0 *1 100,-100/[c3]r90 *1 0,0"); i4.min_depth = 1; assert_equal(i4.min_depth, 1) assert_equal(collect(i4, l), "[c3]r0 *1 1200,-100"); i4.assign(i4_copy); assert_equal(collect(i4, l), "[c1]r0 *1 0,0/[c3]r0 *1 1200,-100/[c2]r0 *1 100,-100/[c3]r90 *1 0,0"); i5 = c0.begin_instances_rec assert_equal(collect(i5, l), "[c1]r0 *1 0,0/[c3]r0 *1 1200,-100/[c2]r0 *1 100,-100/[c3]r90 *1 0,0"); ii = RBA::RecursiveInstanceIterator::new assert_equal(collect(ii, l), "") ii = RBA::RecursiveInstanceIterator::new(l, c2) assert_equal(collect(ii, l), "[c3]r0 *1 1100,0") assert_equal(ii.top_cell.name, "c2") assert_equal(ii.layout == l, true) ii = RBA::RecursiveInstanceIterator::new(l, c0, RBA::Box.new(-100, 0, 2000, 100), false) assert_equal(collect(ii, l), "[c1]r0 *1 0,0/[c3]r0 *1 1200,-100/[c2]r0 *1 100,-100/[c3]r90 *1 0,0") ii = RBA::RecursiveInstanceIterator::new(l, c0, RBA::Box.new(-100, 0, 2000, 100), true) assert_equal(collect(ii, l), "[c3]r0 *1 1200,-100/[c2]r0 *1 100,-100") ii = RBA::RecursiveInstanceIterator::new(l, c0, RBA::Box.new(-100, 0, 2000, 101), true) assert_equal(collect(ii, l), "[c1]r0 *1 0,0/[c3]r0 *1 1200,-100/[c2]r0 *1 100,-100") ii = RBA::RecursiveInstanceIterator::new(l, c0, RBA::Region::new(RBA::Box.new(-100, 0, 2000, 101)), true) assert_equal(collect(ii, l), "[c1]r0 *1 0,0/[c3]r0 *1 1200,-100/[c2]r0 *1 100,-100") ii = RBA::RecursiveInstanceIterator::new(l, c0) assert_equal(collect(ii, l), "[c1]r0 *1 0,0/[c3]r0 *1 1200,-100/[c2]r0 *1 100,-100/[c3]r90 *1 0,0") ii.reset ii.unselect_cells("c0") ii.select_cells("c2") assert_equal(collect(ii, l), "[c3]r0 *1 1200,-100") ii.reset_selection ii.unselect_cells("c*") ii.select_cells([ c2.cell_index ]) assert_equal(collect(ii, l), "[c3]r0 *1 1200,-100") ii.reset_selection ii.unselect_all_cells ii.select_cells("c2") assert_equal(collect(ii, l), "[c3]r0 *1 1200,-100") ii.reset_selection ii.select_all_cells ii.unselect_cells("c2") assert_equal(collect(ii, l), "[c1]r0 *1 0,0/[c2]r0 *1 100,-100/[c3]r90 *1 0,0") ii.reset_selection ii.select_cells("c*") ii.unselect_cells([ c1.cell_index, c2.cell_index ]) assert_equal(collect(ii, l), "[c1]r0 *1 0,0/[c2]r0 *1 100,-100/[c3]r90 *1 0,0") ii = RBA::RecursiveInstanceIterator::new(l, c0) assert_equal(ii.all_targets_enabled?, true) ii.targets = "c3" assert_equal(ii.all_targets_enabled?, false) assert_equal(collect(ii, l), "[c3]r0 *1 1200,-100/[c3]r90 *1 0,0") ii.enable_all_targets assert_equal(ii.all_targets_enabled?, true) assert_equal(collect(ii, l), "[c1]r0 *1 0,0/[c3]r0 *1 1200,-100/[c2]r0 *1 100,-100/[c3]r90 *1 0,0") ii.targets = [ c3.cell_index, c1.cell_index ] assert_equal(ii.all_targets_enabled?, false) assert_equal(collect(ii, l), "[c1]r0 *1 0,0/[c3]r0 *1 1200,-100/[c3]r90 *1 0,0") end def test_2 # Recursive instance iterator tests l = RBA::Layout.new l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) l.insert_layer_at(1, RBA::LayerInfo.new(2, 0)) c0 = l.cell(l.add_cell("c0")) c1 = l.cell(l.add_cell("c1")) c2 = l.cell(l.add_cell("c2")) c3 = l.cell(l.add_cell("c3")) b = RBA::Box.new(0, 100, 1000, 1200) c3.shapes(0).insert(b) bb = RBA::Box.new(1, 101, 1001, 1201) c3.shapes(1).insert(bb) tt = RBA::Trans.new c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1), RBA::Vector::new(10, 20), RBA::Vector::new(11, 21), 2, 3)) c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) res = [] i = c0.begin_instances_rec while !i.at_end? res << i.inst_cell.bbox.transformed(i.trans * i.inst_trans).to_s + " " + (i.path + [ i.current_inst_element ]).collect { |e| "[" + l.cell(e.cell_inst.cell_index).name + " #" + e.ia.to_s + "," + e.ib.to_s + " -> " + e.specific_trans.to_s + "]" }.join("") i.next end assert_equal(res.join("\n") + "\n", <<"END") () [c1 #-1,-1 -> r0 0,0] (1200,0;2201,1101) [c2 #-1,-1 -> r0 100,-100][c3 #-1,-1 -> r0 1100,0] (1200,0;2201,1101) [c2 #-1,-1 -> r0 100,-100] (-1201,0;-100,1001) [c3 #0,0 -> r90 0,0] (-1191,20;-90,1021) [c3 #1,0 -> r90 10,20] (-1190,21;-89,1022) [c3 #0,1 -> r90 11,21] (-1180,41;-79,1042) [c3 #1,1 -> r90 21,41] (-1179,42;-78,1043) [c3 #0,2 -> r90 22,42] (-1169,62;-68,1063) [c3 #1,2 -> r90 32,62] END end end load("test_epilogue.rb")