API enhancement for NetlistCrossReference: obtaining information from one object only (net, circuit), does not need a pair anymore

This commit is contained in:
Matthias Koefferlein 2025-05-22 20:54:21 +02:00
parent 90c4f654b6
commit 57c2add00a
4 changed files with 236 additions and 0 deletions

View File

@ -111,6 +111,24 @@ NetlistCrossReference::other_net_for (const db::Net *net) const
}
}
const NetlistCrossReference::PerNetData *
NetlistCrossReference::per_net_data_for_net (const db::Net *net) const
{
const db::Net *other_net = other_net_for (net);
std::map<std::pair<const db::Net *, const db::Net *>, PerNetData>::iterator i = m_per_net_data.find (std::make_pair (net, other_net));
if (i == m_per_net_data.end ()) {
i = m_per_net_data.find (std::make_pair (other_net, net));
}
if (i == m_per_net_data.end ()) {
static const NetlistCrossReference::PerNetData empty_net_data;
return &empty_net_data;
} else {
return &i->second;
}
}
const NetlistCrossReference::PerNetData *
NetlistCrossReference::per_net_data_for (const std::pair<const db::Net *, const db::Net *> &nets) const
{

View File

@ -280,6 +280,7 @@ public:
const db::SubCircuit *other_subcircuit_for (const db::SubCircuit *subcircuit) const;
const db::Circuit *other_circuit_for (const db::Circuit *circuit) const;
const db::Net *other_net_for (const db::Net *net) const;
const PerNetData *per_net_data_for_net (const db::Net *net) const;
const PerNetData *per_net_data_for (const std::pair<const db::Net *, const db::Net *> &nets) const;
const db::Netlist *netlist_a () const

View File

@ -287,6 +287,19 @@ static pair_data_iterator<db::NetlistCrossReference::NetPairData, db::NetlistCro
}
}
static pair_data_iterator<db::NetlistCrossReference::NetPairData, db::NetlistCrossReference::PerCircuitData::net_pairs_const_iterator> each_net_pair1 (db::NetlistCrossReference *xref, const db::Circuit *circuit)
{
tl_assert (xref->netlist_a () != 0 && xref->netlist_b () != 0);
typedef pair_data_iterator<db::NetlistCrossReference::NetPairData, db::NetlistCrossReference::PerCircuitData::net_pairs_const_iterator> iter_type;
const db::NetlistCrossReference::PerCircuitData *data = xref->per_circuit_data_for (std::make_pair (circuit, circuit));
if (! data) {
return iter_type ();
} else {
return iter_type (xref, data->nets.begin (), data->nets.end ());
}
}
static pair_data_iterator<db::NetlistCrossReference::DevicePairData, db::NetlistCrossReference::PerCircuitData::device_pairs_const_iterator> each_device_pair (db::NetlistCrossReference *xref, const CircuitPairData &circuit_pair)
{
tl_assert (xref->netlist_a () != 0 && xref->netlist_b () != 0);
@ -300,6 +313,19 @@ static pair_data_iterator<db::NetlistCrossReference::DevicePairData, db::Netlist
}
}
static pair_data_iterator<db::NetlistCrossReference::DevicePairData, db::NetlistCrossReference::PerCircuitData::device_pairs_const_iterator> each_device_pair1 (db::NetlistCrossReference *xref, const db::Circuit *circuit)
{
tl_assert (xref->netlist_a () != 0 && xref->netlist_b () != 0);
typedef pair_data_iterator<db::NetlistCrossReference::DevicePairData, db::NetlistCrossReference::PerCircuitData::device_pairs_const_iterator> iter_type;
const db::NetlistCrossReference::PerCircuitData *data = xref->per_circuit_data_for (std::make_pair (circuit, circuit));
if (! data) {
return iter_type ();
} else {
return iter_type (xref, data->devices.begin (), data->devices.end ());
}
}
static pair_data_iterator<db::NetlistCrossReference::PinPairData, db::NetlistCrossReference::PerCircuitData::pin_pairs_const_iterator> each_pin_pair (db::NetlistCrossReference *xref, const CircuitPairData &circuit_pair)
{
tl_assert (xref->netlist_a () != 0 && xref->netlist_b () != 0);
@ -313,6 +339,19 @@ static pair_data_iterator<db::NetlistCrossReference::PinPairData, db::NetlistCro
}
}
static pair_data_iterator<db::NetlistCrossReference::PinPairData, db::NetlistCrossReference::PerCircuitData::pin_pairs_const_iterator> each_pin_pair1 (db::NetlistCrossReference *xref, const db::Circuit *circuit)
{
tl_assert (xref->netlist_a () != 0 && xref->netlist_b () != 0);
typedef pair_data_iterator<db::NetlistCrossReference::PinPairData, db::NetlistCrossReference::PerCircuitData::pin_pairs_const_iterator> iter_type;
const db::NetlistCrossReference::PerCircuitData *data = xref->per_circuit_data_for (std::make_pair (circuit, circuit));
if (! data) {
return iter_type ();
} else {
return iter_type (xref, data->pins.begin (), data->pins.end ());
}
}
static pair_data_iterator<db::NetlistCrossReference::SubCircuitPairData, db::NetlistCrossReference::PerCircuitData::subcircuit_pairs_const_iterator> each_subcircuit_pair (db::NetlistCrossReference *xref, const CircuitPairData &circuit_pair)
{
tl_assert (xref->netlist_a () != 0 && xref->netlist_b () != 0);
@ -326,6 +365,19 @@ static pair_data_iterator<db::NetlistCrossReference::SubCircuitPairData, db::Net
}
}
static pair_data_iterator<db::NetlistCrossReference::SubCircuitPairData, db::NetlistCrossReference::PerCircuitData::subcircuit_pairs_const_iterator> each_subcircuit_pair1 (db::NetlistCrossReference *xref, const db::Circuit *circuit)
{
tl_assert (xref->netlist_a () != 0 && xref->netlist_b () != 0);
typedef pair_data_iterator<db::NetlistCrossReference::SubCircuitPairData, db::NetlistCrossReference::PerCircuitData::subcircuit_pairs_const_iterator> iter_type;
const db::NetlistCrossReference::PerCircuitData *data = xref->per_circuit_data_for (std::make_pair (circuit, circuit));
if (! data) {
return iter_type ();
} else {
return iter_type (xref, data->subcircuits.begin (), data->subcircuits.end ());
}
}
static pair_data_iterator<std::pair<const db::NetTerminalRef *, const db::NetTerminalRef *>, db::NetlistCrossReference::PerNetData::terminal_pairs_const_iterator> each_net_terminal_pair (db::NetlistCrossReference *xref, const db::NetlistCrossReference::NetPairData &net_pair)
{
tl_assert (xref->netlist_a () != 0 && xref->netlist_b () != 0);
@ -339,6 +391,19 @@ static pair_data_iterator<std::pair<const db::NetTerminalRef *, const db::NetTer
}
}
static pair_data_iterator<std::pair<const db::NetTerminalRef *, const db::NetTerminalRef *>, db::NetlistCrossReference::PerNetData::terminal_pairs_const_iterator> each_net_terminal_pair1 (db::NetlistCrossReference *xref, const db::Net *net)
{
tl_assert (xref->netlist_a () != 0 && xref->netlist_b () != 0);
typedef pair_data_iterator<std::pair<const db::NetTerminalRef *, const db::NetTerminalRef *>, db::NetlistCrossReference::PerNetData::terminal_pairs_const_iterator> iter_type;
const db::NetlistCrossReference::PerNetData *data = xref->per_net_data_for_net (net);
if (! data) {
return iter_type ();
} else {
return iter_type (xref, data->terminals.begin (), data->terminals.end ());
}
}
static pair_data_iterator<std::pair<const db::NetPinRef *, const db::NetPinRef *>, db::NetlistCrossReference::PerNetData::pin_pairs_const_iterator> each_net_pin_pair (db::NetlistCrossReference *xref, const db::NetlistCrossReference::NetPairData &net_pair)
{
tl_assert (xref->netlist_a () != 0 && xref->netlist_b () != 0);
@ -352,6 +417,19 @@ static pair_data_iterator<std::pair<const db::NetPinRef *, const db::NetPinRef *
}
}
static pair_data_iterator<std::pair<const db::NetPinRef *, const db::NetPinRef *>, db::NetlistCrossReference::PerNetData::pin_pairs_const_iterator> each_net_pin_pair1 (db::NetlistCrossReference *xref, const db::Net *net)
{
tl_assert (xref->netlist_a () != 0 && xref->netlist_b () != 0);
typedef pair_data_iterator<std::pair<const db::NetPinRef *, const db::NetPinRef *>, db::NetlistCrossReference::PerNetData::pin_pairs_const_iterator> iter_type;
const db::NetlistCrossReference::PerNetData *data = xref->per_net_data_for_net (net);
if (! data) {
return iter_type ();
} else {
return iter_type (xref, data->pins.begin (), data->pins.end ());
}
}
static pair_data_iterator<std::pair<const db::NetSubcircuitPinRef *, const db::NetSubcircuitPinRef *>, db::NetlistCrossReference::PerNetData::subcircuit_pin_pairs_const_iterator> each_net_subcircuit_pin_pair (db::NetlistCrossReference *xref, const db::NetlistCrossReference::NetPairData &net_pair)
{
tl_assert (xref->netlist_a () != 0 && xref->netlist_b () != 0);
@ -365,6 +443,19 @@ static pair_data_iterator<std::pair<const db::NetSubcircuitPinRef *, const db::N
}
}
static pair_data_iterator<std::pair<const db::NetSubcircuitPinRef *, const db::NetSubcircuitPinRef *>, db::NetlistCrossReference::PerNetData::subcircuit_pin_pairs_const_iterator> each_net_subcircuit_pin_pair1 (db::NetlistCrossReference *xref, const db::Net *net)
{
tl_assert (xref->netlist_a () != 0 && xref->netlist_b () != 0);
typedef pair_data_iterator<std::pair<const db::NetSubcircuitPinRef *, const db::NetSubcircuitPinRef *>, db::NetlistCrossReference::PerNetData::subcircuit_pin_pairs_const_iterator> iter_type;
const db::NetlistCrossReference::PerNetData *data = xref->per_net_data_for_net (net);
if (! data) {
return iter_type ();
} else {
return iter_type (xref, data->subcircuit_pins.begin (), data->subcircuit_pins.end ());
}
}
Class<db::NetlistCrossReference> decl_dbNetlistCrossReference (decl_dbNetlistCompareLogger, "db", "NetlistCrossReference",
gsi::iterator_ext ("each_circuit_pair", &each_circuit_pair,
"@brief Delivers the circuit pairs and their status.\n"
@ -374,30 +465,72 @@ Class<db::NetlistCrossReference> decl_dbNetlistCrossReference (decl_dbNetlistCom
"@brief Delivers the net pairs and their status for the given circuit pair.\n"
"See the class description for details."
) +
gsi::iterator_ext ("each_net_pair", &each_net_pair1, gsi::arg ("circuit"),
"@brief Delivers the net pairs and their status for the given circuit.\n"
"This convenience method looks up the circuit pair from the given circuit. This circuit can be "
"a schematic or layout circuit.\n"
"This method has been added in version 0.30.2.\n"
) +
gsi::iterator_ext ("each_device_pair", &each_device_pair, gsi::arg ("circuit_pair"),
"@brief Delivers the device pairs and their status for the given circuit pair.\n"
"See the class description for details."
) +
gsi::iterator_ext ("each_device_pair", &each_device_pair1, gsi::arg ("circuit"),
"@brief Delivers the device pairs and their status for the given circuit pair.\n"
"This convenience method looks up the circuit pair from the given circuit. This circuit can be "
"a schematic or layout circuit.\n"
"This method has been added in version 0.30.2.\n"
) +
gsi::iterator_ext ("each_pin_pair", &each_pin_pair, gsi::arg ("circuit_pair"),
"@brief Delivers the pin pairs and their status for the given circuit pair.\n"
"See the class description for details."
) +
gsi::iterator_ext ("each_pin_pair", &each_pin_pair1, gsi::arg ("circuit"),
"@brief Delivers the pin pairs and their status for the given circuit pair.\n"
"This convenience method looks up the circuit pair from the given circuit. This circuit can be "
"a schematic or layout circuit.\n"
"This method has been added in version 0.30.2.\n"
) +
gsi::iterator_ext ("each_subcircuit_pair", &each_subcircuit_pair, gsi::arg ("circuit_pair"),
"@brief Delivers the subcircuit pairs and their status for the given circuit pair.\n"
"See the class description for details."
) +
gsi::iterator_ext ("each_subcircuit_pair", &each_subcircuit_pair1, gsi::arg ("circuit"),
"@brief Delivers the subcircuit pairs and their status for the given circuit pair.\n"
"This convenience method looks up the circuit pair from the given circuit. This circuit can be "
"a schematic or layout circuit.\n"
"This method has been added in version 0.30.2.\n"
) +
gsi::iterator_ext ("each_net_terminal_pair", &each_net_terminal_pair, gsi::arg ("net_pair"),
"@brief Delivers the device terminal pairs for the given net pair.\n"
"For the net pair, lists the device terminal pairs identified on this net."
) +
gsi::iterator_ext ("each_net_terminal_pair", &each_net_terminal_pair1, gsi::arg ("net"),
"@brief Delivers the device terminal pairs for the given net pair.\n"
"This convenience method looks up the net pair from the given net. This net can be "
"a schematic or layout net.\n"
"This method has been added in version 0.30.2.\n"
) +
gsi::iterator_ext ("each_net_pin_pair", &each_net_pin_pair, gsi::arg ("net_pair"),
"@brief Delivers the pin pairs for the given net pair.\n"
"For the net pair, lists the pin pairs identified on this net."
) +
gsi::iterator_ext ("each_net_pin_pair", &each_net_pin_pair1, gsi::arg ("net"),
"@brief Delivers the pin pairs for the given net pair.\n"
"This convenience method looks up the net pair from the given net. This net can be "
"a schematic or layout net.\n"
"This method has been added in version 0.30.2.\n"
) +
gsi::iterator_ext ("each_net_subcircuit_pin_pair", &each_net_subcircuit_pin_pair, gsi::arg ("net_pair"),
"@brief Delivers the subcircuit pin pairs for the given net pair.\n"
"For the net pair, lists the subcircuit pin pairs identified on this net."
) +
gsi::iterator_ext ("each_net_subcircuit_pin_pair", &each_net_subcircuit_pin_pair1, gsi::arg ("net"),
"@brief Delivers the subcircuit pin pairs for the given net pair.\n"
"This convenience method looks up the net pair from the given net. This net can be "
"a schematic or layout net.\n"
"This method has been added in version 0.30.2.\n"
) +
gsi::method ("other_net_for", &db::NetlistCrossReference::other_net_for, gsi::arg ("net"),
"@brief Gets the matching other net for a given primary net.\n"
"The return value will be nil if no match is found. "

View File

@ -81,12 +81,36 @@ class DBNetlistCrossReference_TestClass < TestBase
end
assert_equal(info.join(","), "/1:Match,BULK/6:Match,IN/2:Match,OUT/3:Match,VDD/5:Match,VSS/4:Match")
info = []
xref.each_pin_pair(cp_inv2.first) do |p|
info << [ p.first, p.second ].collect { |s| s ? s.name : "(nil)" }.join("/") + ":" + p.status.to_s
end
assert_equal(info.join(","), "/1:Match,BULK/6:Match,IN/2:Match,OUT/3:Match,VDD/5:Match,VSS/4:Match")
info = []
xref.each_pin_pair(cp_inv2.second) do |p|
info << [ p.first, p.second ].collect { |s| s ? s.name : "(nil)" }.join("/") + ":" + p.status.to_s
end
assert_equal(info.join(","), "/1:Match,BULK/6:Match,IN/2:Match,OUT/3:Match,VDD/5:Match,VSS/4:Match")
info = []
xref.each_net_pair(cp_inv2) do |p|
info << [ p.first, p.second ].collect { |s| s ? s.name : "(nil)" }.join("/") + ":" + p.status.to_s
end
assert_equal(info.join(","), "/1:Match,BULK/6:Match,IN/2:Match,OUT/3:Match,VDD/5:Match,VSS/4:Match")
info = []
xref.each_net_pair(cp_inv2.first) do |p|
info << [ p.first, p.second ].collect { |s| s ? s.name : "(nil)" }.join("/") + ":" + p.status.to_s
end
assert_equal(info.join(","), "/1:Match,BULK/6:Match,IN/2:Match,OUT/3:Match,VDD/5:Match,VSS/4:Match")
info = []
xref.each_net_pair(cp_inv2.second) do |p|
info << [ p.first, p.second ].collect { |s| s ? s.name : "(nil)" }.join("/") + ":" + p.status.to_s
end
assert_equal(info.join(","), "/1:Match,BULK/6:Match,IN/2:Match,OUT/3:Match,VDD/5:Match,VSS/4:Match")
netp_bulk = nil
xref.each_net_pair(cp_inv2) do |p|
if p.first.name == "BULK"
@ -100,30 +124,90 @@ class DBNetlistCrossReference_TestClass < TestBase
end
assert_equal(info.join(","), "B/B")
info = []
xref.each_net_terminal_pair(netp_bulk.first) do |p|
info << [ p.first, p.second ].collect { |s| s ? s.terminal_def.name : "(nil)" }.join("/")
end
assert_equal(info.join(","), "B/B")
info = []
xref.each_net_terminal_pair(netp_bulk.second) do |p|
info << [ p.first, p.second ].collect { |s| s ? s.terminal_def.name : "(nil)" }.join("/")
end
assert_equal(info.join(","), "B/B")
info = []
xref.each_net_pin_pair(netp_bulk) do |p|
info << [ p.first, p.second ].collect { |s| s ? s.pin.name : "(nil)" }.join("/")
end
assert_equal(info.join(","), "BULK/6")
info = []
xref.each_net_pin_pair(netp_bulk.first) do |p|
info << [ p.first, p.second ].collect { |s| s ? s.pin.name : "(nil)" }.join("/")
end
assert_equal(info.join(","), "BULK/6")
info = []
xref.each_net_pin_pair(netp_bulk.second) do |p|
info << [ p.first, p.second ].collect { |s| s ? s.pin.name : "(nil)" }.join("/")
end
assert_equal(info.join(","), "BULK/6")
info = []
xref.each_net_subcircuit_pin_pair(netp_bulk) do |p|
info << [ p.first, p.second ].collect { |s| s ? s.pin.name : "(nil)" }.join("/")
end
assert_equal(info.join(","), "")
info = []
xref.each_net_subcircuit_pin_pair(netp_bulk.first) do |p|
info << [ p.first, p.second ].collect { |s| s ? s.pin.name : "(nil)" }.join("/")
end
assert_equal(info.join(","), "")
info = []
xref.each_net_subcircuit_pin_pair(netp_bulk.second) do |p|
info << [ p.first, p.second ].collect { |s| s ? s.pin.name : "(nil)" }.join("/")
end
assert_equal(info.join(","), "")
info = []
xref.each_device_pair(cp_inv2) do |p|
info << [ p.first, p.second ].collect { |s| s ? s.name : "(nil)" }.join("/") + ":" + p.status.to_s
end
assert_equal(info.join(","), "/$1:Match,/$3:Match")
info = []
xref.each_device_pair(cp_inv2.first) do |p|
info << [ p.first, p.second ].collect { |s| s ? s.name : "(nil)" }.join("/") + ":" + p.status.to_s
end
assert_equal(info.join(","), "/$1:Match,/$3:Match")
info = []
xref.each_device_pair(cp_inv2.second) do |p|
info << [ p.first, p.second ].collect { |s| s ? s.name : "(nil)" }.join("/") + ":" + p.status.to_s
end
assert_equal(info.join(","), "/$1:Match,/$3:Match")
info = []
xref.each_subcircuit_pair(cp_inv2) do |p|
info << [ p.first, p.second ].collect { |s| s ? s.name : "(nil)" }.join("/") + ":" + p.status.to_s
end
assert_equal(info.join(","), "")
info = []
xref.each_subcircuit_pair(cp_inv2.first) do |p|
info << [ p.first, p.second ].collect { |s| s ? s.name : "(nil)" }.join("/") + ":" + p.status.to_s
end
assert_equal(info.join(","), "")
info = []
xref.each_subcircuit_pair(cp_inv2.second) do |p|
info << [ p.first, p.second ].collect { |s| s ? s.name : "(nil)" }.join("/") + ":" + p.status.to_s
end
assert_equal(info.join(","), "")
cp_inv2pair = nil
xref.each_circuit_pair do |cp|
if cp.first && cp.first.name == "INV2PAIR"