WIP: fixed a potential segfault

This commit is contained in:
Matthias Koefferlein 2021-05-25 21:41:27 +02:00
parent 0452e91e8c
commit 0d6ce92d6b
2 changed files with 113 additions and 17 deletions

View File

@ -402,11 +402,14 @@ static size_t s_instance_count = 0;
static unsigned int init_layer (db::Layout &layout, const db::RecursiveShapeIterator &si) static unsigned int init_layer (db::Layout &layout, const db::RecursiveShapeIterator &si)
{ {
unsigned int layer_index = layout.insert_layer (); unsigned int layer_index = layout.insert_layer ();
unsigned int iter_layer = si.multiple_layers () ? si.layers ().front () : si.layer ();
if (si.layout () && iter_layer < si.layout ()->layers ()) { if (si.layout ()) {
// try to preserve the layer properties // try to preserve the layer properties
layout.set_properties (layer_index, si.layout ()->get_properties (iter_layer)); if (! si.multiple_layers ()) {
layout.set_properties (layer_index, si.layout ()->get_properties (si.layer ()));
} else if (! si.layers ().empty ()) {
layout.set_properties (layer_index, si.layout ()->get_properties (si.layers ().front ()));
}
} }
return layer_index; return layer_index;

View File

@ -32,6 +32,7 @@
#include "dbLayoutVsSchematic.h" #include "dbLayoutVsSchematic.h"
#include "dbLayoutToNetlistFormatDefs.h" #include "dbLayoutToNetlistFormatDefs.h"
#include "dbLayoutVsSchematicFormatDefs.h" #include "dbLayoutVsSchematicFormatDefs.h"
#include "dbShapeProcessor.h"
#include "tlGlobPattern.h" #include "tlGlobPattern.h"
namespace db namespace db
@ -1301,6 +1302,93 @@ db::Net *LayoutToNetlist::probe_net (const db::Region &of_region, const db::Poin
} }
} }
namespace
{
class PolygonAreaAndPerimeterCollector
: public db::PolygonSink
{
public:
typedef db::Polygon polygon_type;
typedef polygon_type::perimeter_type perimeter_type;
typedef polygon_type::area_type area_type;
PolygonAreaAndPerimeterCollector ()
: m_area (0), m_perimeter (0)
{ }
area_type area () const
{
return m_area;
}
perimeter_type perimeter () const
{
return m_perimeter;
}
virtual void put (const db::Polygon &poly)
{
m_area += poly.area ();
m_perimeter += poly.perimeter ();
}
public:
area_type m_area;
perimeter_type m_perimeter;
};
}
static void
compute_area_and_perimeter_of_net_shapes (const db::hier_clusters<db::NetShape> &clusters, db::cell_index_type ci, size_t cid, unsigned int layer_id, db::Polygon::area_type &area, db::Polygon::perimeter_type &perimeter)
{
db::EdgeProcessor ep;
// count vertices and reserve space
size_t n = 0;
for (db::recursive_cluster_shape_iterator<db::NetShape> rci (clusters, layer_id, ci, cid); !rci.at_end (); ++rci) {
n += rci->polygon_ref ().vertices ();
}
ep.reserve (n);
size_t p = 0;
for (db::recursive_cluster_shape_iterator<db::NetShape> rci (clusters, layer_id, ci, cid); !rci.at_end (); ++rci) {
ep.insert (rci.trans () * rci->polygon_ref (), ++p);
}
PolygonAreaAndPerimeterCollector ap_collector;
db::PolygonGenerator pg (ap_collector, false);
db::SimpleMerge op;
ep.process (pg, op);
area = ap_collector.area ();
perimeter = ap_collector.perimeter ();
}
static void
get_merged_shapes_of_net (const db::hier_clusters<db::NetShape> &clusters, db::cell_index_type ci, size_t cid, unsigned int layer_id, db::Shapes &shapes)
{
db::EdgeProcessor ep;
// count vertices and reserve space
size_t n = 0;
for (db::recursive_cluster_shape_iterator<db::NetShape> rci (clusters, layer_id, ci, cid); !rci.at_end (); ++rci) {
n += rci->polygon_ref ().vertices ();
}
ep.reserve (n);
size_t p = 0;
for (db::recursive_cluster_shape_iterator<db::NetShape> rci (clusters, layer_id, ci, cid); !rci.at_end (); ++rci) {
ep.insert (rci.trans () * rci->polygon_ref (), ++p);
}
db::ShapeGenerator sg (shapes);
db::PolygonGenerator pg (sg, false);
db::SimpleMerge op;
ep.process (pg, op);
}
db::Region LayoutToNetlist::antenna_check (const db::Region &gate, double gate_area_factor, double gate_perimeter_factor, const db::Region &metal, double metal_area_factor, double metal_perimeter_factor, double ratio, const std::vector<std::pair<const db::Region *, double> > &diodes) db::Region LayoutToNetlist::antenna_check (const db::Region &gate, double gate_area_factor, double gate_perimeter_factor, const db::Region &metal, double metal_area_factor, double metal_perimeter_factor, double ratio, const std::vector<std::pair<const db::Region *, double> > &diodes)
{ {
// TODO: that's basically too much .. we only need the clusters // TODO: that's basically too much .. we only need the clusters
@ -1326,25 +1414,30 @@ db::Region LayoutToNetlist::antenna_check (const db::Region &gate, double gate_a
continue; continue;
} }
db::Region rgate, rmetal; db::Polygon::area_type agate_int = 0;
db::Polygon::perimeter_type pgate_int = 0;
deliver_shapes_of_net_recursive (0, m_net_clusters, *cid, *c, layer_of (gate), db::ICplxTrans (), rgate, 0); compute_area_and_perimeter_of_net_shapes (m_net_clusters, *cid, *c, layer_of (gate), agate_int, pgate_int);
deliver_shapes_of_net_recursive (0, m_net_clusters, *cid, *c, layer_of (metal), db::ICplxTrans (), rmetal, 0);
db::Polygon::area_type ametal_int = 0;
db::Polygon::perimeter_type pmetal_int = 0;
compute_area_and_perimeter_of_net_shapes (m_net_clusters, *cid, *c, layer_of (metal), ametal_int, pmetal_int);
double agate = 0.0; double agate = 0.0;
if (fabs (gate_area_factor) > 1e-6) { if (fabs (gate_area_factor) > 1e-6) {
agate += rgate.area () * dbu * dbu * gate_area_factor; agate += agate_int * dbu * dbu * gate_area_factor;
} }
if (fabs (gate_perimeter_factor) > 1e-6) { if (fabs (gate_perimeter_factor) > 1e-6) {
agate += rgate.perimeter () * dbu * gate_perimeter_factor; agate += pgate_int * dbu * gate_perimeter_factor;
} }
double ametal = 0.0; double ametal = 0.0;
if (fabs (metal_area_factor) > 1e-6) { if (fabs (metal_area_factor) > 1e-6) {
ametal += rmetal.area () * dbu * dbu * metal_area_factor; ametal += ametal_int * dbu * dbu * metal_area_factor;
} }
if (fabs (metal_perimeter_factor) > 1e-6) { if (fabs (metal_perimeter_factor) > 1e-6) {
ametal += rmetal.perimeter () * dbu * metal_perimeter_factor; ametal += pmetal_int * dbu * metal_perimeter_factor;
} }
double r = ratio; double r = ratio;
@ -1352,15 +1445,17 @@ db::Region LayoutToNetlist::antenna_check (const db::Region &gate, double gate_a
for (std::vector<std::pair<const db::Region *, double> >::const_iterator d = diodes.begin (); d != diodes.end () && ! skip; ++d) { for (std::vector<std::pair<const db::Region *, double> >::const_iterator d = diodes.begin (); d != diodes.end () && ! skip; ++d) {
db::Region rdiode; db::Polygon::area_type adiode_int = 0;
deliver_shapes_of_net_recursive (0, m_net_clusters, *cid, *c, layer_of (*d->first), db::ICplxTrans (), rdiode, 0); db::Polygon::perimeter_type pdiode_int = 0;
compute_area_and_perimeter_of_net_shapes (m_net_clusters, *cid, *c, layer_of (*d->first), adiode_int, pdiode_int);
if (fabs (d->second) < db::epsilon) { if (fabs (d->second) < db::epsilon) {
if (rdiode.area () > 0) { if (adiode_int > 0) {
skip = true; skip = true;
} }
} else { } else {
r += rdiode.area () * dbu * dbu * d->second; r += adiode_int * dbu * dbu * d->second;
} }
} }
@ -1373,9 +1468,7 @@ db::Region LayoutToNetlist::antenna_check (const db::Region &gate, double gate_a
if (agate > dbu * dbu && ametal / agate > r + db::epsilon) { if (agate > dbu * dbu && ametal / agate > r + db::epsilon) {
db::Shapes &shapes = ly.cell (*cid).shapes (dl.layer ()); db::Shapes &shapes = ly.cell (*cid).shapes (dl.layer ());
for (db::Region::const_iterator r = rmetal.begin_merged (); ! r.at_end (); ++r) { get_merged_shapes_of_net (m_net_clusters, *cid, *c, layer_of (metal), shapes);
shapes.insert (*r);
}
} }
} }