Fixed an issue with the OASIS reader (unused cells popped up as dummy top levels)

This happens when OASIS declares a cell name without actually using it.
The intended behavior is to drop such cells.
This commit is contained in:
Matthias Koefferlein 2020-12-30 23:37:01 +01:00
parent 70dcc92640
commit dd84e64446
11 changed files with 64 additions and 8 deletions

View File

@ -54,6 +54,7 @@ CommonReader::make_cell (db::Layout &layout, const std::string &cn)
common_reader_error (tl::sprintf (tl::to_string (tr ("A cell with name %s already exists")), cn)); common_reader_error (tl::sprintf (tl::to_string (tr ("A cell with name %s already exists")), cn));
} }
m_temp_cells.erase (cell.cell_index ());
cell.set_ghost_cell (false); cell.set_ghost_cell (false);
return cell.cell_index (); return cell.cell_index ();
@ -98,6 +99,7 @@ CommonReader::make_cell (db::Layout &layout, size_t id)
common_reader_error (tl::sprintf (tl::to_string (tr ("A cell with ID %ld already exists")), id)); common_reader_error (tl::sprintf (tl::to_string (tr ("A cell with ID %ld already exists")), id));
} }
m_temp_cells.erase (cell.cell_index ());
cell.set_ghost_cell (false); cell.set_ghost_cell (false);
return cell.cell_index (); return cell.cell_index ();
@ -180,6 +182,7 @@ CommonReader::rename_cell (db::Layout &layout, size_t id, const std::string &cn)
db::cell_index_type ci = layout.add_anonymous_cell (); db::cell_index_type ci = layout.add_anonymous_cell ();
layout.cell (ci).set_ghost_cell (true); layout.cell (ci).set_ghost_cell (true);
m_temp_cells.insert (ci);
m_id_map [id] = std::make_pair (cn, ci); m_id_map [id] = std::make_pair (cn, ci);
m_name_map [cn] = std::make_pair (id, ci); m_name_map [cn] = std::make_pair (id, ci);
@ -195,6 +198,7 @@ CommonReader::cell_for_instance (db::Layout &layout, size_t id)
std::map<size_t, std::pair<std::string, db::cell_index_type> >::iterator iid = m_id_map.find (id); std::map<size_t, std::pair<std::string, db::cell_index_type> >::iterator iid = m_id_map.find (id);
if (iid != m_id_map.end ()) { if (iid != m_id_map.end ()) {
m_temp_cells.erase (iid->second.second);
return iid->second.second; return iid->second.second;
} else { } else {
@ -216,6 +220,7 @@ CommonReader::cell_for_instance (db::Layout &layout, const std::string &cn)
std::map<std::string, std::pair<size_t, db::cell_index_type> >::iterator iname = m_name_map.find (cn); std::map<std::string, std::pair<size_t, db::cell_index_type> >::iterator iname = m_name_map.find (cn);
if (iname != m_name_map.end ()) { if (iname != m_name_map.end ()) {
m_temp_cells.erase (iname->second.second);
return iname->second.second; return iname->second.second;
} else { } else {
@ -423,6 +428,12 @@ CommonReader::finish (db::Layout &layout)
} }
// remove temporary cells (some that were "declared" by "rename_cell" but not used by cell_for_instance)
for (std::set<db::cell_index_type>::const_iterator ci = m_temp_cells.begin (); ci != m_temp_cells.end (); ++ci) {
layout.delete_cell (*ci);
}
// resolve layer multi-mapping // resolve layer multi-mapping
for (std::map<std::set<unsigned int>, unsigned int>::const_iterator i = m_multi_mapping_placeholders.begin (); i != m_multi_mapping_placeholders.end (); ++i) { for (std::map<std::set<unsigned int>, unsigned int>::const_iterator i = m_multi_mapping_placeholders.begin (); i != m_multi_mapping_placeholders.end (); ++i) {

View File

@ -251,6 +251,7 @@ protected:
private: private:
std::map<size_t, std::pair<std::string, db::cell_index_type> > m_id_map; std::map<size_t, std::pair<std::string, db::cell_index_type> > m_id_map;
std::map<std::string, std::pair<size_t, db::cell_index_type> > m_name_map; std::map<std::string, std::pair<size_t, db::cell_index_type> > m_name_map;
std::set<db::cell_index_type> m_temp_cells;
std::map<size_t, std::string> m_name_for_id; std::map<size_t, std::string> m_name_for_id;
CellConflictResolution m_cc_resolution; CellConflictResolution m_cc_resolution;
bool m_create_layers; bool m_create_layers;

View File

@ -264,6 +264,11 @@ TEST(2_6)
run_test (_this, "2.6"); run_test (_this, "2.6");
} }
TEST(2_7)
{
run_test (_this, "2.7");
}
TEST(3_1) TEST(3_1)
{ {
run_test (_this, "3.1"); run_test (_this, "3.1");

View File

@ -6,7 +6,7 @@ TARGET = oasis_tests
include($$PWD/../../../../lib_ut.pri) include($$PWD/../../../../lib_ut.pri)
SOURCES = \ SOURCES = \
dbOASISReader.cc \ dbOASISReaderTests.cc \
dbOASISWriter2.cc \ dbOASISWriter2.cc \
dbOASISWriter.cc \ dbOASISWriter.cc \

View File

@ -6,6 +6,6 @@ export LANG
for t in *.ot; do for t in *.ot; do
out=`echo $t | sed 's/.ot$/.oas/'` out=`echo $t | sed 's/.ot$/.oas/'`
echo "$t -> $out" echo "$t -> $out"
./mkoasis.tcl $t $out tclsh ./mkoasis.tcl $t $out
done done

View File

@ -14,12 +14,12 @@ header
uint 0 ;# offset table is in start record uint 0 ;# offset table is in start record
for { set i 0 } { $i < 12 } { incr i } { uint 0 } for { set i 0 } { $i < 12 } { incr i } { uint 0 }
# XYZ gets assigned 1 # ABC gets assigned 1
record CELLNAME_ID record CELLNAME_ID
str ABC str ABC
uint 1 uint 1
# ABC gets assigned 0 implicitly # XYZ gets assigned 0 implicitly
record CELLNAME record CELLNAME
str XYZ ;# FAIL: implicit and explicit assignment may not be mixed str XYZ ;# FAIL: implicit and explicit assignment may not be mixed

View File

@ -20,12 +20,12 @@ header
uint 0 ;# offset table is in start record uint 0 ;# offset table is in start record
for { set i 0 } { $i < 12 } { incr i } { uint 0 } for { set i 0 } { $i < 12 } { incr i } { uint 0 }
# XYZ gets assigned 1 # ABC gets assigned 1
record CELLNAME_ID record CELLNAME_ID
str ABC str ABC
uint 1 uint 1
# ABC gets assigned 0 # XYZ gets assigned 0
record CELLNAME_ID record CELLNAME_ID
str XYZ str XYZ
uint 0 uint 0

View File

@ -14,12 +14,12 @@ header
uint 0 ;# offset table is in start record uint 0 ;# offset table is in start record
for { set i 0 } { $i < 12 } { incr i } { uint 0 } for { set i 0 } { $i < 12 } { incr i } { uint 0 }
# XYZ gets assigned 1 # ABC gets assigned 1
record CELLNAME_ID record CELLNAME_ID
str ABC str ABC
uint 1 uint 1
# ABC gets assigned 0 # XYZ gets assigned 0
record CELLNAME_ID record CELLNAME_ID
str XYZ str XYZ
uint 0 uint 0

BIN
testdata/oasis/t2.7.oas vendored Normal file

Binary file not shown.

35
testdata/oasis/t2.7.ot vendored Normal file
View File

@ -0,0 +1,35 @@
# <test>
# <name>t2.7.ot</name>
# <content-description>Two cells, one just declared but not present</content-description>
# <test-intention>Unused CELLNAME must not generate an empty cell</test-intention>
# <content>
# begin_lib 0.001
# begin_cell {XYZ}
# end_cell
# end_lib
# </content>
# </test>
header
real 0 1000.0
uint 0 ;# offset table is in start record
for { set i 0 } { $i < 12 } { incr i } { uint 0 }
# ABC gets assigned 1
record CELLNAME_ID
str ABC
uint 1
# XYZ gets assigned 0
record CELLNAME_ID
str XYZ
uint 0
# Cell XYZ (empty)
record CELL_ID
uint 0
# no body.
tail

4
testdata/oasis/t2.7_au.txt vendored Normal file
View File

@ -0,0 +1,4 @@
begin_lib 0.001
begin_cell {XYZ}
end_cell
end_lib