WIP: provide a less memory intensive way to deliver shapes from nets.

This commit is contained in:
Matthias Koefferlein 2019-01-04 17:41:09 +01:00
parent e439d50111
commit ad6d9b5715
5 changed files with 95 additions and 37 deletions

View File

@ -219,35 +219,69 @@ static void deliver_shape (const db::PolygonRef &pr, db::Region &region, 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 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); unsigned int lid = layer_of (of_layer);
std::auto_ptr<db::Region> res (new db::Region ()); std::auto_ptr<db::Region> res (new db::Region ());
if (! recursive) { if (! recursive) {
deliver_shapes_of_net_nonrecursive (m_netex, net, lid, *res);
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 ());
}
} else { } else {
deliver_shapes_of_net_recursive (m_netex, net, lid, *res);
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 ());
}
} }
return res.release (); return res.release ();

View File

@ -224,6 +224,17 @@ public:
*/ */
db::Region *shapes_of_net (const db::Net &net, const db::Region &of_layer, bool recursive) const; 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 * @brief Finds the net by probing a specific location on the given layer
* *

View File

@ -141,11 +141,16 @@ Class<db::LayoutToNetlist> decl_dbLayoutToNetlist ("db", "LayoutToNetlist",
gsi::method ("netlist", &db::LayoutToNetlist::netlist, gsi::method ("netlist", &db::LayoutToNetlist::netlist,
"@brief gets the netlist extracted (0 if no extraction happened yet)\n" "@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" "@brief Returns all shapes of a specific net and layer.\n"
"If 'recursive'' is true, the returned region will contain the shapes of\n" "If 'recursive'' is true, the returned region will contain the shapes of\n"
"all subcircuits too.\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"), 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" "@brief Finds the net by probing a specific location on the given layer\n"
"\n" "\n"

View File

@ -148,23 +148,25 @@ static void dump_recursive_nets_to_layout (const db::LayoutToNetlist &l2n, db::L
continue; 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 (); 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) { for (std::map<const db::Region *, unsigned int>::const_iterator m = lmap.begin (); m != lmap.end (); ++m) {
l2n.shapes_of_net (*n, *m->first, true, ly.cell (nci).shapes (m->second));
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);
} }
} }

View File

@ -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)") 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 end
def test_10_LayoutToNetlistExtractionWithoutDevices def test_10_LayoutToNetlistExtractionWithoutDevices