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
{
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 ();

View File

@ -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
*

View File

@ -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"

View File

@ -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));
}
}

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)")
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