WIP: netlist compare - tests for device class equivalence mapping, added Netlist#device_class_by_name

This commit is contained in:
Matthias Koefferlein 2019-03-28 18:01:22 +01:00
parent cefd6e91cf
commit d255617051
5 changed files with 94 additions and 1 deletions

View File

@ -369,6 +369,16 @@ void Netlist::remove_circuit (Circuit *circuit)
m_circuits.erase (circuit);
}
DeviceClass *Netlist::device_class_by_name (const std::string &name)
{
for (device_class_iterator d = begin_device_classes (); d != end_device_classes (); ++d) {
if (d->name () == name) {
return d.operator-> ();
}
}
return 0;
}
void Netlist::add_device_class (DeviceClass *device_class)
{
m_device_classes.push_back (device_class);

View File

@ -281,6 +281,23 @@ public:
*/
void remove_device_class (DeviceClass *device_class);
/**
* @brief Gets a device class by it's name (const version)
*
* This method returns 0 if there is no class with this name.
*/
const DeviceClass *device_class_by_name (const std::string &name) const
{
return const_cast<Netlist *> (this)->device_class_by_name (name);
}
/**
* @brief Gets a device class by it's name (non-const version)
*
* This method returns 0 if there is no class with this name.
*/
DeviceClass *device_class_by_name (const std::string &name);
/**
* @brief Begin iterator for the device classes of the netlist (non-const version)
*/

View File

@ -959,7 +959,7 @@ Class<db::Netlist> decl_dbNetlist ("db", "Netlist",
) +
gsi::method ("circuit_by_name", (db::Circuit *(db::Netlist::*) (const std::string &)) &db::Netlist::circuit_by_name, gsi::arg ("name"),
"@brief Gets the circuit object for a given name.\n"
"If the ID is not a valid circuit name, nil is returned."
"If the name is not a valid circuit name, nil is returned."
) +
gsi::iterator ("each_circuit_top_down", (db::Netlist::top_down_circuit_iterator (db::Netlist::*) ()) &db::Netlist::begin_top_down, (db::Netlist::top_down_circuit_iterator (db::Netlist::*) ()) &db::Netlist::end_top_down,
"@brief Iterates over the circuits top-down\n"
@ -990,6 +990,10 @@ Class<db::Netlist> decl_dbNetlist ("db", "Netlist",
"Use this method with care as it may corrupt the internal structure of the netlist. "
"Only use this method when device refers to this device class."
) +
gsi::method ("device_class_by_name", (db::DeviceClass *(db::Netlist::*) (const std::string &)) &db::Netlist::device_class_by_name, gsi::arg ("name"),
"@brief Gets the device class for a given name.\n"
"If the name is not a valid device class name, nil is returned."
) +
gsi::iterator ("each_device_class", (db::Netlist::device_class_iterator (db::Netlist::*) ()) &db::Netlist::begin_device_classes, (db::Netlist::device_class_iterator (db::Netlist::*) ()) &db::Netlist::end_device_classes,
"@brief Iterates over the device classes of the netlist"
) +

View File

@ -1511,6 +1511,11 @@ public:
return tl::join (m_texts, "\n");
}
void clear ()
{
m_texts.clear ();
}
private:
std::vector<std::string> m_texts;
@ -1552,6 +1557,14 @@ static void prep_nl (db::Netlist &nl, const char *str)
dc->set_name ("NMOS");
nl.add_device_class (dc);
dc = new db::DeviceClassMOS3Transistor ();
dc->set_name ("PMOSB");
nl.add_device_class (dc);
dc = new db::DeviceClassMOS3Transistor ();
dc->set_name ("NMOSB");
nl.add_device_class (dc);
dc = new db::DeviceClassMOS4Transistor ();
dc->set_name ("PMOS4");
nl.add_device_class (dc);
@ -1619,6 +1632,52 @@ TEST(1_SimpleInverter)
EXPECT_EQ (good, true);
}
TEST(1_SimpleInverterMatchedDeviceClasses)
{
const char *nls1 =
"circuit INV ($1=IN,$2=OUT,$3=VDD,$4=VSS);\n"
" device PMOS $1 (S=VDD,G=IN,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
" device NMOS $2 (S=VSS,G=IN,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
"end;\n";
const char *nls2 =
"circuit INV ($1=VDD,$2=IN,$3=VSS,$4=OUT);\n"
" device NMOSB $1 (S=OUT,G=IN,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
" device PMOSB $2 (S=VDD,G=IN,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
"end;\n";
db::Netlist nl1, nl2;
prep_nl (nl1, nls1);
prep_nl (nl2, nls2);
NetlistCompareTestLogger logger;
db::NetlistComparer comp (&logger);
comp.same_device_classes (nl1.device_class_by_name ("PMOS"), nl2.device_class_by_name ("PMOSB"));
bool good = comp.compare (&nl1, &nl2);
EXPECT_EQ (good, false);
logger.clear ();
comp.same_device_classes (nl1.device_class_by_name ("NMOS"), nl2.device_class_by_name ("NMOSB"));
good = comp.compare (&nl1, &nl2);
EXPECT_EQ (logger.text (),
"begin_circuit INV INV\n"
"match_nets VDD VDD\n"
"match_nets VSS VSS\n"
"match_nets OUT OUT\n"
"match_nets IN IN\n"
"match_pins $2 $0\n"
"match_pins $3 $2\n"
"match_pins $1 $3\n"
"match_pins $0 $1\n"
"match_devices $2 $1\n"
"match_devices $1 $2\n"
"end_circuit INV INV MATCH"
);
EXPECT_EQ (good, true);
}
TEST(2_SimpleInverterWithForcedNetAssignment)
{
const char *nls1 =

View File

@ -105,6 +105,9 @@ class DBNetlist_TestClass < TestBase
nl.add(cc)
cc.name = "UVW"
assert_equal(nl.device_class_by_name("UVW") == cc, true)
assert_equal(nl.device_class_by_name("doesntexist") == nil, true)
names = []
nl.each_device_class { |i| names << i.name }
assert_equal(names, [ c.name, cc.name ])