mirror of https://github.com/KLayout/klayout.git
Fixed #807 - now supporting incremental connect and clear_connections in DRC/LVS
This commit is contained in:
parent
58afc47071
commit
1c8442f485
|
|
@ -246,11 +246,21 @@ void LayoutToNetlist::extract_devices (db::NetlistDeviceExtractor &extractor, co
|
||||||
extractor.extract (dss (), m_layout_index, layers, *mp_netlist, m_net_clusters, m_device_scaling);
|
extractor.extract (dss (), m_layout_index, layers, *mp_netlist, m_net_clusters, m_device_scaling);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LayoutToNetlist::connect (const db::Region &l)
|
void LayoutToNetlist::reset_extracted ()
|
||||||
{
|
{
|
||||||
if (m_netlist_extracted) {
|
if (m_netlist_extracted) {
|
||||||
throw tl::Exception (tl::to_string (tr ("The netlist has already been extracted")));
|
|
||||||
|
m_net_clusters.clear ();
|
||||||
|
mp_netlist.reset (0);
|
||||||
|
|
||||||
|
m_netlist_extracted = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayoutToNetlist::connect (const db::Region &l)
|
||||||
|
{
|
||||||
|
reset_extracted ();
|
||||||
|
|
||||||
if (! is_persisted (l)) {
|
if (! is_persisted (l)) {
|
||||||
register_layer (l, make_new_name ());
|
register_layer (l, make_new_name ());
|
||||||
|
|
@ -265,9 +275,8 @@ void LayoutToNetlist::connect (const db::Region &l)
|
||||||
|
|
||||||
void LayoutToNetlist::connect_impl (const db::ShapeCollection &a, const db::ShapeCollection &b)
|
void LayoutToNetlist::connect_impl (const db::ShapeCollection &a, const db::ShapeCollection &b)
|
||||||
{
|
{
|
||||||
if (m_netlist_extracted) {
|
reset_extracted ();
|
||||||
throw tl::Exception (tl::to_string (tr ("The netlist has already been extracted")));
|
|
||||||
}
|
|
||||||
if (! is_persisted (a)) {
|
if (! is_persisted (a)) {
|
||||||
register_layer (a, make_new_name ());
|
register_layer (a, make_new_name ());
|
||||||
}
|
}
|
||||||
|
|
@ -286,9 +295,8 @@ void LayoutToNetlist::connect_impl (const db::ShapeCollection &a, const db::Shap
|
||||||
|
|
||||||
size_t LayoutToNetlist::connect_global_impl (const db::ShapeCollection &l, const std::string &gn)
|
size_t LayoutToNetlist::connect_global_impl (const db::ShapeCollection &l, const std::string &gn)
|
||||||
{
|
{
|
||||||
if (m_netlist_extracted) {
|
reset_extracted ();
|
||||||
throw tl::Exception (tl::to_string (tr ("The netlist has already been extracted")));
|
|
||||||
}
|
|
||||||
if (! is_persisted (l)) {
|
if (! is_persisted (l)) {
|
||||||
register_layer (l, make_new_name ());
|
register_layer (l, make_new_name ());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -359,6 +359,14 @@ public:
|
||||||
*/
|
*/
|
||||||
void extract_devices (db::NetlistDeviceExtractor &extractor, const std::map<std::string, db::ShapeCollection *> &layers);
|
void extract_devices (db::NetlistDeviceExtractor &extractor, const std::map<std::string, db::ShapeCollection *> &layers);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Resets the extracted netlist
|
||||||
|
*
|
||||||
|
* This method will invalidate the netlist and extraction. It is called automatically when
|
||||||
|
* cone of the connect methods is called.
|
||||||
|
*/
|
||||||
|
void reset_extracted ();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Defines an intra-layer connection for the given layer.
|
* @brief Defines an intra-layer connection for the given layer.
|
||||||
* The layer is either an original layer created with "make_layer" and it's variants or
|
* The layer is either an original layer created with "make_layer" and it's variants or
|
||||||
|
|
@ -532,6 +540,14 @@ public:
|
||||||
*/
|
*/
|
||||||
void set_netlist_extracted ();
|
void set_netlist_extracted ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets a value indicating whether the netlist has been extracted
|
||||||
|
*/
|
||||||
|
bool is_netlist_extracted () const
|
||||||
|
{
|
||||||
|
return m_netlist_extracted;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the internal DeepShapeStore object
|
* @brief Gets the internal DeepShapeStore object
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -394,6 +394,18 @@ Class<db::LayoutToNetlist> decl_dbLayoutToNetlist ("db", "LayoutToNetlist",
|
||||||
"\n"
|
"\n"
|
||||||
"If errors occur, the device extractor will contain theses errors.\n"
|
"If errors occur, the device extractor will contain theses errors.\n"
|
||||||
) +
|
) +
|
||||||
|
gsi::method ("reset_extracted", &db::LayoutToNetlist::reset_extracted,
|
||||||
|
"@brief Resets the extracted netlist and enables re-extraction\n"
|
||||||
|
"This method is implicitly called when using \\connect or \\connect_global after a netlist has been extracted.\n"
|
||||||
|
"This enables incremental connect with re-extraction.\n"
|
||||||
|
"\n"
|
||||||
|
"This method has been introduced in version 0.27.1.\n"
|
||||||
|
) +
|
||||||
|
gsi::method ("is_extracted?", &db::LayoutToNetlist::is_netlist_extracted,
|
||||||
|
"@brief Gets a value indicating whether the netlist has been extracted\n"
|
||||||
|
"\n"
|
||||||
|
"This method has been introduced in version 0.27.1.\n"
|
||||||
|
) +
|
||||||
gsi::method ("connect", (void (db::LayoutToNetlist::*) (const db::Region &)) &db::LayoutToNetlist::connect, gsi::arg ("l"),
|
gsi::method ("connect", (void (db::LayoutToNetlist::*) (const db::Region &)) &db::LayoutToNetlist::connect, gsi::arg ("l"),
|
||||||
"@brief Defines an intra-layer connection for the given layer.\n"
|
"@brief Defines an intra-layer connection for the given layer.\n"
|
||||||
"The layer is either an original layer created with \\make_incluidelayer and it's variants or\n"
|
"The layer is either an original layer created with \\make_incluidelayer and it's variants or\n"
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,6 @@ module DRC
|
||||||
|
|
||||||
def initialize(engine)
|
def initialize(engine)
|
||||||
@engine = engine
|
@engine = engine
|
||||||
@netlisted = false
|
|
||||||
@connect_implicit = []
|
@connect_implicit = []
|
||||||
@connect_implicit_per_cell = {}
|
@connect_implicit_per_cell = {}
|
||||||
@connect_explicit = []
|
@connect_explicit = []
|
||||||
|
|
@ -240,7 +239,6 @@ module DRC
|
||||||
# See \connect for more details.
|
# See \connect for more details.
|
||||||
|
|
||||||
def clear_connections
|
def clear_connections
|
||||||
@netlisted = false
|
|
||||||
@connect_implicit = []
|
@connect_implicit = []
|
||||||
@connect_implicit_per_cell = {}
|
@connect_implicit_per_cell = {}
|
||||||
@connect_explicit = []
|
@connect_explicit = []
|
||||||
|
|
@ -544,7 +542,7 @@ module DRC
|
||||||
ensure_data
|
ensure_data
|
||||||
|
|
||||||
# run extraction in a timed environment
|
# run extraction in a timed environment
|
||||||
if ! @netlisted
|
if ! @l2n.is_extracted?
|
||||||
|
|
||||||
# configure implicit net connections
|
# configure implicit net connections
|
||||||
@l2n.clear_join_net_names
|
@l2n.clear_join_net_names
|
||||||
|
|
@ -569,7 +567,6 @@ module DRC
|
||||||
end
|
end
|
||||||
|
|
||||||
@engine._cmd(@l2n, :extract_netlist)
|
@engine._cmd(@l2n, :extract_netlist)
|
||||||
@netlisted = true
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -609,13 +606,13 @@ module DRC
|
||||||
end
|
end
|
||||||
|
|
||||||
def _l2n_data
|
def _l2n_data
|
||||||
@netlisted && self.l2n_data
|
@l2n && @l2n.is_extracted? && self.l2n_data
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def cleanup
|
def cleanup
|
||||||
@netlisted && clear_connections
|
@l2n && @l2n.is_extracted? && clear_connections
|
||||||
end
|
end
|
||||||
|
|
||||||
def ensure_data
|
def ensure_data
|
||||||
|
|
@ -644,14 +641,13 @@ module DRC
|
||||||
def register_layer(data)
|
def register_layer(data)
|
||||||
|
|
||||||
id = data.data_id
|
id = data.data_id
|
||||||
|
ensure_data
|
||||||
|
|
||||||
if @layers && @layers[id]
|
if @layers && @layers[id]
|
||||||
# already registered
|
# already registered
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
ensure_data
|
|
||||||
|
|
||||||
@layers[id] = data
|
@layers[id] = data
|
||||||
@lnum += 1
|
@lnum += 1
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -225,6 +225,46 @@ TEST(5_FlatAntenna)
|
||||||
db::compare_layouts (_this, layout, au, db::NoNormalization);
|
db::compare_layouts (_this, layout, au, db::NoNormalization);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(5_FlatAntennaIncremental)
|
||||||
|
{
|
||||||
|
std::string rs = tl::testdata ();
|
||||||
|
rs += "/drc/drcSimpleTests_5i.drc";
|
||||||
|
|
||||||
|
std::string input = tl::testdata ();
|
||||||
|
input += "/drc/antenna_l1.gds";
|
||||||
|
|
||||||
|
std::string au = tl::testdata ();
|
||||||
|
au += "/drc/drcSimpleTests_au5.gds";
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(6_HierarchicalAntenna)
|
TEST(6_HierarchicalAntenna)
|
||||||
{
|
{
|
||||||
std::string rs = tl::testdata ();
|
std::string rs = tl::testdata ();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
# Hierarchical antenna check
|
# Flat antenna check
|
||||||
|
|
||||||
source($drc_test_source, "RINGO")
|
source($drc_test_source, "RINGO")
|
||||||
target($drc_test_target)
|
target($drc_test_target)
|
||||||
|
|
@ -14,6 +14,17 @@ metal2 = input(8, 0)
|
||||||
|
|
||||||
gate = diff & poly
|
gate = diff & poly
|
||||||
|
|
||||||
|
connect(gate, poly)
|
||||||
|
connect(poly, poly_cont)
|
||||||
|
connect(poly_cont, metal1)
|
||||||
|
|
||||||
|
antenna_check(gate, metal1, 1.0).output(201)
|
||||||
|
antenna_check(gate, metal1, 2.0).output(202)
|
||||||
|
antenna_check(gate, metal1, 3.0).output(203)
|
||||||
|
antenna_check(gate, metal1, 4.0).output(204)
|
||||||
|
|
||||||
|
clear_connections
|
||||||
|
|
||||||
connect(gate, poly)
|
connect(gate, poly)
|
||||||
connect(poly, poly_cont)
|
connect(poly, poly_cont)
|
||||||
connect(poly_cont, metal1)
|
connect(poly_cont, metal1)
|
||||||
|
|
@ -24,3 +35,4 @@ antenna_check(gate, metal2, 1.0).output(101)
|
||||||
antenna_check(gate, metal2, 5.0).output(105)
|
antenna_check(gate, metal2, 5.0).output(105)
|
||||||
antenna_check(gate, metal2, 10.0).output(110)
|
antenna_check(gate, metal2, 10.0).output(110)
|
||||||
antenna_check(gate, metal2, 50.0).output(150)
|
antenna_check(gate, metal2, 50.0).output(150)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
|
||||||
|
# Flat antenna check
|
||||||
|
|
||||||
|
source($drc_test_source, "RINGO")
|
||||||
|
target($drc_test_target)
|
||||||
|
|
||||||
|
diff = input(2, 0)
|
||||||
|
poly = input(3, 0)
|
||||||
|
contact = input(4, 0)
|
||||||
|
poly_cont = input(5, 0)
|
||||||
|
metal1 = input(6, 0)
|
||||||
|
via1 = input(7, 0)
|
||||||
|
metal2 = input(8, 0)
|
||||||
|
|
||||||
|
gate = diff & poly
|
||||||
|
|
||||||
|
connect(gate, poly)
|
||||||
|
connect(poly, poly_cont)
|
||||||
|
connect(poly_cont, metal1)
|
||||||
|
|
||||||
|
antenna_check(gate, metal1, 1.0).output(201)
|
||||||
|
antenna_check(gate, metal1, 2.0).output(202)
|
||||||
|
antenna_check(gate, metal1, 3.0).output(203)
|
||||||
|
antenna_check(gate, metal1, 4.0).output(204)
|
||||||
|
|
||||||
|
connect(metal1, via1)
|
||||||
|
connect(via1, metal2)
|
||||||
|
|
||||||
|
antenna_check(gate, metal2, 1.0).output(101)
|
||||||
|
antenna_check(gate, metal2, 5.0).output(105)
|
||||||
|
antenna_check(gate, metal2, 10.0).output(110)
|
||||||
|
antenna_check(gate, metal2, 50.0).output(150)
|
||||||
|
|
||||||
Binary file not shown.
|
|
@ -576,6 +576,54 @@ end;
|
||||||
self.assertEqual(str(a1_10.flatten() ^ pya.Region(ly_au.top_cell().begin_shapes_rec(ly_au.layer(101, 0)))), "")
|
self.assertEqual(str(a1_10.flatten() ^ pya.Region(ly_au.top_cell().begin_shapes_rec(ly_au.layer(101, 0)))), "")
|
||||||
self.assertEqual(str(a1_30.flatten() ^ pya.Region(ly_au.top_cell().begin_shapes_rec(ly_au.layer(102, 0)))), "")
|
self.assertEqual(str(a1_30.flatten() ^ pya.Region(ly_au.top_cell().begin_shapes_rec(ly_au.layer(102, 0)))), "")
|
||||||
|
|
||||||
|
# --- simple incremental antenna check with metal1 + metal2
|
||||||
|
|
||||||
|
l2n._destroy()
|
||||||
|
l2n = pya.LayoutToNetlist(dss)
|
||||||
|
|
||||||
|
l2n.register(rdiode, "diode")
|
||||||
|
l2n.register(rpoly, "poly")
|
||||||
|
l2n.register(rcont, "cont")
|
||||||
|
l2n.register(rmetal1, "metal1")
|
||||||
|
l2n.register(rvia1, "via1")
|
||||||
|
l2n.register(rmetal2, "metal2")
|
||||||
|
|
||||||
|
l2n.connect(rpoly)
|
||||||
|
l2n.connect(rcont)
|
||||||
|
l2n.connect(rmetal1)
|
||||||
|
l2n.connect(rmetal2)
|
||||||
|
l2n.connect(rpoly, rcont)
|
||||||
|
l2n.connect(rcont, rmetal1)
|
||||||
|
|
||||||
|
self.assertEqual(l2n.is_extracted(), False)
|
||||||
|
l2n.extract_netlist()
|
||||||
|
self.assertEqual(l2n.is_extracted(), True)
|
||||||
|
|
||||||
|
a1_3 = l2n.antenna_check(rpoly, rmetal1, 3)
|
||||||
|
a1_10 = l2n.antenna_check(rpoly, rmetal1, 10)
|
||||||
|
a1_30 = l2n.antenna_check(rpoly, rmetal1, 30)
|
||||||
|
|
||||||
|
# Note: flatten.merged performs some normalization
|
||||||
|
self.assertEqual(str(a1_3.flatten() ^ pya.Region(ly_au.top_cell().begin_shapes_rec(ly_au.layer(100, 0)))), "")
|
||||||
|
self.assertEqual(str(a1_10.flatten() ^ pya.Region(ly_au.top_cell().begin_shapes_rec(ly_au.layer(101, 0)))), "")
|
||||||
|
self.assertEqual(str(a1_30.flatten() ^ pya.Region(ly_au.top_cell().begin_shapes_rec(ly_au.layer(102, 0)))), "")
|
||||||
|
|
||||||
|
l2n.connect(rmetal1, rvia1)
|
||||||
|
l2n.connect(rvia1, rmetal2)
|
||||||
|
|
||||||
|
self.assertEqual(l2n.is_extracted(), False)
|
||||||
|
l2n.extract_netlist()
|
||||||
|
self.assertEqual(l2n.is_extracted(), True)
|
||||||
|
|
||||||
|
a2_5 = l2n.antenna_check(rpoly, rmetal2, 5)
|
||||||
|
a2_10 = l2n.antenna_check(rpoly, rmetal2, 10)
|
||||||
|
a2_17 = l2n.antenna_check(rpoly, rmetal2, 17)
|
||||||
|
|
||||||
|
# Note: flatten.merged performs some normalization
|
||||||
|
self.assertEqual(str(a2_5.flatten() ^ pya.Region(ly_au.top_cell().begin_shapes_rec(ly_au.layer(200, 0)))), "")
|
||||||
|
self.assertEqual(str(a2_10.flatten() ^ pya.Region(ly_au.top_cell().begin_shapes_rec(ly_au.layer(201, 0)))), "")
|
||||||
|
self.assertEqual(str(a2_17.flatten() ^ pya.Region(ly_au.top_cell().begin_shapes_rec(ly_au.layer(202, 0)))), "")
|
||||||
|
|
||||||
# --- simple antenna check with metal2
|
# --- simple antenna check with metal2
|
||||||
|
|
||||||
l2n._destroy()
|
l2n._destroy()
|
||||||
|
|
|
||||||
|
|
@ -170,7 +170,8 @@ class DBLayoutToNetlist_TestClass < TestBase
|
||||||
# Perform netlist extraction
|
# Perform netlist extraction
|
||||||
l2n.extract_netlist
|
l2n.extract_netlist
|
||||||
|
|
||||||
assert_equal(l2n.netlist.to_s, <<END)
|
nl_string = l2n.netlist.to_s
|
||||||
|
assert_equal(nl_string, <<END)
|
||||||
circuit TRANS ($1=$1,$2=$2);
|
circuit TRANS ($1=$1,$2=$2);
|
||||||
end;
|
end;
|
||||||
circuit INV2 (OUT=OUT,$2=$3,$3=$4);
|
circuit INV2 (OUT=OUT,$2=$3,$3=$4);
|
||||||
|
|
@ -218,6 +219,15 @@ END
|
||||||
assert_equal(r.to_s,
|
assert_equal(r.to_s,
|
||||||
"(-980,-420;-980,2420;-620,2420;-620,-420);(-800,820;-800,1180;580,1180;580,820);(-980,2420;-980,3180;-620,3180;-620,2420);(-980,-380;-980,380;-620,380;-620,-380)")
|
"(-980,-420;-980,2420;-620,2420;-620,-420);(-800,820;-800,1180;580,1180;580,820);(-980,2420;-980,3180;-620,3180;-620,2420);(-980,-380;-980,380;-620,380;-620,-380)")
|
||||||
|
|
||||||
|
assert_equal(l2n.is_extracted?, true)
|
||||||
|
l2n.reset_extracted
|
||||||
|
assert_equal(l2n.is_extracted?, false)
|
||||||
|
assert_equal(l2n.netlist.inspect, "nil")
|
||||||
|
|
||||||
|
l2n.extract_netlist
|
||||||
|
assert_equal(l2n.is_extracted?, true)
|
||||||
|
assert_equal(l2n.netlist.to_s, nl_string)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_10_LayoutToNetlistExtractionWithoutDevices
|
def test_10_LayoutToNetlistExtractionWithoutDevices
|
||||||
|
|
@ -755,6 +765,54 @@ END
|
||||||
assert_equal((a2_10.flatten ^ RBA::Region::new(ly_au.top_cell.begin_shapes_rec(ly_au.layer(201, 0)))).to_s, "")
|
assert_equal((a2_10.flatten ^ RBA::Region::new(ly_au.top_cell.begin_shapes_rec(ly_au.layer(201, 0)))).to_s, "")
|
||||||
assert_equal((a2_17.flatten ^ RBA::Region::new(ly_au.top_cell.begin_shapes_rec(ly_au.layer(202, 0)))).to_s, "")
|
assert_equal((a2_17.flatten ^ RBA::Region::new(ly_au.top_cell.begin_shapes_rec(ly_au.layer(202, 0)))).to_s, "")
|
||||||
|
|
||||||
|
# --- simple incremental antenna check with metal1 + metal2
|
||||||
|
|
||||||
|
l2n._destroy
|
||||||
|
l2n = RBA::LayoutToNetlist::new(dss)
|
||||||
|
|
||||||
|
l2n.register(rdiode, "diode")
|
||||||
|
l2n.register(rpoly, "poly")
|
||||||
|
l2n.register(rcont, "cont")
|
||||||
|
l2n.register(rmetal1, "metal1")
|
||||||
|
l2n.register(rvia1, "via1")
|
||||||
|
l2n.register(rmetal2, "metal2")
|
||||||
|
|
||||||
|
l2n.connect(rpoly)
|
||||||
|
l2n.connect(rcont)
|
||||||
|
l2n.connect(rmetal1)
|
||||||
|
l2n.connect(rmetal2)
|
||||||
|
l2n.connect(rpoly, rcont)
|
||||||
|
l2n.connect(rcont, rmetal1)
|
||||||
|
|
||||||
|
assert_equal(l2n.is_extracted?, false)
|
||||||
|
l2n.extract_netlist
|
||||||
|
assert_equal(l2n.is_extracted?, true)
|
||||||
|
|
||||||
|
a1_3 = l2n.antenna_check(rpoly, rmetal1, 3)
|
||||||
|
a1_10 = l2n.antenna_check(rpoly, rmetal1, 10)
|
||||||
|
a1_30 = l2n.antenna_check(rpoly, rmetal1, 30)
|
||||||
|
|
||||||
|
# Note: flatten.merged performs some normalization
|
||||||
|
assert_equal((a1_3.flatten ^ RBA::Region::new(ly_au.top_cell.begin_shapes_rec(ly_au.layer(100, 0)))).to_s, "")
|
||||||
|
assert_equal((a1_10.flatten ^ RBA::Region::new(ly_au.top_cell.begin_shapes_rec(ly_au.layer(101, 0)))).to_s, "")
|
||||||
|
assert_equal((a1_30.flatten ^ RBA::Region::new(ly_au.top_cell.begin_shapes_rec(ly_au.layer(102, 0)))).to_s, "")
|
||||||
|
|
||||||
|
l2n.connect(rmetal1, rvia1)
|
||||||
|
l2n.connect(rvia1, rmetal2)
|
||||||
|
|
||||||
|
assert_equal(l2n.is_extracted?, false)
|
||||||
|
l2n.extract_netlist
|
||||||
|
assert_equal(l2n.is_extracted?, true)
|
||||||
|
|
||||||
|
a2_5 = l2n.antenna_check(rpoly, rmetal2, 5)
|
||||||
|
a2_10 = l2n.antenna_check(rpoly, rmetal2, 10)
|
||||||
|
a2_17 = l2n.antenna_check(rpoly, rmetal2, 17)
|
||||||
|
|
||||||
|
# Note: flatten.merged performs some normalization
|
||||||
|
assert_equal((a2_5.flatten ^ RBA::Region::new(ly_au.top_cell.begin_shapes_rec(ly_au.layer(200, 0)))).to_s, "")
|
||||||
|
assert_equal((a2_10.flatten ^ RBA::Region::new(ly_au.top_cell.begin_shapes_rec(ly_au.layer(201, 0)))).to_s, "")
|
||||||
|
assert_equal((a2_17.flatten ^ RBA::Region::new(ly_au.top_cell.begin_shapes_rec(ly_au.layer(202, 0)))).to_s, "")
|
||||||
|
|
||||||
# --- antenna check with diodes and antenna effect reduction
|
# --- antenna check with diodes and antenna effect reduction
|
||||||
|
|
||||||
l2n._destroy
|
l2n._destroy
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue