Added DevicePortProperty class with tests and GSI binding

This commit is contained in:
Matthias Koefferlein 2018-12-24 01:31:06 +01:00
parent aa5e885215
commit c5222c26e3
9 changed files with 291 additions and 101 deletions

View File

@ -75,6 +75,25 @@ public:
*/
NetPortRef &operator= (const NetPortRef &other);
/**
* @brief Comparison
*/
bool operator< (const NetPortRef &other) const
{
if (mp_device != other.mp_device) {
return mp_device < other.mp_device;
}
return m_port_id < other.m_port_id;
}
/**
* @brief Equality
*/
bool operator== (const NetPortRef &other) const
{
return (mp_device == other.mp_device && m_port_id == other.m_port_id);
}
/**
* @brief Gets the device reference
*/
@ -178,6 +197,25 @@ public:
*/
NetPinRef &operator= (const NetPinRef &other);
/**
* @brief Comparison
*/
bool operator< (const NetPinRef &other) const
{
if (mp_subcircuit != other.mp_subcircuit) {
return mp_subcircuit < other.mp_subcircuit;
}
return m_pin_id < other.m_pin_id;
}
/**
* @brief Equality
*/
bool operator== (const NetPinRef &other) const
{
return (mp_subcircuit == other.mp_subcircuit && m_pin_id == other.m_pin_id);
}
/**
* @brief Gets the pin reference (const version)
*/

View File

@ -65,9 +65,10 @@ std::string VariantUserClass<db::NetlistProperty>::to_string (const void *p) con
return ((const db::NetlistProperty *) p)->to_string ();
}
void VariantUserClass<db::NetlistProperty>::read (void *p, tl::Extractor &ex) const
void VariantUserClass<db::NetlistProperty>::read (void * /*p*/, tl::Extractor & /*ex*/) const
{
((db::NetlistProperty *) p)->read (ex);
// .. nothing yet ..
return;
}
void VariantUserClass<db::NetlistProperty>::assign (void *self, const void *other) const
@ -123,7 +124,7 @@ const tl::VariantUserClass<db::NetlistProperty> *NetlistProperty::variant_class
}
// --------------------------------------------------------------------------------------------
// NetlistName Implementation
// NetNameProperty Implementation
NetNameProperty::NetNameProperty ()
: NetlistProperty ()
@ -188,9 +189,72 @@ std::string NetNameProperty::to_string () const
return "name:" + tl::to_word_or_quoted_string (m_name, valid_netname_chars);
}
void NetNameProperty::read (tl::Extractor &ex)
// --------------------------------------------------------------------------------------------
// DevicePortProperty Implementation
DevicePortProperty::DevicePortProperty ()
: NetlistProperty ()
{
ex.read_word_or_quoted (m_name, valid_netname_chars);
// .. nothing yet ..
}
DevicePortProperty::DevicePortProperty (const DevicePortProperty &other)
: NetlistProperty (other), m_port_ref (other.m_port_ref)
{
// .. nothing yet ..
}
DevicePortProperty::DevicePortProperty (const db::NetPortRef &p)
: NetlistProperty (), m_port_ref (p)
{
// .. nothing yet ..
}
DevicePortProperty &DevicePortProperty::operator= (const DevicePortProperty &other)
{
NetlistProperty::operator= (other);
if (this != &other) {
m_port_ref = other.m_port_ref;
}
return *this;
}
void DevicePortProperty::set_port_ref (const db::NetPortRef &p)
{
m_port_ref = p;
}
bool DevicePortProperty::equals (const NetlistProperty *p) const
{
const DevicePortProperty *pp = static_cast<const DevicePortProperty *> (p);
return NetlistProperty::equals (p) && m_port_ref == pp->m_port_ref;
}
bool DevicePortProperty::less (const NetlistProperty *p) const
{
if (! NetlistProperty::equals (p)) {
return NetlistProperty::less (p);
} else {
const DevicePortProperty *pp = static_cast<const DevicePortProperty *> (p);
return m_port_ref < pp->m_port_ref;
}
}
void DevicePortProperty::assign (const NetlistProperty *p)
{
NetlistProperty::assign (p);
const DevicePortProperty *pp = static_cast<const DevicePortProperty *> (p);
m_port_ref = pp->m_port_ref;
}
std::string DevicePortProperty::to_string () const
{
if (m_port_ref.device () && m_port_ref.port_def ()) {
return "port:" + tl::to_word_or_quoted_string (m_port_ref.device ()->name ()) + ":" + tl::to_word_or_quoted_string (m_port_ref.port_def ()->name ());
} else {
return "port";
}
}
}

View File

@ -149,14 +149,6 @@ public:
{
return std::string ();
}
/**
* @brief Pulls the object from a string
*/
virtual void read (tl::Extractor &)
{
// .. nothing yet ..
}
};
/**
@ -227,59 +219,86 @@ public:
*/
virtual std::string to_string () const;
/**
* @brief Pulls the object from a string
*/
virtual void read (tl::Extractor &);
private:
std::string m_name;
};
#if 0 // @@@
/**
* @brief A reference to an actual port
*/
class DB_PUBLIC DevicePortRef
: public db::NetlistProperty
{
public:
DevicePortRef (db::NetPortRef *port);
// ...
private:
tl::weak_ptr<db::NetPortRef> mp_port;
};
/**
* @brief An abstrace reference to a port
* @brief A reference to a device port
*
* Abstract references are created when turning a string back into a port.
* Abstract references can be turned into actual port references using
* "to_actual_ref".
* This property is used to mark a shape as a device port reference.
* Such a port reference points to a port of a specific device.
* Attaching such a property to a shape allows connecting the
* net to the device later.
*/
class DB_PUBLIC DevicePortAbstractRef
class DB_PUBLIC DevicePortProperty
: public db::NetlistProperty
{
public:
DevicePortAbstractRef (const std::string &device_name, const std::string &port_name);
// ...
/**
* @brief Creates a netlist name property without a specific name
*/
DevicePortProperty ();
/**
* @brief Turns an abstract reference into an actual one
*
* The returned object is either 0, if the translation cannot be done or
* and new'd NetPortRef object. It's the responsibility of the caller
* to delete this object when it's no longer used.
* @brief copy constructor
*/
NetPortRef *to_actual_ref (const db::Netlist *netlist) const;
DevicePortProperty (const db::DevicePortProperty &other);
/**
* @brief Creates a netlist name property with the given name
*/
DevicePortProperty (const db::NetPortRef &port_ref);
/**
* @brief Assignment
*/
DevicePortProperty &operator= (const DevicePortProperty &other);
/**
* @brief Sets the port reference
*/
void set_port_ref (const db::NetPortRef &port_ref);
/**
* @brief Gets the port reference
*/
const db::NetPortRef &port_ref () const
{
return m_port_ref;
}
/**
* @brief Clones the object
*/
virtual DevicePortProperty *clone () const
{
return new DevicePortProperty (*this);
}
/**
* @brief Compares two objects (equal). Both types are guaranteed to be the same.
*/
virtual bool equals (const NetlistProperty *) const;
/**
* @brief Compares two objects (less). Both types are guaranteed to be the same.
*/
virtual bool less (const NetlistProperty *) const;
/**
* @brief Assigned the other object to self. Both types are guaranteed to be identical.
*/
virtual void assign (const NetlistProperty *);
/**
* @brief Converts to a string
*/
virtual std::string to_string () const;
private:
std::string m_device_name, m_port_name;
db::NetPortRef m_port_ref;
};
#endif
}

View File

@ -332,10 +332,11 @@ static const db::Pin &create_pin (db::Circuit *c, const std::string &name)
return c->add_pin (db::Pin (name));
}
static db::Net *create_net (db::Circuit *c)
static db::Net *create_net (db::Circuit *c, const std::string &name)
{
db::Net *n = new db::Net ();
c->add_net (n);
n->set_name (name);
return n;
}
@ -394,7 +395,7 @@ Class<db::Circuit> decl_dbCircuit ("db", "Circuit",
gsi::method ("pin_count", &db::Circuit::pin_count,
"@brief Gets the number of pins in the circuit"
) +
gsi::method_ext ("create_net", &gsi::create_net,
gsi::method_ext ("create_net", &gsi::create_net, gsi::arg ("name", std::string ()),
"@brief Creates a new \\Net object inside the circuit\n"
"This object will describe a net of the circuit. The nets are basically "
"connections between the different components of the circuit (subcircuits, "

View File

@ -35,37 +35,10 @@ static db::NetlistProperty *new_property ()
return new db::NetlistProperty ();
}
static db::NetlistProperty *from_string (const std::string &str)
{
tl::Extractor ex (str.c_str ());
if (ex.at_end ()) {
return new db::NetlistProperty ();
} else if (ex.test ("name")) {
ex.test (":");
std::auto_ptr<db::NetNameProperty> n (new db::NetNameProperty ());
n->read (ex);
return n.release ();
} else {
return 0;
}
}
gsi::Class<db::NetlistProperty> decl_NetlistProperty ("db", "NetlistProperty",
gsi::constructor ("new", &new_property,
"@brief Creates a plain netlist property"
) +
gsi::constructor ("from_s", &from_string, gsi::arg ("str"),
"@brief Creates a netlist property from a string\n"
"This method can turn the string returned by \\to_string back into a property object.\n"
"@param str The string to read the property from\n"
"@return A fresh property object created from the string\n"
) +
gsi::method ("to_s", &db::NetlistProperty::to_string,
"@brief Convert the property to a string.\n"
"@return The string representing this property\n"
@ -113,4 +86,37 @@ gsi::Class<db::NetNameProperty> decl_NetNameProperty (decl_NetlistProperty, "db"
"This class was introduced in version 0.26.\n"
);
// ---------------------------------------------------------------
// db::DevicePortProperty binding
static db::DevicePortProperty *new_devport ()
{
return new db::DevicePortProperty ();
}
static db::DevicePortProperty *new_devport2 (const db::NetPortRef &n)
{
return new db::DevicePortProperty (n);
}
gsi::Class<db::DevicePortProperty> decl_DevicePortProperty (decl_NetlistProperty, "db", "DevicePortProperty",
gsi::constructor ("new", &new_devport,
"@brief Creates a new device port property"
) +
gsi::constructor ("new", &new_devport2, gsi::arg ("port_ref"),
"@brief Creates a new device port property with the given port reference"
) +
gsi::method ("port_ref=", &db::DevicePortProperty::set_port_ref, gsi::arg ("p"),
"@brief Sets the port reference\n"
) +
gsi::method ("port_ref", &db::DevicePortProperty::port_ref,
"@brief Gets the port reference\n"
),
"@brief A device port reference property.\n"
"\n"
"The netlist property annotates a shape or other object with a reference to a device port."
"\n\n"
"This class was introduced in version 0.26.\n"
);
}

View File

@ -28,7 +28,7 @@
#include <memory>
TEST(1_Basic)
TEST(1_NameBasic)
{
db::NetNameProperty name;
EXPECT_EQ (name.to_string (), "name:''");
@ -45,13 +45,28 @@ TEST(1_Basic)
n2.set_name ("\"quoted\"");
EXPECT_EQ (n2.to_string (), "name:'\"quoted\"'");
tl::Extractor ex ("net42");
n2.read (ex);
EXPECT_EQ (n2.name (), "net42");
}
TEST(2_Variants)
TEST(2_PortRefBasic)
{
db::GenericDeviceClass dc;
dc.add_port_definition (db::DevicePortDefinition ("A", "Port A"));
dc.add_port_definition (db::DevicePortDefinition ("B", "Port B"));
db::Device d (&dc, "D");
db::DevicePortProperty dp (db::NetPortRef (&d, 1));
EXPECT_EQ (dp.to_string (), "port:D:B");
dp.set_port_ref (db::NetPortRef (&d, 0));
EXPECT_EQ (dp.to_string (), "port:D:A");
EXPECT_EQ (dp.port_ref () == db::NetPortRef (&d, 0), true);
db::DevicePortProperty dp2 = dp;
EXPECT_EQ (dp2.to_string (), "port:D:A");
}
TEST(3_Variants)
{
std::auto_ptr<db::NetNameProperty> nn (new db::NetNameProperty ());
nn->set_name ("net42");
@ -67,3 +82,4 @@ TEST(2_Variants)
EXPECT_EQ (vv.is_user<db::NetlistProperty> (), true);
EXPECT_EQ (dynamic_cast<db::NetNameProperty &>(vv.to_user<db::NetlistProperty> ()).name (), "net42");
}

View File

@ -661,3 +661,31 @@ TEST(8_NetSubCircuitsEditing)
EXPECT_EQ (sc2->net_for_pin (0), n2);
EXPECT_EQ (sc2->net_for_pin (1), 0);
}
TEST(9_NetPortRefBasics)
{
db::Device d1, d2;
EXPECT_EQ (db::NetPortRef (&d1, 0) == db::NetPortRef (&d1, 0), true);
EXPECT_EQ (db::NetPortRef (&d1, 0) == db::NetPortRef (&d1, 1), false);
EXPECT_EQ (db::NetPortRef (&d1, 0) == db::NetPortRef (&d2, 0), false);
EXPECT_EQ (db::NetPortRef (&d1, 0) < db::NetPortRef (&d1, 0), false);
EXPECT_EQ (db::NetPortRef (&d1, 0) < db::NetPortRef (&d1, 1), true);
EXPECT_EQ (db::NetPortRef (&d1, 1) < db::NetPortRef (&d1, 0), false);
EXPECT_NE ((db::NetPortRef (&d1, 0) < db::NetPortRef (&d2, 0)), (db::NetPortRef (&d2, 0) < db::NetPortRef (&d1, 0)));
}
TEST(10_NetPinRefBasics)
{
db::SubCircuit d1, d2;
EXPECT_EQ (db::NetPinRef (&d1, 0) == db::NetPinRef (&d1, 0), true);
EXPECT_EQ (db::NetPinRef (&d1, 0) == db::NetPinRef (&d1, 1), false);
EXPECT_EQ (db::NetPinRef (&d1, 0) == db::NetPinRef (&d2, 0), false);
EXPECT_EQ (db::NetPinRef (&d1, 0) < db::NetPinRef (&d1, 0), false);
EXPECT_EQ (db::NetPinRef (&d1, 0) < db::NetPinRef (&d1, 1), true);
EXPECT_EQ (db::NetPinRef (&d1, 1) < db::NetPinRef (&d1, 0), false);
EXPECT_NE ((db::NetPinRef (&d1, 0) < db::NetPinRef (&d2, 0)), (db::NetPinRef (&d2, 0) < db::NetPinRef (&d1, 0)));
}

View File

@ -180,8 +180,7 @@ class DBNetlist_TestClass < TestBase
assert_equal(names, [ "D1", "D2" ])
assert_equal(dcs, [ "DC", "DC" ])
net = c.create_net
net.name = "NET"
net = c.create_net("NET")
d1.connect_port(1, net)
assert_equal(d1.net_for_port(1).name, "NET")
@ -257,8 +256,7 @@ class DBNetlist_TestClass < TestBase
assert_equal(names, [ "SC1", "SC2" ])
assert_equal(ccn, [ "CC", "CC" ])
net = c.create_net
net.name = "NET"
net = c.create_net("NET")
sc1.connect_pin(1, net)
assert_equal(sc1.net_for_pin(1).name, "NET")
@ -283,12 +281,12 @@ class DBNetlist_TestClass < TestBase
net.each_pin { |p| assert_equal(p.net.name, "NET") }
net.clear
assert_equal(sc1.net_for_pin(1).inspec, "nil")
assert_equal(sc1.net_for_pin(1).inspect, "nil")
assert_equal(sc1.net_for_pin(0).inspect, "nil")
end
def test_5_SubCircuit
def test_6_SubCircuitBasic
nl = RBA::Netlist::new
@ -308,7 +306,7 @@ class DBNetlist_TestClass < TestBase
end
def test_6_GenericDeviceClass
def test_7_GenericDeviceClass
nl = RBA::Netlist::new
@ -349,7 +347,7 @@ class DBNetlist_TestClass < TestBase
end
def test_7_Circuit
def test_8_Circuit
nl = RBA::Netlist::new

View File

@ -31,9 +31,6 @@ class DBNetlistProperty_TestClass < TestBase
assert_equal(np.is_a?(RBA::NetlistProperty), true)
assert_equal(np.to_s, "")
np2 = RBA::NetlistProperty::from_s("")
assert_equal(np2.is_a?(RBA::NetlistProperty), true)
end
def test_2_NetName
@ -47,14 +44,37 @@ class DBNetlistProperty_TestClass < TestBase
assert_equal(np.to_s, "name:abc")
assert_equal(np.name, "abc")
np2 = RBA::NetlistProperty::from_s("name:xyz")
assert_equal(np2.is_a?(RBA::NetlistProperty), true)
assert_equal(np2.is_a?(RBA::NetNameProperty), true)
assert_equal(np2.name, "xyz")
end
def test_3_DevicePort
np = RBA::DevicePortProperty::new
assert_equal(np.is_a?(RBA::DevicePortProperty), true)
assert_equal(np.is_a?(RBA::DevicePortProperty), true)
assert_equal(np.to_s, "port")
dc = RBA::GenericDeviceClass::new
dp = RBA::DevicePortDefinition::new
dp.name = "A"
dc.add_port(dp)
dp.name = "B"
dc.add_port(dp)
c = RBA::Circuit::new
d = c.create_device(dc, "D")
n = c.create_net("NET")
d.connect_port(0, n)
# there is no other way to produce a NetPortRef object yet
n.each_port { |p| np.port_ref = p }
assert_equal(np.to_s, "port:D:A")
assert_equal(np.port_ref.device.name, "D")
end
def test_3_VariantBinding
def test_4_VariantBinding
ly = RBA::Layout::new
l1 = ly.insert_layer(RBA::LayerInfo::new(1, 0))