fill_with_left, implementation + tests

This commit is contained in:
Matthias Koefferlein 2021-03-29 20:58:16 +02:00
parent f0386b616a
commit b725f5fb0f
8 changed files with 137 additions and 18 deletions

View File

@ -4302,13 +4302,38 @@ CODE
# pattern = fill_pattern("FILL_CELL").shape(1, 0, box(0.0, 0.0, 1.0, 1.0)).origin(-0.5, -0.5)
# to_fill.fill(pattern, hstep(2.0, 1.0), vstep(-1.0, 2.0), auto_origin)
# @/code
#
# The fill function can only work with a target layout for output.
# It will not work for report output.
#
# The layers generated by the fill cells is only available for input later in the
# script if the output layout is identical to the input layouts.
# If you need the area missed by the fill function, try \fill_with_left.
def fill(*args)
self._fill(false, *args)
end
# %DRC%
# @name fill
# @brief Fills the region with regular pattern of shapes
# @synopsis layer.fill_with_left([ options ])
#
# This method has the same call syntax and functionality than \fill. Other than this method
# it will return the area not covered by fill cells as a DRC layer.
def fill_with_left(*args)
self._fill(true, *args)
end
def _fill(with_left, *args)
m = with_left ? "fill_with_left" : "fill"
# generation of new cells not tested in deep mode
@deep && raise("fill command not supported in deep mode currently")
@deep && raise("#{m} command not supported in deep mode currently")
m = "fill"
(@engine._output_layout && @engine._output_cell) || raise("#{m} command needs an output layout and output cell")
source = @engine.source
row_step = nil
@ -4359,6 +4384,8 @@ CODE
dbu_trans = RBA::VCplxTrans::new(1.0 / @engine.dbu)
result = nil
fill_cell = pattern.create_cell(@engine._output_layout, @engine)
top_cell = @engine._output_cell
ko = dbu_trans * pattern.cell_origin
@ -4379,6 +4406,13 @@ CODE
tp.tile_border(bx, by)
tp.threads = (@engine.threads || 1)
result_arg = "nil"
if with_left
result = RBA::Region::new
result_arg = "result"
tp.output(result_arg, result)
end
tp.input("region", self.data)
tp.var("top_cell", top_cell)
tp.var("ko", ko)
@ -4387,16 +4421,30 @@ CODE
tp.var("origin", origin)
tp.var("fc_index", fc_index)
tp.queue(<<"END")
var tc_box = _frame.bbox;
var tile_box = _tile ? (tc_box & _tile.bbox) : tc_box;
!tile_box.empty && (
tile_box.right = tile_box.right + rs.x - 1;
tile_box.top = tile_box.top + cs.y - 1;
tile_box = tile_box & tc_box;
(region & tile_box).fill(top_cell, fc_index, ko, rs, cs, origin, nil, Vector.new, nil, _tile.bbox)
)
if with_left
tp.queue(<<"END")
var tc_box = _frame.bbox;
var tile_box = _tile ? (tc_box & _tile.bbox) : tc_box;
!tile_box.empty && (
tile_box = tile_box.enlarged(Vector.new(rs.x, cs.y));
tile_box = tile_box & tc_box;
var left = Region.new;
(region & tile_box).fill(top_cell, fc_index, ko, rs, cs, origin, left, Vector.new, left, _tile.bbox);
_output(#{result_arg}, left)
)
END
else
tp.queue(<<"END")
var tc_box = _frame.bbox;
var tile_box = _tile ? (tc_box & _tile.bbox) : tc_box;
!tile_box.empty && (
tile_box.right = tile_box.right + rs.x - 1;
tile_box.top = tile_box.top + cs.y - 1;
tile_box = tile_box & tc_box;
(region & tile_box).fill(top_cell, fc_index, ko, rs, cs, origin, nil, Vector.new, nil, _tile.bbox)
)
END
end
begin
@engine._output_layout.start_changes
@ -4409,14 +4457,20 @@ END
else
if with_left
result = RBA::Region::new
end
@engine.run_timed("\"#{m}\" in: #{@engine.src_line}", self.data) do
self.data.fill(top_cell, fc_index, ko, rs, cs, origin)
self.data.fill(top_cell, fc_index, ko, rs, cs, origin, result, RBA::Vector::new, result)
end
end
self.data.disable_progress
return result ? DRCLayer::new(@engine, result) : nil
end
# %DRC%

View File

@ -187,7 +187,7 @@ module DRC
def initialize(name)
@cell_name = name
@shapes = []
@origin = RBA::DVector::new
@origin = nil
end
def create_cell(layout, engine)
@ -201,7 +201,12 @@ module DRC
end
def cell_origin
@origin
@origin || self._computed_origin
end
def _computed_origin
b = self.bbox
return b.empty? ? RBA::DVector::new : (b.p1 - RBA::DPoint::new)
end
def bbox

View File

@ -1203,3 +1203,13 @@ TEST(41_fillTiled)
run_test (_this, "41", false);
}
TEST(42_fillWithLeft)
{
run_test (_this, "42", false);
}
TEST(43_fillWithLeftTiled)
{
run_test (_this, "43", false);
}

View File

@ -1504,9 +1504,14 @@ VariantUserClassImpl::execute_gsi (const tl::ExpressionParserContext & /*context
tl::Heap heap;
size_t narg = 0;
for (gsi::MethodBase::argument_iterator a = meth->begin_arguments (); a != meth->end_arguments () && narg < args.size (); ++a, ++narg) {
// Note: this const_cast is ugly, but it will basically enable "out" parameters
// TODO: clean this up.
gsi::do_on_type<writer> () (a->type (), &arglist, const_cast<tl::Variant *> (&args [narg]), *a, &heap);
try {
// Note: this const_cast is ugly, but it will basically enable "out" parameters
// TODO: clean this up.
gsi::do_on_type<writer> () (a->type (), &arglist, const_cast<tl::Variant *> (&args [narg]), *a, &heap);
} catch (tl::Exception &ex) {
std::string msg = ex.msg () + tl::sprintf (tl::to_string (tr (" (argument '%s')")), a->spec ()->name ());
throw tl::Exception (msg);
}
}
SerialArgs retlist (meth->retsize ());
@ -1518,7 +1523,12 @@ VariantUserClassImpl::execute_gsi (const tl::ExpressionParserContext & /*context
throw tl::Exception (tl::sprintf (tl::to_string (tr ("Iterators not supported yet (method %s, class %s)")), method.c_str (), mp_cls->name ()));
} else {
out = tl::Variant ();
gsi::do_on_type<reader> () (meth->ret_type ().type (), &out, &retlist, meth->ret_type (), &heap);
try {
gsi::do_on_type<reader> () (meth->ret_type ().type (), &out, &retlist, meth->ret_type (), &heap);
} catch (tl::Exception &ex) {
std::string msg = ex.msg () + tl::to_string (tr (" (return value)"));
throw tl::Exception (msg);
}
}
}

19
testdata/drc/drcSimpleTests_42.drc vendored Normal file
View File

@ -0,0 +1,19 @@
source $drc_test_source
target $drc_test_target
if $drc_test_deep
deep
end
l1 = input(1, 0)
f1 = l1
p1 = fill_pattern("PAT1").shape(100, 0, box(0, 0, 1.um, 1.um)).origin(-0.5.um, -0.5.um)
f1.fill_with_left(p1, hstep(2.0, 1.0), vstep(-1.0, 2.0)).output(100, 0)
l1.output(1, 0)
f1.output(10, 0)

BIN
testdata/drc/drcSimpleTests_42.gds vendored Normal file

Binary file not shown.

21
testdata/drc/drcSimpleTests_43.drc vendored Normal file
View File

@ -0,0 +1,21 @@
source $drc_test_source
target $drc_test_target
if $drc_test_deep
deep
end
tiles(5, 5)
l1 = input(1, 0)
f1 = l1
p1 = fill_pattern("PAT1").shape(100, 0, box(0, 0, 1.um, 1.um)).origin(-0.5.um, -0.5.um)
f1.fill_with_left(p1, hstep(2.0, 1.0), vstep(-1.0, 2.0)).output(100, 0)
l1.output(1, 0)
f1.output(10, 0)

BIN
testdata/drc/drcSimpleTests_43.gds vendored Normal file

Binary file not shown.