mirror of https://github.com/KLayout/klayout.git
Merge pull request #1193 from KLayout/issue-1189
Issue 1189 High memory footprint for DRC deck
This commit is contained in:
commit
1f2e8b4012
|
|
@ -707,7 +707,6 @@ bool run_deep_xor (const XORData &xor_data)
|
|||
{
|
||||
db::DeepShapeStore dss;
|
||||
dss.set_threads (xor_data.threads);
|
||||
dss.set_keep_layouts (true); // avoids excessive cell mapping
|
||||
|
||||
double dbu = std::min (xor_data.layout_a->dbu (), xor_data.layout_b->dbu ());
|
||||
|
||||
|
|
|
|||
|
|
@ -426,13 +426,13 @@ static unsigned int init_layer (db::Layout &layout, const db::RecursiveShapeIter
|
|||
}
|
||||
|
||||
DeepShapeStore::DeepShapeStore ()
|
||||
: m_keep_layouts (false)
|
||||
: m_keep_layouts (true)
|
||||
{
|
||||
++s_instance_count;
|
||||
}
|
||||
|
||||
DeepShapeStore::DeepShapeStore (const std::string &topcell_name, double dbu)
|
||||
: m_keep_layouts (false)
|
||||
: m_keep_layouts (true)
|
||||
{
|
||||
++s_instance_count;
|
||||
|
||||
|
|
|
|||
|
|
@ -417,6 +417,9 @@ Class<db::TilingProcessor> decl_TilingProcessor ("db", "TilingProcessor",
|
|||
"Regions don't always come with a database unit, hence a database unit should be specified with the \\dbu= method unless "
|
||||
"a layout object is specified as input too.\n"
|
||||
"\n"
|
||||
"Caution: the Region object must stay valid during the lifetime of the tiling processor. Take care to store it in "
|
||||
"a variable to prevent early destruction of the Region object. Not doing so may crash the application.\n"
|
||||
"\n"
|
||||
"The name specifies the variable under which the input can be used in the scripts."
|
||||
) +
|
||||
method_ext ("input", &tp_input9, gsi::arg ("name"), gsi::arg ("region"), gsi::arg ("trans"),
|
||||
|
|
@ -425,6 +428,9 @@ Class<db::TilingProcessor> decl_TilingProcessor ("db", "TilingProcessor",
|
|||
"Regions don't always come with a database unit, hence a database unit should be specified with the \\dbu= method unless "
|
||||
"a layout object is specified as input too.\n"
|
||||
"\n"
|
||||
"Caution: the Region object must stay valid during the lifetime of the tiling processor. Take care to store it in "
|
||||
"a variable to prevent early destruction of the Region object. Not doing so may crash the application.\n"
|
||||
"\n"
|
||||
"The name specifies the variable under which the input can be used in the scripts."
|
||||
"\n"
|
||||
"This variant allows one to specify an additional transformation too. It has been introduced in version 0.23.2.\n"
|
||||
|
|
@ -435,6 +441,9 @@ Class<db::TilingProcessor> decl_TilingProcessor ("db", "TilingProcessor",
|
|||
"Edge collections don't always come with a database unit, hence a database unit should be specified with the \\dbu= method unless "
|
||||
"a layout object is specified as input too.\n"
|
||||
"\n"
|
||||
"Caution: the Edges object must stay valid during the lifetime of the tiling processor. Take care to store it in "
|
||||
"a variable to prevent early destruction of the Edges object. Not doing so may crash the application.\n"
|
||||
"\n"
|
||||
"The name specifies the variable under which the input can be used in the scripts."
|
||||
) +
|
||||
method_ext ("input", &tp_input11, gsi::arg ("name"), gsi::arg ("edges"), gsi::arg ("trans"),
|
||||
|
|
@ -443,6 +452,9 @@ Class<db::TilingProcessor> decl_TilingProcessor ("db", "TilingProcessor",
|
|||
"Edge collections don't always come with a database unit, hence a database unit should be specified with the \\dbu= method unless "
|
||||
"a layout object is specified as input too.\n"
|
||||
"\n"
|
||||
"Caution: the Edges object must stay valid during the lifetime of the tiling processor. Take care to store it in "
|
||||
"a variable to prevent early destruction of the Edges object. Not doing so may crash the application.\n"
|
||||
"\n"
|
||||
"The name specifies the variable under which the input can be used in the scripts."
|
||||
"\n"
|
||||
"This variant allows one to specify an additional transformation too. It has been introduced in version 0.23.2.\n"
|
||||
|
|
@ -454,6 +466,9 @@ Class<db::TilingProcessor> decl_TilingProcessor ("db", "TilingProcessor",
|
|||
"Edge pair collections don't always come with a database unit, hence a database unit should be specified with the \\dbu= method unless "
|
||||
"a layout object is specified as input too.\n"
|
||||
"\n"
|
||||
"Caution: the EdgePairs object must stay valid during the lifetime of the tiling processor. Take care to store it in "
|
||||
"a variable to prevent early destruction of the EdgePairs object. Not doing so may crash the application.\n"
|
||||
"\n"
|
||||
"The name specifies the variable under which the input can be used in the scripts."
|
||||
"\n"
|
||||
"This variant has been introduced in version 0.27.\n"
|
||||
|
|
@ -464,6 +479,9 @@ Class<db::TilingProcessor> decl_TilingProcessor ("db", "TilingProcessor",
|
|||
"Edge pair collections don't always come with a database unit, hence a database unit should be specified with the \\dbu= method unless "
|
||||
"a layout object is specified as input too.\n"
|
||||
"\n"
|
||||
"Caution: the EdgePairs object must stay valid during the lifetime of the tiling processor. Take care to store it in "
|
||||
"a variable to prevent early destruction of the EdgePairs object. Not doing so may crash the application.\n"
|
||||
"\n"
|
||||
"The name specifies the variable under which the input can be used in the scripts."
|
||||
"\n"
|
||||
"This variant has been introduced in version 0.27.\n"
|
||||
|
|
@ -474,6 +492,9 @@ Class<db::TilingProcessor> decl_TilingProcessor ("db", "TilingProcessor",
|
|||
"Text collections don't always come with a database unit, hence a database unit should be specified with the \\dbu= method unless "
|
||||
"a layout object is specified as input too.\n"
|
||||
"\n"
|
||||
"Caution: the Texts object must stay valid during the lifetime of the tiling processor. Take care to store it in "
|
||||
"a variable to prevent early destruction of the Texts object. Not doing so may crash the application.\n"
|
||||
"\n"
|
||||
"The name specifies the variable under which the input can be used in the scripts."
|
||||
"\n"
|
||||
"This variant has been introduced in version 0.27.\n"
|
||||
|
|
@ -484,6 +505,9 @@ Class<db::TilingProcessor> decl_TilingProcessor ("db", "TilingProcessor",
|
|||
"Text collections don't always come with a database unit, hence a database unit should be specified with the \\dbu= method unless "
|
||||
"a layout object is specified as input too.\n"
|
||||
"\n"
|
||||
"Caution: the Texts object must stay valid during the lifetime of the tiling processor. Take care to store it in "
|
||||
"a variable to prevent early destruction of the Texts object. Not doing so may crash the application.\n"
|
||||
"\n"
|
||||
"The name specifies the variable under which the input can be used in the scripts."
|
||||
"\n"
|
||||
"This variant has been introduced in version 0.27.\n"
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ static size_t shapes_in_top (const db::Layout &layout, unsigned int layer)
|
|||
TEST(2_RefCounting)
|
||||
{
|
||||
db::DeepShapeStore store;
|
||||
store.set_keep_layouts (false);
|
||||
db::Layout layout;
|
||||
|
||||
unsigned int l1 = layout.insert_layer ();
|
||||
|
|
|
|||
|
|
@ -232,15 +232,15 @@ class DRCOpNode
|
|||
attr_accessor :description
|
||||
attr_accessor :engine
|
||||
|
||||
def initialize(engine, node = nil)
|
||||
@node = node
|
||||
def initialize(engine, &factory)
|
||||
@factory = factory
|
||||
self.engine = engine
|
||||
self.description = "Basic"
|
||||
end
|
||||
|
||||
def create_node(cache)
|
||||
n = cache[self.object_id]
|
||||
if !n
|
||||
if !n || n.destroyed?
|
||||
n = self.do_create_node(cache)
|
||||
cache[self.object_id] = n
|
||||
end
|
||||
|
|
@ -248,7 +248,7 @@ class DRCOpNode
|
|||
end
|
||||
|
||||
def do_create_node(cache)
|
||||
@node
|
||||
@factory.call
|
||||
end
|
||||
|
||||
def dump(indent)
|
||||
|
|
@ -362,8 +362,8 @@ CODE
|
|||
return self.inverted
|
||||
else
|
||||
# TODO: what if the expression isn't region?
|
||||
empty = RBA::CompoundRegionOperationNode::new_empty(RBA::CompoundRegionOperationNode::ResultType::Region)
|
||||
DRCOpNodeCase::new(@engine, [ self, DRCOpNode::new(@engine, empty), @engine.primary ])
|
||||
empty = DRCOpNode::new(@engine) { RBA::CompoundRegionOperationNode::new_empty(RBA::CompoundRegionOperationNode::ResultType::Region) }
|
||||
DRCOpNodeCase::new(@engine, [ self, empty, @engine.primary ])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -476,7 +476,7 @@ module DRC
|
|||
|
||||
layer.requires_region
|
||||
|
||||
res = DRCOpNode::new(self, RBA::CompoundRegionOperationNode::new_secondary(layer.data))
|
||||
res = DRCOpNode::new(self) { RBA::CompoundRegionOperationNode::new_secondary(layer.data) }
|
||||
res.description = "secondary"
|
||||
return res
|
||||
|
||||
|
|
@ -493,7 +493,7 @@ module DRC
|
|||
# is called on.
|
||||
|
||||
def primary
|
||||
res = DRCOpNode::new(self, RBA::CompoundRegionOperationNode::new_primary)
|
||||
res = DRCOpNode::new(self) { RBA::CompoundRegionOperationNode::new_primary }
|
||||
res.description = "primary"
|
||||
return res
|
||||
end
|
||||
|
|
@ -520,7 +520,7 @@ module DRC
|
|||
# @/code
|
||||
|
||||
def foreign
|
||||
res = DRCOpNode::new(self, RBA::CompoundRegionOperationNode::new_foreign)
|
||||
res = DRCOpNode::new(self) { RBA::CompoundRegionOperationNode::new_foreign }
|
||||
res.description = "foreign"
|
||||
return res
|
||||
end
|
||||
|
|
@ -1555,10 +1555,12 @@ CODE
|
|||
|
||||
def _make_node(arg)
|
||||
if arg.is_a?(DRCLayer)
|
||||
arg = DRCOpNode::new(self, RBA::CompoundRegionOperationNode::new_secondary(arg.data))
|
||||
arg.description = "secondary"
|
||||
node = DRCOpNode::new(self) { RBA::CompoundRegionOperationNode::new_secondary(arg.data) }
|
||||
node.description = "secondary"
|
||||
return node
|
||||
else
|
||||
return arg
|
||||
end
|
||||
arg
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ module DRC
|
|||
|
||||
cv = RBA::CellView::active
|
||||
|
||||
@time = Time::now
|
||||
@force_gc = ($drc_force_gc == true) # for testing, $drc_force_gc can be set to true
|
||||
@generator = ""
|
||||
@rdb_index = nil
|
||||
@l2ndb_index = nil
|
||||
|
|
@ -73,6 +75,11 @@ module DRC
|
|||
|
||||
end
|
||||
|
||||
# for testing
|
||||
def force_gc(f)
|
||||
@force_gc = f
|
||||
end
|
||||
|
||||
def both
|
||||
DRCBothEdges::new
|
||||
end
|
||||
|
|
@ -2137,7 +2144,10 @@ CODE
|
|||
t = RBA::Timer::new
|
||||
t.start
|
||||
self._process_events
|
||||
GC.start # force a garbage collection before the operation to free unused memory
|
||||
if @force_gc || Time::now - @time > 0.5
|
||||
GC.start # force a garbage collection before the operation to free unused memory
|
||||
@time = Time::now
|
||||
end
|
||||
res = yield
|
||||
t.stop
|
||||
|
||||
|
|
|
|||
|
|
@ -4250,11 +4250,13 @@ CODE
|
|||
tp.output("res", res)
|
||||
tp.input("input", self.data)
|
||||
tp.threads = (@engine.threads || 1)
|
||||
|
||||
if tile_boundary
|
||||
tp.input("boundary", tile_boundary.data)
|
||||
boundary = tile_boundary.data
|
||||
else
|
||||
tp.input("boundary", RBA::Region::new(self.data.bbox))
|
||||
boundary = RBA::Region::new(self.data.bbox)
|
||||
end
|
||||
tp.input("boundary", boundary)
|
||||
|
||||
tp.var("vmin", limits[0] || 0.0)
|
||||
tp.var("vmax", limits[1] || 1.0)
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ TEST(1)
|
|||
|
||||
lym::Macro drc;
|
||||
drc.set_text (tl::sprintf (
|
||||
"force_gc true\n"
|
||||
"source('%s', \"TOP\")\n"
|
||||
"target('%s', \"TOP\")\n"
|
||||
"l1 = input(1, 0)\n"
|
||||
|
|
@ -70,6 +71,7 @@ TEST(2)
|
|||
{
|
||||
lym::Macro drc;
|
||||
drc.set_text (
|
||||
"force_gc true\n"
|
||||
"dbu 0.001\n"
|
||||
"def compare(a, b, ex)\n"
|
||||
" a = a.to_s\n"
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@
|
|||
|
||||
static void run_test (tl::TestBase *_this, const std::string &number, bool deep)
|
||||
{
|
||||
std::string force_gc = "true";
|
||||
|
||||
std::string rs = tl::testdata ();
|
||||
rs += "/drc/drcGenericTests_" + number + ".drc";
|
||||
|
||||
|
|
@ -45,10 +47,11 @@ static void run_test (tl::TestBase *_this, const std::string &number, bool deep)
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = %s\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
"$drc_test_deep = %s\n"
|
||||
, input, output, deep ? "true" : "false")
|
||||
, force_gc, input, output, deep ? "true" : "false")
|
||||
);
|
||||
config.set_interpreter (lym::Macro::Ruby);
|
||||
EXPECT_EQ (config.run (), 0);
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ TEST(1)
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = nil\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
, output)
|
||||
|
|
@ -82,6 +83,7 @@ TEST(2)
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
, input, output)
|
||||
|
|
@ -122,6 +124,7 @@ TEST(3_Flat)
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
, input, output)
|
||||
|
|
@ -162,6 +165,7 @@ TEST(4_Hierarchical)
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
, input, output)
|
||||
|
|
@ -202,6 +206,7 @@ TEST(5_FlatAntenna)
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
, input, output)
|
||||
|
|
@ -242,6 +247,7 @@ TEST(5_FlatAntennaIncremental)
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
, input, output)
|
||||
|
|
@ -282,6 +288,7 @@ TEST(6_HierarchicalAntenna)
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
, input, output)
|
||||
|
|
@ -322,6 +329,7 @@ TEST(7_AntennaWithDiodes)
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
, input, output)
|
||||
|
|
@ -362,6 +370,7 @@ TEST(8_TextsAndPolygons)
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
, input, output)
|
||||
|
|
@ -427,6 +436,7 @@ TEST(9_NetlistExtraction)
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
"$drc_test_target_simplified = '%s'\n"
|
||||
|
|
@ -471,6 +481,7 @@ TEST(10_NetlistExtractionFlat)
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
"$drc_test_target_simplified = '%s'\n"
|
||||
|
|
@ -515,6 +526,7 @@ TEST(11_CustomDevices)
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
"$drc_test_target_simplified = '%s'\n"
|
||||
|
|
@ -555,6 +567,7 @@ TEST(12_NetlistJoinLabels)
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
"$drc_test_target_simplified = nil\n"
|
||||
|
|
@ -591,6 +604,7 @@ TEST(13a_KissingCorners)
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
, input, output)
|
||||
|
|
@ -634,6 +648,7 @@ TEST(13b_KissingCornersDeep)
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
, input, output)
|
||||
|
|
@ -681,6 +696,7 @@ TEST(14_SwitchingTargets)
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
"$drc_test_target2 = '%s'\n"
|
||||
|
|
@ -732,6 +748,7 @@ TEST(15_issue548)
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
, input, output)
|
||||
|
|
@ -773,6 +790,7 @@ TEST(16_issue570)
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
, input, output)
|
||||
|
|
@ -814,6 +832,7 @@ TEST(17_issue570)
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
, input, output)
|
||||
|
|
@ -854,6 +873,7 @@ TEST(18_forget)
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
, input, output)
|
||||
|
|
@ -894,6 +914,7 @@ TEST(19_shielding)
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
, input, output)
|
||||
|
|
@ -934,6 +955,7 @@ TEST(20_interact_with_count)
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
, input, output)
|
||||
|
|
@ -974,6 +996,7 @@ TEST(21_breaking)
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
, input, output)
|
||||
|
|
@ -1014,6 +1037,7 @@ TEST(22_opposite_filter)
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
, input, output)
|
||||
|
|
@ -1054,6 +1078,7 @@ TEST(23_rect_filter)
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
, input, output)
|
||||
|
|
@ -1094,6 +1119,7 @@ TEST(24_enclosing)
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
, input, output)
|
||||
|
|
@ -1119,6 +1145,8 @@ TEST(24_enclosing)
|
|||
|
||||
static void run_test (tl::TestBase *_this, const std::string &number, bool deep, bool oasis = false)
|
||||
{
|
||||
std::string force_gc = "true";
|
||||
|
||||
std::string rs = tl::testdata ();
|
||||
rs += "/drc/drcSimpleTests_" + number + ".drc";
|
||||
|
||||
|
|
@ -1134,10 +1162,11 @@ static void run_test (tl::TestBase *_this, const std::string &number, bool deep,
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = '%s'\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
"$drc_test_deep = %s\n"
|
||||
, input, output, deep ? "true" : "false")
|
||||
, force_gc, input, output, deep ? "true" : "false")
|
||||
);
|
||||
config.set_interpreter (lym::Macro::Ruby);
|
||||
EXPECT_EQ (config.run (), 0);
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
void runtest (tl::TestBase *_this, int mode)
|
||||
{
|
||||
std::string force_gc = "true";
|
||||
|
||||
std::string rs = tl::testdata ();
|
||||
rs += "/drc/drcSuiteTests.drc";
|
||||
|
||||
|
|
@ -44,10 +46,11 @@ void runtest (tl::TestBase *_this, int mode)
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = %s\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
"$drc_test_mode = %d\n"
|
||||
, input, output, mode)
|
||||
, force_gc, input, output, mode)
|
||||
);
|
||||
config.set_interpreter (lym::Macro::Ruby);
|
||||
EXPECT_EQ (config.run (), 0);
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ TEST(1)
|
|||
|
||||
lym::Macro lvs;
|
||||
lvs.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"\n"
|
||||
"source('%s', 'INVERTER')\n"
|
||||
"\n"
|
||||
"deep\n"
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ void run_test (tl::TestBase *_this, const std::string &suffix, const std::string
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$lvs_test_source = '%s'\n"
|
||||
"$lvs_test_target_lvsdb = '%s'\n"
|
||||
"$lvs_test_target_cir = '%s'\n"
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ void run_test (tl::TestBase *_this, const std::string &lvs_rs, const std::string
|
|||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$lvs_test_source = '%s'\n"
|
||||
"$lvs_test_target_lvsdb = '%s'\n"
|
||||
"$lvs_test_target_cir = '%s'\n"
|
||||
|
|
@ -141,7 +142,7 @@ TEST(16_private)
|
|||
TEST(17_private)
|
||||
{
|
||||
test_is_long_runner ();
|
||||
run_test (_this, "test_17.lylvs", "test_17b.cir.gz", "test_17.gds.gz", true, "test_17b_2.lvsdb");
|
||||
run_test (_this, "test_17.lylvs", "test_17b.cir.gz", "test_17.gds.gz", true, "test_17b_3.lvsdb");
|
||||
}
|
||||
|
||||
TEST(18_private)
|
||||
|
|
@ -159,7 +160,7 @@ TEST(19_private)
|
|||
TEST(20_private)
|
||||
{
|
||||
// test_is_long_runner ();
|
||||
run_test (_this, "test_20.lylvs", "test_20.cir.gz", "test_20.gds.gz", true, "test_20b_2.lvsdb");
|
||||
run_test (_this, "test_20.lylvs", "test_20.cir.gz", "test_20.gds.gz", true, "test_20b_3.lvsdb");
|
||||
}
|
||||
|
||||
TEST(21_private)
|
||||
|
|
|
|||
|
|
@ -1001,6 +1001,10 @@ method_adaptor (int mid, int argc, VALUE *argv, VALUE self, bool ctor)
|
|||
const gsi::ClassBase *cls_decl;
|
||||
Proxy *p = 0;
|
||||
|
||||
// this prevents side effects of callbacks raised from within the called functions -
|
||||
// if these trigger the GC, self is protected from destruction herein.
|
||||
GCLocker gc_locker (self);
|
||||
|
||||
if (TYPE (self) == T_CLASS) {
|
||||
// we have a static method
|
||||
cls_decl = find_cclass (self);
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ public:
|
|||
void mark_this ();
|
||||
|
||||
private:
|
||||
std::set<VALUE> m_objects;
|
||||
std::map<VALUE, size_t> m_objects;
|
||||
|
||||
static VALUE m_klass;
|
||||
static VALUE m_instance;
|
||||
|
|
@ -84,20 +84,31 @@ LockedObjectVault::~LockedObjectVault ()
|
|||
void
|
||||
LockedObjectVault::add (VALUE object)
|
||||
{
|
||||
m_objects.insert (object);
|
||||
auto i = m_objects.find (object);
|
||||
if (i != m_objects.end ()) {
|
||||
i->second += 1;
|
||||
} else {
|
||||
m_objects.insert (std::make_pair (object, size_t (1)));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LockedObjectVault::remove (VALUE object)
|
||||
{
|
||||
m_objects.erase (object);
|
||||
auto i = m_objects.find (object);
|
||||
if (i != m_objects.end ()) {
|
||||
i->second -= 1;
|
||||
if (i->second == 0) {
|
||||
m_objects.erase (i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LockedObjectVault::mark_this ()
|
||||
{
|
||||
for (std::set<VALUE>::iterator o = m_objects.begin (); o != m_objects.end (); ++o) {
|
||||
rb_gc_mark (*o);
|
||||
for (auto o = m_objects.begin (); o != m_objects.end (); ++o) {
|
||||
rb_gc_mark (o->first);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -158,90 +169,6 @@ gc_unlock_object (VALUE value)
|
|||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief A final finalizer
|
||||
* Final destruction of finalized objects is delegated to this class.
|
||||
* It's main purpose is to temporarily disable C++ destruction while
|
||||
* in a callback. Deleting C++ objects in a callback leads to unpredictable
|
||||
* side effects and must be avoided.
|
||||
*/
|
||||
class InternalGC
|
||||
{
|
||||
public:
|
||||
InternalGC ()
|
||||
: m_enabled (true)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables or disables the GC
|
||||
* Returns the previous state
|
||||
*/
|
||||
bool enable (bool e)
|
||||
{
|
||||
std::swap (e, m_enabled);
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Queues (if disabled) or deletes the given object (plus all queued ones) if enabled
|
||||
*/
|
||||
void destroy_maybe (const gsi::ClassBase *cls, void *obj)
|
||||
{
|
||||
if (! m_enabled) {
|
||||
m_queue.push_back (std::make_pair (cls, obj));
|
||||
} else {
|
||||
m_queue.clear ();
|
||||
cls->destroy (obj);
|
||||
for (std::vector<std::pair<const gsi::ClassBase *, void *> >::const_iterator q = m_queue.begin (); q != m_queue.end (); ++q) {
|
||||
q->first->destroy (q->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::pair<const gsi::ClassBase *, void *> > m_queue;
|
||||
bool m_enabled;
|
||||
};
|
||||
|
||||
static InternalGC s_gc;
|
||||
|
||||
/**
|
||||
* @brief Destroys the object through the internal GC
|
||||
*/
|
||||
inline void destroy_object (const gsi::ClassBase *cls, void *obj)
|
||||
{
|
||||
s_gc.destroy_maybe (cls, obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief A GC disabler
|
||||
* By instantiating this object, the gc is disabled while the object is alive.
|
||||
* Specifically in callbacks it's important to disable the GC to avoid undesired
|
||||
* side effects.
|
||||
*/
|
||||
class GCDisabler
|
||||
{
|
||||
public:
|
||||
GCDisabler (InternalGC *gc = 0)
|
||||
: mp_gc (gc ? gc : &s_gc)
|
||||
{
|
||||
m_was_enabled = mp_gc->enable (false);
|
||||
}
|
||||
|
||||
~GCDisabler()
|
||||
{
|
||||
mp_gc->enable (m_was_enabled);
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_was_enabled;
|
||||
InternalGC *mp_gc;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Proxy implementation
|
||||
|
||||
|
|
@ -309,8 +236,6 @@ bool Proxy::can_call () const
|
|||
void
|
||||
Proxy::call (int id, gsi::SerialArgs &args, gsi::SerialArgs &ret) const
|
||||
{
|
||||
GCDisabler gc_disabler;
|
||||
|
||||
tl_assert (id < int (m_cbfuncs.size ()) && id >= 0);
|
||||
|
||||
const gsi::MethodBase *meth = m_cbfuncs [id].method;
|
||||
|
|
@ -635,7 +560,7 @@ Proxy::set (void *obj, bool owned, bool const_ref, bool can_destroy, VALUE self)
|
|||
// Destroy the object if we are owner. We don't destroy the object if it was locked
|
||||
// (either because we are not owner or from C++ side using keep())
|
||||
if (prev_owned) {
|
||||
destroy_object (cls, prev_obj);
|
||||
cls->destroy (prev_obj);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -891,8 +816,6 @@ SignalHandler::define_class (VALUE module, const char *name)
|
|||
|
||||
void SignalHandler::call (const gsi::MethodBase *meth, gsi::SerialArgs &args, gsi::SerialArgs &ret) const
|
||||
{
|
||||
GCDisabler gc_disabler;
|
||||
|
||||
VALUE argv = rb_ary_new2 (long (std::distance (meth->begin_arguments (), meth->end_arguments ())));
|
||||
RB_GC_GUARD (argv);
|
||||
|
||||
|
|
|
|||
|
|
@ -251,6 +251,31 @@ void gc_lock_object (VALUE value);
|
|||
*/
|
||||
void gc_unlock_object (VALUE value);
|
||||
|
||||
/**
|
||||
* @brief A Locker for the object based on the RIIA pattern
|
||||
*/
|
||||
class GCLocker
|
||||
{
|
||||
public:
|
||||
GCLocker (VALUE value)
|
||||
: m_value (value)
|
||||
{
|
||||
gc_lock_object (m_value);
|
||||
}
|
||||
|
||||
~GCLocker ()
|
||||
{
|
||||
gc_unlock_object (m_value);
|
||||
}
|
||||
|
||||
private:
|
||||
GCLocker ();
|
||||
GCLocker (const GCLocker &other);
|
||||
GCLocker &operator= (const GCLocker &other);
|
||||
|
||||
VALUE m_value;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Makes the locked object vault required for gc_lock_object and gc_unlock_object
|
||||
*
|
||||
|
|
|
|||
|
|
@ -31,11 +31,11 @@ layout(
|
|||
layer(l25)
|
||||
layer(l26)
|
||||
layer(l27)
|
||||
layer(l1)
|
||||
layer(l22)
|
||||
layer(l2)
|
||||
layer(l4)
|
||||
layer(l6)
|
||||
layer(l22)
|
||||
layer(l1)
|
||||
|
||||
# Mask layer connectivity
|
||||
connect(l5 l5 l4)
|
||||
|
|
@ -54,21 +54,21 @@ layout(
|
|||
connect(l17 l18 l17 l26 l27)
|
||||
connect(l20 l20 l19)
|
||||
connect(l19 l20 l19 l27)
|
||||
connect(l21 l9 l21 l2 l22)
|
||||
connect(l21 l9 l21 l22 l2)
|
||||
connect(l23 l9 l11 l23)
|
||||
connect(l24 l11 l13 l24)
|
||||
connect(l25 l13 l15 l25)
|
||||
connect(l26 l15 l17 l26)
|
||||
connect(l27 l17 l19 l27)
|
||||
connect(l1 l1)
|
||||
connect(l22 l21 l22)
|
||||
connect(l2 l3 l21 l2 l4 l6)
|
||||
connect(l4 l5 l2 l4)
|
||||
connect(l6 l2 l6)
|
||||
connect(l22 l21 l22)
|
||||
connect(l1 l1)
|
||||
|
||||
# Global nets and connectivity
|
||||
global(l1 vss)
|
||||
global(l6 vss)
|
||||
global(l1 vss)
|
||||
|
||||
# Device class section
|
||||
class(active_res RES)
|
||||
|
|
@ -193,22 +193,22 @@ layout(
|
|||
rect(l21 (-170 80) (170 170))
|
||||
rect(l21 (-170 1070) (170 170))
|
||||
rect(l21 (-5 -1010) (170 170))
|
||||
polygon(l2 (-465 -1120) (0 340) (-105 0) (0 420) (525 0) (0 -760))
|
||||
rect(l2 (-525 1670) (445 420))
|
||||
rect(l22 (-125 -1190) (330 270))
|
||||
rect(l22 (-250 -220) (330 270))
|
||||
rect(l22 (950 -960) (150 2010))
|
||||
rect(l22 (-1100 -1320) (950 150))
|
||||
polygon(l2 (-1495 -1050) (0 340) (-105 0) (0 420) (525 0) (0 -760))
|
||||
rect(l2 (-525 1670) (445 420))
|
||||
)
|
||||
net(4
|
||||
polygon(l9 (1485 760) (0 840) (-245 0) (0 170) (245 0) (0 560) (170 0) (0 -1570))
|
||||
rect(l21 (-170 80) (170 170))
|
||||
rect(l21 (-170 1070) (170 170))
|
||||
rect(l21 (-335 -650) (170 170))
|
||||
polygon(l2 (-125 -1480) (0 760) (525 0) (0 -420) (-105 0) (0 -340))
|
||||
rect(l2 (-340 1670) (445 420))
|
||||
rect(l22 (-650 -830) (330 270))
|
||||
rect(l22 (-250 -220) (330 270))
|
||||
rect(l22 (-1280 -150) (950 150))
|
||||
rect(l22 (-1100 -1320) (150 2010))
|
||||
polygon(l2 (1075 -2220) (0 760) (525 0) (0 -420) (-105 0) (0 -340))
|
||||
rect(l2 (-340 1670) (445 420))
|
||||
)
|
||||
net(5 name(vdd)
|
||||
rect(l5 (-385 1780) (2950 1300))
|
||||
|
|
|
|||
|
|
@ -31,11 +31,11 @@ layout(
|
|||
layer(l25)
|
||||
layer(l26)
|
||||
layer(l27)
|
||||
layer(l1)
|
||||
layer(l22)
|
||||
layer(l2)
|
||||
layer(l4)
|
||||
layer(l6)
|
||||
layer(l22)
|
||||
layer(l1)
|
||||
|
||||
# Mask layer connectivity
|
||||
connect(l5 l5 l4)
|
||||
|
|
@ -54,21 +54,21 @@ layout(
|
|||
connect(l17 l18 l17 l26 l27)
|
||||
connect(l20 l20 l19)
|
||||
connect(l19 l20 l19 l27)
|
||||
connect(l21 l9 l21 l2 l22)
|
||||
connect(l21 l9 l21 l22 l2)
|
||||
connect(l23 l9 l11 l23)
|
||||
connect(l24 l11 l13 l24)
|
||||
connect(l25 l13 l15 l25)
|
||||
connect(l26 l15 l17 l26)
|
||||
connect(l27 l17 l19 l27)
|
||||
connect(l1 l1)
|
||||
connect(l22 l21 l22)
|
||||
connect(l2 l3 l21 l2 l4 l6)
|
||||
connect(l4 l5 l2 l4)
|
||||
connect(l6 l2 l6)
|
||||
connect(l22 l21 l22)
|
||||
connect(l1 l1)
|
||||
|
||||
# Global nets and connectivity
|
||||
global(l1 vss)
|
||||
global(l6 vss)
|
||||
global(l1 vss)
|
||||
|
||||
# Device class section
|
||||
class(active_res RES)
|
||||
|
|
@ -193,22 +193,22 @@ layout(
|
|||
rect(l21 (-170 80) (170 170))
|
||||
rect(l21 (-170 1070) (170 170))
|
||||
rect(l21 (-5 -1010) (170 170))
|
||||
polygon(l2 (-465 -1120) (0 340) (-105 0) (0 420) (525 0) (0 -760))
|
||||
rect(l2 (-525 1670) (445 420))
|
||||
rect(l22 (-125 -1190) (330 270))
|
||||
rect(l22 (-250 -220) (330 270))
|
||||
rect(l22 (950 -960) (150 2010))
|
||||
rect(l22 (-1100 -1320) (950 150))
|
||||
polygon(l2 (-1495 -1050) (0 340) (-105 0) (0 420) (525 0) (0 -760))
|
||||
rect(l2 (-525 1670) (445 420))
|
||||
)
|
||||
net(4
|
||||
polygon(l9 (1485 760) (0 840) (-245 0) (0 170) (245 0) (0 560) (170 0) (0 -1570))
|
||||
rect(l21 (-170 80) (170 170))
|
||||
rect(l21 (-170 1070) (170 170))
|
||||
rect(l21 (-335 -650) (170 170))
|
||||
polygon(l2 (-125 -1480) (0 760) (525 0) (0 -420) (-105 0) (0 -340))
|
||||
rect(l2 (-340 1670) (445 420))
|
||||
rect(l22 (-650 -830) (330 270))
|
||||
rect(l22 (-250 -220) (330 270))
|
||||
rect(l22 (-1280 -150) (950 150))
|
||||
rect(l22 (-1100 -1320) (150 2010))
|
||||
polygon(l2 (1075 -2220) (0 760) (525 0) (0 -420) (-105 0) (0 -340))
|
||||
rect(l2 (-340 1670) (445 420))
|
||||
)
|
||||
net(5 name(vdd)
|
||||
rect(l5 (-385 1780) (2950 1300))
|
||||
|
|
|
|||
|
|
@ -31,11 +31,11 @@ layout(
|
|||
layer(l25)
|
||||
layer(l26)
|
||||
layer(l27)
|
||||
layer(l1)
|
||||
layer(l22)
|
||||
layer(l2)
|
||||
layer(l4)
|
||||
layer(l6)
|
||||
layer(l22)
|
||||
layer(l1)
|
||||
|
||||
# Mask layer connectivity
|
||||
connect(l5 l5 l4)
|
||||
|
|
@ -54,21 +54,21 @@ layout(
|
|||
connect(l17 l18 l17 l26 l27)
|
||||
connect(l20 l20 l19)
|
||||
connect(l19 l20 l19 l27)
|
||||
connect(l21 l9 l21 l2 l22)
|
||||
connect(l21 l9 l21 l22 l2)
|
||||
connect(l23 l9 l11 l23)
|
||||
connect(l24 l11 l13 l24)
|
||||
connect(l25 l13 l15 l25)
|
||||
connect(l26 l15 l17 l26)
|
||||
connect(l27 l17 l19 l27)
|
||||
connect(l1 l1)
|
||||
connect(l22 l21 l22)
|
||||
connect(l2 l3 l21 l2 l4 l6)
|
||||
connect(l4 l5 l2 l4)
|
||||
connect(l6 l2 l6)
|
||||
connect(l22 l21 l22)
|
||||
connect(l1 l1)
|
||||
|
||||
# Global nets and connectivity
|
||||
global(l1 vss)
|
||||
global(l6 vss)
|
||||
global(l1 vss)
|
||||
|
||||
# Device class section
|
||||
class(active_res RES)
|
||||
|
|
@ -193,22 +193,22 @@ layout(
|
|||
rect(l21 (-170 80) (170 170))
|
||||
rect(l21 (-170 1070) (170 170))
|
||||
rect(l21 (-5 -1010) (170 170))
|
||||
polygon(l2 (-465 -1120) (0 340) (-105 0) (0 420) (525 0) (0 -760))
|
||||
rect(l2 (-525 1670) (445 420))
|
||||
rect(l22 (-125 -1190) (330 270))
|
||||
rect(l22 (-250 -220) (330 270))
|
||||
rect(l22 (950 -960) (150 2010))
|
||||
rect(l22 (-1100 -1320) (950 150))
|
||||
polygon(l2 (-1495 -1050) (0 340) (-105 0) (0 420) (525 0) (0 -760))
|
||||
rect(l2 (-525 1670) (445 420))
|
||||
)
|
||||
net(4
|
||||
polygon(l9 (1485 760) (0 840) (-245 0) (0 170) (245 0) (0 560) (170 0) (0 -1570))
|
||||
rect(l21 (-170 80) (170 170))
|
||||
rect(l21 (-170 1070) (170 170))
|
||||
rect(l21 (-335 -650) (170 170))
|
||||
polygon(l2 (-125 -1480) (0 760) (525 0) (0 -420) (-105 0) (0 -340))
|
||||
rect(l2 (-340 1670) (445 420))
|
||||
rect(l22 (-650 -830) (330 270))
|
||||
rect(l22 (-250 -220) (330 270))
|
||||
rect(l22 (-1280 -150) (950 150))
|
||||
rect(l22 (-1100 -1320) (150 2010))
|
||||
polygon(l2 (1075 -2220) (0 760) (525 0) (0 -420) (-105 0) (0 -340))
|
||||
rect(l2 (-340 1670) (445 420))
|
||||
)
|
||||
net(5 name(vdd)
|
||||
rect(l5 (-385 1780) (2950 1300))
|
||||
|
|
|
|||
|
|
@ -31,11 +31,11 @@ layout(
|
|||
layer(l25)
|
||||
layer(l26)
|
||||
layer(l27)
|
||||
layer(l1)
|
||||
layer(l22)
|
||||
layer(l2)
|
||||
layer(l4)
|
||||
layer(l6)
|
||||
layer(l22)
|
||||
layer(l1)
|
||||
|
||||
# Mask layer connectivity
|
||||
connect(l5 l5 l4)
|
||||
|
|
@ -54,21 +54,21 @@ layout(
|
|||
connect(l17 l18 l17 l26 l27)
|
||||
connect(l20 l20 l19)
|
||||
connect(l19 l20 l19 l27)
|
||||
connect(l21 l9 l21 l2 l22)
|
||||
connect(l21 l9 l21 l22 l2)
|
||||
connect(l23 l9 l11 l23)
|
||||
connect(l24 l11 l13 l24)
|
||||
connect(l25 l13 l15 l25)
|
||||
connect(l26 l15 l17 l26)
|
||||
connect(l27 l17 l19 l27)
|
||||
connect(l1 l1)
|
||||
connect(l22 l21 l22)
|
||||
connect(l2 l3 l21 l2 l4 l6)
|
||||
connect(l4 l5 l2 l4)
|
||||
connect(l6 l2 l6)
|
||||
connect(l22 l21 l22)
|
||||
connect(l1 l1)
|
||||
|
||||
# Global nets and connectivity
|
||||
global(l1 vss)
|
||||
global(l6 vss)
|
||||
global(l1 vss)
|
||||
|
||||
# Device class section
|
||||
class(active_res RES)
|
||||
|
|
@ -193,22 +193,22 @@ layout(
|
|||
rect(l21 (-170 80) (170 170))
|
||||
rect(l21 (-170 1070) (170 170))
|
||||
rect(l21 (-5 -1010) (170 170))
|
||||
polygon(l2 (-465 -1120) (0 340) (-105 0) (0 420) (525 0) (0 -760))
|
||||
rect(l2 (-525 1670) (445 420))
|
||||
rect(l22 (-125 -1190) (330 270))
|
||||
rect(l22 (-250 -220) (330 270))
|
||||
rect(l22 (950 -960) (150 2010))
|
||||
rect(l22 (-1100 -1320) (950 150))
|
||||
polygon(l2 (-1495 -1050) (0 340) (-105 0) (0 420) (525 0) (0 -760))
|
||||
rect(l2 (-525 1670) (445 420))
|
||||
)
|
||||
net(4
|
||||
polygon(l9 (1485 760) (0 840) (-245 0) (0 170) (245 0) (0 560) (170 0) (0 -1570))
|
||||
rect(l21 (-170 80) (170 170))
|
||||
rect(l21 (-170 1070) (170 170))
|
||||
rect(l21 (-335 -650) (170 170))
|
||||
polygon(l2 (-125 -1480) (0 760) (525 0) (0 -420) (-105 0) (0 -340))
|
||||
rect(l2 (-340 1670) (445 420))
|
||||
rect(l22 (-650 -830) (330 270))
|
||||
rect(l22 (-250 -220) (330 270))
|
||||
rect(l22 (-1280 -150) (950 150))
|
||||
rect(l22 (-1100 -1320) (150 2010))
|
||||
polygon(l2 (1075 -2220) (0 760) (525 0) (0 -420) (-105 0) (0 -340))
|
||||
rect(l2 (-340 1670) (445 420))
|
||||
)
|
||||
net(5 name(vdd)
|
||||
rect(l5 (-385 1780) (2950 1300))
|
||||
|
|
|
|||
Loading…
Reference in New Issue