Added Netlist#top_circuit and Netlist#top_circuits convenience methods

This commit is contained in:
Matthias Koefferlein 2024-07-24 20:57:17 +02:00
parent 16abeb2bdc
commit 6baabc30bb
5 changed files with 198 additions and 0 deletions

View File

@ -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) {

View File

@ -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

View File

@ -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"

View File

@ -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 ()));

View File

@ -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")