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;
|
||||
}
|
||||
|
||||
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 ()
|
||||
{
|
||||
if (! m_valid_topology) {
|
||||
|
|
|
|||
|
|
@ -271,6 +271,32 @@ public:
|
|||
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)
|
||||
* 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"
|
||||
"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"),
|
||||
"@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"
|
||||
|
|
|
|||
|
|
@ -208,6 +208,18 @@ static std::string parents2string (const db::Circuit *c)
|
|||
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)
|
||||
{
|
||||
std::string res;
|
||||
|
|
@ -220,6 +232,64 @@ static std::string td2string (const db::Netlist *nl)
|
|||
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)
|
||||
{
|
||||
std::string res;
|
||||
|
|
@ -1038,20 +1108,44 @@ TEST(12_NetlistTopology)
|
|||
{
|
||||
std::unique_ptr<db::Netlist> nl (new db::Netlist ());
|
||||
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 ();
|
||||
c1->set_name ("c1");
|
||||
nl->add_circuit (c1);
|
||||
EXPECT_EQ (nl->top_circuit_count (), size_t (1));
|
||||
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_nc (nl.get ()), "c1");
|
||||
|
||||
db::Circuit *c2 = new db::Circuit ();
|
||||
c2->set_name ("c2");
|
||||
nl->add_circuit (c2);
|
||||
EXPECT_EQ (nl->top_circuit_count (), size_t (2));
|
||||
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_nc (nl.get ()), "c1,c2");
|
||||
|
||||
std::unique_ptr<db::NetlistLocker> locker (new db::NetlistLocker (nl.get ()));
|
||||
|
||||
|
|
|
|||
|
|
@ -832,18 +832,25 @@ END
|
|||
|
||||
nl = RBA::Netlist::new
|
||||
assert_equal(nl.top_circuit_count, 0)
|
||||
assert_equal(nl.top_circuit == nil, true)
|
||||
|
||||
c1 = RBA::Circuit::new
|
||||
c1.name = "C1"
|
||||
c1.cell_index = 17
|
||||
nl.add(c1)
|
||||
assert_equal(nl.top_circuit_count, 1)
|
||||
assert_equal(nl.top_circuit.name, "C1")
|
||||
|
||||
c2 = RBA::Circuit::new
|
||||
c2.name = "C2"
|
||||
c1.cell_index = 42
|
||||
nl.add(c2)
|
||||
assert_equal(nl.top_circuit_count, 2)
|
||||
begin
|
||||
nl.top_circuit
|
||||
assert_equal(true, false)
|
||||
rescue
|
||||
end
|
||||
|
||||
c3 = RBA::Circuit::new
|
||||
c3.name = "C3"
|
||||
|
|
@ -854,6 +861,10 @@ END
|
|||
nl.each_circuit_top_down { |c| names << c.name }
|
||||
assert_equal(names.join(","), "C3,C2,C1")
|
||||
|
||||
names = []
|
||||
nl.top_circuits.each { |c| names << c.name }
|
||||
assert_equal(names.join(","), "C3,C2,C1")
|
||||
|
||||
names = []
|
||||
nl.each_circuit_bottom_up { |c| names << c.name }
|
||||
assert_equal(names.join(","), "C1,C2,C3")
|
||||
|
|
|
|||
Loading…
Reference in New Issue