mirror of https://github.com/KLayout/klayout.git
WIP: fixed a potential segfault
This commit is contained in:
parent
0452e91e8c
commit
0d6ce92d6b
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue