mirror of https://github.com/KLayout/klayout.git
Added Netlist#top_circuit and Netlist#top_circuits convenience methods
This commit is contained in:
parent
16abeb2bdc
commit
6baabc30bb
|
|
@ -366,6 +366,47 @@ size_t Netlist::top_circuit_count () const
|
||||||
return m_top_circuits;
|
return m_top_circuits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Circuit *Netlist::top_circuit ()
|
||||||
|
{
|
||||||
|
size_t ntop = top_circuit_count ();
|
||||||
|
if (ntop == 0) {
|
||||||
|
return 0;
|
||||||
|
} else if (ntop > 1) {
|
||||||
|
throw tl::Exception (tl::to_string (tr ("Netlist contains more than a single top circuit")));
|
||||||
|
} else {
|
||||||
|
return begin_top_down ().operator-> ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Circuit *Netlist::top_circuit () const
|
||||||
|
{
|
||||||
|
return const_cast<Netlist *> (this)->top_circuit ();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Circuit *> Netlist::top_circuits ()
|
||||||
|
{
|
||||||
|
size_t ntop = top_circuit_count ();
|
||||||
|
std::vector<Circuit *> result;
|
||||||
|
result.reserve (ntop);
|
||||||
|
for (auto c = begin_top_down (); ntop > 0 && c != end_top_down (); ++c) {
|
||||||
|
result.push_back (c.operator-> ());
|
||||||
|
--ntop;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<const Circuit *> Netlist::top_circuits () const
|
||||||
|
{
|
||||||
|
size_t ntop = top_circuit_count ();
|
||||||
|
std::vector<const Circuit *> result;
|
||||||
|
result.reserve (ntop);
|
||||||
|
for (auto c = begin_top_down (); ntop > 0 && c != end_top_down (); ++c) {
|
||||||
|
result.push_back (c.operator-> ());
|
||||||
|
--ntop;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
Netlist::bottom_up_circuit_iterator Netlist::begin_bottom_up ()
|
Netlist::bottom_up_circuit_iterator Netlist::begin_bottom_up ()
|
||||||
{
|
{
|
||||||
if (! m_valid_topology) {
|
if (! m_valid_topology) {
|
||||||
|
|
|
||||||
|
|
@ -271,6 +271,32 @@ public:
|
||||||
return m_circuit_by_cell_index.object_by (cell_index);
|
return m_circuit_by_cell_index.object_by (cell_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the top circuit if there is one
|
||||||
|
* This method will assert if there is more than a single top circuit.
|
||||||
|
* It will return 0 if there is no top circuit.
|
||||||
|
*/
|
||||||
|
Circuit *top_circuit ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the top circuit if there is one (const version)
|
||||||
|
* This method will assert if there is more than a single top circuit.
|
||||||
|
* It will return 0 if there is no top circuit.
|
||||||
|
*/
|
||||||
|
const Circuit *top_circuit () const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the top circuits
|
||||||
|
* This convenience method will return a list of top circuits.
|
||||||
|
*/
|
||||||
|
std::vector<Circuit *> top_circuits ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the top circuits (const version)
|
||||||
|
* This convenience method will return a list of top circuits.
|
||||||
|
*/
|
||||||
|
std::vector<const Circuit *> top_circuits () const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the top-down circuits iterator (begin)
|
* @brief Gets the top-down circuits iterator (begin)
|
||||||
* This iterator will deliver the circuits in a top-down way - i.e. child circuits
|
* This iterator will deliver the circuits in a top-down way - i.e. child circuits
|
||||||
|
|
|
||||||
|
|
@ -2044,6 +2044,32 @@ Class<db::Netlist> decl_dbNetlist ("db", "Netlist",
|
||||||
"\n"
|
"\n"
|
||||||
"This method has been introduced in version 0.28.4.\n"
|
"This method has been introduced in version 0.28.4.\n"
|
||||||
) +
|
) +
|
||||||
|
gsi::method ("top_circuit", static_cast<db::Circuit *(db::Netlist::*) ()> (&db::Netlist::top_circuit),
|
||||||
|
"@brief Gets the top circuit.\n"
|
||||||
|
"This method will return nil, if there is no top circuit. It will raise an error, if there is more than "
|
||||||
|
"a single top circuit.\n"
|
||||||
|
"\n"
|
||||||
|
"This convenience method has been added in version 0.29.5."
|
||||||
|
) +
|
||||||
|
gsi::method ("top_circuit", static_cast<const db::Circuit *(db::Netlist::*) () const> (&db::Netlist::top_circuit),
|
||||||
|
"@brief Gets the top circuit (const version).\n"
|
||||||
|
"This method will return nil, if there is no top circuit. It will raise an error, if there is more than "
|
||||||
|
"a single top circuit.\n"
|
||||||
|
"\n"
|
||||||
|
"This convenience method has been added in version 0.29.5."
|
||||||
|
) +
|
||||||
|
gsi::method ("top_circuits", static_cast<std::vector<db::Circuit *> (db::Netlist::*) ()> (&db::Netlist::top_circuits),
|
||||||
|
"@brief Gets the top circuits.\n"
|
||||||
|
"Returns a list of top circuits.\n"
|
||||||
|
"\n"
|
||||||
|
"This convenience method has been added in version 0.29.5."
|
||||||
|
) +
|
||||||
|
gsi::method ("top_circuits", static_cast<std::vector<const db::Circuit *> (db::Netlist::*) () const> (&db::Netlist::top_circuits),
|
||||||
|
"@brief Gets the top circuits.\n"
|
||||||
|
"Returns a list of top circuits.\n"
|
||||||
|
"\n"
|
||||||
|
"This convenience method has been added in version 0.29.5."
|
||||||
|
) +
|
||||||
gsi::method_ext ("nets_by_name", &nets_by_name_const_from_netlist, gsi::arg ("name_pattern"),
|
gsi::method_ext ("nets_by_name", &nets_by_name_const_from_netlist, gsi::arg ("name_pattern"),
|
||||||
"@brief Gets the net objects for a given name filter (const version).\n"
|
"@brief Gets the net objects for a given name filter (const version).\n"
|
||||||
"The name filter is a glob pattern. This method will return all \\Net objects matching the glob pattern.\n"
|
"The name filter is a glob pattern. This method will return all \\Net objects matching the glob pattern.\n"
|
||||||
|
|
|
||||||
|
|
@ -208,6 +208,18 @@ static std::string parents2string (const db::Circuit *c)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string td2string_nc (db::Netlist *nl)
|
||||||
|
{
|
||||||
|
std::string res;
|
||||||
|
for (db::Netlist::top_down_circuit_iterator r = nl->begin_top_down (); r != nl->end_top_down (); ++r) {
|
||||||
|
if (!res.empty ()) {
|
||||||
|
res += ",";
|
||||||
|
}
|
||||||
|
res += r->name ();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static std::string td2string (const db::Netlist *nl)
|
static std::string td2string (const db::Netlist *nl)
|
||||||
{
|
{
|
||||||
std::string res;
|
std::string res;
|
||||||
|
|
@ -220,6 +232,64 @@ static std::string td2string (const db::Netlist *nl)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string tcs2string_nc (db::Netlist *nl)
|
||||||
|
{
|
||||||
|
std::string res;
|
||||||
|
std::vector<db::Circuit *> tops = nl->top_circuits ();
|
||||||
|
for (auto i = tops.begin (); i != tops.end (); ++i) {
|
||||||
|
if (!res.empty ()) {
|
||||||
|
res += ",";
|
||||||
|
}
|
||||||
|
res += (*i)->name ();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string tcs2string (const db::Netlist *nl)
|
||||||
|
{
|
||||||
|
std::string res;
|
||||||
|
std::vector<const db::Circuit *> tops = nl->top_circuits ();
|
||||||
|
for (auto i = tops.begin (); i != tops.end (); ++i) {
|
||||||
|
if (!res.empty ()) {
|
||||||
|
res += ",";
|
||||||
|
}
|
||||||
|
res += (*i)->name ();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string tc2string_nc (db::Netlist *nl)
|
||||||
|
{
|
||||||
|
const db::Circuit *tc = nl->top_circuit ();
|
||||||
|
if (!tc) {
|
||||||
|
return "(nil)";
|
||||||
|
} else {
|
||||||
|
return tc->name ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string tc2string (const db::Netlist *nl)
|
||||||
|
{
|
||||||
|
const db::Circuit *tc = nl->top_circuit ();
|
||||||
|
if (!tc) {
|
||||||
|
return "(nil)";
|
||||||
|
} else {
|
||||||
|
return tc->name ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string bu2string_nc (db::Netlist *nl)
|
||||||
|
{
|
||||||
|
std::string res;
|
||||||
|
for (db::Netlist::bottom_up_circuit_iterator r = nl->begin_bottom_up (); r != nl->end_bottom_up (); ++r) {
|
||||||
|
if (!res.empty ()) {
|
||||||
|
res += ",";
|
||||||
|
}
|
||||||
|
res += r->name ();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static std::string bu2string (const db::Netlist *nl)
|
static std::string bu2string (const db::Netlist *nl)
|
||||||
{
|
{
|
||||||
std::string res;
|
std::string res;
|
||||||
|
|
@ -1038,20 +1108,44 @@ TEST(12_NetlistTopology)
|
||||||
{
|
{
|
||||||
std::unique_ptr<db::Netlist> nl (new db::Netlist ());
|
std::unique_ptr<db::Netlist> nl (new db::Netlist ());
|
||||||
EXPECT_EQ (nl->top_circuit_count (), size_t (0));
|
EXPECT_EQ (nl->top_circuit_count (), size_t (0));
|
||||||
|
EXPECT_EQ (tcs2string (nl.get ()), "");
|
||||||
|
EXPECT_EQ (tcs2string_nc (nl.get ()), "");
|
||||||
|
EXPECT_EQ (tc2string (nl.get ()), "(nil)");
|
||||||
|
EXPECT_EQ (tc2string_nc (nl.get ()), "(nil)");
|
||||||
|
|
||||||
db::Circuit *c1 = new db::Circuit ();
|
db::Circuit *c1 = new db::Circuit ();
|
||||||
c1->set_name ("c1");
|
c1->set_name ("c1");
|
||||||
nl->add_circuit (c1);
|
nl->add_circuit (c1);
|
||||||
EXPECT_EQ (nl->top_circuit_count (), size_t (1));
|
EXPECT_EQ (nl->top_circuit_count (), size_t (1));
|
||||||
EXPECT_EQ (td2string (nl.get ()), "c1");
|
EXPECT_EQ (td2string (nl.get ()), "c1");
|
||||||
|
EXPECT_EQ (td2string_nc (nl.get ()), "c1");
|
||||||
|
EXPECT_EQ (tcs2string (nl.get ()), "c1");
|
||||||
|
EXPECT_EQ (tcs2string_nc (nl.get ()), "c1");
|
||||||
|
EXPECT_EQ (tc2string (nl.get ()), "c1");
|
||||||
|
EXPECT_EQ (tc2string_nc (nl.get ()), "c1");
|
||||||
EXPECT_EQ (bu2string (nl.get ()), "c1");
|
EXPECT_EQ (bu2string (nl.get ()), "c1");
|
||||||
|
EXPECT_EQ (bu2string_nc (nl.get ()), "c1");
|
||||||
|
|
||||||
db::Circuit *c2 = new db::Circuit ();
|
db::Circuit *c2 = new db::Circuit ();
|
||||||
c2->set_name ("c2");
|
c2->set_name ("c2");
|
||||||
nl->add_circuit (c2);
|
nl->add_circuit (c2);
|
||||||
EXPECT_EQ (nl->top_circuit_count (), size_t (2));
|
EXPECT_EQ (nl->top_circuit_count (), size_t (2));
|
||||||
EXPECT_EQ (td2string (nl.get ()), "c2,c1");
|
EXPECT_EQ (td2string (nl.get ()), "c2,c1");
|
||||||
|
EXPECT_EQ (td2string_nc (nl.get ()), "c2,c1");
|
||||||
|
EXPECT_EQ (tcs2string (nl.get ()), "c2,c1");
|
||||||
|
EXPECT_EQ (tcs2string_nc (nl.get ()), "c2,c1");
|
||||||
|
try {
|
||||||
|
tc2string (nl.get ());
|
||||||
|
EXPECT_EQ (true, false);
|
||||||
|
} catch (...) {
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
tc2string_nc (nl.get ());
|
||||||
|
EXPECT_EQ (true, false);
|
||||||
|
} catch (...) {
|
||||||
|
}
|
||||||
EXPECT_EQ (bu2string (nl.get ()), "c1,c2");
|
EXPECT_EQ (bu2string (nl.get ()), "c1,c2");
|
||||||
|
EXPECT_EQ (bu2string_nc (nl.get ()), "c1,c2");
|
||||||
|
|
||||||
std::unique_ptr<db::NetlistLocker> locker (new db::NetlistLocker (nl.get ()));
|
std::unique_ptr<db::NetlistLocker> locker (new db::NetlistLocker (nl.get ()));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -832,18 +832,25 @@ END
|
||||||
|
|
||||||
nl = RBA::Netlist::new
|
nl = RBA::Netlist::new
|
||||||
assert_equal(nl.top_circuit_count, 0)
|
assert_equal(nl.top_circuit_count, 0)
|
||||||
|
assert_equal(nl.top_circuit == nil, true)
|
||||||
|
|
||||||
c1 = RBA::Circuit::new
|
c1 = RBA::Circuit::new
|
||||||
c1.name = "C1"
|
c1.name = "C1"
|
||||||
c1.cell_index = 17
|
c1.cell_index = 17
|
||||||
nl.add(c1)
|
nl.add(c1)
|
||||||
assert_equal(nl.top_circuit_count, 1)
|
assert_equal(nl.top_circuit_count, 1)
|
||||||
|
assert_equal(nl.top_circuit.name, "C1")
|
||||||
|
|
||||||
c2 = RBA::Circuit::new
|
c2 = RBA::Circuit::new
|
||||||
c2.name = "C2"
|
c2.name = "C2"
|
||||||
c1.cell_index = 42
|
c1.cell_index = 42
|
||||||
nl.add(c2)
|
nl.add(c2)
|
||||||
assert_equal(nl.top_circuit_count, 2)
|
assert_equal(nl.top_circuit_count, 2)
|
||||||
|
begin
|
||||||
|
nl.top_circuit
|
||||||
|
assert_equal(true, false)
|
||||||
|
rescue
|
||||||
|
end
|
||||||
|
|
||||||
c3 = RBA::Circuit::new
|
c3 = RBA::Circuit::new
|
||||||
c3.name = "C3"
|
c3.name = "C3"
|
||||||
|
|
@ -854,6 +861,10 @@ END
|
||||||
nl.each_circuit_top_down { |c| names << c.name }
|
nl.each_circuit_top_down { |c| names << c.name }
|
||||||
assert_equal(names.join(","), "C3,C2,C1")
|
assert_equal(names.join(","), "C3,C2,C1")
|
||||||
|
|
||||||
|
names = []
|
||||||
|
nl.top_circuits.each { |c| names << c.name }
|
||||||
|
assert_equal(names.join(","), "C3,C2,C1")
|
||||||
|
|
||||||
names = []
|
names = []
|
||||||
nl.each_circuit_bottom_up { |c| names << c.name }
|
nl.each_circuit_bottom_up { |c| names << c.name }
|
||||||
assert_equal(names.join(","), "C1,C2,C3")
|
assert_equal(names.join(","), "C1,C2,C3")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue