Merge remote-tracking branch 'origin/master' into master-mac-qt6

This commit is contained in:
Kazunari Sekigawa 2022-08-11 07:06:25 +09:00
commit ca4267ee5f
10 changed files with 416 additions and 126 deletions

View File

@ -1419,7 +1419,7 @@ NetlistComparer::do_device_assignment (const db::Circuit *c1, const db::NetGraph
bool mapped = true;
std::vector<std::pair<size_t, size_t> > k = compute_device_key_for_other (*d, g2, device_categorizer.is_strict_device_category (device_cat), mapped);
std::multimap<std::vector<std::pair<size_t, size_t> >, std::pair<const db::Device *, size_t> >::iterator dm = device_map.find (k);
auto dm = device_map.find (k);
if (! mapped || dm == device_map.end () || dm->first != k) {
@ -1430,6 +1430,30 @@ NetlistComparer::do_device_assignment (const db::Circuit *c1, const db::NetGraph
} else {
auto dmm = dm;
++dmm;
size_t n = 1;
while (dmm != device_map.end () && dmm->first == k) {
++dmm;
++n;
}
if (n > 1) {
// device ambiguities may arise from different devices being connected in parallel:
// try to identify the device which matches
db::DeviceCompare dc;
for (auto i = dm; i != dmm; ++i) {
if (dc.equals (std::make_pair (i->second.first, i->second.second), std::make_pair (d.operator-> (), device_cat))) {
dm = i;
break;
}
}
}
c1_device = dm->second.first;
c1_device_cat = dm->second.second;

View File

@ -1025,6 +1025,7 @@ NetlistCompareCore::derive_node_identities_from_ambiguity_group (const NodeRange
// ambiguous pins
std::vector<size_t> pa, pb;
std::set<const db::Net *> seen;
for (std::vector<std::pair<const NetGraphNode *, const NetGraphNode *> >::const_iterator p = pairs.begin (); p != pairs.end (); ++p) {
@ -1043,6 +1044,9 @@ NetlistCompareCore::derive_node_identities_from_ambiguity_group (const NodeRange
}
}
tl_assert (seen.find (p->first->net ()) == seen.end ());
seen.insert (p->first->net ());
if (ambiguous) {
if (logger) {
logger->match_ambiguous_nets (p->first->net (), p->second->net ());
@ -1068,7 +1072,7 @@ NetlistCompareCore::derive_node_identities_from_ambiguity_group (const NodeRange
// Note: this would propagate ambiguities to all *derived* mappings. But this probably goes too far:
// bool ambiguous = equivalent_other_nodes.has_attribute (p->second);
// Instead we ignore propagated ambiguitied for now:
// Instead we ignore propagated ambiguities for now:
bool ambiguous = false;
if (db::NetlistCompareGlobalOptions::options ()->debug_netcompare || tl::verbosity () >= 40) {
@ -1085,6 +1089,13 @@ NetlistCompareCore::derive_node_identities_from_ambiguity_group (const NodeRange
NetGraphNode *n = & mp_graph->node (i->second);
// tentative evaluation paths may render equivalences which are included in the initial node set,
// hence we filter those out here
if (seen.find (n->net ()) != seen.end ()) {
continue;
}
seen.insert (n->net ());
size_t other_net_index = n->other_net_index ();
NetGraphNode *n_other = & mp_other_graph->node (other_net_index);
@ -1157,7 +1168,7 @@ NetlistCompareCore::derive_node_identities_from_singular_match (const NetGraphNo
}
return tentative ? failed_match : 0;
} else if (! n->has_any_other () && ! n_other->has_any_other ()) {
} else if ((! n->has_any_other () && ! n_other->has_any_other ()) || (n->has_unknown_other () && n_other->has_unknown_other ())) { // @@@
// in tentative mode, reject this choice if both nets are named and
// their names differ -> this favors net matching by name
@ -1177,7 +1188,11 @@ NetlistCompareCore::derive_node_identities_from_singular_match (const NetGraphNo
bool exact_match = (mp_graph->node (ni) == mp_other_graph->node (other_ni));
TentativeNodeMapping::map_pair (tentative, mp_graph, ni, mp_other_graph, other_ni, dm, dm_other, *device_equivalence, scm, scm_other, *subcircuit_equivalence, depth, exact_match);
if (n->has_unknown_other ()) {
TentativeNodeMapping::map_pair_from_unknown (tentative, mp_graph, ni, mp_other_graph, other_ni, dm, dm_other, *device_equivalence, scm, scm_other, *subcircuit_equivalence, depth);
} else {
TentativeNodeMapping::map_pair (tentative, mp_graph, ni, mp_other_graph, other_ni, dm, dm_other, *device_equivalence, scm, scm_other, *subcircuit_equivalence, depth, exact_match);
}
if (! tentative) {
++*progress;
@ -1212,11 +1227,6 @@ NetlistCompareCore::derive_node_identities_from_singular_match (const NetGraphNo
return new_nodes;
} else if (n->has_unknown_other ()) {
// accept any other net
return 0;
} else if (n->has_other ()) {
// this decision leads to a contradiction

View File

@ -1566,15 +1566,21 @@ TEST(8_DiodesDontMatchOnSwappedPins)
EXPECT_EQ (logger.text (),
"begin_circuit TRIANGLE TRIANGLE\n"
"match_nets P3 P3\n"
"net_mismatch P1 P1\n"
"net_mismatch P2 P2\n"
"match_pins $0 $0\n"
"match_pins $1 $1\n"
"match_pins $2 $2\n"
"match_devices $3 $1\n"
"match_devices $2 $3\n"
"device_mismatch $1 $2\n"
"net_mismatch P1 (null)\n"
"net_mismatch P2 (null)\n"
"net_mismatch P3 (null)\n"
"net_mismatch (null) P1\n"
"net_mismatch (null) P2\n"
"net_mismatch (null) P3\n"
"match_pins $0 (null)\n"
"match_pins $1 (null)\n"
"match_pins $2 (null)\n"
"match_pins (null) $0\n"
"match_pins (null) $1\n"
"match_pins (null) $2\n"
"device_mismatch $1 $1\n"
"device_mismatch $2 $2\n"
"device_mismatch $3 $3\n"
"end_circuit TRIANGLE TRIANGLE NOMATCH"
);
EXPECT_EQ (good, false);
@ -4882,3 +4888,145 @@ TEST(30_ComparePrimaryAndOtherParameters)
EXPECT_EQ (good, true);
}
TEST(31_ParallelMOSFets)
{
db::Netlist a, b, c;
tl::InputStream fa (tl::testdata () + "/algo/nl_compare_31_a.cir");
tl::InputStream fb (tl::testdata () + "/algo/nl_compare_31_b.cir");
tl::InputStream fc (tl::testdata () + "/algo/nl_compare_31_c.cir");
db::NetlistSpiceReader reader;
reader.read (fa, a);
reader.read (fb, b);
reader.read (fc, c);
NetlistCompareTestLogger logger;
std::string txt;
bool good;
db::NetlistComparer comp (&logger);
comp.set_dont_consider_net_names (true);
good = comp.compare (&a, &b);
txt = logger.text ();
EXPECT_EQ (good, true);
EXPECT_EQ (txt,
"begin_circuit LVS_TEST LVS_TEST\n"
"match_nets 2 2\n"
"match_nets 1 1\n"
"match_pins 1 1\n"
"match_pins 2 2\n"
"match_devices 1I39A $1\n"
"match_devices 1I38 $150\n"
"end_circuit LVS_TEST LVS_TEST MATCH"
);
logger.clear ();
good = comp.compare (&a, &b);
txt = logger.text ();
EXPECT_EQ (good, true);
EXPECT_EQ (txt,
"begin_circuit LVS_TEST LVS_TEST\n"
"match_nets 2 2\n"
"match_nets 1 1\n"
"match_pins 1 1\n"
"match_pins 2 2\n"
"match_devices 1I39A $1\n"
"match_devices 1I38 $150\n"
"end_circuit LVS_TEST LVS_TEST MATCH"
);
}
TEST(32_InverterChain)
{
db::Netlist a, b, c;
tl::InputStream fa (tl::testdata () + "/algo/nl_compare_32a.cir");
tl::InputStream fb (tl::testdata () + "/algo/nl_compare_32b.cir");
db::NetlistSpiceReader reader;
reader.read (fa, a);
reader.read (fb, b);
NetlistCompareTestLogger logger;
std::string txt;
bool good;
db::NetlistComparer comp (&logger);
comp.set_dont_consider_net_names (true);
good = comp.compare (&a, &b);
txt = logger.text ();
EXPECT_EQ (good, true);
EXPECT_EQ (txt,
"begin_circuit INV_CHAIN INV_CHAIN\n"
"match_nets 20 2\n"
"match_nets 21 1\n"
"match_ambiguous_nets 10 11\n"
"match_nets 11 12\n"
"match_nets 12 13\n"
"match_ambiguous_nets 16 5\n"
"match_nets 17 6\n"
"match_nets 18 7\n"
"match_nets 4 18\n"
"match_nets 5 19\n"
"match_nets 6 20\n"
"match_nets 15 4\n"
"match_nets 2 16\n"
"match_nets 3 17\n"
"match_nets 9 10\n"
"match_nets 8 9\n"
"match_nets 13 14\n"
"match_nets 14 3\n"
"match_nets 19 8\n"
"match_nets 1 15\n"
"match_nets 7 21\n"
"match_pins 20 2\n"
"match_pins 21 1\n"
"match_devices $12 2_1.N1\n"
"match_devices $28 2_1.P1\n"
"match_devices $13 2_2.N1\n"
"match_devices $29 2_2.P1\n"
"match_devices $14 2_3.N1\n"
"match_devices $30 2_3.P1\n"
"match_devices $15 2_4.N1\n"
"match_devices $31 2_4.P1\n"
"match_devices $16 2_5.N1\n"
"match_devices $32 2_5.P1\n"
"match_devices $7 _1.N1\n"
"match_devices $23 _1.P1\n"
"match_devices $8 _2.N1\n"
"match_devices $24 _2.P1\n"
"match_devices $9 _3.N1\n"
"match_devices $25 _3.P1\n"
"match_devices $10 _4.N1\n"
"match_devices $26 _4.P1\n"
"match_devices $11 _5.N1\n"
"match_devices $27 _5.P1\n"
"match_devices $1 0_1.N1\n"
"match_devices $17 0_1.P1\n"
"match_devices $2 0_2.N1\n"
"match_devices $18 0_2.P1\n"
"match_devices $3 0_3.N1\n"
"match_devices $19 0_3.P1\n"
"match_devices $4 0_4.N1\n"
"match_devices $20 0_4.P1\n"
"match_devices $5 0_5.N1\n"
"match_devices $21 0_5.P1\n"
"match_devices $6 0_6.N1\n"
"match_devices $22 0_6.P1\n"
"end_circuit INV_CHAIN INV_CHAIN MATCH"
);
}

12
testdata/algo/nl_compare_31_a.cir vendored Normal file
View File

@ -0,0 +1,12 @@
* cell LVS_TEST
* pin VDDO
* pin VP
.SUBCKT LVS_TEST 1 2
* net 1 VDDO
* net 2 VP
* device instance 1I38 r0 *1 0,0 PCH_18_MAC
M1I38 1 2 1 1 PCH_18_MAC L=0.225U W=10653U AS=0P AD=0P PS=0U PD=0U
* device instance 1I39A r0 *1 0,0 PCH_18_MAC
M1I39A 1 2 1 1 PCH_18_MAC L=0.135U W=1809U AS=0P AD=0P PS=0U PD=0U
.ENDS LVS_TEST

14
testdata/algo/nl_compare_31_b.cir vendored Normal file
View File

@ -0,0 +1,14 @@
* cell lvs_test
* pin VDDO
* pin VP
.SUBCKT lvs_test 1 2
* net 1 VDDO
* net 2 VP
* device instance $1 r0 *1 24.014,63.84 PCH_18_MAC
M$1 1 2 1 1 PCH_18_MAC L=0.135U W=1809U AS=5.790774P AD=5.619278P PS=115.96U
+ PD=115.184U
* device instance $150 r0 *1 1.308,124.128 PCH_18_MAC
M$150 1 2 1 1 PCH_18_MAC L=0.225U W=10653U AS=29.399936P AD=29.399936P
+ PS=562.496U PD=562.496U
.ENDS lvs_test

14
testdata/algo/nl_compare_31_c.cir vendored Normal file
View File

@ -0,0 +1,14 @@
* cell lvs_test
* pin VDDO
* pin VP
.SUBCKT lvs_test 1 2
* net 1 VDDO
* net 2 VP
* device instance $150 r0 *1 1.308,124.128 PCH_18_MAC
M$150 1 2 1 1 PCH_18_MAC L=0.225U W=10653U AS=29.399936P AD=29.399936P
+ PS=562.496U PD=562.496U
* device instance $1 r0 *1 24.014,63.84 PCH_18_MAC
M$1 1 2 1 1 PCH_18_MAC L=0.135U W=1809U AS=5.790774P AD=5.619278P PS=115.96U
+ PD=115.184U
.ENDS lvs_test

34
testdata/algo/nl_compare_32a.cir vendored Normal file
View File

@ -0,0 +1,34 @@
.SUBCKT inv_chain 20 21
M$1 20 1 2 20 NCH_SVT_MAC L=0.016U W=3U
M$2 20 2 3 20 NCH_SVT_MAC L=0.016U W=3U
M$3 20 3 4 20 NCH_SVT_MAC L=0.016U W=3U
M$4 20 4 5 20 NCH_SVT_MAC L=0.016U W=3U
M$5 20 5 6 20 NCH_SVT_MAC L=0.016U W=3U
M$6 20 6 7 20 NCH_SVT_MAC L=0.016U W=3U
M$7 20 8 9 20 NCH_SVT_MAC L=0.016U W=3U
M$8 20 9 10 20 NCH_SVT_MAC L=0.016U W=3U
M$9 20 10 11 20 NCH_SVT_MAC L=0.016U W=3U
M$10 20 11 12 20 NCH_SVT_MAC L=0.016U W=3U
M$11 20 12 13 20 NCH_SVT_MAC L=0.016U W=3U
M$12 20 14 15 20 NCH_SVT_MAC L=0.016U W=3U
M$13 20 15 16 20 NCH_SVT_MAC L=0.016U W=3U
M$14 20 16 17 20 NCH_SVT_MAC L=0.016U W=3U
M$15 20 17 18 20 NCH_SVT_MAC L=0.016U W=3U
M$16 20 18 19 20 NCH_SVT_MAC L=0.016U W=3U
M$17 21 1 2 21 PCH_SVT_MAC L=0.016U W=3U
M$18 21 2 3 21 PCH_SVT_MAC L=0.016U W=3U
M$19 21 3 4 21 PCH_SVT_MAC L=0.016U W=3U
M$20 21 4 5 21 PCH_SVT_MAC L=0.016U W=3U
M$21 21 5 6 21 PCH_SVT_MAC L=0.016U W=3U
M$22 21 6 7 21 PCH_SVT_MAC L=0.016U W=3U
M$23 21 8 9 21 PCH_SVT_MAC L=0.016U W=3U
M$24 21 9 10 21 PCH_SVT_MAC L=0.016U W=3U
M$25 21 10 11 21 PCH_SVT_MAC L=0.016U W=3U
M$26 21 11 12 21 PCH_SVT_MAC L=0.016U W=3U
M$27 21 12 13 21 PCH_SVT_MAC L=0.016U W=3U
M$28 21 14 15 21 PCH_SVT_MAC L=0.016U W=3U
M$29 21 15 16 21 PCH_SVT_MAC L=0.016U W=3U
M$30 21 16 17 21 PCH_SVT_MAC L=0.016U W=3U
M$31 21 17 18 21 PCH_SVT_MAC L=0.016U W=3U
M$32 21 18 19 21 PCH_SVT_MAC L=0.016U W=3U
.ENDS inv_chain

34
testdata/algo/nl_compare_32b.cir vendored Normal file
View File

@ -0,0 +1,34 @@
.SUBCKT INV_CHAIN 1 2
M2_1.N1 4 3 2 2 NCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M2_1.P1 4 3 1 1 PCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M2_2.N1 5 4 2 2 NCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M2_2.P1 5 4 1 1 PCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M2_3.N1 6 5 2 2 NCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M2_3.P1 6 5 1 1 PCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M2_4.N1 7 6 2 2 NCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M2_4.P1 7 6 1 1 PCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M2_5.N1 8 7 2 2 NCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M2_5.P1 8 7 1 1 PCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M_1.N1 10 9 2 2 NCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M_1.P1 10 9 1 1 PCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M_2.N1 11 10 2 2 NCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M_2.P1 11 10 1 1 PCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M_3.N1 12 11 2 2 NCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M_3.P1 12 11 1 1 PCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M_4.N1 13 12 2 2 NCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M_4.P1 13 12 1 1 PCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M_5.N1 14 13 2 2 NCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M_5.P1 14 13 1 1 PCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M0_1.N1 16 15 2 2 NCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M0_1.P1 16 15 1 1 PCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M0_2.N1 17 16 2 2 NCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M0_2.P1 17 16 1 1 PCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M0_3.N1 18 17 2 2 NCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M0_3.P1 18 17 1 1 PCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M0_4.N1 19 18 2 2 NCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M0_4.P1 19 18 1 1 PCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M0_5.N1 20 19 2 2 NCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M0_5.P1 20 19 1 1 PCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M0_6.N1 21 20 2 2 NCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
M0_6.P1 21 20 1 1 PCH_SVT_MAC L=0.016U W=3U AS=0P AD=0P PS=0U PD=0U
.ENDS INV_CHAIN

View File

@ -2501,26 +2501,26 @@ xref(
net(12 13 warning)
net(34 16 match)
net(32 15 match)
net(15 18 warning)
net(16 17 warning)
net(47 20 match)
net(35 19 match)
net(19 22 warning)
net(20 21 warning)
net(49 24 match)
net(37 23 match)
net(23 26 warning)
net(24 25 warning)
net(50 28 match)
net(39 27 match)
net(16 18 match)
net(15 17 match)
net(35 20 match)
net(47 19 match)
net(20 22 match)
net(19 21 match)
net(37 24 match)
net(49 23 match)
net(24 26 match)
net(23 25 match)
net(39 28 match)
net(50 27 match)
net(2 6 match)
net(4 8 match)
net(6 10 match)
net(8 12 match)
net(4 7 match)
net(6 9 match)
net(8 11 match)
net(3 5 match)
net(5 7 match)
net(7 9 match)
net(9 11 match)
net(5 8 match)
net(7 10 match)
net(9 12 match)
net(1 2 match)
net(52 1 match)
net(26 3 match)
@ -2545,46 +2545,46 @@ xref(
device(4 10 match)
device(9 11 match)
device(3 12 match)
device(13 15 match)
device(6 16 match)
device(15 17 match)
device(8 18 match)
device(19 21 match)
device(12 22 match)
device(17 23 match)
device(10 24 match)
device(21 27 match)
device(14 28 match)
device(23 29 match)
device(16 30 match)
device(27 33 match)
device(20 34 match)
device(25 35 match)
device(18 36 match)
device(29 39 match)
device(22 40 match)
device(30 41 match)
device(24 42 match)
device(32 45 match)
device(28 46 match)
device(31 47 match)
device(26 48 match)
device(6 15 match)
device(13 16 match)
device(8 17 match)
device(15 18 match)
device(12 21 match)
device(19 22 match)
device(10 23 match)
device(17 24 match)
device(14 27 match)
device(21 28 match)
device(16 29 match)
device(23 30 match)
device(20 33 match)
device(27 34 match)
device(18 35 match)
device(25 36 match)
device(22 39 match)
device(29 40 match)
device(24 41 match)
device(30 42 match)
device(28 45 match)
device(32 46 match)
device(26 47 match)
device(31 48 match)
device(34 1 match)
device(33 2 match)
device(42 7 match)
device(41 8 match)
device(36 13 match)
device(35 14 match)
device(44 19 match)
device(43 20 match)
device(38 25 match)
device(37 26 match)
device(46 31 match)
device(45 32 match)
device(40 37 match)
device(39 38 match)
device(48 43 match)
device(47 44 match)
device(35 13 match)
device(36 14 match)
device(43 19 match)
device(44 20 match)
device(37 25 match)
device(38 26 match)
device(45 31 match)
device(46 32 match)
device(39 37 match)
device(40 38 match)
device(47 43 match)
device(48 44 match)
)
)
)

View File

@ -2501,26 +2501,26 @@ xref(
net(12 13 warning)
net(34 16 match)
net(32 15 match)
net(15 18 warning)
net(16 17 warning)
net(49 20 match)
net(35 19 match)
net(18 22 warning)
net(20 21 warning)
net(39 24 match)
net(37 23 match)
net(22 26 warning)
net(24 25 warning)
net(42 28 match)
net(40 27 match)
net(16 18 match)
net(15 17 match)
net(35 20 match)
net(49 19 match)
net(20 22 match)
net(18 21 match)
net(37 24 match)
net(39 23 match)
net(24 26 match)
net(22 25 match)
net(40 28 match)
net(42 27 match)
net(2 6 match)
net(4 8 match)
net(6 10 match)
net(8 12 match)
net(4 7 match)
net(6 9 match)
net(8 11 match)
net(3 5 match)
net(5 7 match)
net(7 9 match)
net(9 11 match)
net(5 8 match)
net(7 10 match)
net(9 12 match)
net(1 2 match)
net(52 1 match)
net(26 3 match)
@ -2545,46 +2545,46 @@ xref(
device(4 10 match)
device(9 11 match)
device(3 12 match)
device(13 15 match)
device(6 16 match)
device(15 17 match)
device(8 18 match)
device(19 21 match)
device(12 22 match)
device(17 23 match)
device(10 24 match)
device(21 27 match)
device(14 28 match)
device(23 29 match)
device(16 30 match)
device(27 33 match)
device(20 34 match)
device(25 35 match)
device(18 36 match)
device(29 39 match)
device(22 40 match)
device(30 41 match)
device(24 42 match)
device(32 45 match)
device(28 46 match)
device(31 47 match)
device(26 48 match)
device(6 15 match)
device(13 16 match)
device(8 17 match)
device(15 18 match)
device(12 21 match)
device(19 22 match)
device(10 23 match)
device(17 24 match)
device(14 27 match)
device(21 28 match)
device(16 29 match)
device(23 30 match)
device(20 33 match)
device(27 34 match)
device(18 35 match)
device(25 36 match)
device(22 39 match)
device(29 40 match)
device(24 41 match)
device(30 42 match)
device(28 45 match)
device(32 46 match)
device(26 47 match)
device(31 48 match)
device(34 1 match)
device(33 2 match)
device(42 7 match)
device(41 8 match)
device(36 13 match)
device(35 14 match)
device(44 19 match)
device(43 20 match)
device(38 25 match)
device(37 26 match)
device(46 31 match)
device(45 32 match)
device(40 37 match)
device(39 38 match)
device(48 43 match)
device(47 44 match)
device(35 13 match)
device(36 14 match)
device(43 19 match)
device(44 20 match)
device(37 25 match)
device(38 26 match)
device(45 31 match)
device(46 32 match)
device(39 37 match)
device(40 38 match)
device(47 43 match)
device(48 44 match)
)
)
)