WIP: introduced device IDs

This commit is contained in:
Matthias Koefferlein 2018-12-27 00:59:44 +01:00
parent 724d1bc255
commit 2171b98bd8
6 changed files with 111 additions and 5 deletions

View File

@ -46,6 +46,7 @@ Pin::Pin (const std::string &name)
// Device class implementation
Device::Device ()
: mp_device_class (0), m_id (0)
{
// .. nothing yet ..
}
@ -60,12 +61,13 @@ Device::~Device ()
}
Device::Device (DeviceClass *device_class, const std::string &name)
: mp_device_class (device_class), m_name (name)
: mp_device_class (device_class), m_name (name), m_id (0)
{
// .. nothing yet ..
}
Device::Device (const Device &other)
: mp_device_class (0), m_id (0)
{
operator= (other);
}
@ -470,13 +472,13 @@ void Net::set_circuit (Circuit *circuit)
// Circuit class implementation
Circuit::Circuit ()
: mp_netlist (0)
: mp_netlist (0), m_valid_device_id_table (false)
{
// .. nothing yet ..
}
Circuit::Circuit (const Circuit &other)
: mp_netlist (0)
: mp_netlist (0), m_valid_device_id_table (false)
{
operator= (other);
}
@ -486,6 +488,7 @@ Circuit &Circuit::operator= (const Circuit &other)
if (this != &other) {
m_name = other.m_name;
invalidate_device_id_table ();
for (const_pin_iterator i = other.begin_pins (); i != other.end_pins (); ++i) {
add_pin (*i);
@ -589,12 +592,47 @@ void Circuit::remove_net (Net *net)
void Circuit::add_device (Device *device)
{
size_t id = 0;
if (! m_devices.empty ()) {
tl_assert (m_devices.back () != 0);
id = m_devices.back ()->id ();
}
device->set_id (id + 1);
m_devices.push_back (device);
invalidate_device_id_table ();
}
void Circuit::remove_device (Device *device)
{
m_devices.erase (device);
invalidate_device_id_table ();
}
void Circuit::validate_device_id_table ()
{
m_device_id_table.clear ();
for (device_iterator d = begin_devices (); d != end_devices (); ++d) {
m_device_id_table.insert (std::make_pair (d->id (), d.operator-> ()));
}
m_valid_device_id_table = true;
}
void Circuit::invalidate_device_id_table ()
{
m_valid_device_id_table = false;
m_device_id_table.clear ();
}
Device *Circuit::device_by_id (size_t id)
{
if (! m_valid_device_id_table) {
validate_device_id_table ();
}
std::map<size_t, Device *>::const_iterator d = m_device_id_table.find (id);
return d != m_device_id_table.end () ? d->second : 0;
}
void Circuit::add_sub_circuit (SubCircuit *sub_circuit)

View File

@ -589,6 +589,17 @@ public:
return mp_device_class;
}
/**
* @brief Gets the device ID
* The ID is a unique integer which identifies the device.
* It can be used to retrieve the device from the circuit using Circuit::device_by_id.
* When assigned, the device ID is not 0.
*/
size_t id () const
{
return m_id;
}
/**
* @brief Sets the name
*/
@ -655,6 +666,7 @@ private:
std::string m_name;
std::vector<Net::terminal_iterator> m_terminal_refs;
std::vector<double> m_parameters;
size_t m_id;
/**
* @brief Sets the terminal reference for a specific terminal
@ -668,6 +680,14 @@ private:
{
mp_device_class = dc;
}
/**
* @brief Sets the device ID
*/
void set_id (size_t id)
{
m_id = id;
}
};
/**
@ -999,6 +1019,23 @@ public:
*/
void remove_device (Device *device);
/**
* @brief Gets the device from a given ID (const version)
*
* If the ID is not valid, null is returned.
*/
const Device *device_by_id (size_t id) const
{
return (const_cast<Circuit *> (this)->device_by_id (id));
}
/**
* @brief Gets the device from a given ID (const version)
*
* If the ID is not valid, null is returned.
*/
Device *device_by_id (size_t id);
/**
* @brief Begin iterator for the devices of the circuit (non-const version)
*/
@ -1127,6 +1164,8 @@ private:
sub_circuit_list m_sub_circuits;
Netlist *mp_netlist;
std::vector<Net::pin_iterator> m_pin_refs;
bool m_valid_device_id_table;
std::map<size_t, Device *> m_device_id_table;
/**
* @brief Sets the pin reference for a specific pin
@ -1138,6 +1177,9 @@ private:
void set_netlist (Netlist *netlist);
void combine_parallel_devices (const db::DeviceClass &cls);
void combine_serial_devices (const db::DeviceClass &cls);
void validate_device_id_table ();
void invalidate_device_id_table ();
};
/**

View File

@ -51,6 +51,12 @@ Class<db::Device> decl_dbDevice ("db", "Device",
gsi::method ("device_class", &db::Device::device_class,
"@brief Gets the device class the device belongs to.\n"
) +
gsi::method ("id", &db::Device::id,
"@brief Gets the device ID.\n"
"The ID is a unique integer which identifies the device.\n"
"It can be used to retrieve the device from the circuit using \\Circuit#device_by_id.\n"
"When assigned, the device ID is not 0.\n"
) +
gsi::method ("name=", &db::Device::set_name, gsi::arg ("name"),
"@brief Sets the name of the device.\n"
"Device names are used to name a device inside a netlist file. "
@ -607,6 +613,10 @@ Class<db::Circuit> decl_dbCircuit ("db", "Circuit",
gsi::iterator ("each_pin", (db::Circuit::pin_iterator (db::Circuit::*) ()) &db::Circuit::begin_pins, (db::Circuit::pin_iterator (db::Circuit::*) ()) &db::Circuit::end_pins,
"@brief Iterates over the pins of the circuit"
) +
gsi::method ("device_by_id", (db::Device *(db::Circuit::*) (size_t)) &db::Circuit::device_by_id, gsi::arg ("id"),
"@brief Gets the device object for a given ID.\n"
"If the ID is not a valid device ID, nil is returned."
) +
gsi::method ("pin_by_id", &db::Circuit::pin_by_id, gsi::arg ("id"),
"@brief Gets the \\Pin object corresponding to a specific ID\n"
"If the ID is not a valid pin ID, nil is returned."

View File

@ -526,8 +526,7 @@ static std::string netlist2string (const db::Netlist &nl)
res += std::string ("Circuit ") + c->name () + " (" + ps + "):\n";
// @@@ good for debugging
#if 0
#if 0 // for debugging
for (db::Circuit::const_net_iterator n = c->begin_nets (); n != c->end_nets (); ++n) {
res += " N" + net_name (n.operator-> ()) + " pins=" + tl::to_string (n->pin_count ()) + " terminals=" + tl::to_string (n->terminal_count ()) + "\n";
}

View File

@ -264,12 +264,26 @@ TEST(4_CircuitDevices)
"c:\n"
);
db::Device *dd = new db::Device (&dc1, "dd");
db::Device *d1 = new db::Device (&dc1, "d1");
db::Device *d2a = new db::Device (&dc2, "d2a");
db::Device *d2b = new db::Device (&dc2, "d2b");
c->add_device (d1);
EXPECT_EQ (d1->id (), 1);
EXPECT_EQ (c->device_by_id (d1->id ()) == d1, true);
c->add_device (dd);
EXPECT_EQ (dd->id (), 2);
EXPECT_EQ (c->device_by_id (dd->id ()) == dd, true);
c->add_device (d2a);
EXPECT_EQ (d2a->id (), 3);
EXPECT_EQ (c->device_by_id (d2a->id ()) == d2a, true);
c->add_device (d2b);
EXPECT_EQ (d2b->id (), 4);
EXPECT_EQ (c->device_by_id (d2b->id ()) == d2b, true);
c->remove_device (dd);
dd = 0;
EXPECT_EQ (c->device_by_id (d2a->id ()) == d2a, true);
EXPECT_EQ (c->device_by_id (2) == 0, true);
EXPECT_EQ (d1->parameter_value (0), 1.0);
EXPECT_EQ (d1->parameter_value (1), 2.0);

View File

@ -157,6 +157,9 @@ class DBNetlist_TestClass < TestBase
d1 = c.create_device(dc)
d1.name = "D1"
assert_equal(d1.name, "D1")
assert_equal(d1.id, 1)
assert_equal(c.device_by_id(d1.id).id, 1)
assert_equal(c.device_by_id(2).inspect, "nil")
d2 = c.create_device(dc)
assert_equal(d2.device_class.id, dc.id)