mirror of https://github.com/KLayout/klayout.git
Unit tests fixed and a bugfix in the netlist compare
One unit test was failing because the netlist compare did not
properly consider dropped pins:
* A severe bug ("g1" should be "g2")
* Incomplete detection of dropped pins upwards in the hierarchy
The general pin and net mapping scheme has been enhanced so that
net mapping to "0" is valid (this will happen in case of dropped
pins) and this condition is used to detect pins without match
requirement.
This commit is contained in:
parent
ccb1871fb3
commit
aa28aa807a
|
|
@ -2951,14 +2951,34 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2,
|
|||
// Report missing net assignment
|
||||
|
||||
for (db::NetGraph::node_iterator i = g1.begin (); i != g1.end (); ++i) {
|
||||
if (! i->has_other () && mp_logger) {
|
||||
mp_logger->net_mismatch (i->net (), 0);
|
||||
if (! i->has_other ()) {
|
||||
if (mp_logger) {
|
||||
if (good) {
|
||||
mp_logger->match_nets (i->net (), 0);
|
||||
} else {
|
||||
mp_logger->net_mismatch (i->net (), 0);
|
||||
}
|
||||
}
|
||||
if (good) {
|
||||
// in the "good" case, match the nets against 0
|
||||
g1.identify (g1.node_index_for_net (i->net ()), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (db::NetGraph::node_iterator i = g2.begin (); i != g2.end (); ++i) {
|
||||
if (! i->has_other () && mp_logger) {
|
||||
mp_logger->net_mismatch (0, i->net ());
|
||||
if (! i->has_other ()) {
|
||||
if (mp_logger) {
|
||||
if (good) {
|
||||
mp_logger->match_nets (0, i->net ());
|
||||
} else {
|
||||
mp_logger->net_mismatch (0, i->net ());
|
||||
}
|
||||
}
|
||||
if (good) {
|
||||
// in the "good" case, match the nets against 0
|
||||
g2.identify (g2.node_index_for_net (i->net ()), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2969,22 +2989,33 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2,
|
|||
return good;
|
||||
}
|
||||
|
||||
void
|
||||
NetlistComparer::handle_pin_mismatch (const db::Circuit *c1, const db::Pin *pin1, const db::Circuit *c2, const db::Pin *pin2, bool &good, bool &pin_mismatch) const
|
||||
bool
|
||||
NetlistComparer::handle_pin_mismatch (const db::NetGraph &g1, const db::Circuit *c1, const db::Pin *pin1, const db::NetGraph &g2, const db::Circuit *c2, const db::Pin *pin2) const
|
||||
{
|
||||
const db::Circuit *c = pin1 ? c1 : c2;
|
||||
const db::Pin *pin = pin1 ? pin1 : pin2;
|
||||
const db::NetGraph *graph = pin1 ? &g1 : &g2;
|
||||
const db::Net *net = c->net_for_pin (pin->id ());
|
||||
|
||||
// If the pin isn't connected internally inside the circuit we can ignore it
|
||||
if (c->net_for_pin (pin->id ()) && c->net_for_pin (pin->id ())->is_passive ()) {
|
||||
if (mp_logger) {
|
||||
mp_logger->match_pins (pin1, pin2);
|
||||
// Nets which are paired with "null" trigger this condition:
|
||||
if (net) {
|
||||
const db::NetGraphNode &n = graph->node (graph->node_index_for_net (net));
|
||||
if (n.has_other ()) {
|
||||
if (mp_logger) {
|
||||
mp_logger->match_pins (pin1, pin2);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine whether the pin in question is used - only in this case we will report an error.
|
||||
// Otherwise, the report will be "match" against 0.
|
||||
// "used" follows a heuristic criterion derived from the subcircuits which make use of this circuit:
|
||||
// if one of these connects the pin to a net with either connections upwards, other subcircuits or
|
||||
// devices, the pin is regarded "used".
|
||||
// TODO: it would be better probably to have a global concept of "used pins" which considers all
|
||||
// devices and propagates their presence as "used" property upwards, then downwards to the subcircuit
|
||||
// pins.
|
||||
|
||||
bool is_not_connected = true;
|
||||
for (db::Circuit::const_refs_iterator r = c->begin_refs (); r != c->end_refs () && is_not_connected; ++r) {
|
||||
|
|
@ -2999,12 +3030,12 @@ NetlistComparer::handle_pin_mismatch (const db::Circuit *c1, const db::Pin *pin1
|
|||
if (mp_logger) {
|
||||
mp_logger->match_pins (pin1, pin2);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
if (mp_logger) {
|
||||
mp_logger->pin_mismatch (pin1, pin2);
|
||||
}
|
||||
good = false;
|
||||
pin_mismatch = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3042,18 +3073,21 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<const db::Pin *> abstract_pins;
|
||||
std::multimap<size_t, const db::Pin *> net2pin;
|
||||
std::vector<const db::Pin *> abstract_pins2;
|
||||
std::multimap<size_t, const db::Pin *> net2pin2;
|
||||
for (db::Circuit::const_pin_iterator p = c2->begin_pins (); p != c2->end_pins (); ++p) {
|
||||
const db::Net *net = c2->net_for_pin (p->id ());
|
||||
if (net) {
|
||||
net2pin.insert (std::make_pair (g2.node_index_for_net (net), p.operator-> ()));
|
||||
net2pin2.insert (std::make_pair (g2.node_index_for_net (net), p.operator-> ()));
|
||||
} else if (abstract_pin_name_mapping.find (p.operator-> ()) == abstract_pin_name_mapping.end ()) {
|
||||
abstract_pins.push_back (p.operator-> ());
|
||||
abstract_pins2.push_back (p.operator-> ());
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<const db::Pin *>::iterator next_abstract = abstract_pins.begin ();
|
||||
// collect missing assignment for circuit 1
|
||||
std::multimap<size_t, const db::Pin *> net2pin1;
|
||||
|
||||
std::vector<const db::Pin *>::iterator next_abstract = abstract_pins2.begin ();
|
||||
|
||||
CircuitMapper &c12_pin_mapping = c12_circuit_and_pin_mapping [c1];
|
||||
c12_pin_mapping.set_other (c2);
|
||||
|
|
@ -3078,7 +3112,7 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g
|
|||
c12_pin_mapping.map_pin (p->id (), fp->second->id ());
|
||||
c22_pin_mapping.map_pin (fp->second->id (), p->id ());
|
||||
|
||||
} else if (next_abstract != abstract_pins.end ()) {
|
||||
} else if (next_abstract != abstract_pins2.end ()) {
|
||||
|
||||
// assign an abstract pin - this is a dummy assignment which is mitigated
|
||||
// by declaring the pins equivalent in derive_pin_equivalence
|
||||
|
|
@ -3093,7 +3127,10 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g
|
|||
} else {
|
||||
|
||||
// otherwise this is an error for subcircuits or worth a report for top-level circuits
|
||||
handle_pin_mismatch (c1, p.operator-> (), c2, 0, good, pin_mismatch);
|
||||
if (! handle_pin_mismatch (g1, c1, p.operator-> (), g2, c2, 0)) {
|
||||
good = false;
|
||||
pin_mismatch = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -3104,14 +3141,15 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g
|
|||
const db::NetGraphNode &n = *(g1.begin () + g1.node_index_for_net (net));
|
||||
|
||||
if (! n.has_other ()) {
|
||||
handle_pin_mismatch (c1, p.operator-> (), c2, 0, good, pin_mismatch);
|
||||
// remember and handle later when we know which pins are not mapped
|
||||
net2pin1.insert (std::make_pair (g1.node_index_for_net (net), p.operator-> ()));
|
||||
continue;
|
||||
}
|
||||
|
||||
std::multimap<size_t, const db::Pin *>::iterator np = net2pin.find (n.other_net_index ());
|
||||
std::multimap<size_t, const db::Pin *>::iterator np = net2pin2.find (n.other_net_index ());
|
||||
for (db::Net::const_pin_iterator pi = net->begin_pins (); pi != net->end_pins (); ++pi) {
|
||||
|
||||
if (np != net2pin.end () && np->first == n.other_net_index ()) {
|
||||
if (np != net2pin2.end () && np->first == n.other_net_index ()) {
|
||||
|
||||
if (mp_logger) {
|
||||
mp_logger->match_pins (pi->pin (), np->second);
|
||||
|
|
@ -3122,11 +3160,12 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g
|
|||
|
||||
std::multimap<size_t, const db::Pin *>::iterator np_delete = np;
|
||||
++np;
|
||||
net2pin.erase (np_delete);
|
||||
net2pin2.erase (np_delete);
|
||||
|
||||
} else {
|
||||
|
||||
handle_pin_mismatch (c1, pi->pin (), c2, 0, good, pin_mismatch);
|
||||
// remember and handle later when we know which pins are not mapped
|
||||
net2pin1.insert (std::make_pair (g1.node_index_for_net (net), p.operator-> ()));
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -3134,16 +3173,28 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g
|
|||
|
||||
}
|
||||
|
||||
for (std::multimap<size_t, const db::Pin *>::iterator np = net2pin.begin (); np != net2pin.end (); ++np) {
|
||||
handle_pin_mismatch (c1, 0, c2, np->second, good, pin_mismatch);
|
||||
for (std::multimap<size_t, const db::Pin *>::iterator np = net2pin1.begin (); np != net2pin1.end (); ++np) {
|
||||
if (! handle_pin_mismatch (g1, c1, np->second, g2, c2, 0)) {
|
||||
good = false;
|
||||
pin_mismatch = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (std::multimap<size_t, const db::Pin *>::iterator np = net2pin2.begin (); np != net2pin2.end (); ++np) {
|
||||
if (! handle_pin_mismatch (g1, c1, 0, g2, c2, np->second)) {
|
||||
good = false;
|
||||
pin_mismatch = true;
|
||||
}
|
||||
}
|
||||
|
||||
// abstract pins must match.
|
||||
while (next_abstract != abstract_pins.end ()) {
|
||||
handle_pin_mismatch (c1, 0, c2, *next_abstract, good, pin_mismatch);
|
||||
while (next_abstract != abstract_pins2.end ()) {
|
||||
if (! handle_pin_mismatch (g1, c1, 0, g2, c2, *next_abstract)) {
|
||||
good = false;
|
||||
pin_mismatch = true;
|
||||
}
|
||||
++next_abstract;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -3384,7 +3435,7 @@ NetlistComparer::do_subcircuit_assignment (const db::Circuit *c1, const db::NetG
|
|||
|
||||
bool mapped = true;
|
||||
for (std::vector<std::pair<size_t, size_t> >::iterator i = k.begin (); i != k.end (); ++i) {
|
||||
if (! g1.begin () [i->second].has_other ()) {
|
||||
if (! g2.begin () [i->second].has_other ()) {
|
||||
mapped = false;
|
||||
} else {
|
||||
i->second = g2.begin () [i->second].other_net_index ();
|
||||
|
|
|
|||
|
|
@ -314,7 +314,7 @@ protected:
|
|||
void do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g1, const db::Circuit *c2, const db::NetGraph &g2, std::map<const db::Circuit *, CircuitMapper> &c12_circuit_and_pin_mapping, std::map<const db::Circuit *, CircuitMapper> &c22_circuit_and_pin_mapping, bool &pin_mismatch, bool &good) const;
|
||||
void do_device_assignment (const db::Circuit *c1, const db::NetGraph &g1, const db::Circuit *c2, const db::NetGraph &g2, const db::DeviceFilter &device_filter, DeviceCategorizer &device_categorizer, bool &good) const;
|
||||
void do_subcircuit_assignment (const db::Circuit *c1, const db::NetGraph &g1, const db::Circuit *c2, const db::NetGraph &g2, CircuitCategorizer &circuit_categorizer, const db::CircuitPinMapper &circuit_pin_mapper, std::map<const db::Circuit *, CircuitMapper> &c12_circuit_and_pin_mapping, std::map<const db::Circuit *, CircuitMapper> &c22_circuit_and_pin_mapping, bool &good) const;
|
||||
void handle_pin_mismatch (const db::Circuit *c1, const db::Pin *pin1, const db::Circuit *c2, const db::Pin *p2, bool &good, bool &pin_mismatch) const;
|
||||
bool handle_pin_mismatch (const NetGraph &g1, const db::Circuit *c1, const db::Pin *pin1, const NetGraph &g2, const db::Circuit *c2, const db::Pin *p2) const;
|
||||
|
||||
mutable NetlistCompareLogger *mp_logger;
|
||||
std::map<std::pair<const db::Circuit *, const db::Circuit *>, std::vector<std::pair<const Net *, const Net *> > > m_same_nets;
|
||||
|
|
|
|||
|
|
@ -2055,11 +2055,11 @@ TEST(14_Subcircuit2NandMismatchNoSwap)
|
|||
"net_mismatch INT IN1\n"
|
||||
"net_mismatch IN1 INT\n"
|
||||
"net_mismatch IN2 IN2\n"
|
||||
"match_pins $0 (null)\n"
|
||||
"match_pins $1 $1\n"
|
||||
"match_pins $2 $2\n"
|
||||
"match_pins $3 $3\n"
|
||||
"match_pins $4 $4\n"
|
||||
"match_pins $0 (null)\n"
|
||||
"match_pins (null) $0\n"
|
||||
"match_subcircuits $2 $1\n"
|
||||
"subcircuit_mismatch $1 $2\n"
|
||||
|
|
@ -3366,3 +3366,362 @@ TEST(21_BusLikeAmbiguousConnections)
|
|||
EXPECT_EQ (good, true);
|
||||
}
|
||||
|
||||
TEST(22_NodesRemoved)
|
||||
{
|
||||
const char *nls1 =
|
||||
"circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,VSS=VSS);\n"
|
||||
" subcircuit INV2PAIR $1 ($2=FB,$3=VDD,$4=VSS,$5=$I7,$6=OSC);\n"
|
||||
" subcircuit INV2PAIR $2 ($2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I21);\n"
|
||||
" subcircuit INV2PAIR $3 ($2=$I23,$3=VDD,$4=VSS,$5=$I21,$6=$I5);\n"
|
||||
" subcircuit INV2PAIR $4 ($2=$I24,$3=VDD,$4=VSS,$5=$I5,$6=$I6);\n"
|
||||
" subcircuit INV2PAIR $5 ($2=$I25,$3=VDD,$4=VSS,$5=$I6,$6=$I7);\n"
|
||||
"end;\n"
|
||||
"circuit INV2PAIR ($2=$I8,$3=$I5,$4=$I4,$5=$I3,$6=$I2);\n"
|
||||
" subcircuit INV2 $1 (IN=$I3,$3=$I7,OUT=$I6,VSS=$I4,VDD=$I5);\n"
|
||||
" subcircuit INV2 $2 (IN=$I6,$3=$I8,OUT=$I2,VSS=$I4,VDD=$I5);\n"
|
||||
"end;\n"
|
||||
"circuit INV2 (IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD);\n"
|
||||
" device PMOS $1 (S=$3,G=IN,D=VDD) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||
" device PMOS $2 (S=VDD,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
|
||||
" device NMOS $3 (S=$3,G=IN,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||
" device NMOS $4 (S=VSS,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
|
||||
"end;\n";
|
||||
|
||||
const char *nls2 =
|
||||
"circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,VSS=VSS);\n"
|
||||
" subcircuit INV2PAIR $1 (BULK=VSS,$2=FB,$3=VDD,$4=VSS,$5=$I7,$6=OSC,$7=VDD);\n"
|
||||
" subcircuit INV2PAIR $2 (BULK=VSS,$2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I13,$7=VDD);\n"
|
||||
" subcircuit INV2PAIR $3 (BULK=VSS,$2=$I23,$3=VDD,$4=VSS,$5=$I13,$6=$I5,$7=VDD);\n"
|
||||
" subcircuit INV2PAIR $4 (BULK=VSS,$2=$I24,$3=VDD,$4=VSS,$5=$I5,$6=$I6,$7=VDD);\n"
|
||||
" subcircuit INV2PAIR $5 (BULK=VSS,$2=$I25,$3=VDD,$4=VSS,$5=$I6,$6=$I7,$7=VDD);\n"
|
||||
"end;\n"
|
||||
"circuit INV2PAIR (BULK=BULK,$2=$I8,$3=$I6,$4=$I5,$5=$I3,$6=$I2,$7=$I1);\n"
|
||||
" subcircuit INV2 $1 ($1=$I1,IN=$I3,$3=$I7,OUT=$I4,VSS=$I5,VDD=$I6,BULK=BULK);\n"
|
||||
" subcircuit INV2 $2 ($1=$I1,IN=$I4,$3=$I8,OUT=$I2,VSS=$I5,VDD=$I6,BULK=BULK);\n"
|
||||
"end;\n"
|
||||
"circuit INV2 ($1=$1,IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD,BULK=BULK);\n"
|
||||
" device PMOS $1 (S=$3,G=IN,D=VDD) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||
" device PMOS $2 (S=VDD,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
|
||||
" device NMOS $3 (S=$3,G=IN,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||
" device NMOS $4 (S=VSS,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
|
||||
"end;\n";
|
||||
|
||||
db::Netlist nl1, nl2;
|
||||
prep_nl (nl1, nls1);
|
||||
prep_nl (nl2, nls2);
|
||||
|
||||
NetlistCompareTestLogger logger;
|
||||
db::NetlistComparer comp (&logger);
|
||||
|
||||
bool good = comp.compare (&nl1, &nl2);
|
||||
|
||||
std::string txt = logger.text ();
|
||||
|
||||
EXPECT_EQ (txt,
|
||||
"begin_circuit INV2 INV2\n"
|
||||
"match_nets VDD VDD\n"
|
||||
"match_nets OUT OUT\n"
|
||||
"match_nets $3 $3\n"
|
||||
"match_nets IN IN\n"
|
||||
"match_nets VSS VSS\n"
|
||||
"match_nets (null) $1\n"
|
||||
"match_nets (null) BULK\n"
|
||||
"match_pins IN IN\n"
|
||||
"match_pins $1 $2\n"
|
||||
"match_pins OUT OUT\n"
|
||||
"match_pins VSS VSS\n"
|
||||
"match_pins VDD VDD\n"
|
||||
"match_pins (null) $0\n"
|
||||
"match_pins (null) BULK\n"
|
||||
"match_devices $1 $1\n"
|
||||
"match_devices $2 $2\n"
|
||||
"match_devices $3 $3\n"
|
||||
"match_devices $4 $4\n"
|
||||
"end_circuit INV2 INV2 MATCH\n"
|
||||
"begin_circuit INV2PAIR INV2PAIR\n"
|
||||
"match_nets $I2 $I2\n"
|
||||
"match_nets $I5 $I6\n"
|
||||
"match_nets $I4 $I5\n"
|
||||
"match_nets $I6 $I4\n"
|
||||
"match_nets $I3 $I3\n"
|
||||
"match_nets $I7 $I7\n"
|
||||
"match_nets $I8 $I8\n"
|
||||
"match_nets (null) BULK\n"
|
||||
"match_nets (null) $I1\n"
|
||||
"match_pins $0 $1\n"
|
||||
"match_pins $1 $2\n"
|
||||
"match_pins $2 $3\n"
|
||||
"match_pins $3 $4\n"
|
||||
"match_pins $4 $5\n"
|
||||
"match_pins (null) BULK\n"
|
||||
"match_pins (null) $6\n"
|
||||
"match_subcircuits $1 $1\n"
|
||||
"match_subcircuits $2 $2\n"
|
||||
"end_circuit INV2PAIR INV2PAIR MATCH\n"
|
||||
"begin_circuit RINGO RINGO\n"
|
||||
"match_nets OSC OSC\n"
|
||||
"match_nets $I7 $I7\n"
|
||||
"match_nets $I6 $I6\n"
|
||||
"match_nets $I5 $I5\n"
|
||||
"match_nets $I21 $I13\n"
|
||||
"match_nets FB FB\n"
|
||||
"match_nets VSS VSS\n"
|
||||
"match_nets VDD VDD\n"
|
||||
"match_nets $I22 $I22\n"
|
||||
"match_nets $I23 $I23\n"
|
||||
"match_nets $I24 $I24\n"
|
||||
"match_nets $I25 $I25\n"
|
||||
"match_pins FB FB\n"
|
||||
"match_pins OSC OSC\n"
|
||||
"match_pins VDD VDD\n"
|
||||
"match_pins VSS VSS\n"
|
||||
"match_subcircuits $1 $1\n"
|
||||
"match_subcircuits $2 $2\n"
|
||||
"match_subcircuits $3 $3\n"
|
||||
"match_subcircuits $4 $4\n"
|
||||
"match_subcircuits $5 $5\n"
|
||||
"end_circuit RINGO RINGO MATCH"
|
||||
);
|
||||
EXPECT_EQ (good, true);
|
||||
}
|
||||
|
||||
TEST(23_NodesRemovedWithError)
|
||||
{
|
||||
const char *nls1 =
|
||||
"circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,VSS=VSS);\n"
|
||||
" subcircuit INV2PAIR $1 ($2=FB,$3=VDD,$4=VSS,$5=$I7,$6=OSC);\n"
|
||||
" subcircuit INV2PAIR $2 ($2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I21);\n"
|
||||
" subcircuit INV2PAIR $3 ($2=$I23,$3=VDD,$4=VSS,$5=$I21,$6=$I5);\n"
|
||||
" subcircuit INV2PAIR $4 ($2=$I24,$3=VDD,$4=VSS,$5=$I5,$6=$I6);\n"
|
||||
" subcircuit INV2PAIR $5 ($2=$I25,$3=VDD,$4=VSS,$5=$I6,$6=$I7);\n"
|
||||
"end;\n"
|
||||
"circuit INV2PAIR ($2=$I8,$3=$I5,$4=$I4,$5=$I3,$6=$I2);\n"
|
||||
// NOTE: $1 pin should not be connected to different nets, although it's not functional
|
||||
" subcircuit INV2 $1 ($1=$3,IN=$I3,$3=$I7,OUT=$I6,VSS=$I4,VDD=$I5);\n"
|
||||
" subcircuit INV2 $2 ($1=$6,IN=$I6,$3=$I8,OUT=$I2,VSS=$I4,VDD=$I5);\n"
|
||||
"end;\n"
|
||||
"circuit INV2 ($1=$1,IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD);\n"
|
||||
" device PMOS $1 (S=$3,G=IN,D=VDD) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||
" device PMOS $2 (S=VDD,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
|
||||
" device NMOS $3 (S=$3,G=IN,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||
" device NMOS $4 (S=VSS,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
|
||||
"end;\n";
|
||||
|
||||
const char *nls2 =
|
||||
"circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,VSS=VSS);\n"
|
||||
" subcircuit INV2PAIR $1 (BULK=VSS,$2=FB,$3=VDD,$4=VSS,$5=$I7,$6=OSC,$7=VDD);\n"
|
||||
" subcircuit INV2PAIR $2 (BULK=VSS,$2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I13,$7=VDD);\n"
|
||||
" subcircuit INV2PAIR $3 (BULK=VSS,$2=$I23,$3=VDD,$4=VSS,$5=$I13,$6=$I5,$7=VDD);\n"
|
||||
" subcircuit INV2PAIR $4 (BULK=VSS,$2=$I24,$3=VDD,$4=VSS,$5=$I5,$6=$I6,$7=VDD);\n"
|
||||
" subcircuit INV2PAIR $5 (BULK=VSS,$2=$I25,$3=VDD,$4=VSS,$5=$I6,$6=$I7,$7=VDD);\n"
|
||||
"end;\n"
|
||||
"circuit INV2PAIR (BULK=BULK,$2=$I8,$3=$I6,$4=$I5,$5=$I3,$6=$I2,$7=$I1);\n"
|
||||
" subcircuit INV2 $1 ($1=$I1,IN=$I3,$3=$I7,OUT=$I4,VSS=$I5,VDD=$I6,BULK=BULK);\n"
|
||||
" subcircuit INV2 $2 ($1=$I1,IN=$I4,$3=$I8,OUT=$I2,VSS=$I5,VDD=$I6,BULK=BULK);\n"
|
||||
"end;\n"
|
||||
"circuit INV2 ($1=$1,IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD,BULK=BULK);\n"
|
||||
" device PMOS $1 (S=$3,G=IN,D=VDD) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||
" device PMOS $2 (S=VDD,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
|
||||
" device NMOS $3 (S=$3,G=IN,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||
" device NMOS $4 (S=VSS,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
|
||||
"end;\n";
|
||||
|
||||
db::Netlist nl1, nl2;
|
||||
prep_nl (nl1, nls1);
|
||||
prep_nl (nl2, nls2);
|
||||
|
||||
NetlistCompareTestLogger logger;
|
||||
db::NetlistComparer comp (&logger);
|
||||
|
||||
bool good = comp.compare (&nl1, &nl2);
|
||||
|
||||
std::string txt = logger.text ();
|
||||
|
||||
EXPECT_EQ (txt,
|
||||
"begin_circuit INV2 INV2\n"
|
||||
"match_nets $1 $1\n"
|
||||
"match_nets VDD VDD\n"
|
||||
"match_nets OUT OUT\n"
|
||||
"match_nets $3 $3\n"
|
||||
"match_nets IN IN\n"
|
||||
"match_nets VSS VSS\n"
|
||||
"match_nets (null) BULK\n"
|
||||
"match_pins $0 $0\n"
|
||||
"match_pins IN IN\n"
|
||||
"match_pins $2 $2\n"
|
||||
"match_pins OUT OUT\n"
|
||||
"match_pins VSS VSS\n"
|
||||
"match_pins VDD VDD\n"
|
||||
"match_pins (null) BULK\n"
|
||||
"match_devices $1 $1\n"
|
||||
"match_devices $2 $2\n"
|
||||
"match_devices $3 $3\n"
|
||||
"match_devices $4 $4\n"
|
||||
"end_circuit INV2 INV2 MATCH\n"
|
||||
"begin_circuit INV2PAIR INV2PAIR\n"
|
||||
"match_nets $I2 $I2\n"
|
||||
"match_nets $I5 $I6\n"
|
||||
"match_nets $I4 $I5\n"
|
||||
"match_nets $I6 $I4\n"
|
||||
"match_nets $I3 $I3\n"
|
||||
"match_nets $I7 $I7\n"
|
||||
"net_mismatch $3 $I1\n"
|
||||
"match_nets $I8 $I8\n"
|
||||
"net_mismatch $6 BULK\n"
|
||||
"match_pins $0 $1\n"
|
||||
"match_pins $1 $2\n"
|
||||
"match_pins $2 $3\n"
|
||||
"match_pins $3 $4\n"
|
||||
"match_pins $4 $5\n"
|
||||
"match_pins (null) BULK\n"
|
||||
"match_pins (null) $6\n"
|
||||
"match_subcircuits $1 $1\n"
|
||||
"subcircuit_mismatch $2 $2\n"
|
||||
"end_circuit INV2PAIR INV2PAIR NOMATCH\n"
|
||||
"begin_circuit RINGO RINGO\n"
|
||||
"match_nets OSC OSC\n"
|
||||
"match_nets $I7 $I7\n"
|
||||
"match_nets $I6 $I6\n"
|
||||
"match_nets $I5 $I5\n"
|
||||
"match_nets $I21 $I13\n"
|
||||
"match_nets FB FB\n"
|
||||
"match_nets VSS VSS\n"
|
||||
"match_nets VDD VDD\n"
|
||||
"match_nets $I22 $I22\n"
|
||||
"match_nets $I23 $I23\n"
|
||||
"match_nets $I24 $I24\n"
|
||||
"match_nets $I25 $I25\n"
|
||||
"match_pins FB FB\n"
|
||||
"match_pins OSC OSC\n"
|
||||
"match_pins VDD VDD\n"
|
||||
"match_pins VSS VSS\n"
|
||||
"match_subcircuits $1 $1\n"
|
||||
"match_subcircuits $2 $2\n"
|
||||
"match_subcircuits $3 $3\n"
|
||||
"match_subcircuits $4 $4\n"
|
||||
"match_subcircuits $5 $5\n"
|
||||
"end_circuit RINGO RINGO MATCH"
|
||||
);
|
||||
EXPECT_EQ (good, false);
|
||||
}
|
||||
|
||||
TEST(24_NodesRemovedButConnectedInOther)
|
||||
{
|
||||
const char *nls1 =
|
||||
"circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,VSS=VSS);\n"
|
||||
" subcircuit INV2PAIR $1 ($2=FB,$3=VDD,$4=VSS,$5=$I7,$6=OSC);\n"
|
||||
" subcircuit INV2PAIR $2 ($2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I21);\n"
|
||||
" subcircuit INV2PAIR $3 ($2=$I23,$3=VDD,$4=VSS,$5=$I21,$6=$I5);\n"
|
||||
" subcircuit INV2PAIR $4 ($2=$I24,$3=VDD,$4=VSS,$5=$I5,$6=$I6);\n"
|
||||
" subcircuit INV2PAIR $5 ($2=$I25,$3=VDD,$4=VSS,$5=$I6,$6=$I7);\n"
|
||||
"end;\n"
|
||||
"circuit INV2PAIR ($2=$I8,$3=$I5,$4=$I4,$5=$I3,$6=$I2);\n"
|
||||
" subcircuit INV2 $1 (IN=$I3,$3=$I7,OUT=$I6,VSS=$I4,VDD=$I5);\n"
|
||||
" subcircuit INV2 $2 (IN=$I6,$3=$I8,OUT=$I2,VSS=$I4,VDD=$I5);\n"
|
||||
"end;\n"
|
||||
"circuit INV2 (IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD);\n"
|
||||
" device PMOS $1 (S=$3,G=IN,D=VDD) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||
" device PMOS $2 (S=VDD,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
|
||||
" device NMOS $3 (S=$3,G=IN,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||
" device NMOS $4 (S=VSS,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
|
||||
"end;\n";
|
||||
|
||||
const char *nls2 =
|
||||
"circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,VSS=VSS);\n"
|
||||
" subcircuit INV2PAIR $1 (BULK=VSS,$2=FB,$3=VDD,$4=VSS,$5=$I7,$6=OSC,$7=VDD);\n"
|
||||
" subcircuit INV2PAIR $2 (BULK=VSS,$2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I13,$7=VDD);\n"
|
||||
" subcircuit INV2PAIR $3 (BULK=VSS,$2=$I23,$3=VDD,$4=VSS,$5=$I13,$6=$I5,$7=VDD);\n"
|
||||
" subcircuit INV2PAIR $4 (BULK=VSS,$2=$I24,$3=VDD,$4=VSS,$5=$I5,$6=$I6,$7=VDD);\n"
|
||||
" subcircuit INV2PAIR $5 (BULK=VSS,$2=$I25,$3=VDD,$4=VSS,$5=$I6,$6=$I7,$7=VDD);\n"
|
||||
"end;\n"
|
||||
// rewired here: BULK->VSS (pin $4), $1->$I3/$I4 (both rewired pins are deleted in the first netlist)
|
||||
// This proves that we can basically do everything with the dropped pins.
|
||||
"circuit INV2PAIR (BULK=BULK,$2=$I8,$3=$I6,$4=$I5,$5=$I3,$6=$I2,$7=$I1);\n"
|
||||
" subcircuit INV2 $1 ($1=$I3,IN=$I3,$3=$I7,OUT=$I4,VSS=$I5,VDD=$I6,BULK=$I5);\n"
|
||||
" subcircuit INV2 $2 ($1=$I4,IN=$I4,$3=$I8,OUT=$I2,VSS=$I5,VDD=$I6,BULK=$I5);\n"
|
||||
"end;\n"
|
||||
"circuit INV2 ($1=$1,IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD,BULK=BULK);\n"
|
||||
" device PMOS $1 (S=$3,G=IN,D=VDD) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||
" device PMOS $2 (S=VDD,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
|
||||
" device NMOS $3 (S=$3,G=IN,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||
" device NMOS $4 (S=VSS,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
|
||||
"end;\n";
|
||||
|
||||
db::Netlist nl1, nl2;
|
||||
prep_nl (nl1, nls1);
|
||||
prep_nl (nl2, nls2);
|
||||
|
||||
NetlistCompareTestLogger logger;
|
||||
db::NetlistComparer comp (&logger);
|
||||
|
||||
bool good = comp.compare (&nl1, &nl2);
|
||||
|
||||
std::string txt = logger.text ();
|
||||
|
||||
EXPECT_EQ (txt,
|
||||
"begin_circuit INV2 INV2\n"
|
||||
"match_nets VDD VDD\n"
|
||||
"match_nets OUT OUT\n"
|
||||
"match_nets $3 $3\n"
|
||||
"match_nets IN IN\n"
|
||||
"match_nets VSS VSS\n"
|
||||
"match_nets (null) $1\n"
|
||||
"match_nets (null) BULK\n"
|
||||
"match_pins IN IN\n"
|
||||
"match_pins $1 $2\n"
|
||||
"match_pins OUT OUT\n"
|
||||
"match_pins VSS VSS\n"
|
||||
"match_pins VDD VDD\n"
|
||||
"match_pins (null) $0\n"
|
||||
"match_pins (null) BULK\n"
|
||||
"match_devices $1 $1\n"
|
||||
"match_devices $2 $2\n"
|
||||
"match_devices $3 $3\n"
|
||||
"match_devices $4 $4\n"
|
||||
"end_circuit INV2 INV2 MATCH\n"
|
||||
"begin_circuit INV2PAIR INV2PAIR\n"
|
||||
"match_nets $I2 $I2\n"
|
||||
"match_nets $I5 $I6\n"
|
||||
"match_nets $I4 $I5\n"
|
||||
"match_nets $I6 $I4\n"
|
||||
"match_nets $I3 $I3\n"
|
||||
"match_nets $I7 $I7\n"
|
||||
"match_nets $I8 $I8\n"
|
||||
"match_nets (null) BULK\n"
|
||||
"match_nets (null) $I1\n"
|
||||
"match_pins $0 $1\n"
|
||||
"match_pins $1 $2\n"
|
||||
"match_pins $2 $3\n"
|
||||
"match_pins $3 $4\n"
|
||||
"match_pins $4 $5\n"
|
||||
"match_pins (null) BULK\n"
|
||||
"match_pins (null) $6\n"
|
||||
"match_subcircuits $1 $1\n"
|
||||
"match_subcircuits $2 $2\n"
|
||||
"end_circuit INV2PAIR INV2PAIR MATCH\n"
|
||||
"begin_circuit RINGO RINGO\n"
|
||||
"match_nets OSC OSC\n"
|
||||
"match_nets $I7 $I7\n"
|
||||
"match_nets $I6 $I6\n"
|
||||
"match_nets $I5 $I5\n"
|
||||
"match_nets $I21 $I13\n"
|
||||
"match_nets FB FB\n"
|
||||
"match_nets VSS VSS\n"
|
||||
"match_nets VDD VDD\n"
|
||||
"match_nets $I22 $I22\n"
|
||||
"match_nets $I23 $I23\n"
|
||||
"match_nets $I24 $I24\n"
|
||||
"match_nets $I25 $I25\n"
|
||||
"match_pins FB FB\n"
|
||||
"match_pins OSC OSC\n"
|
||||
"match_pins VDD VDD\n"
|
||||
"match_pins VSS VSS\n"
|
||||
"match_subcircuits $1 $1\n"
|
||||
"match_subcircuits $2 $2\n"
|
||||
"match_subcircuits $3 $3\n"
|
||||
"match_subcircuits $4 $4\n"
|
||||
"match_subcircuits $5 $5\n"
|
||||
"end_circuit RINGO RINGO MATCH"
|
||||
);
|
||||
EXPECT_EQ (good, true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1404,7 +1404,7 @@ TEST(22_BlankCircuit)
|
|||
nl2.purge ();
|
||||
|
||||
EXPECT_EQ (nl2.to_string (),
|
||||
"circuit RINGO (IN=IN,OSC=OSC,VSS=VSS,VDD=VDD);\n"
|
||||
"circuit RINGO (OSC=OSC,VSS=VSS,VDD=VDD);\n"
|
||||
" subcircuit INV2 INV2_SC1 (IN=$I8,$2=FB,OUT=OSC,$4=VSS,$5=VDD);\n"
|
||||
" subcircuit INV2 INV2_SC2 (IN=FB,$2=(null),OUT=$I8,$4=VSS,$5=VDD);\n"
|
||||
"end;\n"
|
||||
|
|
|
|||
Loading…
Reference in New Issue