mirror of https://github.com/KLayout/klayout.git
WIP: provide a less memory intensive way to deliver shapes from nets.
This commit is contained in:
parent
e439d50111
commit
ad6d9b5715
|
|
@ -219,35 +219,69 @@ static void deliver_shape (const db::PolygonRef &pr, db::Region ®ion, const T
|
|||
}
|
||||
}
|
||||
|
||||
template <class Tr>
|
||||
static void deliver_shape (const db::PolygonRef &pr, db::Shapes &shapes, const Tr &tr)
|
||||
{
|
||||
if (pr.obj ().is_box ()) {
|
||||
shapes.insert (pr.obj ().box ().transformed (pr.trans ()).transformed (tr));
|
||||
} else {
|
||||
db::Layout *layout = shapes.layout ();
|
||||
if (layout) {
|
||||
shapes.insert (db::PolygonRef (pr.obj ().transformed (pr.trans ()).transformed (tr), layout->shape_repository ()));
|
||||
} else {
|
||||
shapes.insert (pr.obj ().transformed (pr.trans ()).transformed (tr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class To>
|
||||
static void deliver_shapes_of_net_recursive (const db::NetlistExtractor &netex, const db::Net &net, unsigned int layer_id, To &to)
|
||||
{
|
||||
const db::Circuit *circuit = net.circuit ();
|
||||
tl_assert (circuit != 0);
|
||||
|
||||
db::cell_index_type ci = circuit->cell_index ();
|
||||
|
||||
for (db::recursive_cluster_shape_iterator<db::PolygonRef> rci (netex.clusters (), layer_id, ci, net.cluster_id ()); !rci.at_end (); ++rci) {
|
||||
deliver_shape (*rci, to, rci.trans ());
|
||||
}
|
||||
}
|
||||
|
||||
template <class To>
|
||||
static void deliver_shapes_of_net_nonrecursive (const db::NetlistExtractor &netex, const db::Net &net, unsigned int layer_id, To &to)
|
||||
{
|
||||
const db::Circuit *circuit = net.circuit ();
|
||||
tl_assert (circuit != 0);
|
||||
|
||||
db::cell_index_type ci = circuit->cell_index ();
|
||||
|
||||
const db::local_cluster<db::PolygonRef> &lc = netex.clusters ().clusters_per_cell (ci).cluster_by_id (net.cluster_id ());
|
||||
|
||||
for (db::local_cluster<db::PolygonRef>::shape_iterator s = lc.begin (layer_id); !s.at_end (); ++s) {
|
||||
deliver_shape (*s, to, db::UnitTrans ());
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutToNetlist::shapes_of_net (const db::Net &net, const db::Region &of_layer, bool recursive, db::Shapes &to) const
|
||||
{
|
||||
unsigned int lid = layer_of (of_layer);
|
||||
|
||||
if (! recursive) {
|
||||
deliver_shapes_of_net_nonrecursive (m_netex, net, lid, to);
|
||||
} else {
|
||||
deliver_shapes_of_net_recursive (m_netex, net, lid, to);
|
||||
}
|
||||
}
|
||||
|
||||
db::Region *LayoutToNetlist::shapes_of_net (const db::Net &net, const db::Region &of_layer, bool recursive) const
|
||||
{
|
||||
unsigned int lid = layer_of (of_layer);
|
||||
std::auto_ptr<db::Region> res (new db::Region ());
|
||||
|
||||
if (! recursive) {
|
||||
|
||||
const db::Circuit *circuit = net.circuit ();
|
||||
tl_assert (circuit != 0);
|
||||
|
||||
db::cell_index_type ci = circuit->cell_index ();
|
||||
|
||||
const db::local_cluster<db::PolygonRef> &lc = m_netex.clusters ().clusters_per_cell (ci).cluster_by_id (net.cluster_id ());
|
||||
|
||||
for (db::local_cluster<db::PolygonRef>::shape_iterator s = lc.begin (lid); !s.at_end (); ++s) {
|
||||
deliver_shape (*s, *res, db::UnitTrans ());
|
||||
}
|
||||
|
||||
deliver_shapes_of_net_nonrecursive (m_netex, net, lid, *res);
|
||||
} else {
|
||||
|
||||
const db::Circuit *circuit = net.circuit ();
|
||||
tl_assert (circuit != 0);
|
||||
|
||||
db::cell_index_type ci = circuit->cell_index ();
|
||||
|
||||
for (db::recursive_cluster_shape_iterator<db::PolygonRef> rci (m_netex.clusters (), lid, ci, net.cluster_id ()); !rci.at_end (); ++rci) {
|
||||
deliver_shape (*rci, *res, rci.trans ());
|
||||
}
|
||||
|
||||
deliver_shapes_of_net_recursive (m_netex, net, lid, *res);
|
||||
}
|
||||
|
||||
return res.release ();
|
||||
|
|
|
|||
|
|
@ -224,6 +224,17 @@ public:
|
|||
*/
|
||||
db::Region *shapes_of_net (const db::Net &net, const db::Region &of_layer, bool recursive) const;
|
||||
|
||||
/**
|
||||
* @brief Delivers all shapes of a specific net and layer to the given Shapes container.
|
||||
*
|
||||
* If "recursive" is true, the returned region will contain the shapes of
|
||||
* all subcircuits too.
|
||||
*
|
||||
* This methods returns a new'd Region. It's the responsibility of the caller
|
||||
* to delete this object.
|
||||
*/
|
||||
void shapes_of_net (const db::Net &net, const db::Region &of_layer, bool recursive, db::Shapes &to) const;
|
||||
|
||||
/**
|
||||
* @brief Finds the net by probing a specific location on the given layer
|
||||
*
|
||||
|
|
|
|||
|
|
@ -141,11 +141,16 @@ Class<db::LayoutToNetlist> decl_dbLayoutToNetlist ("db", "LayoutToNetlist",
|
|||
gsi::method ("netlist", &db::LayoutToNetlist::netlist,
|
||||
"@brief gets the netlist extracted (0 if no extraction happened yet)\n"
|
||||
) +
|
||||
gsi::factory ("shapes_of_net", &db::LayoutToNetlist::shapes_of_net, gsi::arg ("net"), gsi::arg ("of_layer"), gsi::arg ("recursive"),
|
||||
gsi::factory ("shapes_of_net", (db::Region *(db::LayoutToNetlist::*) (const db::Net &, const db::Region &, bool) const) &db::LayoutToNetlist::shapes_of_net, gsi::arg ("net"), gsi::arg ("of_layer"), gsi::arg ("recursive"),
|
||||
"@brief Returns all shapes of a specific net and layer.\n"
|
||||
"If 'recursive'' is true, the returned region will contain the shapes of\n"
|
||||
"all subcircuits too.\n"
|
||||
) +
|
||||
gsi::method ("shapes_of_net", (void (db::LayoutToNetlist::*) (const db::Net &, const db::Region &, bool, db::Shapes &) const) &db::LayoutToNetlist::shapes_of_net, gsi::arg ("net"), gsi::arg ("of_layer"), gsi::arg ("recursive"), gsi::arg ("to"),
|
||||
"@brief Sends all shapes of a specific net and layer to the given Shapes container.\n"
|
||||
"If 'recursive'' is true, the returned region will contain the shapes of\n"
|
||||
"all subcircuits too.\n"
|
||||
) +
|
||||
gsi::method ("probe_net", (db::Net *(db::LayoutToNetlist::*) (const db::Region &, const db::DPoint &)) &db::LayoutToNetlist::probe_net, gsi::arg ("of_layer"), gsi::arg ("point"),
|
||||
"@brief Finds the net by probing a specific location on the given layer\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -148,23 +148,25 @@ static void dump_recursive_nets_to_layout (const db::LayoutToNetlist &l2n, db::L
|
|||
continue;
|
||||
}
|
||||
|
||||
bool any = false;
|
||||
for (std::map<const db::Region *, unsigned int>::const_iterator m = lmap.begin (); m != lmap.end () && !any; ++m) {
|
||||
any = !db::recursive_cluster_shape_iterator<db::PolygonRef> (l2n.net_clusters (), l2n.layer_of (*m->first), c->cell_index (), n->cluster_id ()).at_end ();
|
||||
}
|
||||
|
||||
if (!any) {
|
||||
continue;
|
||||
}
|
||||
|
||||
db::cell_index_type nci = std::numeric_limits<db::cell_index_type>::max ();
|
||||
|
||||
if (nci == std::numeric_limits<db::cell_index_type>::max ()) {
|
||||
std::string nn = "RNET_" + c->name () + "_" + n->expanded_name ();
|
||||
nci = ly.add_cell (nn.c_str ());
|
||||
cell.insert (db::CellInstArray (db::CellInst (nci), db::Trans ()));
|
||||
}
|
||||
|
||||
for (std::map<const db::Region *, unsigned int>::const_iterator m = lmap.begin (); m != lmap.end (); ++m) {
|
||||
|
||||
std::auto_ptr<db::Region> shapes (l2n.shapes_of_net (*n, *m->first, true));
|
||||
if (shapes->empty ()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nci == std::numeric_limits<db::cell_index_type>::max ()) {
|
||||
std::string nn = "RNET_" + c->name () + "_" + n->expanded_name ();
|
||||
nci = ly.add_cell (nn.c_str ());
|
||||
cell.insert (db::CellInstArray (db::CellInst (nci), db::Trans ()));
|
||||
}
|
||||
|
||||
shapes->insert_into (&ly, nci, m->second);
|
||||
|
||||
l2n.shapes_of_net (*n, *m->first, true, ly.cell (nci).shapes (m->second));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,6 +120,12 @@ END
|
|||
|
||||
assert_equal(l2n.shapes_of_net(n, rmetal1, true).to_s, "(1660,-420;1660,2420;2020,2420;2020,-420);(1840,820;1840,1180;3220,1180;3220,820);(1660,2420;1660,3180;2020,3180;2020,2420);(1660,-380;1660,380;2020,380;2020,-380)")
|
||||
|
||||
shapes = RBA::Shapes::new
|
||||
l2n.shapes_of_net(n, rmetal1, true, shapes)
|
||||
r = RBA::Region::new
|
||||
shapes.each { |s| r.insert(s.polygon) }
|
||||
assert_equal(r.to_s, "(1660,-420;1660,2420;2020,2420;2020,-420);(1840,820;1840,1180;3220,1180;3220,820);(1660,2420;1660,3180;2020,3180;2020,2420);(1660,-380;1660,380;2020,380;2020,-380)")
|
||||
|
||||
end
|
||||
|
||||
def test_10_LayoutToNetlistExtractionWithoutDevices
|
||||
|
|
|
|||
Loading…
Reference in New Issue