mirror of https://github.com/KLayout/klayout.git
Fixed issue #2014 (strm2oas lef/def/gds collect drops cells referenced by sky130 spare)
Problem was that there was the implicit assumption that substitution cells would be top cells (or at least: not child cells of other substitution cells).
This commit is contained in:
parent
449a9a968e
commit
bcf14ede3e
|
|
@ -354,6 +354,13 @@ CellMapping::do_create_missing_mapping (db::Layout &layout_a, const db::Layout &
|
|||
std::vector<db::cell_index_type> &new_cells = *(new_cells_ptr ? new_cells_ptr : &new_cells_int);
|
||||
std::vector<db::cell_index_type> new_cells_b;
|
||||
|
||||
std::vector<std::pair<db::cell_index_type, db::cell_index_type> > all_a2b;
|
||||
for (std::vector<db::cell_index_type>::const_iterator b = cell_index_b.begin (); b != cell_index_b.end (); ++b) {
|
||||
auto m = m_b2a_mapping.find (*b);
|
||||
tl_assert (m != m_b2a_mapping.end ());
|
||||
all_a2b.push_back (std::make_pair (m->second, *b));
|
||||
}
|
||||
|
||||
std::set<db::cell_index_type> called_b;
|
||||
for (std::vector<db::cell_index_type>::const_iterator i = cell_index_b.begin (); i != cell_index_b.end (); ++i) {
|
||||
layout_b.cell (*i).collect_called_cells (called_b);
|
||||
|
|
@ -368,6 +375,7 @@ CellMapping::do_create_missing_mapping (db::Layout &layout_a, const db::Layout &
|
|||
db::cell_index_type new_cell = layout_a.add_cell (layout_b, *b);
|
||||
new_cells.push_back (new_cell);
|
||||
new_cells_b.push_back (*b);
|
||||
all_a2b.push_back (std::make_pair (new_cell, *b));
|
||||
|
||||
if (mapped_pairs) {
|
||||
mapped_pairs->push_back (std::make_pair (*b, new_cell));
|
||||
|
|
@ -378,34 +386,34 @@ CellMapping::do_create_missing_mapping (db::Layout &layout_a, const db::Layout &
|
|||
}
|
||||
}
|
||||
|
||||
if (! new_cells.empty ()) {
|
||||
if (all_a2b.empty ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Note: this avoids frequent cell index table rebuilds if source and target layout are identical
|
||||
db::LayoutLocker locker (&layout_a);
|
||||
// Note: this avoids frequent cell index table rebuilds if source and target layout are identical
|
||||
db::LayoutLocker locker (&layout_a);
|
||||
|
||||
// Create instances for the new cells in layout A according to their instantiation in layout B
|
||||
double mag = layout_b.dbu () / layout_a.dbu ();
|
||||
for (size_t i = 0; i < new_cells.size (); ++i) {
|
||||
// Create instances for the new cells in layout A according to their instantiation in layout B
|
||||
double mag = layout_b.dbu () / layout_a.dbu ();
|
||||
for (auto i = all_a2b.begin (); i != all_a2b.end (); ++i) {
|
||||
|
||||
const db::Cell &b = layout_b.cell (new_cells_b [i]);
|
||||
for (db::Cell::parent_inst_iterator pb = b.begin_parent_insts (); ! pb.at_end (); ++pb) {
|
||||
const db::Cell &b = layout_b.cell (i->second);
|
||||
for (db::Cell::parent_inst_iterator pb = b.begin_parent_insts (); ! pb.at_end (); ++pb) {
|
||||
|
||||
if (called_b.find (pb->parent_cell_index ()) != called_b.end ()) {
|
||||
if (called_b.find (pb->parent_cell_index ()) != called_b.end ()) {
|
||||
|
||||
db::Cell &pa = layout_a.cell (m_b2a_mapping [pb->parent_cell_index ()]);
|
||||
db::Cell &pa = layout_a.cell (m_b2a_mapping [pb->parent_cell_index ()]);
|
||||
|
||||
db::Instance bi = pb->child_inst ();
|
||||
db::Instance bi = pb->child_inst ();
|
||||
|
||||
db::CellInstArray bci = bi.cell_inst ();
|
||||
bci.object ().cell_index (new_cells [i]);
|
||||
bci.transform_into (db::ICplxTrans (mag), &layout_a.array_repository ());
|
||||
|
||||
if (bi.has_prop_id ()) {
|
||||
pa.insert (db::CellInstArrayWithProperties (bci, bi.prop_id ()));
|
||||
} else {
|
||||
pa.insert (bci);
|
||||
}
|
||||
db::CellInstArray bci = bi.cell_inst ();
|
||||
bci.object ().cell_index (i->first);
|
||||
bci.transform_into (db::ICplxTrans (mag), &layout_a.array_repository ());
|
||||
|
||||
if (bi.has_prop_id ()) {
|
||||
pa.insert (db::CellInstArrayWithProperties (bci, bi.prop_id ()));
|
||||
} else {
|
||||
pa.insert (bci);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -485,8 +485,41 @@ TEST(7)
|
|||
cib.push_back (b1.cell_index ());
|
||||
cib.push_back (b2.cell_index ());
|
||||
cm.create_multi_mapping_full (h, cib, *g, cia);
|
||||
EXPECT_EQ (m2s (cm, *g, h), "a0->b0;a1->b1;a2->b2;a3->a3;a4->a4;a5->a5");
|
||||
EXPECT_EQ (m2s (cm, h, *g), "b0->a0;b1->a1;b2->a2;a3->a3;a4->a4;a5->a5");
|
||||
|
||||
EXPECT_EQ (l2s (h), "b0#0:;b1#1:cell_index=3 r0 0,0,cell_index=4 r0 0,0;b2#2:cell_index=4 r0 0,0;a3#3:cell_index=4 r0 0,0,cell_index=5 r0 0,0;a4#4:;a5#5:");
|
||||
}
|
||||
|
||||
// Issue #2014
|
||||
TEST(8)
|
||||
{
|
||||
std::unique_ptr<db::Layout> g (new db::Layout ());
|
||||
db::Cell &a (g->cell (g->add_cell ("a")));
|
||||
db::Cell &b (g->cell (g->add_cell ("b")));
|
||||
db::Cell &b1 (g->cell (g->add_cell ("b1")));
|
||||
db::Cell &b2 (g->cell (g->add_cell ("b2")));
|
||||
db::Cell &c (g->cell (g->add_cell ("c")));
|
||||
|
||||
b.insert (db::CellInstArray (db::CellInst (a.cell_index ()), db::Trans ()));
|
||||
b.insert (db::CellInstArray (db::CellInst (c.cell_index ()), db::Trans ()));
|
||||
b.insert (db::CellInstArray (db::CellInst (b1.cell_index ()), db::Trans ()));
|
||||
b.insert (db::CellInstArray (db::CellInst (b2.cell_index ()), db::Trans ()));
|
||||
|
||||
db::Layout h;
|
||||
db::Cell &ha (h.cell (h.add_cell ("a")));
|
||||
db::Cell &hb (h.cell (h.add_cell ("b")));
|
||||
db::Cell &hc (h.cell (h.add_cell ("c")));
|
||||
|
||||
db::CellMapping cm;
|
||||
std::vector<db::cell_index_type> cib, cia;
|
||||
cia.push_back (a.cell_index ());
|
||||
cia.push_back (b.cell_index ());
|
||||
cia.push_back (c.cell_index ());
|
||||
cib.push_back (ha.cell_index ());
|
||||
cib.push_back (hb.cell_index ());
|
||||
cib.push_back (hc.cell_index ());
|
||||
cm.create_multi_mapping_full (h, cib, *g, cia);
|
||||
EXPECT_EQ (m2s (cm, h, *g), "a->a;b->b;b1->b1;b2->b2;c->c");
|
||||
|
||||
EXPECT_EQ (l2s (h), "a#0:;b#1:cell_index=0 r0 0,0,cell_index=2 r0 0,0,cell_index=3 r0 0,0,cell_index=4 r0 0,0;c#2:;b1#3:;b2#4:");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue