diff --git a/src/db/db/dbDevice.cc b/src/db/db/dbDevice.cc index 816a2c77c..199464c73 100644 --- a/src/db/db/dbDevice.cc +++ b/src/db/db/dbDevice.cc @@ -133,6 +133,17 @@ const Net *Device::net_for_terminal (size_t terminal_id) const return 0; } +const NetTerminalRef *Device::terminal_ref_for_terminal (size_t terminal_id) const +{ + if (terminal_id < m_terminal_refs.size ()) { + Net::terminal_iterator p = m_terminal_refs [terminal_id]; + if (! tl::is_null_iterator (p)) { + return p.operator-> (); + } + } + return 0; +} + void Device::connect_terminal (size_t terminal_id, Net *net) { if (net_for_terminal (terminal_id) == net) { diff --git a/src/db/db/dbDevice.h b/src/db/db/dbDevice.h index b0671200f..708e48d04 100644 --- a/src/db/db/dbDevice.h +++ b/src/db/db/dbDevice.h @@ -254,6 +254,22 @@ public: return const_cast (((const Device *) this)->net_for_terminal (terminal_id)); } + /** + * @brief Gets the terminal reference for the given terminal on a device + * Returns 0 if no net is attached or the device is not embedded into a netlist. + * A terminal ref is the connector between a net and a device. It is useful for example + * to get the shapes of a terminal. + */ + const NetTerminalRef *terminal_ref_for_terminal (size_t terminal_id) const; + + /** + * @brief Gets the terminal reference for the given terminal on a device (non-const version) + */ + NetTerminalRef *terminal_ref_for_terminal (size_t terminal_id) + { + return const_cast (((const Device *) this)->terminal_ref_for_terminal (terminal_id)); + } + /** * @brief Connects the given terminal to the given net * If the net is 0 the terminal is disconnected. diff --git a/src/db/db/gsiDeclDbNetlist.cc b/src/db/db/gsiDeclDbNetlist.cc index f27df1f2e..05e2c85bc 100644 --- a/src/db/db/gsiDeclDbNetlist.cc +++ b/src/db/db/gsiDeclDbNetlist.cc @@ -268,6 +268,24 @@ static db::Net *net_for_terminal_by_name (db::Device *device, const std::string } } +static const db::NetTerminalRef *terminal_ref_by_name_const (const db::Device *device, const std::string &name) +{ + if (! device->device_class () || ! device->device_class ()->has_terminal_with_name (name)) { + return 0; + } else { + return device->terminal_ref_for_terminal (device->device_class ()->terminal_id_for_name (name)); + } +} + +static db::NetTerminalRef *terminal_ref_by_name (db::Device *device, const std::string &name) +{ + if (! device->device_class () || ! device->device_class ()->has_terminal_with_name (name)) { + return 0; + } else { + return device->terminal_ref_for_terminal (device->device_class ()->terminal_id_for_name (name)); + } +} + Class decl_dbDevice (decl_dbNetlistObject, "db", "Device", gsi::method ("device_class", &db::Device::device_class, "@brief Gets the device class the device belongs to.\n" @@ -354,18 +372,50 @@ Class decl_dbDevice (decl_dbNetlistObject, "db", "Device", "\n\n" "This constness variant has been introduced in version 0.26.8" ) + - gsi::method_ext ("net_for_terminal", net_for_terminal_by_name_const, gsi::arg ("terminal_name"), + gsi::method_ext ("net_for_terminal", &net_for_terminal_by_name_const, gsi::arg ("terminal_name"), "@brief Gets the net connected to the specified terminal.\n" "If the terminal is not connected, nil is returned for the net." "\n\n" "This convenience method has been introduced in version 0.27.3.\n" ) + - gsi::method_ext ("net_for_terminal", net_for_terminal_by_name, gsi::arg ("terminal_name"), + gsi::method_ext ("net_for_terminal", &net_for_terminal_by_name, gsi::arg ("terminal_name"), "@brief Gets the net connected to the specified terminal (non-const version).\n" "If the terminal is not connected, nil is returned for the net." "\n\n" "This convenience method has been introduced in version 0.27.3.\n" ) + + gsi::method ("terminal_ref", (const db::NetTerminalRef *(db::Device::*) (size_t) const) &db::Device::terminal_ref_for_terminal, gsi::arg ("terminal_id"), + "@brief Gets the terminal refeference for a specific terminal.\n" + "The terminal ref is the connector between a net and a device terminal. " + "It knows the net the terminal is connected to and is useful to obtain the shapes making the terminal of the device. " + "If the terminal is not connected, nil is returned for the net.\n" + "\n" + "This method has been introduced in version 0.30." + ) + + gsi::method ("terminal_ref", (db::NetTerminalRef *(db::Device::*) (size_t)) &db::Device::terminal_ref_for_terminal, gsi::arg ("terminal_id"), + "@brief Gets the terminal refeference for a specific terminal (non-const version).\n" + "The terminal ref is the connector between a net and a device terminal. " + "It knows the net the terminal is connected to and is useful to obtain the shapes making the terminal of the device. " + "If the terminal is not connected, nil is returned for the net.\n" + "\n" + "This method has been introduced in version 0.30." + ) + + gsi::method_ext ("terminal_ref", &terminal_ref_by_name_const, gsi::arg ("terminal_name"), + "@brief Gets the terminal refeference for a specific terminal where the terminal is given by name.\n" + "The terminal ref is the connector between a net and a device terminal. " + "It knows the net the terminal is connected to and is useful to obtain the shapes making the terminal of the device. " + "If the terminal is not connected, nil is returned for the net.\n" + "\n" + "This method has been introduced in version 0.30." + ) + + gsi::method_ext ("terminal_ref", &terminal_ref_by_name, gsi::arg ("terminal_name"), + "@brief Gets the terminal refeference for a specific terminal where the terminal is given by name (non-const version).\n" + "The terminal ref is the connector between a net and a device terminal. " + "It knows the net the terminal is connected to and is useful to obtain the shapes making the terminal of the device. " + "If the terminal is not connected, nil is returned for the net.\n" + "\n" + "This method has been introduced in version 0.30." + ) + gsi::method ("connect_terminal", &db::Device::connect_terminal, gsi::arg ("terminal_id"), gsi::arg ("net"), "@brief Connects the given terminal to the specified net.\n" ) + diff --git a/testdata/ruby/dbNetlist.rb b/testdata/ruby/dbNetlist.rb index 3e8d919c1..aaf5e9cad 100644 --- a/testdata/ruby/dbNetlist.rb +++ b/testdata/ruby/dbNetlist.rb @@ -347,6 +347,11 @@ class DBNetlist_TestClass < TestBase assert_equal(d1.net_for_terminal("X").inspect, "nil") assert_equal(d1.net_for_terminal(0).inspect, "nil") + assert_equal(d1.terminal_ref(1).net.name, "NET") + assert_equal(d1.terminal_ref("B").net.name, "NET") + assert_equal(d1.terminal_ref("X").inspect, "nil") + assert_equal(d1.terminal_ref(0).inspect, "nil") + d1.disconnect_terminal("B") assert_equal(net.terminal_count, 0) assert_equal(d1.net_for_terminal(1).inspect, "nil")