WIP: fixed a basic issue with empty layers

Previous: empty layers occupied a special layer in the DSS
But what when empty layers are required as outputs?
ONE layer isn't good -> would overwrite the layer and it's
no longer empty for others.
So we need to keep the layers separate.
This commit is contained in:
Matthias Koefferlein 2019-06-23 23:44:15 +02:00
parent 464a1f35fb
commit 624811d55e
6 changed files with 8 additions and 89 deletions

View File

@ -222,24 +222,11 @@ DeepLayer::check_dss () const
struct DeepShapeStore::LayoutHolder
{
LayoutHolder (const db::ICplxTrans &trans)
: refs (0), layout (false), builder (&layout, trans), m_empty_layer (std::numeric_limits<unsigned int>::max ())
: refs (0), layout (false), builder (&layout, trans)
{
// .. nothing yet ..
}
unsigned int empty_layer () const
{
if (m_empty_layer == std::numeric_limits<unsigned int>::max ()) {
const_cast<LayoutHolder *> (this)->make_empty_layer ();
}
return m_empty_layer;
}
unsigned int new_empty_layer ()
{
return layout.insert_layer ();
}
void add_layer_ref (unsigned int layer)
{
layer_refs [layer] += 1;
@ -260,15 +247,6 @@ struct DeepShapeStore::LayoutHolder
db::Layout layout;
db::HierarchyBuilder builder;
std::map<unsigned int, int> layer_refs;
private:
unsigned int m_empty_layer;
void make_empty_layer ()
{
m_empty_layer = layout.insert_layer ();
layer_refs [m_empty_layer] += 1; // the empty layer is not deleted
}
};
// ----------------------------------------------------------------------------------
@ -571,28 +549,6 @@ DeepLayer DeepShapeStore::create_polygon_layer (const db::RecursiveShapeIterator
return DeepLayer (this, layout_index, layer_index);
}
DeepLayer DeepShapeStore::empty_layer (unsigned int layout_index) const
{
return DeepLayer (const_cast<DeepShapeStore *> (this), layout_index, m_layouts[layout_index]->empty_layer ());
}
DeepLayer DeepShapeStore::empty_layer () const
{
require_singular ();
return empty_layer (0);
}
DeepLayer DeepShapeStore::new_empty_layer (unsigned int layout_index) const
{
return DeepLayer (const_cast<DeepShapeStore *> (this), layout_index, m_layouts[layout_index]->new_empty_layer ());
}
DeepLayer DeepShapeStore::new_empty_layer () const
{
require_singular ();
return new_empty_layer (0);
}
DeepLayer DeepShapeStore::create_custom_layer (const db::RecursiveShapeIterator &si, HierarchyBuilderShapeReceiver *pipe, const db::ICplxTrans &trans)
{
unsigned int layout_index = layout_for_iter (si, trans);

View File

@ -343,32 +343,6 @@ public:
*/
DeepLayer create_copy (const DeepLayer &source, HierarchyBuilderShapeReceiver *pipe);
/**
* @brief Gets the empty working layer
*
* This method will deliver an empty layer for the given layout index. CAUTION: don't modify this layer as it may
* be reused.
*/
DeepLayer empty_layer (unsigned int layout_index) const;
/**
* @brief Gets the empty working layer for the singular layout
*/
DeepLayer empty_layer () const;
/**
* @brief Gets a new empty working layer
*
* This method will deliver an empty layer for the given layout index. This layer is a fresh one and can be
* modified.
*/
DeepLayer new_empty_layer (unsigned int layout_index) const;
/**
* @brief Gets a new empty working layer for the singular layout
*/
DeepLayer new_empty_layer () const;
/**
* @brief Inserts the deep layer's shapes into some target layout
*/

View File

@ -337,11 +337,7 @@ void LayoutToNetlist::register_layer (const db::Region &region, const std::strin
db::DeepRegion *delegate = dynamic_cast<db::DeepRegion *> (region.delegate());
if (! delegate) {
if (region.empty ()) {
dl = dss ().empty_layer (m_layout_index);
} else {
dl = dss ().create_from_flat (region, true);
}
dl = dss ().create_from_flat (region, true);
} else {
@ -436,9 +432,6 @@ db::DeepLayer LayoutToNetlist::deep_layer_of (const db::Region &region) const
std::pair<bool, db::DeepLayer> lff = dss ().layer_for_flat (region);
if (lff.first) {
return lff.second;
} else if (region.empty ()) {
// provide a substitute empty layer for empty
return dss ().empty_layer (m_layout_index);
} else {
throw (tl::Exception (tl::to_string (tr ("Non-hierarchical layers cannot be used in netlist extraction"))));
}

View File

@ -167,10 +167,6 @@ void NetlistDeviceExtractor::extract (db::DeepShapeStore &dss, unsigned int layo
if (alias.first) {
// use deep layer alias for a given flat one (if found)
layers.push_back (alias.second.layer ());
} else if (l->second->empty ()) {
// provide a substitute empty layer (CAUTION: we can't use the
// singleton "empty_layer" because this may be used as OUTPUT).
layers.push_back (dss.new_empty_layer (layout_index).layer ());
} else {
throw tl::Exception (tl::sprintf (tl::to_string (tr ("Invalid region passed to input layer '%s' for device extraction (device %s): must be of deep region kind")), ld->name, name ()));
}

View File

@ -1136,7 +1136,7 @@ TEST(5_ResAndCapWithBulkExtraction)
db::Region rmetal2_lbl (db::RecursiveShapeIterator (ly, tc, metal2_lbl), dss);
db::Region rcap (db::RecursiveShapeIterator (ly, tc, cap), dss);
db::Region rres (db::RecursiveShapeIterator (ly, tc, res), dss);
db::Region rbulk (new db::DeepRegion (dss.empty_layer ()));
db::Region rbulk;
// derived regions
@ -1409,7 +1409,7 @@ TEST(6_BJT3TransistorExtraction)
db::Region rmetal2_lbl (db::RecursiveShapeIterator (ly, tc, metal2_lbl), dss);
db::Region rpplus (db::RecursiveShapeIterator (ly, tc, pplus), dss);
db::Region rnplus (db::RecursiveShapeIterator (ly, tc, nplus), dss);
db::Region rbulk (new db::DeepRegion (dss.empty_layer ()));
db::Region rbulk;
// derived regions

View File

@ -1155,19 +1155,19 @@ void
NetlistBrowserPage::configure_marker (Marker *marker, bool with_fill)
{
if (m_marker_line_width >= 0) {
mp_markers.back ()->set_line_width (m_marker_line_width);
marker->set_line_width (m_marker_line_width);
}
if (m_marker_vertex_size >= 0) {
mp_markers.back ()->set_vertex_size (m_marker_vertex_size);
marker->set_vertex_size (m_marker_vertex_size);
}
if (m_marker_halo >= 0) {
mp_markers.back ()->set_halo (m_marker_halo);
marker->set_halo (m_marker_halo);
}
if (m_marker_dither_pattern >= 0 && with_fill) {
mp_markers.back ()->set_dither_pattern (m_marker_dither_pattern);
marker->set_dither_pattern (m_marker_dither_pattern);
}
}