Some bug fixes, added tests for hier DRC (at least for what is there yet)

This commit is contained in:
Matthias Koefferlein 2019-02-18 22:24:34 +01:00
parent 0bed4615aa
commit 7f71cc3a56
10 changed files with 212 additions and 46 deletions

View File

@ -440,6 +440,14 @@ template void AsIfFlatRegion::produce_markers_for_grid_check<db::UnitTrans> (con
EdgePairs
AsIfFlatRegion::grid_check (db::Coord gx, db::Coord gy) const
{
if (gx < 0 || gy < 0) {
throw tl::Exception (tl::to_string (tr ("Grid check requires a positive grid value")));
}
if (gx == 0 && gy == 0) {
return EdgePairs ();
}
std::auto_ptr<db::FlatEdgePairs> res (new db::FlatEdgePairs ());
for (RegionIterator p (begin_merged ()); ! p.at_end (); ++p) {
@ -567,6 +575,14 @@ AsIfFlatRegion::snapped_polygon (const db::Polygon &poly, db::Coord gx, db::Coor
RegionDelegate *
AsIfFlatRegion::snapped (db::Coord gx, db::Coord gy)
{
if (gx < 0 || gy < 0) {
throw tl::Exception (tl::to_string (tr ("Grid check requires a positive grid value")));
}
if (gx == 0 && gy == 0) {
return this;
}
std::auto_ptr<FlatRegion> new_region (new FlatRegion (merged_semantics ()));
gx = std::max (db::Coord (1), gx);

View File

@ -716,7 +716,7 @@ DeepRegion::to_string (size_t nmax) const
EdgePairs
DeepRegion::grid_check (db::Coord gx, db::Coord gy) const
{
if (gx <= 0 || gy <= 0) {
if (gx < 0 || gy < 0) {
throw tl::Exception (tl::to_string (tr ("Grid check requires a positive grid value")));
}
@ -725,6 +725,10 @@ DeepRegion::grid_check (db::Coord gx, db::Coord gy) const
return db::AsIfFlatRegion::grid_check (gx, gy);
}
if (gx == 0) {
return EdgePairs ();
}
ensure_merged_polygons_valid ();
db::Layout &layout = m_merged_polygons.layout ();
@ -796,7 +800,7 @@ DeepRegion::angle_check (double min, double max, bool inverse) const
RegionDelegate *
DeepRegion::snapped (db::Coord gx, db::Coord gy)
{
if (gx <= 0 || gy <= 0) {
if (gx < 0 || gy < 0) {
throw tl::Exception (tl::to_string (tr ("Snapping requires a positive grid value")));
}
@ -805,6 +809,10 @@ DeepRegion::snapped (db::Coord gx, db::Coord gy)
return db::AsIfFlatRegion::snapped (gx, gy);
}
if (! gx) {
return this;
}
ensure_merged_polygons_valid ();
db::cell_variants_collector<db::GridReducer> vars (gx);

View File

@ -102,7 +102,7 @@ TEST(2)
db::compare_layouts (_this, layout, au, db::NoNormalization);
}
TEST(3)
TEST(3_Flat)
{
std::string rs = tl::testsrc ();
rs += "/testdata/drc/drcSimpleTests_3.drc";
@ -141,3 +141,43 @@ TEST(3)
db::compare_layouts (_this, layout, au, db::NoNormalization);
}
TEST(4_Hierarchical)
{
std::string rs = tl::testsrc ();
rs += "/testdata/drc/drcSimpleTests_4.drc";
std::string input = tl::testsrc ();
input += "/testdata/drc/drctest.gds";
std::string au = tl::testsrc ();
au += "/testdata/drc/drcSimpleTests_au4.oas";
std::string output = this->tmp_file ("tmp.gds");
{
// Set some variables
lym::Macro config;
config.set_text (tl::sprintf (
"$drc_test_source = '%s'\n"
"$drc_test_target = '%s'\n"
, input, output)
);
config.set_interpreter (lym::Macro::Ruby);
EXPECT_EQ (config.run (), 0);
}
lym::Macro drc;
drc.load_from (rs);
EXPECT_EQ (drc.run (), 0);
db::Layout layout;
{
tl::InputStream stream (output);
db::Reader reader (stream);
reader.read (layout);
}
db::compare_layouts (_this, layout, au, db::NoNormalization);
}

View File

@ -72,25 +72,36 @@ void runtest (tl::TestBase *_this, int mode)
db::compare_layouts (_this, layout, au, db::WriteOAS);
}
TEST(1)
TEST(1_Flat)
{
runtest (_this, 1);
}
TEST(2)
TEST(2_BigFlat)
{
test_is_long_runner ();
runtest (_this, 2);
}
TEST(3)
TEST(3_Tiled)
{
test_is_long_runner ();
runtest (_this, 3);
}
TEST(4)
TEST(4_BigTiled)
{
test_is_long_runner ();
runtest (_this, 4);
}
TEST(5_Hier)
{
runtest (_this, 5);
}
TEST(6_BigHier)
{
test_is_long_runner ();
runtest (_this, 6);
}

49
testdata/drc/drcSimpleTests_4.drc vendored Normal file
View File

@ -0,0 +1,49 @@
# Foreign cell test
source($drc_test_source, "TOPTOP_SMALL")
target($drc_test_target)
cell("TOPTOP_SMALL")
l1_flat = input(1)
l1_flat.is_deep? && raise("l1_flat should not be deep")
is_deep? && raise("is_deep? is true")
deep
is_deep? || raise("is_deep? is false")
l1 = input(1)
l1.is_deep? || raise("l1 should be deep")
l2 = input(2)
l2.is_deep? || raise("l2 should be deep")
flat
is_deep? && raise("is_deep? is true")
l2_flat = input(2)
l2_flat.is_deep? && raise("l2_flat should not be deep")
l1.output(1, 0)
l2.output(2, 0)
l1_flat.output(11, 0)
l2_flat.output(12, 0)
l1.and(l2).output(1000, 0)
l1_flat.and(l2).output(1001, 0)
l1.and(l2_flat).output(1002, 0)
l1_flat.and(l2_flat).output(1003, 0)
l1.space(0.2).output(1010, 0)
l1_flat.space(0.2).output(1011, 0)
l1.separation(l2, 0.3).output(1020, 0)
l1_flat.separation(l2, 0.3).output(1021, 0)
l1.separation(l2_flat, 0.3).output(1022, 0)
l1_flat.separation(l2_flat, 0.3).output(1023, 0)

BIN
testdata/drc/drcSimpleTests_au4.oas vendored Normal file

Binary file not shown.

View File

@ -4,12 +4,16 @@ def message(m)
$stdout.flush
end
def run_testsuite(dm, ic, tiled = false)
def expect_eq(a, b)
a == b || raise("unexpected value #{a.to_s}, should be #{b.to_s}")
end
def run_testsuite(dm, ic, tiled = false, hier = false)
has_float_range = ((0..0.5).max != 0)
lb = 100
a = input(RBA::LayerInfo::new(1, 0))
b = input(2)
c = input(3)
@ -21,16 +25,16 @@ def run_testsuite(dm, ic, tiled = false)
layers.each { |l| h[l] = true }
h[RBA::LayerInfo::new(1, 0)] || raise("missing layer 1/0 in layers list")
c.is_merged? == false || raise("unexpected value")
expect_eq(c.is_merged?, false)
message "--- general #{lb}"
l1 = a&b
l1.output(lb, dm)
l1.is_empty? && raise("must not be empty")
expect_eq(l1.is_empty?, false)
a.and(b).xor(l1).is_empty? || raise("xor not empty")
tiled || (a.and(b).is_merged? == true || raise("unexpected value"))
tiled || hier || expect_eq(a.and(b).is_merged?, true)
a.xor(b).output(RBA::LayerInfo::new(lb + 1, dm))
a.xor(b).xor(a ^ b).is_empty? || raise("xor not empty")
@ -43,28 +47,36 @@ def run_testsuite(dm, ic, tiled = false)
a.join(b).xor(a + b).is_empty? || raise("xor not empty")
if !tiled
a.join(b).data.size == 16 * ic || raise("unexpected shape count")
expect_eq(a.join(b).data.size, 16 * ic)
end
c.raw.is_clean? == false || raise("unexpected value")
# c.raw switched the semantics
c.is_clean? == false || raise("unexpected value")
(c.area / ic).to_s == "10.0" || raise("unexpected value")
(c.edges.length / ic).to_s == "18.0" || raise("unexpected value")
(c.perimeter / ic).to_s == "18.0" || raise("unexpected value")
c.clean
c.is_clean? == true || raise("unexpected value")
(c.area / ic).to_s == "9.0" || raise("unexpected value")
(c.edges.length / ic).to_s == "14.0" || raise("unexpected value")
(c.perimeter / ic).to_s == "14.0" || raise("unexpected value")
(c.dup.area / ic).to_s == "9.0" || raise("unexpected value")
(c.raw.clean.area / ic).to_s == "9.0" || raise("unexpected value")
(c.area / ic).to_s == "9.0" || raise("unexpected value")
(c.raw.area / ic).to_s == "10.0" || raise("unexpected value")
c.clean
# NOTE: there is no clean/raw semantics in deep mode
if ! hier
expect_eq(c.raw.is_clean?, false)
# c.raw switched the semantics
expect_eq(c.is_clean?, false)
expect_eq((c.area / ic).to_s, "10.0")
expect_eq((c.edges.length / ic).to_s, "18.0")
expect_eq((c.perimeter / ic).to_s, "18.0")
c.clean
expect_eq(c.is_clean?, true)
end
expect_eq((c.area / ic).to_s, "9.0")
expect_eq((c.edges.length / ic).to_s, "14.0")
expect_eq((c.perimeter / ic).to_s, "14.0")
expect_eq((c.dup.area / ic).to_s, "9.0")
# NOTE: there is no clean/raw semantics in deep mode
if ! hier
expect_eq((c.raw.clean.area / ic).to_s, "9.0")
expect_eq((c.area / ic).to_s, "9.0")
expect_eq((c.raw.area / ic).to_s, "10.0")
c.clean
end
if ic == 1
c.bbox.to_s == "(-4,-5;0,-2)" || raise("unexpected value")
expect_eq(c.bbox.to_s, "(-4,-5;0,-2)")
end
lb += 10 #110
@ -80,15 +92,15 @@ def run_testsuite(dm, ic, tiled = false)
a.edges.end_segments(0, 0.5).extended_out(0.01).output(lb + 7, dm)
a.edges.end_segments(0.5, 0.5).extended_out(0.01).output(lb + 8, dm)
a.polygons? == true || raise("unexpected value")
a.edges? == false || raise("unexpected value")
a.edge_pairs? == false || raise("unexpected value")
a.edges.edge_pairs? == false || raise("unexpected value")
a.edges.polygons? == false || raise("unexpected value")
a.edges.edges? == true || raise("unexpected value")
a.space(0.5).edge_pairs? == true || raise("unexpected value")
a.space(0.5).polygons? == false || raise("unexpected value")
a.space(0.5).edges? == false || raise("unexpected value")
expect_eq(a.polygons?, true)
expect_eq(a.edges?, false)
expect_eq(a.edge_pairs?, false)
expect_eq(a.edges.edge_pairs?, false)
expect_eq(a.edges.polygons?, false)
expect_eq(a.edges.edges?, true)
expect_eq(a.space(0.5).edge_pairs?, true)
expect_eq(a.space(0.5).polygons?, false)
expect_eq(a.space(0.5).edges?, false)
lb += 10 #120
message "--- extended #{lb}"
@ -132,7 +144,7 @@ def run_testsuite(dm, ic, tiled = false)
b.interacting(a).in(b).output(lb + 1, dm)
(b|a).not_in(b).output(lb + 2, dm)
x.in(b).output(lb + 3, dm)
b.sized(0.1).in(b).is_empty? == true || raise("unexpected value")
expect_eq(b.sized(0.1).in(b).is_empty?, true)
lb += 10 #170
message "--- inside, outside, overlapping, interacting #{lb}"
@ -209,14 +221,18 @@ def run_testsuite(dm, ic, tiled = false)
lb += 10 #180
message "--- merge #{lb}"
c.raw
if !hier
c.raw
end
if !tiled
c.merged.is_merged? == true || raise("unexpected value")
expect_eq(c.merged.is_merged?, true)
end
c.merged.output(lb, dm)
c.merged(2).output(lb + 1, dm)
c.merged(3).output(lb + 2, dm)
c.clean
if !hier
c.clean
end
cdup = c.dup
cdup.merge.xor(c.merged).output(lb + 3, dm)
cdup.xor(c.merged).output(lb + 4, dm)
@ -252,9 +268,11 @@ def run_testsuite(dm, ic, tiled = false)
a.non_rectangles.output(lb + 1, dm)
a.rectilinear.output(lb + 2, dm)
a.non_rectilinear.output(lb + 3, dm)
c.raw
c.non_rectangles.output(lb + 4, dm)
c.clean
if !hier
c.raw
c.non_rectangles.output(lb + 4, dm)
c.clean
end
c.rectangles.output(lb + 5, dm)
lb += 10 #210
@ -561,12 +579,18 @@ if $drc_test_mode == 1
source($drc_test_source, "TOP")
target($drc_test_target, "TOP")
flat
run_testsuite(0, 1)
elsif $drc_test_mode == 2
target($drc_test_target, "TOPTOP")
source($drc_test_source, "TOPTOP")
flat
run_testsuite(0, 900)
elsif $drc_test_mode == 3
@ -592,5 +616,23 @@ elsif $drc_test_mode == 4
run_testsuite(0, 900, true)
elsif $drc_test_mode == 5
source($drc_test_source, "TOP")
target($drc_test_target, "TOP")
deep
run_testsuite(0, 1, false, true)
elsif $drc_test_mode == 6
target($drc_test_target, "TOPTOP")
source($drc_test_source, "TOPTOP")
deep
run_testsuite(0, 900, false, true)
end

BIN
testdata/drc/drcSuiteTests_au5.oas vendored Normal file

Binary file not shown.

BIN
testdata/drc/drcSuiteTests_au6.oas vendored Normal file

Binary file not shown.

Binary file not shown.