mirror of
https://github.com/KLayout/klayout.git
synced 2026-08-29 01:14:35 +02:00
Enhancements for net export feature
- some refactoring - better performance (was slow because layer iteration was done outside of loop and recursive cluster iterator) - with selected nets, only the required hierarchy is produced. For this a new argument is added to LayoutToNetlist::create_cell_mapping (nets) which allows selecting the nets for which a cell mapping is requested
This commit is contained in:
@@ -295,7 +295,7 @@ CellMapping::create_from_names (const db::Layout &layout_a, db::cell_index_type
|
||||
}
|
||||
|
||||
std::vector<db::cell_index_type>
|
||||
CellMapping::create_missing_mapping (db::Layout &layout_a, db::cell_index_type /*cell_index_a*/, const db::Layout &layout_b, db::cell_index_type cell_index_b, const std::set<db::cell_index_type> *exclude_cells)
|
||||
CellMapping::create_missing_mapping (db::Layout &layout_a, db::cell_index_type /*cell_index_a*/, const db::Layout &layout_b, db::cell_index_type cell_index_b, const std::set<db::cell_index_type> *exclude_cells, const std::set<db::cell_index_type> *include_cells)
|
||||
{
|
||||
std::vector<db::cell_index_type> new_cells;
|
||||
std::vector<db::cell_index_type> new_cells_b;
|
||||
@@ -305,7 +305,9 @@ CellMapping::create_missing_mapping (db::Layout &layout_a, db::cell_index_type /
|
||||
called_b.insert (cell_index_b);
|
||||
|
||||
for (std::set<db::cell_index_type>::const_iterator b = called_b.begin (); b != called_b.end (); ++b) {
|
||||
if (m_b2a_mapping.find (*b) == m_b2a_mapping.end () && (! exclude_cells || exclude_cells->find (*b) == exclude_cells->end ())) {
|
||||
if (m_b2a_mapping.find (*b) == m_b2a_mapping.end ()
|
||||
&& (! exclude_cells || exclude_cells->find (*b) == exclude_cells->end ())
|
||||
&& (! include_cells || include_cells->find (*b) != include_cells->end ())) {
|
||||
db::cell_index_type new_cell = layout_a.add_cell (layout_b.cell_name (*b));
|
||||
new_cells.push_back (new_cell);
|
||||
new_cells_b.push_back (*b);
|
||||
|
||||
@@ -190,9 +190,12 @@ public:
|
||||
*
|
||||
* If given, "exclude_cells" can specify a list of cells not to map.
|
||||
*
|
||||
* If given, "include_cells" can specify a list of cells which are included in the
|
||||
* cell tree to create. Cells not in the "include_cells" list are ignored.
|
||||
*
|
||||
* The returned vector lists the new cells.
|
||||
*/
|
||||
std::vector<db::cell_index_type> create_missing_mapping (db::Layout &layout_a, db::cell_index_type cell_index_a, const db::Layout &layout_b, db::cell_index_type cell_index_b, const std::set<db::cell_index_type> *exclude_cells = 0);
|
||||
std::vector<db::cell_index_type> create_missing_mapping (db::Layout &layout_a, db::cell_index_type cell_index_a, const db::Layout &layout_b, db::cell_index_type cell_index_b, const std::set<db::cell_index_type> *exclude_cells = 0, const std::set<db::cell_index_type> *include_cells = 0);
|
||||
|
||||
private:
|
||||
void extract_unique (std::map <db::cell_index_type, std::vector<db::cell_index_type> >::const_iterator cand,
|
||||
|
||||
@@ -713,7 +713,7 @@ DeepShapeStore::issue_variants (unsigned int layout_index, const std::map<db::ce
|
||||
}
|
||||
|
||||
const db::CellMapping &
|
||||
DeepShapeStore::cell_mapping_to_original (unsigned int layout_index, db::Layout *into_layout, db::cell_index_type into_cell, const std::set<db::cell_index_type> *excluded_cells)
|
||||
DeepShapeStore::cell_mapping_to_original (unsigned int layout_index, db::Layout *into_layout, db::cell_index_type into_cell, const std::set<db::cell_index_type> *excluded_cells, const std::set<db::cell_index_type> *included_cells)
|
||||
{
|
||||
const db::Layout *source_layout = &m_layouts [layout_index]->layout;
|
||||
if (source_layout->begin_top_down () == source_layout->end_top_cells ()) {
|
||||
@@ -774,7 +774,7 @@ DeepShapeStore::cell_mapping_to_original (unsigned int layout_index, db::Layout
|
||||
|
||||
// Add new cells for the variants and (possible) devices which are cells added during the device
|
||||
// extraction process
|
||||
cm->second.create_missing_mapping (*into_layout, into_cell, *source_layout, source_top, excluded_cells);
|
||||
cm->second.create_missing_mapping (*into_layout, into_cell, *source_layout, source_top, excluded_cells, included_cells);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -375,9 +375,11 @@ public:
|
||||
* "layout_index" is the layout to return to it's original. "into_layout" is the original layout, "into_cell"
|
||||
* the original cell.
|
||||
*
|
||||
* "excluded_cells" - if not 0 - will exclude the given cells (and flatten them).
|
||||
* "excluded_cells" - if not 0 - will exclude the given cells
|
||||
*
|
||||
* "included_cells" - if not 0 - will only include the given cells in the cell mapping
|
||||
*/
|
||||
const db::CellMapping &cell_mapping_to_original (unsigned int layout_index, db::Layout *into_layout, db::cell_index_type into_cell, const std::set<db::cell_index_type> *excluded_cells = 0);
|
||||
const db::CellMapping &cell_mapping_to_original (unsigned int layout_index, db::Layout *into_layout, db::cell_index_type into_cell, const std::set<db::cell_index_type> *excluded_cells = 0, const std::set<db::cell_index_type> *included_cells = 0);
|
||||
|
||||
/**
|
||||
* @brief Create cell variants from the given variant collector
|
||||
|
||||
+118
-56
@@ -445,7 +445,7 @@ unsigned int LayoutToNetlist::layer_of (const db::Region ®ion) const
|
||||
return deep_layer_of (region).layer ();
|
||||
}
|
||||
|
||||
db::CellMapping LayoutToNetlist::cell_mapping_into (db::Layout &layout, db::Cell &cell, bool with_device_cells)
|
||||
db::CellMapping LayoutToNetlist::make_cell_mapping_into (db::Layout &layout, db::Cell &cell, const std::vector<const db::Net *> *nets, bool with_device_cells)
|
||||
{
|
||||
std::set<db::cell_index_type> device_cells;
|
||||
if (! with_device_cells && mp_netlist.get ()) {
|
||||
@@ -454,7 +454,31 @@ db::CellMapping LayoutToNetlist::cell_mapping_into (db::Layout &layout, db::Cell
|
||||
}
|
||||
}
|
||||
|
||||
return dss ().cell_mapping_to_original (m_layout_index, &layout, cell.cell_index (), &device_cells);
|
||||
std::set<db::cell_index_type> net_cells;
|
||||
if (nets) {
|
||||
// Compute the "included cell" list for cell_mapping_to_original: these are all cells which
|
||||
// are required to represent the net hierarchically.
|
||||
for (std::vector<const db::Net *>::const_iterator n = nets->begin (); n != nets->end (); ++n) {
|
||||
const db::Net *net = *n;
|
||||
db::cell_index_type net_cell = net->circuit ()->cell_index ();
|
||||
if (net_cells.find (net_cell) == net_cells.end ()) {
|
||||
net_cells.insert (net_cell);
|
||||
internal_layout()->cell (net_cell).collect_caller_cells (net_cells);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dss ().cell_mapping_to_original (m_layout_index, &layout, cell.cell_index (), &device_cells, nets ? &net_cells : 0);
|
||||
}
|
||||
|
||||
db::CellMapping LayoutToNetlist::cell_mapping_into (db::Layout &layout, db::Cell &cell, const std::vector<const db::Net *> &nets, bool with_device_cells)
|
||||
{
|
||||
return make_cell_mapping_into (layout, cell, &nets, with_device_cells);
|
||||
}
|
||||
|
||||
db::CellMapping LayoutToNetlist::cell_mapping_into (db::Layout &layout, db::Cell &cell, bool with_device_cells)
|
||||
{
|
||||
return make_cell_mapping_into (layout, cell, 0, with_device_cells);
|
||||
}
|
||||
|
||||
db::CellMapping LayoutToNetlist::const_cell_mapping_into (const db::Layout &layout, const db::Cell &cell)
|
||||
@@ -563,11 +587,11 @@ static bool deliver_shape (const db::PolygonRef &pr, db::Shapes &shapes, const T
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class To>
|
||||
static bool deliver_shapes_of_net_recursive (const db::Netlist * /*nl*/, const db::hier_clusters<db::PolygonRef> &clusters, db::cell_index_type ci, size_t cid, unsigned int layer_id, const db::ICplxTrans &tr, To &to, db::properties_id_type propid)
|
||||
template <class To, class Shape>
|
||||
static bool deliver_shapes_of_net_recursive (const db::Netlist * /*nl*/, const db::hier_clusters<Shape> &clusters, db::cell_index_type ci, size_t cid, unsigned int layer_id, const db::ICplxTrans &tr, To &to, db::properties_id_type propid)
|
||||
{
|
||||
// deliver the net shapes
|
||||
for (db::recursive_cluster_shape_iterator<db::PolygonRef> rci (clusters, layer_id, ci, cid); !rci.at_end (); ++rci) {
|
||||
for (db::recursive_cluster_shape_iterator<Shape> rci (clusters, layer_id, ci, cid); !rci.at_end (); ++rci) {
|
||||
if (! deliver_shape (*rci, to, tr * rci.trans (), propid)) {
|
||||
return false;
|
||||
}
|
||||
@@ -575,56 +599,61 @@ static bool deliver_shapes_of_net_recursive (const db::Netlist * /*nl*/, const d
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class To>
|
||||
static bool deliver_shapes_of_net_nonrecursive (const db::Netlist *nl, const db::hier_clusters<db::PolygonRef> &clusters, db::cell_index_type ci, size_t cid, unsigned int layer_id, const db::ICplxTrans &tr, To &to, db::properties_id_type propid)
|
||||
template <class To, class Shape>
|
||||
static bool deliver_shapes_of_net (bool recursive, const db::Netlist *nl, const db::hier_clusters<Shape> &clusters, db::cell_index_type ci, size_t cid, const std::map<unsigned int, To *> &lmap, const db::ICplxTrans &tr, db::properties_id_type propid)
|
||||
{
|
||||
// NOTE: this scheme will deliver the shapes from the cell, including (!)
|
||||
// subcells that are purged
|
||||
// shortcut
|
||||
if (lmap.empty ()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
db::cell_index_type prev_ci = ci;
|
||||
const db::connected_clusters<Shape> &cc = clusters.clusters_per_cell (ci);
|
||||
const db::local_cluster<Shape> &lc = cc.cluster_by_id (cid);
|
||||
|
||||
// deliver the net shapes
|
||||
for (db::recursive_cluster_shape_iterator<db::PolygonRef> rci (clusters, layer_id, ci, cid); !rci.at_end (); ) {
|
||||
|
||||
db::cell_index_type cci = rci.cell_index ();
|
||||
if (cci != prev_ci && cci != ci && (! nl || nl->circuit_by_cell_index (cci) || nl->device_abstract_by_cell_index (cci))) {
|
||||
|
||||
rci.skip_cell ();
|
||||
|
||||
} else {
|
||||
|
||||
if (! deliver_shape (*rci, to, tr * rci.trans (), propid)) {
|
||||
for (typename std::map<unsigned int, To *>::const_iterator l = lmap.begin (); l != lmap.end (); ++l) {
|
||||
for (typename db::local_cluster<Shape>::shape_iterator s = lc.begin (l->first); ! s.at_end (); ++s) {
|
||||
if (! deliver_shape (*s, *l->second, tr, propid)) {
|
||||
return false;
|
||||
}
|
||||
prev_ci = cci;
|
||||
|
||||
++rci;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
const typename db::connected_clusters<Shape>::connections_type &conn = cc.connections_for_cluster (cid);
|
||||
for (typename db::connected_clusters<Shape>::connections_type::const_iterator c = conn.begin (); c != conn.end (); ) {
|
||||
|
||||
db::cell_index_type cci = c->inst_cell_index ();
|
||||
if (! recursive && (! nl || nl->circuit_by_cell_index (cci) || nl->device_abstract_by_cell_index (cci))) {
|
||||
// skip this cell in non-recursive mode (and all following instances of the same cell too)
|
||||
typename db::connected_clusters<Shape>::connections_type::const_iterator cc = c;
|
||||
while (++cc != conn.end ()) {
|
||||
if (cc->inst_cell_index () != cci) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
c = cc;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! deliver_shapes_of_net (recursive, nl, clusters, cci, c->id (), lmap, tr * c->inst_trans (), propid)) {
|
||||
return false;
|
||||
}
|
||||
++c;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class To>
|
||||
static bool deliver_shapes_of_net (bool recursive, const db::Netlist *nl, const db::hier_clusters<db::PolygonRef> &clusters, db::cell_index_type ci, size_t cid, unsigned int layer_id, const db::ICplxTrans &tr, To &to, db::properties_id_type propid)
|
||||
{
|
||||
if (recursive) {
|
||||
return deliver_shapes_of_net_recursive (nl, clusters, ci, cid, layer_id, tr, to, propid);
|
||||
} else {
|
||||
return deliver_shapes_of_net_nonrecursive (nl, clusters, ci, cid, layer_id, tr, to, propid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LayoutToNetlist::shapes_of_net (const db::Net &net, const db::Region &of_layer, bool recursive, db::Shapes &to, db::properties_id_type propid) const
|
||||
{
|
||||
unsigned int lid = layer_of (of_layer);
|
||||
const db::Circuit *circuit = net.circuit ();
|
||||
tl_assert (circuit != 0);
|
||||
|
||||
deliver_shapes_of_net (recursive, mp_netlist.get (), m_net_clusters, circuit->cell_index (), net.cluster_id (), lid, db::ICplxTrans (), to, propid);
|
||||
std::map<unsigned int, db::Shapes *> lmap;
|
||||
lmap [lid] = &to;
|
||||
|
||||
deliver_shapes_of_net (recursive, mp_netlist.get (), m_net_clusters, circuit->cell_index (), net.cluster_id (), lmap, db::ICplxTrans (), propid);
|
||||
}
|
||||
|
||||
db::Region *LayoutToNetlist::shapes_of_net (const db::Net &net, const db::Region &of_layer, bool recursive) const
|
||||
@@ -634,8 +663,10 @@ db::Region *LayoutToNetlist::shapes_of_net (const db::Net &net, const db::Region
|
||||
tl_assert (circuit != 0);
|
||||
|
||||
std::auto_ptr<db::Region> res (new db::Region ());
|
||||
std::map<unsigned int, db::Region *> lmap;
|
||||
lmap [lid] = res.get ();
|
||||
|
||||
deliver_shapes_of_net (recursive, mp_netlist.get (), m_net_clusters, circuit->cell_index (), net.cluster_id (), lid, db::ICplxTrans (), *res, 0);
|
||||
deliver_shapes_of_net (recursive, mp_netlist.get (), m_net_clusters, circuit->cell_index (), net.cluster_id (), lmap, db::ICplxTrans (), 0);
|
||||
|
||||
return res.release ();
|
||||
}
|
||||
@@ -661,14 +692,15 @@ LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &
|
||||
bool any_connections = circuit_cell_name_prefix && ! ccl.connections_for_cluster (cid).empty ();
|
||||
if (! any_connections) {
|
||||
|
||||
bool consider_cell = any_connections;
|
||||
for (std::map<unsigned int, const db::Region *>::const_iterator l = lmap.begin (); l != lmap.end () && !consider_cell; ++l) {
|
||||
StopOnFirst sof;
|
||||
std::map<unsigned int, StopOnFirst *> sof_lmap;
|
||||
for (std::map<unsigned int, const db::Region *>::const_iterator l = lmap.begin (); l != lmap.end (); ++l) {
|
||||
if (l->second) {
|
||||
StopOnFirst sof;
|
||||
consider_cell = !deliver_shapes_of_net (hier_mode == BNH_Flatten, mp_netlist.get (), m_net_clusters, ci, cid, layer_of (*l->second), tr, sof, 0);
|
||||
sof_lmap.insert (std::make_pair (layer_of (*l->second), &sof));
|
||||
}
|
||||
}
|
||||
|
||||
bool consider_cell = !deliver_shapes_of_net (hier_mode == BNH_Flatten, mp_netlist.get (), m_net_clusters, ci, cid, sof_lmap, tr, 0);
|
||||
if (! consider_cell) {
|
||||
// shortcut if cell is empty -> no net cell will be produced
|
||||
return;
|
||||
@@ -683,12 +715,15 @@ LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &
|
||||
|
||||
}
|
||||
|
||||
std::map<unsigned int, db::Shapes *> target_lmap;
|
||||
for (std::map<unsigned int, const db::Region *>::const_iterator l = lmap.begin (); l != lmap.end (); ++l) {
|
||||
if (l->second) {
|
||||
deliver_shapes_of_net (hier_mode == BNH_Flatten, mp_netlist.get (), m_net_clusters, ci, cid, layer_of (*l->second), tr, target_cell->shapes (l->first), netname_propid);
|
||||
target_lmap.insert (std::make_pair (layer_of (*l->second), &target_cell->shapes (l->first)));
|
||||
}
|
||||
}
|
||||
|
||||
deliver_shapes_of_net (hier_mode == BNH_Flatten, mp_netlist.get (), m_net_clusters, ci, cid, target_lmap, tr, netname_propid);
|
||||
|
||||
if (hier_mode != BNH_SubcircuitCells && ! device_cell_name_prefix) {
|
||||
return;
|
||||
}
|
||||
@@ -780,26 +815,53 @@ LayoutToNetlist::build_all_nets (const db::CellMapping &cmap, db::Layout &target
|
||||
}
|
||||
|
||||
void
|
||||
LayoutToNetlist::build_nets (const std::set<const db::Net *> *nets, const db::CellMapping &cmap, db::Layout &target, const std::map<unsigned int, const db::Region *> &lmap, const char *net_cell_name_prefix, const tl::Variant &netname_prop, BuildNetHierarchyMode hier_mode, const char *circuit_cell_name_prefix, const char *device_cell_name_prefix) const
|
||||
LayoutToNetlist::build_net_rec (const db::Net &net, db::Layout &target, db::cell_index_type circuit_cell, const db::CellMapping &cmap, const std::map<unsigned int, const db::Region *> &lmap, const char *net_cell_name_prefix, db::properties_id_type netname_propid, BuildNetHierarchyMode hier_mode, const char *cell_name_prefix, const char *device_cell_name_prefix, cell_reuse_table_type &reuse_table, const ICplxTrans &tr) const
|
||||
{
|
||||
if (! cmap.has_mapping (circuit_cell)) {
|
||||
|
||||
const db::Cell &cc = internal_layout ()->cell (circuit_cell);
|
||||
|
||||
for (db::Cell::parent_inst_iterator p = cc.begin_parent_insts (); ! p.at_end (); ++p) {
|
||||
|
||||
db::CellInstArray ci = p->child_inst ().cell_inst ();
|
||||
for (db::CellInstArray::iterator ia = ci.begin (); ! ia.at_end(); ++ia) {
|
||||
|
||||
db::ICplxTrans tr_parent = ci.complex_trans (*ia) * tr;
|
||||
build_net_rec (net, target, p->parent_cell_index (), cmap, lmap, net_cell_name_prefix, netname_propid, hier_mode, cell_name_prefix, device_cell_name_prefix, reuse_table, tr_parent);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
double mag = internal_layout ()->dbu () / target.dbu ();
|
||||
|
||||
db::cell_index_type target_ci = cmap.cell_mapping (circuit_cell);
|
||||
build_net_rec (net, target, target.cell (target_ci), lmap, net_cell_name_prefix, netname_propid, hier_mode, cell_name_prefix, device_cell_name_prefix, reuse_table, db::ICplxTrans (mag) * tr);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LayoutToNetlist::build_nets (const std::vector<const db::Net *> *nets, const db::CellMapping &cmap, db::Layout &target, const std::map<unsigned int, const db::Region *> &lmap, const char *net_cell_name_prefix, const tl::Variant &netname_prop, BuildNetHierarchyMode hier_mode, const char *circuit_cell_name_prefix, const char *device_cell_name_prefix) const
|
||||
{
|
||||
if (! m_netlist_extracted) {
|
||||
throw tl::Exception (tl::to_string (tr ("The netlist has not been extracted yet")));
|
||||
}
|
||||
|
||||
std::set<const db::Net *> net_set;
|
||||
if (nets) {
|
||||
net_set.insert (nets->begin (), nets->end ());
|
||||
}
|
||||
|
||||
cell_reuse_table_type cell_reuse_table;
|
||||
double mag = internal_layout ()->dbu () / target.dbu ();
|
||||
|
||||
const db::Netlist *netlist = mp_netlist.get ();
|
||||
for (db::Netlist::const_circuit_iterator c = netlist->begin_circuits (); c != netlist->end_circuits (); ++c) {
|
||||
|
||||
if (! cmap.has_mapping (c->cell_index ())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool is_top_circuit = c->begin_parents () == c->end_parents ();
|
||||
|
||||
db::cell_index_type target_ci = cmap.cell_mapping (c->cell_index ());
|
||||
|
||||
for (db::Circuit::const_net_iterator n = c->begin_nets (); n != c->end_nets (); ++n) {
|
||||
|
||||
// exlude local nets in recursive mode except if they are explicitly selected
|
||||
@@ -807,9 +869,9 @@ LayoutToNetlist::build_nets (const std::set<const db::Net *> *nets, const db::Ce
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! nets || nets->find (n.operator-> ()) != nets->end ()) {
|
||||
if (! nets || net_set.find (n.operator-> ()) != net_set.end ()) {
|
||||
db::properties_id_type netname_propid = make_netname_propid (target, netname_prop, *n);
|
||||
build_net_rec (*n, target, target.cell (target_ci), lmap, net_cell_name_prefix, netname_propid, hier_mode, circuit_cell_name_prefix, device_cell_name_prefix, cell_reuse_table, db::ICplxTrans (mag));
|
||||
build_net_rec (*n, target, c->cell_index (), cmap, lmap, net_cell_name_prefix, netname_propid, hier_mode, circuit_cell_name_prefix, device_cell_name_prefix, cell_reuse_table, db::ICplxTrans ());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -835,15 +897,15 @@ LayoutToNetlist::build_nets (const std::set<const db::Net *> *nets, const db::Ce
|
||||
if (n) {
|
||||
|
||||
double dbu = target.dbu ();
|
||||
db::ICplxTrans tr = db::ICplxTrans (mag) * (db::CplxTrans (dbu).inverted () * subcircuit.trans () * db::CplxTrans (dbu));
|
||||
db::ICplxTrans tr = db::CplxTrans (dbu).inverted () * subcircuit.trans () * db::CplxTrans (dbu);
|
||||
|
||||
db::properties_id_type netname_propid = make_netname_propid (target, netname_prop, *n);
|
||||
|
||||
if (net_cell_name_prefix) {
|
||||
std::string ncn = std::string (net_cell_name_prefix) + subcircuit.expanded_name () + ":";
|
||||
build_net_rec (*n, target, target.cell (target_ci), lmap, ncn.c_str (), netname_propid, hier_mode, circuit_cell_name_prefix, device_cell_name_prefix, cell_reuse_table, tr);
|
||||
build_net_rec (*n, target, c->cell_index (), cmap, lmap, ncn.c_str (), netname_propid, hier_mode, circuit_cell_name_prefix, device_cell_name_prefix, cell_reuse_table, tr);
|
||||
} else {
|
||||
build_net_rec (*n, target, target.cell (target_ci), lmap, net_cell_name_prefix, netname_propid, hier_mode, circuit_cell_name_prefix, device_cell_name_prefix, cell_reuse_table, tr);
|
||||
build_net_rec (*n, target, c->cell_index (), cmap, lmap, net_cell_name_prefix, netname_propid, hier_mode, circuit_cell_name_prefix, device_cell_name_prefix, cell_reuse_table, tr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -435,10 +435,19 @@ public:
|
||||
*/
|
||||
db::CellMapping cell_mapping_into (db::Layout &layout, db::Cell &cell, bool with_device_cells = false);
|
||||
|
||||
/**
|
||||
* @brief Creates a cell mapping for copying shapes from the internal layout to the given target layout for a given list of nets
|
||||
* This version will only create cells which are required to represent the given nets.
|
||||
* If 'with_device_cells' is true, cells will be produced for devices. These are cells not corresponding to circuits, so they are disabled normally.
|
||||
* Use this option, if you want to access device terminal shapes per device.
|
||||
* CAUTION: This function may create new cells in "layout".
|
||||
*/
|
||||
db::CellMapping cell_mapping_into (db::Layout &layout, db::Cell &cell, const std::vector<const db::Net *> &nets, bool with_device_cells = false);
|
||||
|
||||
/**
|
||||
* @brief Creates a cell mapping for copying shapes from the internal layout to the given target layout.
|
||||
* This version will not create new cells in the target layout.
|
||||
* If the required cells do not exist there yet, flatting will happen.
|
||||
* If the required cells do not exist there yet, flattening will happen.
|
||||
*/
|
||||
db::CellMapping const_cell_mapping_into (const db::Layout &layout, const db::Cell &cell);
|
||||
|
||||
@@ -601,7 +610,7 @@ public:
|
||||
/**
|
||||
* @brief Like build_all_nets, but with the ability to select some nets
|
||||
*/
|
||||
void build_nets (const std::set<const db::Net *> *nets, const db::CellMapping &cmap, db::Layout &target, const std::map<unsigned int, const db::Region *> &lmap, const char *net_cell_name_prefix, const tl::Variant &netname_prop, BuildNetHierarchyMode hier_mode, const char *circuit_cell_name_prefix, const char *device_cell_name_prefix) const;
|
||||
void build_nets (const std::vector<const Net *> *nets, const db::CellMapping &cmap, db::Layout &target, const std::map<unsigned int, const db::Region *> &lmap, const char *net_cell_name_prefix, const tl::Variant &netname_prop, BuildNetHierarchyMode hier_mode, const char *circuit_cell_name_prefix, const char *device_cell_name_prefix) const;
|
||||
|
||||
/**
|
||||
* @brief Finds the net by probing a specific location on the given layer
|
||||
@@ -730,12 +739,14 @@ private:
|
||||
|
||||
void init ();
|
||||
size_t search_net (const db::ICplxTrans &trans, const db::Cell *cell, const db::local_cluster<db::PolygonRef> &test_cluster, std::vector<db::InstElement> &rev_inst_path);
|
||||
void build_net_rec (const db::Net &net, db::Layout &target, cell_index_type circuit_cell, const db::CellMapping &cmap, const std::map<unsigned int, const db::Region *> &lmap, const char *net_cell_name_prefix, db::properties_id_type netname_propid, BuildNetHierarchyMode hier_mode, const char *cell_name_prefix, const char *device_cell_name_prefix, cell_reuse_table_type &reuse_table, const ICplxTrans &tr) const;
|
||||
void build_net_rec (const db::Net &net, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const char *net_cell_name_prefix, db::properties_id_type netname_propid, BuildNetHierarchyMode hier_mode, const char *cell_name_prefix, const char *device_cell_name_prefix, cell_reuse_table_type &reuse_table, const ICplxTrans &tr) const;
|
||||
void build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const Net *net, const char *net_cell_name_prefix, db::properties_id_type netname_propid, BuildNetHierarchyMode hier_mode, const char *cell_name_prefix, const char *device_cell_name_prefix, cell_reuse_table_type &reuse_table, const ICplxTrans &tr) const;
|
||||
db::DeepLayer deep_layer_of (const db::Region ®ion) const;
|
||||
void ensure_layout () const;
|
||||
std::string make_new_name (const std::string &stem = std::string ());
|
||||
db::properties_id_type make_netname_propid (db::Layout &ly, const tl::Variant &netname_prop, const db::Net &net) const;
|
||||
db::CellMapping make_cell_mapping_into (db::Layout &layout, db::Cell &cell, const std::vector<const db::Net *> *nets, bool with_device_cells);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -81,6 +81,14 @@ static void build_all_nets (const db::LayoutToNetlist *l2n, const db::CellMappin
|
||||
l2n->build_all_nets (cmap, target, lmap, net_cell_name_prefix.is_nil () ? 0 : np.c_str (), netname_prop, hier_mode, circuit_cell_name_prefix.is_nil () ? 0 : cp.c_str (), device_cell_name_prefix.is_nil () ? 0 : dp.c_str ());
|
||||
}
|
||||
|
||||
static void build_nets (const db::LayoutToNetlist *l2n, const std::vector<const db::Net *> &nets, const db::CellMapping &cmap, db::Layout &target, const std::map<unsigned int, const db::Region *> &lmap, const tl::Variant &net_cell_name_prefix, const tl::Variant &netname_prop, db::LayoutToNetlist::BuildNetHierarchyMode hier_mode, const tl::Variant &circuit_cell_name_prefix, const tl::Variant &device_cell_name_prefix)
|
||||
{
|
||||
std::string cp = circuit_cell_name_prefix.to_string ();
|
||||
std::string np = net_cell_name_prefix.to_string ();
|
||||
std::string dp = device_cell_name_prefix.to_string ();
|
||||
l2n->build_nets (&nets, cmap, target, lmap, net_cell_name_prefix.is_nil () ? 0 : np.c_str (), netname_prop, hier_mode, circuit_cell_name_prefix.is_nil () ? 0 : cp.c_str (), device_cell_name_prefix.is_nil () ? 0 : dp.c_str ());
|
||||
}
|
||||
|
||||
static std::vector<std::string> l2n_layer_names (const db::LayoutToNetlist *l2n)
|
||||
{
|
||||
std::vector<std::string> ln;
|
||||
@@ -331,11 +339,21 @@ Class<db::LayoutToNetlist> decl_dbLayoutToNetlist ("db", "LayoutToNetlist",
|
||||
"This method is required to derive the internal layer index - for example for\n"
|
||||
"investigating the cluster tree.\n"
|
||||
) +
|
||||
gsi::method ("cell_mapping_into", &db::LayoutToNetlist::cell_mapping_into, gsi::arg ("layout"), gsi::arg ("cell"), gsi::arg ("with_device_cells", false),
|
||||
gsi::method ("cell_mapping_into", (db::CellMapping (db::LayoutToNetlist::*) (db::Layout &, db::Cell &, bool)) &db::LayoutToNetlist::cell_mapping_into, gsi::arg ("layout"), gsi::arg ("cell"), gsi::arg ("with_device_cells", false),
|
||||
"@brief Creates a cell mapping for copying shapes from the internal layout to the given target layout.\n"
|
||||
"If 'with_device_cells' is true, cells will be produced for devices. These are cells not corresponding to circuits, so they are disabled normally.\n"
|
||||
"Use this option, if you want to access device terminal shapes per device.\n"
|
||||
"CAUTION: this function may create new cells in 'layout'.\n"
|
||||
"\n"
|
||||
"CAUTION: this function may create new cells in 'layout'. Use \\const_cell_mapping_into if you want to use the target layout's hierarchy and not modify it.\n"
|
||||
) +
|
||||
gsi::method ("cell_mapping_into", (db::CellMapping (db::LayoutToNetlist::*) (db::Layout &, db::Cell &, const std::vector<const db::Net *> &, bool)) &db::LayoutToNetlist::cell_mapping_into, gsi::arg ("layout"), gsi::arg ("cell"), gsi::arg ("nets"), gsi::arg ("with_device_cells", false),
|
||||
"@brief Creates a cell mapping for copying shapes from the internal layout to the given target layout.\n"
|
||||
"This version will only create cells which are required to represent the nets from the 'nets' argument.\n"
|
||||
"\n"
|
||||
"If 'with_device_cells' is true, cells will be produced for devices. These are cells not corresponding to circuits, so they are disabled normally.\n"
|
||||
"Use this option, if you want to access device terminal shapes per device.\n"
|
||||
"\n"
|
||||
"CAUTION: this function may create new cells in 'layout'. Use \\const_cell_mapping_into if you want to use the target layout's hierarchy and not modify it.\n"
|
||||
) +
|
||||
gsi::method ("const_cell_mapping_into", &db::LayoutToNetlist::const_cell_mapping_into, gsi::arg ("layout"), gsi::arg ("cell"),
|
||||
"@brief Creates a cell mapping for copying shapes from the internal layout to the given target layout.\n"
|
||||
@@ -389,9 +407,10 @@ Class<db::LayoutToNetlist> decl_dbLayoutToNetlist ("db", "LayoutToNetlist",
|
||||
gsi::method_ext ("build_all_nets", &build_all_nets, gsi::arg ("cmap"), gsi::arg ("target"), gsi::arg ("lmap"), gsi::arg ("net_cell_name_prefix", tl::Variant (), "nil"), gsi::arg ("netname_prop", tl::Variant (), "nil"), gsi::arg ("hier_mode", db::LayoutToNetlist::BNH_Flatten, "BNH_Flatten"), gsi::arg ("circuit_cell_name_prefix", tl::Variant (), "nil"), gsi::arg ("device_cell_name_prefix", tl::Variant (), "nil"),
|
||||
"@brief Builds a full hierarchical representation of the nets\n"
|
||||
"\n"
|
||||
"This method copies all nets into cells corresponding to the circuits. It uses the cmap\n"
|
||||
"object to determine the target cell (create them with \"cell_mapping_into\" or \"const_cell_mapping_into\").\n"
|
||||
"If no mapping is requested, the specific circuit it skipped.\n"
|
||||
"This method copies all nets into cells corresponding to the circuits. It uses the 'cmap'\n"
|
||||
"object to determine the target cell (create it with \"cell_mapping_into\" or \"const_cell_mapping_into\").\n"
|
||||
"If no mapping is provided for a specific circuit cell, the nets are copied into the next mapped parent as "
|
||||
"many times as the circuit cell appears there (circuit flattening).\n"
|
||||
"\n"
|
||||
"The method has three net annotation modes:\n"
|
||||
"@ul\n"
|
||||
@@ -427,6 +446,9 @@ Class<db::LayoutToNetlist> decl_dbLayoutToNetlist ("db", "LayoutToNetlist",
|
||||
"@param net_cell_name_prefix See method description\n"
|
||||
"@param device_cell_name_prefix See above\n"
|
||||
) +
|
||||
gsi::method_ext ("build_nets", &build_nets, gsi::arg ("nets"), gsi::arg ("cmap"), gsi::arg ("target"), gsi::arg ("lmap"), gsi::arg ("net_cell_name_prefix", tl::Variant (), "nil"), gsi::arg ("netname_prop", tl::Variant (), "nil"), gsi::arg ("hier_mode", db::LayoutToNetlist::BNH_Flatten, "BNH_Flatten"), gsi::arg ("circuit_cell_name_prefix", tl::Variant (), "nil"), gsi::arg ("device_cell_name_prefix", tl::Variant (), "nil"),
|
||||
"@brief Like \\build_all_nets, but with the ability to select some nets."
|
||||
) +
|
||||
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"
|
||||
|
||||
@@ -86,7 +86,164 @@ TEST(1_ReaderBasic)
|
||||
std::string au = tl::testsrc ();
|
||||
au = tl::combine_path (au, "testdata");
|
||||
au = tl::combine_path (au, "algo");
|
||||
au = tl::combine_path (au, "l2n_reader_au.gds");
|
||||
au = tl::combine_path (au, "l2n_reader_au_1.gds");
|
||||
|
||||
db::compare_layouts (_this, ly2, au);
|
||||
}
|
||||
|
||||
{
|
||||
db::Layout ly2;
|
||||
ly2.dbu (l2n.internal_layout ()->dbu ());
|
||||
db::Cell &top2 = ly2.cell (ly2.add_cell ("TOP"));
|
||||
|
||||
std::map<unsigned int, const db::Region *> lmap;
|
||||
lmap [ly2.insert_layer (db::LayerProperties (10, 0))] = l2n.layer_by_name ("psd");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (11, 0))] = l2n.layer_by_name ("nsd");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (3, 0)) ] = l2n.layer_by_name ("poly");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (4, 0)) ] = l2n.layer_by_name ("diff_cont");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (5, 0)) ] = l2n.layer_by_name ("poly_cont");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (6, 0)) ] = l2n.layer_by_name ("metal1");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (7, 0)) ] = l2n.layer_by_name ("via1");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (8, 0)) ] = l2n.layer_by_name ("metal2");
|
||||
|
||||
std::vector<const db::Net *> nets;
|
||||
nets.push_back (l2n.netlist ()->circuit_by_name ("RINGO")->net_by_name ("VSS"));
|
||||
nets.push_back (l2n.netlist ()->circuit_by_name ("RINGO")->net_by_name ("VDD"));
|
||||
|
||||
db::CellMapping cm = l2n.cell_mapping_into (ly2, top2, nets);
|
||||
|
||||
l2n.build_nets (&nets, cm, ly2, lmap, "NET_", tl::Variant (), db::LayoutToNetlist::BNH_Disconnected, 0, "DEVICE_");
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au = tl::combine_path (au, "testdata");
|
||||
au = tl::combine_path (au, "algo");
|
||||
au = tl::combine_path (au, "l2n_reader_au_1b.gds");
|
||||
|
||||
db::compare_layouts (_this, ly2, au);
|
||||
}
|
||||
|
||||
{
|
||||
db::Layout ly2;
|
||||
ly2.dbu (l2n.internal_layout ()->dbu ());
|
||||
db::Cell &top2 = ly2.cell (ly2.add_cell ("TOP"));
|
||||
|
||||
std::map<unsigned int, const db::Region *> lmap;
|
||||
lmap [ly2.insert_layer (db::LayerProperties (10, 0))] = l2n.layer_by_name ("psd");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (11, 0))] = l2n.layer_by_name ("nsd");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (3, 0)) ] = l2n.layer_by_name ("poly");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (4, 0)) ] = l2n.layer_by_name ("diff_cont");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (5, 0)) ] = l2n.layer_by_name ("poly_cont");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (6, 0)) ] = l2n.layer_by_name ("metal1");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (7, 0)) ] = l2n.layer_by_name ("via1");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (8, 0)) ] = l2n.layer_by_name ("metal2");
|
||||
|
||||
std::vector<const db::Net *> nets;
|
||||
nets.push_back (l2n.netlist ()->circuit_by_name ("RINGO")->net_by_name ("VSS"));
|
||||
nets.push_back (l2n.netlist ()->circuit_by_name ("RINGO")->net_by_name ("VDD"));
|
||||
|
||||
db::CellMapping cm = l2n.cell_mapping_into (ly2, top2, nets);
|
||||
|
||||
l2n.build_nets (&nets, cm, ly2, lmap, "NET_", tl::Variant (), db::LayoutToNetlist::BNH_Flatten, 0, "DEVICE_");
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au = tl::combine_path (au, "testdata");
|
||||
au = tl::combine_path (au, "algo");
|
||||
au = tl::combine_path (au, "l2n_reader_au_1c.gds");
|
||||
|
||||
db::compare_layouts (_this, ly2, au);
|
||||
}
|
||||
|
||||
{
|
||||
db::Layout ly2;
|
||||
ly2.dbu (l2n.internal_layout ()->dbu ());
|
||||
db::Cell &top2 = ly2.cell (ly2.add_cell ("TOP"));
|
||||
|
||||
std::map<unsigned int, const db::Region *> lmap;
|
||||
lmap [ly2.insert_layer (db::LayerProperties (10, 0))] = l2n.layer_by_name ("psd");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (11, 0))] = l2n.layer_by_name ("nsd");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (3, 0)) ] = l2n.layer_by_name ("poly");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (4, 0)) ] = l2n.layer_by_name ("diff_cont");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (5, 0)) ] = l2n.layer_by_name ("poly_cont");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (6, 0)) ] = l2n.layer_by_name ("metal1");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (7, 0)) ] = l2n.layer_by_name ("via1");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (8, 0)) ] = l2n.layer_by_name ("metal2");
|
||||
|
||||
std::vector<const db::Net *> nets;
|
||||
nets.push_back (l2n.netlist ()->circuit_by_name ("RINGO")->net_by_name ("VSS"));
|
||||
nets.push_back (l2n.netlist ()->circuit_by_name ("RINGO")->net_by_name ("VDD"));
|
||||
|
||||
db::CellMapping cm = l2n.cell_mapping_into (ly2, top2, nets);
|
||||
|
||||
l2n.build_nets (&nets, cm, ly2, lmap, "NET_", tl::Variant (), db::LayoutToNetlist::BNH_SubcircuitCells, "CIRCUIT_", "DEVICE_");
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au = tl::combine_path (au, "testdata");
|
||||
au = tl::combine_path (au, "algo");
|
||||
au = tl::combine_path (au, "l2n_reader_au_1d.gds");
|
||||
|
||||
db::compare_layouts (_this, ly2, au);
|
||||
}
|
||||
|
||||
{
|
||||
db::Layout ly2;
|
||||
ly2.dbu (l2n.internal_layout ()->dbu ());
|
||||
db::Cell &top2 = ly2.cell (ly2.add_cell ("TOP"));
|
||||
|
||||
std::map<unsigned int, const db::Region *> lmap;
|
||||
lmap [ly2.insert_layer (db::LayerProperties (10, 0))] = l2n.layer_by_name ("psd");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (11, 0))] = l2n.layer_by_name ("nsd");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (3, 0)) ] = l2n.layer_by_name ("poly");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (4, 0)) ] = l2n.layer_by_name ("diff_cont");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (5, 0)) ] = l2n.layer_by_name ("poly_cont");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (6, 0)) ] = l2n.layer_by_name ("metal1");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (7, 0)) ] = l2n.layer_by_name ("via1");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (8, 0)) ] = l2n.layer_by_name ("metal2");
|
||||
|
||||
std::vector<const db::Net *> nets;
|
||||
nets.push_back (l2n.netlist ()->circuit_by_name ("RINGO")->net_by_name ("VSS"));
|
||||
nets.push_back (l2n.netlist ()->circuit_by_name ("RINGO")->net_by_name ("VDD"));
|
||||
nets.push_back (l2n.netlist ()->circuit_by_name ("INV2")->net_by_name ("IN"));
|
||||
|
||||
db::CellMapping cm = l2n.cell_mapping_into (ly2, top2, nets);
|
||||
|
||||
l2n.build_nets (&nets, cm, ly2, lmap, "NET_", tl::Variant (), db::LayoutToNetlist::BNH_SubcircuitCells, "CIRCUIT_", 0);
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au = tl::combine_path (au, "testdata");
|
||||
au = tl::combine_path (au, "algo");
|
||||
au = tl::combine_path (au, "l2n_reader_au_1e.gds");
|
||||
|
||||
db::compare_layouts (_this, ly2, au);
|
||||
}
|
||||
|
||||
{
|
||||
db::Layout ly2;
|
||||
ly2.dbu (l2n.internal_layout ()->dbu ());
|
||||
db::Cell &top2 = ly2.cell (ly2.add_cell ("TOP"));
|
||||
|
||||
std::map<unsigned int, const db::Region *> lmap;
|
||||
lmap [ly2.insert_layer (db::LayerProperties (10, 0))] = l2n.layer_by_name ("psd");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (11, 0))] = l2n.layer_by_name ("nsd");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (3, 0)) ] = l2n.layer_by_name ("poly");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (4, 0)) ] = l2n.layer_by_name ("diff_cont");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (5, 0)) ] = l2n.layer_by_name ("poly_cont");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (6, 0)) ] = l2n.layer_by_name ("metal1");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (7, 0)) ] = l2n.layer_by_name ("via1");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (8, 0)) ] = l2n.layer_by_name ("metal2");
|
||||
|
||||
std::vector<const db::Net *> nets;
|
||||
nets.push_back (l2n.netlist ()->circuit_by_name ("RINGO")->net_by_name ("VSS"));
|
||||
nets.push_back (l2n.netlist ()->circuit_by_name ("RINGO")->net_by_name ("VDD"));
|
||||
nets.push_back (l2n.netlist ()->circuit_by_name ("INV2")->net_by_name ("IN"));
|
||||
|
||||
db::CellMapping cm = l2n.const_cell_mapping_into (ly2, top2);
|
||||
|
||||
l2n.build_nets (&nets, cm, ly2, lmap, "NET_", tl::Variant (), db::LayoutToNetlist::BNH_SubcircuitCells, "CIRCUIT_", "DEVICE_");
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au = tl::combine_path (au, "testdata");
|
||||
au = tl::combine_path (au, "algo");
|
||||
au = tl::combine_path (au, "l2n_reader_au_1f.gds");
|
||||
|
||||
db::compare_layouts (_this, ly2, au);
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="central_stack">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page">
|
||||
<layout class="QVBoxLayout">
|
||||
@@ -192,7 +192,7 @@
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="lay::NetlistBrowserPage" name="browser_frame">
|
||||
<widget class="lay::NetlistBrowserPage" name="browser_page">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Ignored">
|
||||
<horstretch>0</horstretch>
|
||||
|
||||
@@ -76,7 +76,7 @@ NetlistBrowserDialog::NetlistBrowserDialog (lay::PluginRoot *root, lay::LayoutVi
|
||||
{
|
||||
Ui::NetlistBrowserDialog::setupUi (this);
|
||||
|
||||
browser_frame->set_plugin_root (root);
|
||||
browser_page->set_plugin_root (root);
|
||||
|
||||
if (view ()) {
|
||||
view ()->cellviews_changed_event.add (this, &NetlistBrowserDialog::cellviews_changed);
|
||||
@@ -282,7 +282,7 @@ NetlistBrowserDialog::probe_net (const db::DPoint &p, bool trace_path)
|
||||
}
|
||||
|
||||
// select the net if one was found
|
||||
browser_frame->select_net (net);
|
||||
browser_page->select_net (net);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -353,40 +353,9 @@ END_PROTECTED
|
||||
void
|
||||
NetlistBrowserDialog::export_clicked ()
|
||||
{
|
||||
BEGIN_PROTECTED
|
||||
|
||||
#if 0 // @@@
|
||||
if (m_l2n_index >= int (view ()->num_rdbs ()) || m_l2n_index < 0) {
|
||||
return;
|
||||
if (m_l2n_index < int (view ()->num_l2ndbs ()) && m_l2n_index >= 0) {
|
||||
browser_page->export_all ();
|
||||
}
|
||||
|
||||
const rdb::Database *rdb = view ()->get_rdb (m_l2n_index);
|
||||
if (! rdb) {
|
||||
return;
|
||||
}
|
||||
|
||||
const lay::CellView &cv = view ()->cellview (m_cv_index);
|
||||
if (! cv.is_valid ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
view ()->manager ()->transaction (tl::to_string (QObject::tr ("Export Net")));
|
||||
|
||||
// ....
|
||||
|
||||
view ()->manager ()->commit ();
|
||||
view ()->update_content ();
|
||||
|
||||
} catch (...) {
|
||||
view ()->manager ()->commit ();
|
||||
view ()->update_content ();
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
|
||||
END_PROTECTED
|
||||
}
|
||||
|
||||
void
|
||||
@@ -431,9 +400,9 @@ BEGIN_PROTECTED
|
||||
tl::log << tl::to_string (QObject::tr ("Loading file: ")) << l2ndb->filename ();
|
||||
tl::SelfTimer timer (tl::verbosity () >= 11, tl::to_string (QObject::tr ("Loading")));
|
||||
|
||||
browser_frame->set_l2ndb (0);
|
||||
browser_page->set_l2ndb (0);
|
||||
l2ndb->load (l2ndb->filename ());
|
||||
browser_frame->set_l2ndb (l2ndb);
|
||||
browser_page->set_l2ndb (l2ndb);
|
||||
|
||||
}
|
||||
|
||||
@@ -450,7 +419,7 @@ BEGIN_PROTECTED
|
||||
std::string fmts = tl::to_string (QObject::tr ("All files (*)"));
|
||||
#if 0 // TODO: would be good to have this:
|
||||
// collect the formats available ...
|
||||
for (tl::Registrar<rdb::FormatDeclaration>::iterator rdr = tl::Registrar<rdb::FormatDeclaration>::begin (); rdr != tl::Registrar<rdb::FormatDeclaration>::end (); ++rdr) {
|
||||
for (tl::Registrar<db::NetlistFormatDeclaration>::iterator rdr = tl::Registrar<db::NetlistFormatDeclaration>::begin (); rdr != tl::Registrar<db::NetlistFormatDeclaration>::end (); ++rdr) {
|
||||
fmts += ";;" + rdr->file_format ();
|
||||
}
|
||||
#else
|
||||
@@ -480,7 +449,7 @@ NetlistBrowserDialog::configure (const std::string &name, const std::string &val
|
||||
{
|
||||
bool need_update = false;
|
||||
bool taken = true;
|
||||
bool show_all = browser_frame->show_all ();
|
||||
bool show_all = browser_page->show_all ();
|
||||
|
||||
if (name == cfg_l2ndb_show_all) {
|
||||
|
||||
@@ -577,12 +546,12 @@ NetlistBrowserDialog::configure (const std::string &name, const std::string &val
|
||||
}
|
||||
|
||||
if (active () && need_update) {
|
||||
browser_frame->set_max_shape_count (m_max_shape_count);
|
||||
browser_frame->set_window (m_window, m_window_dim);
|
||||
browser_frame->set_highlight_style (m_marker_color, m_marker_line_width, m_marker_vertex_size, m_marker_halo, m_marker_dither_pattern, m_marker_intensity, m_use_original_colors, m_auto_color_enabled ? &m_auto_colors : 0);
|
||||
browser_page->set_max_shape_count (m_max_shape_count);
|
||||
browser_page->set_window (m_window, m_window_dim);
|
||||
browser_page->set_highlight_style (m_marker_color, m_marker_line_width, m_marker_vertex_size, m_marker_halo, m_marker_dither_pattern, m_marker_intensity, m_use_original_colors, m_auto_color_enabled ? &m_auto_colors : 0);
|
||||
}
|
||||
|
||||
browser_frame->show_all (show_all);
|
||||
browser_page->show_all (show_all);
|
||||
|
||||
return taken;
|
||||
}
|
||||
@@ -636,7 +605,7 @@ NetlistBrowserDialog::l2ndbs_changed ()
|
||||
void
|
||||
NetlistBrowserDialog::cellview_changed (int)
|
||||
{
|
||||
browser_frame->update_highlights ();
|
||||
browser_page->update_highlights ();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -725,13 +694,13 @@ NetlistBrowserDialog::update_content ()
|
||||
m_unload_all_action->setEnabled (l2ndb != 0);
|
||||
m_reload_action->setEnabled (l2ndb != 0);
|
||||
|
||||
browser_frame->enable_updates (false); // Avoid building the internal lists several times ...
|
||||
browser_frame->set_l2ndb (l2ndb);
|
||||
browser_frame->set_max_shape_count (m_max_shape_count);
|
||||
browser_frame->set_highlight_style (m_marker_color, m_marker_line_width, m_marker_vertex_size, m_marker_halo, m_marker_dither_pattern, m_marker_intensity, m_use_original_colors, m_auto_color_enabled ? &m_auto_colors : 0);
|
||||
browser_frame->set_window (m_window, m_window_dim);
|
||||
browser_frame->set_view (view (), m_cv_index);
|
||||
browser_frame->enable_updates (true);
|
||||
browser_page->enable_updates (false); // Avoid building the internal lists several times ...
|
||||
browser_page->set_l2ndb (l2ndb);
|
||||
browser_page->set_max_shape_count (m_max_shape_count);
|
||||
browser_page->set_highlight_style (m_marker_color, m_marker_line_width, m_marker_vertex_size, m_marker_halo, m_marker_dither_pattern, m_marker_intensity, m_use_original_colors, m_auto_color_enabled ? &m_auto_colors : 0);
|
||||
browser_page->set_window (m_window, m_window_dim);
|
||||
browser_page->set_view (view (), m_cv_index);
|
||||
browser_page->enable_updates (true);
|
||||
|
||||
if (l2ndb) {
|
||||
// Note: it appears to be required to show the browser page after it has been configured.
|
||||
@@ -769,8 +738,8 @@ NetlistBrowserDialog::deactivated ()
|
||||
lay::PluginRoot::instance ()->config_set (cfg_l2ndb_window_state, lay::save_dialog_state (this, false /*don't store the section sizes*/).c_str ());
|
||||
}
|
||||
|
||||
browser_frame->set_l2ndb (0);
|
||||
browser_frame->set_view (0, 0);
|
||||
browser_page->set_l2ndb (0);
|
||||
browser_page->set_view (0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "layNetInfoDialog.h"
|
||||
#include "layNetExportDialog.h"
|
||||
#include "tlProgress.h"
|
||||
#include "tlExceptions.h"
|
||||
#include "dbLayoutToNetlist.h"
|
||||
#include "dbNetlistDeviceClasses.h"
|
||||
#include "dbCellMapping.h"
|
||||
@@ -1157,18 +1158,24 @@ NetlistBrowserPage::clear_markers ()
|
||||
void
|
||||
NetlistBrowserPage::export_selected ()
|
||||
{
|
||||
BEGIN_PROTECTED
|
||||
|
||||
std::vector<const db::Net *> nets = selected_nets ();
|
||||
if (nets.empty ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
export_nets (&nets);
|
||||
|
||||
END_PROTECTED
|
||||
}
|
||||
|
||||
void
|
||||
NetlistBrowserPage::export_all ()
|
||||
{
|
||||
BEGIN_PROTECTED
|
||||
export_nets (0);
|
||||
END_PROTECTED
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1198,15 +1205,16 @@ NetlistBrowserPage::export_nets (const std::vector<const db::Net *> *nets)
|
||||
|
||||
db::cell_index_type target_top_index = target_layout.add_cell (source_layout.cell_name (source_top.cell_index ()));
|
||||
|
||||
db::CellMapping cm = database->cell_mapping_into (target_layout, target_layout.cell (target_top_index));
|
||||
std::map<unsigned int, const db::Region *> lm = database->create_layermap (target_layout, dialog->start_layer_number ());
|
||||
|
||||
std::set<const db::Net *> net_set;
|
||||
if (nets) {
|
||||
net_set.insert (nets->begin (), nets->end ());
|
||||
db::CellMapping cm;
|
||||
if (! nets) {
|
||||
cm = database->cell_mapping_into (target_layout, target_layout.cell (target_top_index));
|
||||
} else {
|
||||
cm = database->cell_mapping_into (target_layout, target_layout.cell (target_top_index), *nets);
|
||||
}
|
||||
|
||||
database->build_nets (nets ? &net_set : 0, cm, target_layout, lm,
|
||||
std::map<unsigned int, const db::Region *> lm = database->create_layermap (target_layout, dialog->start_layer_number ());
|
||||
|
||||
database->build_nets (nets, cm, target_layout, lm,
|
||||
dialog->net_prefix ().empty () ? 0 : dialog->net_prefix ().c_str (),
|
||||
dialog->net_propname (),
|
||||
dialog->produce_circuit_cells () ? db::LayoutToNetlist::BNH_SubcircuitCells : db::LayoutToNetlist::BNH_Flatten,
|
||||
|
||||
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Reference in New Issue
Block a user