mirror of https://github.com/KLayout/klayout.git
WIP: netlist browser - extended the net export scheme of build_net to support net annotation and flattening.
This commit is contained in:
parent
062b74aad7
commit
2aaec56adb
|
|
@ -484,13 +484,13 @@ namespace
|
|||
}
|
||||
|
||||
template <class Tr>
|
||||
static bool deliver_shape (const db::PolygonRef &, StopOnFirst, const Tr &)
|
||||
static bool deliver_shape (const db::PolygonRef &, StopOnFirst, const Tr &, db::properties_id_type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class Tr>
|
||||
static bool deliver_shape (const db::PolygonRef &pr, db::Region ®ion, const Tr &tr)
|
||||
static bool deliver_shape (const db::PolygonRef &pr, db::Region ®ion, const Tr &tr, db::properties_id_type /*propid*/)
|
||||
{
|
||||
if (pr.obj ().is_box ()) {
|
||||
region.insert (pr.obj ().box ().transformed (pr.trans ()).transformed (tr));
|
||||
|
|
@ -501,27 +501,41 @@ static bool deliver_shape (const db::PolygonRef &pr, db::Region ®ion, const T
|
|||
}
|
||||
|
||||
template <class Tr>
|
||||
static bool deliver_shape (const db::PolygonRef &pr, db::Shapes &shapes, const Tr &tr)
|
||||
static bool deliver_shape (const db::PolygonRef &pr, db::Shapes &shapes, const Tr &tr, db::properties_id_type propid)
|
||||
{
|
||||
if (pr.obj ().is_box ()) {
|
||||
shapes.insert (pr.obj ().box ().transformed (pr.trans ()).transformed (tr));
|
||||
if (propid) {
|
||||
shapes.insert (db::BoxWithProperties (pr.obj ().box ().transformed (pr.trans ()).transformed (tr), propid));
|
||||
} else {
|
||||
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 ()));
|
||||
db::PolygonRef polygon_ref (pr.obj ().transformed (pr.trans ()).transformed (tr), layout->shape_repository ());
|
||||
if (propid) {
|
||||
shapes.insert (db::PolygonRefWithProperties (polygon_ref, propid));
|
||||
} else {
|
||||
shapes.insert (polygon_ref);
|
||||
}
|
||||
} else {
|
||||
shapes.insert (pr.obj ().transformed (pr.trans ()).transformed (tr));
|
||||
db::Polygon polygon (pr.obj ().transformed (pr.trans ()).transformed (tr));
|
||||
if (propid) {
|
||||
shapes.insert (db::PolygonWithProperties (polygon, propid));
|
||||
} else {
|
||||
shapes.insert (polygon);
|
||||
}
|
||||
}
|
||||
}
|
||||
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)
|
||||
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)
|
||||
{
|
||||
// deliver the net shapes
|
||||
for (db::recursive_cluster_shape_iterator<db::PolygonRef> rci (clusters, layer_id, ci, cid); !rci.at_end (); ++rci) {
|
||||
if (! deliver_shape (*rci, to, tr * rci.trans ())) {
|
||||
if (! deliver_shape (*rci, to, tr * rci.trans (), propid)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -529,7 +543,7 @@ static bool deliver_shapes_of_net_recursive (const db::Netlist * /*nl*/, const d
|
|||
}
|
||||
|
||||
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)
|
||||
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)
|
||||
{
|
||||
// NOTE: this scheme will deliver the shapes from the cell, including (!)
|
||||
// subcells that are purged
|
||||
|
|
@ -546,7 +560,7 @@ static bool deliver_shapes_of_net_nonrecursive (const db::Netlist *nl, const db:
|
|||
|
||||
} else {
|
||||
|
||||
if (! deliver_shape (*rci, to, tr * rci.trans ())) {
|
||||
if (! deliver_shape (*rci, to, tr * rci.trans (), propid)) {
|
||||
return false;
|
||||
}
|
||||
prev_ci = cci;
|
||||
|
|
@ -560,17 +574,24 @@ static bool deliver_shapes_of_net_nonrecursive (const db::Netlist *nl, const db:
|
|||
return true;
|
||||
}
|
||||
|
||||
void LayoutToNetlist::shapes_of_net (const db::Net &net, const db::Region &of_layer, bool recursive, db::Shapes &to) const
|
||||
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);
|
||||
|
||||
if (! recursive) {
|
||||
deliver_shapes_of_net_nonrecursive (mp_netlist.get (), m_net_clusters, circuit->cell_index (), net.cluster_id (), lid, db::ICplxTrans (), to);
|
||||
} else {
|
||||
deliver_shapes_of_net_recursive (mp_netlist.get (), m_net_clusters, circuit->cell_index (), net.cluster_id (), lid, db::ICplxTrans (), to);
|
||||
}
|
||||
deliver_shapes_of_net (recursive, mp_netlist.get (), m_net_clusters, circuit->cell_index (), net.cluster_id (), lid, db::ICplxTrans (), to, propid);
|
||||
}
|
||||
|
||||
db::Region *LayoutToNetlist::shapes_of_net (const db::Net &net, const db::Region &of_layer, bool recursive) const
|
||||
|
|
@ -581,26 +602,22 @@ db::Region *LayoutToNetlist::shapes_of_net (const db::Net &net, const db::Region
|
|||
|
||||
std::auto_ptr<db::Region> res (new db::Region ());
|
||||
|
||||
if (! recursive) {
|
||||
deliver_shapes_of_net_nonrecursive (mp_netlist.get (), m_net_clusters, circuit->cell_index (), net.cluster_id (), lid, db::ICplxTrans (), *res);
|
||||
} else {
|
||||
deliver_shapes_of_net_recursive (mp_netlist.get (), m_net_clusters, circuit->cell_index (), net.cluster_id (), lid, db::ICplxTrans (), *res);
|
||||
}
|
||||
deliver_shapes_of_net (recursive, mp_netlist.get (), m_net_clusters, circuit->cell_index (), net.cluster_id (), lid, db::ICplxTrans (), *res, 0);
|
||||
|
||||
return res.release ();
|
||||
}
|
||||
|
||||
void
|
||||
LayoutToNetlist::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, const char *cell_name_prefix, const char *device_cell_name_prefix, std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> &cmap, const db::ICplxTrans &tr) const
|
||||
LayoutToNetlist::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, std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> &cmap, const db::ICplxTrans &tr) const
|
||||
{
|
||||
const db::Circuit *circuit = net.circuit ();
|
||||
tl_assert (circuit != 0);
|
||||
|
||||
build_net_rec (circuit->cell_index (), net.cluster_id (), target, target_cell, lmap, &net, net_cell_name_prefix, cell_name_prefix, device_cell_name_prefix, cmap, tr);
|
||||
build_net_rec (circuit->cell_index (), net.cluster_id (), target, target_cell, lmap, &net, net_cell_name_prefix, netname_propid, hier_mode, cell_name_prefix, device_cell_name_prefix, cmap, tr);
|
||||
}
|
||||
|
||||
void
|
||||
LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &target, db::Cell &tc, const std::map<unsigned int, const db::Region *> &lmap, const db::Net *net, const char *net_cell_name_prefix, const char *circuit_cell_name_prefix, const char *device_cell_name_prefix, std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> &cmap, const db::ICplxTrans &tr) const
|
||||
LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &target, db::Cell &tc, const std::map<unsigned int, const db::Region *> &lmap, const db::Net *net, const char *net_cell_name_prefix, db::properties_id_type netname_propid, BuildNetHierarchyMode hier_mode, const char *circuit_cell_name_prefix, const char *device_cell_name_prefix, std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> &cmap, const db::ICplxTrans &tr) const
|
||||
{
|
||||
db::Cell *target_cell = &tc;
|
||||
|
||||
|
|
@ -615,7 +632,7 @@ LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &
|
|||
for (std::map<unsigned int, const db::Region *>::const_iterator l = lmap.begin (); l != lmap.end () && !consider_cell; ++l) {
|
||||
if (l->second) {
|
||||
StopOnFirst sof;
|
||||
consider_cell = !deliver_shapes_of_net_nonrecursive (mp_netlist.get (), m_net_clusters, ci, cid, layer_of (*l->second), tr, 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -635,11 +652,11 @@ LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &
|
|||
|
||||
for (std::map<unsigned int, const db::Region *>::const_iterator l = lmap.begin (); l != lmap.end (); ++l) {
|
||||
if (l->second) {
|
||||
deliver_shapes_of_net_nonrecursive (mp_netlist.get (), m_net_clusters, ci, cid, layer_of (*l->second), tr, target_cell->shapes (l->first));
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if (! circuit_cell_name_prefix && ! device_cell_name_prefix) {
|
||||
if (hier_mode != BNH_SubcircuitCells && ! device_cell_name_prefix) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -673,7 +690,7 @@ LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &
|
|||
db::cell_index_type target_ci = target.add_cell ((std::string (name_prefix) + cell_name).c_str ());
|
||||
cm = cmap.insert (std::make_pair (std::make_pair (subci, subcid), target_ci)).first;
|
||||
|
||||
build_net_rec (subci, subcid, target, target.cell (target_ci), lmap, 0, 0, circuit_cell_name_prefix, device_cell_name_prefix, cmap, tr_mag);
|
||||
build_net_rec (subci, subcid, target, target.cell (target_ci), lmap, 0, 0, netname_propid, hier_mode, circuit_cell_name_prefix, device_cell_name_prefix, cmap, tr_mag);
|
||||
|
||||
} else {
|
||||
cm = cmap.insert (std::make_pair (std::make_pair (subci, subcid), std::numeric_limits<db::cell_index_type>::max ())).first;
|
||||
|
|
@ -690,8 +707,24 @@ LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &
|
|||
}
|
||||
}
|
||||
|
||||
db::properties_id_type
|
||||
LayoutToNetlist::make_netname_propid (db::Layout &ly, const tl::Variant &netname_prop, const db::Net &net) const
|
||||
{
|
||||
if (! netname_prop.is_nil ()) {
|
||||
|
||||
db::property_names_id_type name_propnameid = ly.properties_repository ().prop_name_id (netname_prop);
|
||||
db::PropertiesRepository::properties_set propset;
|
||||
propset.insert (std::make_pair (name_propnameid, tl::Variant (net.expanded_name ())));
|
||||
|
||||
return ly.properties_repository ().properties_id (propset);
|
||||
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LayoutToNetlist::build_net (const db::Net &net, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const char *cell_name_prefix, const char *device_cell_name_prefix) const
|
||||
LayoutToNetlist::build_net (const db::Net &net, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const tl::Variant &netname_prop, BuildNetHierarchyMode hier_mode, const char *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")));
|
||||
|
|
@ -700,11 +733,13 @@ LayoutToNetlist::build_net (const db::Net &net, db::Layout &target, db::Cell &ta
|
|||
std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> cell_map;
|
||||
|
||||
double mag = internal_layout ()->dbu () / target.dbu ();
|
||||
build_net_rec (net, target, target_cell, lmap, 0, cell_name_prefix, device_cell_name_prefix, cell_map, db::ICplxTrans (mag));
|
||||
|
||||
db::properties_id_type netname_propid = make_netname_propid (target, netname_prop, net);
|
||||
build_net_rec (net, target, target_cell, lmap, 0, netname_propid, hier_mode, cell_name_prefix, device_cell_name_prefix, cell_map, db::ICplxTrans (mag));
|
||||
}
|
||||
|
||||
void
|
||||
LayoutToNetlist::build_all_nets (const db::CellMapping &cmap, db::Layout &target, const std::map<unsigned int, const db::Region *> &lmap, const char *net_cell_name_prefix, const char *circuit_cell_name_prefix, const char *device_cell_name_prefix) const
|
||||
LayoutToNetlist::build_all_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")));
|
||||
|
|
@ -727,15 +762,16 @@ LayoutToNetlist::build_all_nets (const db::CellMapping &cmap, db::Layout &target
|
|||
for (db::Circuit::const_net_iterator n = c->begin_nets (); n != c->end_nets (); ++n) {
|
||||
|
||||
// exlude local nets in recursive mode
|
||||
if (circuit_cell_name_prefix && ! is_top_circuit && n->pin_count () > 0) {
|
||||
if (hier_mode != BNH_Disconnected && ! is_top_circuit && n->pin_count () > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
build_net_rec (*n, target, target.cell (target_ci), lmap, net_cell_name_prefix, circuit_cell_name_prefix, device_cell_name_prefix, cell_map, db::ICplxTrans (mag));
|
||||
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_map, db::ICplxTrans (mag));
|
||||
|
||||
}
|
||||
|
||||
if (circuit_cell_name_prefix) {
|
||||
if (hier_mode != BNH_Disconnected) {
|
||||
|
||||
// with recursive nets we skip nets in subcircuits which are connected upwards. This means, nets will
|
||||
// get lost if there is no connection to this pin from the outside. Hence we need to deliver nets from
|
||||
|
|
@ -756,11 +792,13 @@ LayoutToNetlist::build_all_nets (const db::CellMapping &cmap, db::Layout &target
|
|||
double dbu = target.dbu ();
|
||||
db::ICplxTrans tr = db::ICplxTrans (mag) * (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 (), circuit_cell_name_prefix, device_cell_name_prefix, cell_map, tr);
|
||||
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_map, tr);
|
||||
} else {
|
||||
build_net_rec (*n, target, target.cell (target_ci), lmap, net_cell_name_prefix, circuit_cell_name_prefix, device_cell_name_prefix, cell_map, tr);
|
||||
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_map, tr);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -922,8 +960,8 @@ db::Region LayoutToNetlist::antenna_check (const db::Region &gate, const db::Reg
|
|||
|
||||
db::Region rgate, rmetal;
|
||||
|
||||
deliver_shapes_of_net_recursive (0, m_net_clusters, *cid, *c, layer_of (gate), db::ICplxTrans (), rgate);
|
||||
deliver_shapes_of_net_recursive (0, m_net_clusters, *cid, *c, layer_of (metal), db::ICplxTrans (), rmetal);
|
||||
deliver_shapes_of_net_recursive (0, m_net_clusters, *cid, *c, layer_of (gate), db::ICplxTrans (), rgate, 0);
|
||||
deliver_shapes_of_net_recursive (0, m_net_clusters, *cid, *c, layer_of (metal), db::ICplxTrans (), rmetal, 0);
|
||||
|
||||
double agate = rgate.area () * dbu * dbu;
|
||||
double ametal = rmetal.area () * dbu * dbu;
|
||||
|
|
@ -934,7 +972,7 @@ db::Region LayoutToNetlist::antenna_check (const db::Region &gate, const db::Reg
|
|||
for (std::vector<std::pair<const db::Region *, double> >::const_iterator d = diodes.begin (); d != diodes.end () && ! skip; ++d) {
|
||||
|
||||
db::Region rdiode;
|
||||
deliver_shapes_of_net_recursive (0, m_net_clusters, *cid, *c, layer_of (*d->first), db::ICplxTrans (), rdiode);
|
||||
deliver_shapes_of_net_recursive (0, m_net_clusters, *cid, *c, layer_of (*d->first), db::ICplxTrans (), rdiode, 0);
|
||||
|
||||
if (fabs (d->second) < db::epsilon) {
|
||||
if (rdiode.area () > 0) {
|
||||
|
|
|
|||
|
|
@ -491,32 +491,64 @@ public:
|
|||
*
|
||||
* This methods returns a new'd Region. It's the responsibility of the caller
|
||||
* to delete this object.
|
||||
*
|
||||
* propid is an optional properties ID which is attached to the shapes if not 0.
|
||||
*/
|
||||
void shapes_of_net (const db::Net &net, const db::Region &of_layer, bool recursive, db::Shapes &to) const;
|
||||
void shapes_of_net (const db::Net &net, const db::Region &of_layer, bool recursive, db::Shapes &to, properties_id_type propid = 0) const;
|
||||
|
||||
/**
|
||||
* @brief An enum describing the way the net hierarchy is mapped
|
||||
*/
|
||||
enum BuildNetHierarchyMode
|
||||
{
|
||||
/**
|
||||
* @brief Flatten the net
|
||||
* Collects all shapes of a net and puts that into the net cell or circuit cell
|
||||
*/
|
||||
BNH_Flatten = 0,
|
||||
/**
|
||||
* @brief Build a net hierarchy adding cells for each subcircuit on the net
|
||||
* Uses the circuit_cell_prefix to build the subcircuit cell names
|
||||
*/
|
||||
BNH_SubcircuitCells = 1,
|
||||
/**
|
||||
* @brief No hierarchy
|
||||
* Just output the shapes of the net belonging to the circuit cell.
|
||||
* Connections are not indicated!
|
||||
*/
|
||||
BNH_Disconnected = 2
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Builds a net representation in the given layout and cell
|
||||
*
|
||||
* This method has two modes: recursive and top-level mode. In recursive mode,
|
||||
* it will create a proper hierarchy below the given target cell to hold all subcircuits the
|
||||
* net connects to. It will copy the net's parts from this subcircuits into these cells.
|
||||
* This method puts the shapes of a net into the given target cell using a variety of options
|
||||
* to represent the net name and the hierarchy of the net.
|
||||
*
|
||||
* In top-level mode, only the shapes from the net inside it's circuit are copied to
|
||||
* the given target cell. No other cells are created.
|
||||
* If the netname_prop name is not nil, a property with the given name is created and assigned
|
||||
* the net name.
|
||||
*
|
||||
* Recursive mode is picked when a cell name prefix is given. The new cells will be
|
||||
* named like cell_name_prefix + circuit name.
|
||||
* Net hierarchy is covered in three ways:
|
||||
* * No connection indicated (hier_mode == BNH_Disconnected: the net shapes are simply put into their
|
||||
* respective circuits. The connections are not indicated.
|
||||
* * Subnet hierarchy (hier_mode == BNH_SubcircuitCells): for each root net, a full hierarchy is built
|
||||
* to accommodate the subnets (see build_net in recursive mode).
|
||||
* * Flat (hier_mode == BNH_Flatten): each net is flattened and put into the circuit it
|
||||
* belongs to.
|
||||
*
|
||||
* If a device cell name prefix is given, cells will be produced for each device abstract
|
||||
* using a name like device_cell_name_prefix + device name.
|
||||
* using a name like device_cell_name_prefix + device name. Otherwise the device shapes are
|
||||
* treated as part of the net.
|
||||
*
|
||||
* @param target The target layout
|
||||
* @param target_cell The target cell
|
||||
* @param lmap Target layer indexes (keys) and net regions (values)
|
||||
* @param hier_mode See description of this method
|
||||
* @param netname_prop An (optional) property name to which to attach the net name
|
||||
* @param cell_name_prefix Chooses recursive mode if non-null
|
||||
* @param device_cell_name_prefix See above
|
||||
*/
|
||||
void build_net (const db::Net &net, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const char *cell_name_prefix, const char *device_cell_name_prefix) const;
|
||||
void build_net (const db::Net &net, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const tl::Variant &netname_prop, BuildNetHierarchyMode hier_mode, const char *cell_name_prefix, const char *device_cell_name_prefix) const;
|
||||
|
||||
/**
|
||||
* @brief Builds a full hierarchical representation of the nets
|
||||
|
|
@ -525,28 +557,37 @@ public:
|
|||
* object to determine the target cell (create them with "cell_mapping_into" or "const_cell_mapping_into").
|
||||
* If no mapping is requested, the specific circuit it skipped.
|
||||
*
|
||||
* The method has two net annotation modes:
|
||||
* * No annotation (net_cell_name_prefix == 0): the shapes will be put into the target cell simply
|
||||
* The method has three net annotation modes:
|
||||
* * No annotation (net_cell_name_prefix == 0 and netname_prop == nil): the shapes will be put
|
||||
* into the target cell simply
|
||||
* * Net name property (net_cell_name_prefix == 0 and netname_prop != nil): the shapes will be
|
||||
* annotated with a property named with netname_prop and containing the net name string.
|
||||
* * Individual subcells per net (net_cell_name_prefix != 0): for each net, a subcell is created
|
||||
* and the net shapes will be put there (name of the subcell = net_cell_name_prefix + net name).
|
||||
* (this mode can be combined with netname_prop too).
|
||||
*
|
||||
* In addition, net hierarchy is covered in two ways:
|
||||
* * No connection indicated (circuit_cell_name_prefix == 0: the net shapes are simply put into their
|
||||
* In addition, net hierarchy is covered in three ways:
|
||||
* * No connection indicated (hier_mode == BNH_Disconnected: the net shapes are simply put into their
|
||||
* respective circuits. The connections are not indicated.
|
||||
* * Subnet hierarchy (circuit_cell_name_prefix != 0): for each root net, a full hierarchy is built
|
||||
* * Subnet hierarchy (hier_mode == BNH_SubcircuitCells): for each root net, a full hierarchy is built
|
||||
* to accommodate the subnets (see build_net in recursive mode).
|
||||
* * Flat (hier_mode == BNH_Flatten): each net is flattened and put into the circuit it
|
||||
* belongs to.
|
||||
*
|
||||
* If a device cell name prefix is given, cells will be produced for each device abstract
|
||||
* using a name like device_cell_name_prefix + device name.
|
||||
* using a name like device_cell_name_prefix + device name. Otherwise the device shapes are
|
||||
* treated as part of the net.
|
||||
*
|
||||
* @param cmap The mapping of internal layout to target layout for the circuit mapping
|
||||
* @param target The target layout
|
||||
* @param lmap Target layer indexes (keys) and net regions (values)
|
||||
* @param hier_mode See description of this method
|
||||
* @param netname_prop An (optional) property name to which to attach the net name
|
||||
* @param circuit_cell_name_prefix See method description
|
||||
* @param net_cell_name_prefix See method description
|
||||
* @param device_cell_name_prefix See above
|
||||
*/
|
||||
void build_all_nets (const db::CellMapping &cmap, db::Layout &target, const std::map<unsigned int, const db::Region *> &lmap, const char *net_cell_name_prefix, const char *circuit_cell_name_prefix, const char *device_cell_name_prefix) const;
|
||||
void build_all_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
|
||||
|
|
@ -636,11 +677,12 @@ 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, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const char *net_cell_name_prefix, const char *cell_name_prefix, const char *device_cell_name_prefix, std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> &cmap, 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, const char *cell_name_prefix, const char *device_cell_name_prefix, std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> &cmap, 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, std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> &cmap, 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, std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> &cmap, 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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,19 +65,34 @@ static db::Cell *l2n_internal_top_cell (db::LayoutToNetlist *l2n)
|
|||
return const_cast<db::Cell *> (l2n->internal_top_cell ());
|
||||
}
|
||||
|
||||
static void build_net (const db::LayoutToNetlist *l2n, const db::Net &net, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const tl::Variant &circuit_cell_name_prefix, const tl::Variant &device_cell_name_prefix)
|
||||
static int bnh_flatten ()
|
||||
{
|
||||
return int (db::LayoutToNetlist::BNH_Flatten);
|
||||
}
|
||||
|
||||
static int bnh_disconnected ()
|
||||
{
|
||||
return int (db::LayoutToNetlist::BNH_Disconnected);
|
||||
}
|
||||
|
||||
static int bnh_subcircuit_cells ()
|
||||
{
|
||||
return int (db::LayoutToNetlist::BNH_SubcircuitCells);
|
||||
}
|
||||
|
||||
static void build_net (const db::LayoutToNetlist *l2n, const db::Net &net, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const tl::Variant &netname_prop, int hier_mode, const tl::Variant &circuit_cell_name_prefix, const tl::Variant &device_cell_name_prefix)
|
||||
{
|
||||
std::string p = circuit_cell_name_prefix.to_string ();
|
||||
std::string dp = device_cell_name_prefix.to_string ();
|
||||
l2n->build_net (net, target, target_cell, lmap, circuit_cell_name_prefix.is_nil () ? 0 : p.c_str (), device_cell_name_prefix.is_nil () ? 0 : dp.c_str ());
|
||||
l2n->build_net (net, target, target_cell, lmap, netname_prop, (db::LayoutToNetlist::BuildNetHierarchyMode) hier_mode, circuit_cell_name_prefix.is_nil () ? 0 : p.c_str (), device_cell_name_prefix.is_nil () ? 0 : dp.c_str ());
|
||||
}
|
||||
|
||||
static void build_all_nets (const db::LayoutToNetlist *l2n, 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 &circuit_cell_name_prefix, const tl::Variant &device_cell_name_prefix)
|
||||
static void build_all_nets (const db::LayoutToNetlist *l2n, 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, int 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_all_nets (cmap, target, lmap, net_cell_name_prefix.is_nil () ? 0 : np.c_str (), circuit_cell_name_prefix.is_nil () ? 0 : cp.c_str (), device_cell_name_prefix.is_nil () ? 0 : dp.c_str ());
|
||||
l2n->build_all_nets (cmap, target, lmap, net_cell_name_prefix.is_nil () ? 0 : np.c_str (), netname_prop, (db::LayoutToNetlist::BuildNetHierarchyMode) 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)
|
||||
|
|
@ -349,66 +364,91 @@ Class<db::LayoutToNetlist> decl_dbLayoutToNetlist ("db", "LayoutToNetlist",
|
|||
"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"),
|
||||
gsi::method ("shapes_of_net", (void (db::LayoutToNetlist::*) (const db::Net &, const db::Region &, bool, db::Shapes &, db::properties_id_type) const) &db::LayoutToNetlist::shapes_of_net, gsi::arg ("net"), gsi::arg ("of_layer"), gsi::arg ("recursive"), gsi::arg ("to"), gsi::arg ("propid", db::properties_id_type (0), "0"),
|
||||
"@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"
|
||||
"\"prop_id\" is an optional properties ID. If given, this property set will be attached to the shapes."
|
||||
) +
|
||||
gsi::method_ext ("build_net", &build_net, gsi::arg ("net"), gsi::arg ("target"), gsi::arg ("target_cell"), gsi::arg ("lmap"), gsi::arg ("circuit_cell_name_prefix", tl::Variant (), "nil"), gsi::arg ("device_cell_name_prefix", tl::Variant (), "nil"),
|
||||
gsi::constant ("BNH_Flatten", &bnh_flatten,
|
||||
"@brief This constant tells \\build_net and \\build_all_nets to flatten the nets (used for the \"hier_mode\" parameter)."
|
||||
) +
|
||||
gsi::constant ("BNH_Disconnected", &bnh_disconnected,
|
||||
"@brief This constant tells \\build_net and \\build_all_nets to produce local nets without connections to subcircuits (used for the \"hier_mode\" parameter)."
|
||||
) +
|
||||
gsi::constant ("BNH_SubcircuitCells", &bnh_subcircuit_cells,
|
||||
"@brief This constant tells \\build_net and \\build_all_nets to produce a hierarchy of subcircuit cells per net (used for the \"hier_mode\" parameter)."
|
||||
) +
|
||||
gsi::method_ext ("build_net", &build_net, gsi::arg ("net"), gsi::arg ("target"), gsi::arg ("target_cell"), gsi::arg ("lmap"), gsi::arg ("netname_prop", tl::Variant (), "nil"), gsi::arg ("hier_mode", int (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 net representation in the given layout and cell\n"
|
||||
"\n"
|
||||
"This method has two modes: recursive and top-level mode. In recursive mode,\n"
|
||||
"it will create a proper hierarchy below the given target cell to hold all subcircuits the\n"
|
||||
"net connects to. It will copy the net's parts from this subcircuits into these cells.\n"
|
||||
"This method puts the shapes of a net into the given target cell using a variety of options\n"
|
||||
"to represent the net name and the hierarchy of the net.\n"
|
||||
"\n"
|
||||
"In top-level mode, only the shapes from the net inside it's circuit are copied to\n"
|
||||
"the given target cell. No other cells are created.\n"
|
||||
"If the netname_prop name is not nil, a property with the given name is created and assigned\n"
|
||||
"the net name.\n"
|
||||
"\n"
|
||||
"Recursive mode is picked when a circuit cell name prefix is given. The new cells will be\n"
|
||||
"named like circuit_cell_name_prefix + circuit name.\n"
|
||||
"\n"
|
||||
"If a device cell name prefix is given, device shapes will be output on device cells named\n"
|
||||
"like device_cell_name_prefix + device name.\n"
|
||||
"Net hierarchy is covered in three ways:\n"
|
||||
"@ul\n"
|
||||
" @li No connection indicated (hier_mode == \\BNH_Disconnected: the net shapes are simply put into their\n"
|
||||
" respective circuits. The connections are not indicated. @/li\n"
|
||||
" @li Subnet hierarchy (hier_mode == \\BNH_SubcircuitCells): for each root net, a full hierarchy is built\n"
|
||||
" to accommodate the subnets (see build_net in recursive mode). @/li\n"
|
||||
" @li Flat (hier_mode == \\BNH_Flatten): each net is flattened and put into the circuit it\n"
|
||||
" belongs to. @/li\n"
|
||||
"@/ul\n"
|
||||
"If a device cell name prefix is given, cells will be produced for each device abstract\n"
|
||||
"using a name like device_cell_name_prefix + device name. Otherwise the device shapes are\n"
|
||||
"treated as part of the net.\n"
|
||||
"\n"
|
||||
"@param target The target layout\n"
|
||||
"@param target_cell The target cell\n"
|
||||
"@param lmap Target layer indexes (keys) and net regions (values)\n"
|
||||
"@param circuit_cell_name_prefix Chooses recursive mode if non-nil\n"
|
||||
"@param device_cell_name_prefix If given, devices will be output as separate cells\n"
|
||||
"@param hier_mode See description of this method\n"
|
||||
"@param netname_prop An (optional) property name to which to attach the net name\n"
|
||||
"@param cell_name_prefix Chooses recursive mode if non-null\n"
|
||||
"@param device_cell_name_prefix See above\n"
|
||||
) +
|
||||
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 ("circuit_cell_name_prefix", tl::Variant (), "nil"), gsi::arg ("device_cell_name_prefix", tl::Variant (), "nil"),
|
||||
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", int (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"
|
||||
"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"
|
||||
"\n"
|
||||
"The method has two net annotation modes:\n"
|
||||
"\n"
|
||||
"The method has three net annotation modes:\n"
|
||||
"@ul\n"
|
||||
"@li 'No annotation'' (net_cell_name_prefix == 0): the shapes will be put into the target cell simply @/li\n"
|
||||
"@li Individual subcells per net (net_cell_name_prefix != 0): for each net, a subcell is created\n"
|
||||
" and the net shapes will be put there (name of the subcell = net_cell_name_prefix + net name). @/li\n"
|
||||
" @li No annotation (net_cell_name_prefix == nil and netname_prop == nil): the shapes will be put\n"
|
||||
" into the target cell simply. @/li\n"
|
||||
" @li Net name property (net_cell_name_prefix == nil and netname_prop != nil): the shapes will be\n"
|
||||
" annotated with a property named with netname_prop and containing the net name string. @/li\n"
|
||||
" @li Individual subcells per net (net_cell_name_prefix != 0): for each net, a subcell is created\n"
|
||||
" and the net shapes will be put there (name of the subcell = net_cell_name_prefix + net name).\n"
|
||||
" (this mode can be combined with netname_prop too). @/li\n"
|
||||
"@/ul\n"
|
||||
"\n"
|
||||
"In addition, net hierarchy is covered in two ways:\n"
|
||||
"\n"
|
||||
"In addition, net hierarchy is covered in three ways:\n"
|
||||
"@ul\n"
|
||||
"@li No connection indicated (circuit_cell_name_prefix == 0: the net shapes are simply put into their\n"
|
||||
" respective circuits. The connections are not indicated. @/li\n"
|
||||
"@li Subnet hierarchy (circuit_cell_name_prefix != 0): for each root net, a full hierarchy is built\n"
|
||||
" to accommodate the subnets (see build_net in recursive mode). @/li\n"
|
||||
" @li No connection indicated (hier_mode == \\BNH_Disconnected: the net shapes are simply put into their\n"
|
||||
" respective circuits. The connections are not indicated. @/li\n"
|
||||
" @li Subnet hierarchy (hier_mode == \\BNH_SubcircuitCells): for each root net, a full hierarchy is built\n"
|
||||
" to accommodate the subnets (see build_net in recursive mode). @/li\n"
|
||||
" @li Flat (hier_mode == \\BNH_Flatten): each net is flattened and put into the circuit it\n"
|
||||
" belongs to. @/li\n"
|
||||
"@/ul\n"
|
||||
"\n"
|
||||
"If a device name prefix is given, device shapes will be output on device cells named\n"
|
||||
"like device_name_prefix + device name.\n"
|
||||
"If a device cell name prefix is given, cells will be produced for each device abstract\n"
|
||||
"using a name like device_cell_name_prefix + device name. Otherwise the device shapes are\n"
|
||||
"treated as part of the net.\n"
|
||||
"\n"
|
||||
"@param cmap The mapping of internal layout to target layout for the circuit mapping\n"
|
||||
"@param target The target layout\n"
|
||||
"@param lmap Target layer indexes (keys) and net regions (values)\n"
|
||||
"@param net_cell_name_prefix See method description\n"
|
||||
"@param hier_mode See description of this method\n"
|
||||
"@param netname_prop An (optional) property name to which to attach the net name\n"
|
||||
"@param circuit_cell_name_prefix See method description\n"
|
||||
"@param device_cell_name_prefix If given, devices will be output as separate cells\n"
|
||||
"@param net_cell_name_prefix See method description\n"
|
||||
"@param device_cell_name_prefix See above\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"
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ TEST(1_ReaderBasic)
|
|||
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");
|
||||
|
||||
l2n.build_all_nets (cm, ly2, lmap, "NET_", 0, "DEVICE_");
|
||||
l2n.build_all_nets (cm, ly2, lmap, "NET_", tl::Variant (), db::LayoutToNetlist::BNH_Disconnected, 0, "DEVICE_");
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au = tl::combine_path (au, "testdata");
|
||||
|
|
@ -177,7 +177,7 @@ TEST(2_ReaderWithGlobalNets)
|
|||
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");
|
||||
|
||||
l2n.build_all_nets (cm, ly2, lmap, "NET_", "CIRCUIT_", "DEVICE_");
|
||||
l2n.build_all_nets (cm, ly2, lmap, "NET_", tl::Variant (), db::LayoutToNetlist::BNH_SubcircuitCells, "CIRCUIT_", "DEVICE_");
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au = tl::combine_path (au, "testdata");
|
||||
|
|
|
|||
|
|
@ -397,7 +397,7 @@ TEST(1_BasicExtraction)
|
|||
lmap [ly2.insert_layer (db::LayerProperties (7, 0)) ] = rvia1.get ();
|
||||
lmap [ly2.insert_layer (db::LayerProperties (8, 0)) ] = rmetal2.get ();
|
||||
|
||||
l2n.build_all_nets (cm, ly2, lmap, 0, 0, 0);
|
||||
l2n.build_all_nets (cm, ly2, lmap, 0, tl::Variant (), db::LayoutToNetlist::BNH_Disconnected, 0, 0);
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au = tl::combine_path (au, "testdata");
|
||||
|
|
@ -424,7 +424,7 @@ TEST(1_BasicExtraction)
|
|||
lmap [ly2.insert_layer (db::LayerProperties (7, 0)) ] = rvia1.get ();
|
||||
lmap [ly2.insert_layer (db::LayerProperties (8, 0)) ] = rmetal2.get ();
|
||||
|
||||
l2n.build_all_nets (cm, ly2, lmap, "NET_", 0, 0);
|
||||
l2n.build_all_nets (cm, ly2, lmap, "NET_", tl::Variant (), db::LayoutToNetlist::BNH_Disconnected, 0, 0);
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au = tl::combine_path (au, "testdata");
|
||||
|
|
@ -451,7 +451,7 @@ TEST(1_BasicExtraction)
|
|||
lmap [ly2.insert_layer (db::LayerProperties (7, 0)) ] = rvia1.get ();
|
||||
lmap [ly2.insert_layer (db::LayerProperties (8, 0)) ] = rmetal2.get ();
|
||||
|
||||
l2n.build_all_nets (cm, ly2, lmap, 0, "CIRCUIT_", 0);
|
||||
l2n.build_all_nets (cm, ly2, lmap, 0, tl::Variant (), db::LayoutToNetlist::BNH_SubcircuitCells, "CIRCUIT_", 0);
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au = tl::combine_path (au, "testdata");
|
||||
|
|
@ -478,7 +478,34 @@ TEST(1_BasicExtraction)
|
|||
lmap [ly2.insert_layer (db::LayerProperties (7, 0)) ] = rvia1.get ();
|
||||
lmap [ly2.insert_layer (db::LayerProperties (8, 0)) ] = rmetal2.get ();
|
||||
|
||||
l2n.build_all_nets (cm, ly2, lmap, "NET_", "CIRCUIT_", "DEVICE_");
|
||||
l2n.build_all_nets (cm, ly2, lmap, 0, tl::Variant (42), db::LayoutToNetlist::BNH_Flatten, 0, 0);
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au = tl::combine_path (au, "testdata");
|
||||
au = tl::combine_path (au, "algo");
|
||||
au = tl::combine_path (au, "device_extract_au1_rebuild_pf.gds");
|
||||
|
||||
db::compare_layouts (_this, ly2, au);
|
||||
}
|
||||
|
||||
{
|
||||
db::Layout ly2;
|
||||
ly2.dbu (ly.dbu ());
|
||||
db::Cell &top2 = ly2.cell (ly2.add_cell ("TOP"));
|
||||
|
||||
db::CellMapping cm = l2n.cell_mapping_into (ly2, top2, true /*with device cells*/);
|
||||
|
||||
std::map<unsigned int, const db::Region *> lmap;
|
||||
lmap [ly2.insert_layer (db::LayerProperties (10, 0))] = &rpsd;
|
||||
lmap [ly2.insert_layer (db::LayerProperties (11, 0))] = &rnsd;
|
||||
lmap [ly2.insert_layer (db::LayerProperties (3, 0)) ] = rpoly.get ();
|
||||
lmap [ly2.insert_layer (db::LayerProperties (4, 0)) ] = rdiff_cont.get ();
|
||||
lmap [ly2.insert_layer (db::LayerProperties (5, 0)) ] = rpoly_cont.get ();
|
||||
lmap [ly2.insert_layer (db::LayerProperties (6, 0)) ] = rmetal1.get ();
|
||||
lmap [ly2.insert_layer (db::LayerProperties (7, 0)) ] = rvia1.get ();
|
||||
lmap [ly2.insert_layer (db::LayerProperties (8, 0)) ] = rmetal2.get ();
|
||||
|
||||
l2n.build_all_nets (cm, ly2, lmap, "NET_", tl::Variant (), db::LayoutToNetlist::BNH_SubcircuitCells, "CIRCUIT_", "DEVICE_");
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au = tl::combine_path (au, "testdata");
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@ TEST(1_WriterBasic)
|
|||
lmap [ly2.insert_layer (db::LayerProperties (7, 0)) ] = rvia1.get ();
|
||||
lmap [ly2.insert_layer (db::LayerProperties (8, 0)) ] = rmetal2.get ();
|
||||
|
||||
l2n.build_all_nets (cm, ly2, lmap, "NET_", 0, "DEVICE_");
|
||||
l2n.build_all_nets (cm, ly2, lmap, "NET_", tl::Variant (), db::LayoutToNetlist::BNH_Disconnected, 0, "DEVICE_");
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au = tl::combine_path (au, "testdata");
|
||||
|
|
@ -452,7 +452,7 @@ TEST(2_WriterWithGlobalNets)
|
|||
lmap [ly2.insert_layer (db::LayerProperties (7, 0)) ] = rvia1.get ();
|
||||
lmap [ly2.insert_layer (db::LayerProperties (8, 0)) ] = rmetal2.get ();
|
||||
|
||||
l2n.build_all_nets (cm, ly2, lmap, "NET_", "CIRCUIT_", "DEVICE_");
|
||||
l2n.build_all_nets (cm, ly2, lmap, "NET_", tl::Variant (), db::LayoutToNetlist::BNH_SubcircuitCells, "CIRCUIT_", "DEVICE_");
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au = tl::combine_path (au, "testdata");
|
||||
|
|
|
|||
|
|
@ -101,4 +101,6 @@ unit_tests.depends += plugins $$MAIN_DEPENDS
|
|||
|
||||
RESOURCES += \
|
||||
laybasic/laybasic/layResources.qrc \
|
||||
laybasic/laybasic/layResources.qrc
|
||||
laybasic/laybasic/layResources.qrc \
|
||||
plugins/streamers/lay/lay/layResources.qrc \
|
||||
plugins/streamers/lay/lay/layResources.qrc
|
||||
|
|
|
|||
|
|
@ -466,7 +466,7 @@ MainWindow::MainWindow (QApplication *app, lay::Plugin *plugin_parent, const cha
|
|||
|
||||
init_menu ();
|
||||
|
||||
lay::register_help_handler (this, SLOT (show_help (const QString &)));
|
||||
lay::register_help_handler (this, SLOT (show_help (const QString &)), SLOT (show_modal_help (const QString &)));
|
||||
|
||||
mp_assistant = new lay::HelpDialog (this);
|
||||
|
||||
|
|
@ -697,7 +697,7 @@ MainWindow::~MainWindow ()
|
|||
}
|
||||
tl::DeferredMethodScheduler::instance ()->enable (false);
|
||||
|
||||
lay::register_help_handler (0, 0);
|
||||
lay::register_help_handler (0, 0, 0);
|
||||
|
||||
// since the configuration actions unregister themselves, we need to do this before the main
|
||||
// window is gone:
|
||||
|
|
@ -4783,6 +4783,12 @@ MainWindow::show_help (const QString &url)
|
|||
show_assistant_url (tl::to_string (url), false);
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::show_modal_help (const QString &url)
|
||||
{
|
||||
show_assistant_url (tl::to_string (url), true);
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::show_assistant_url (const std::string &url, bool modal)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -832,11 +832,17 @@ public slots:
|
|||
void cm_navigator_close ();
|
||||
|
||||
/**
|
||||
* @brief shows the given URL as a model help window
|
||||
* @brief shows the given URL as a non-modal help window
|
||||
* Intended as a connection target for QLabel linkVisisted signals.
|
||||
*/
|
||||
void show_help (const QString &url);
|
||||
|
||||
/**
|
||||
* @brief shows the given URL as a modal help window
|
||||
* Intended as a connection target for QLabel linkVisisted signals.
|
||||
*/
|
||||
void show_modal_help (const QString &url);
|
||||
|
||||
/**
|
||||
* @brief visibility of one of the dock widgets changed
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -6,94 +6,45 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>531</width>
|
||||
<height>321</height>
|
||||
<width>508</width>
|
||||
<height>454</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Export Net Options</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="7" column="2">
|
||||
<widget class="QLineEdit" name="device_cell_prefix"/>
|
||||
</item>
|
||||
<item row="6" column="0" colspan="3">
|
||||
<widget class="QCheckBox" name="produce_device_cells_cb">
|
||||
<property name="text">
|
||||
<string>Produce cells for devices</string>
|
||||
<item row="11" column="0" colspan="4">
|
||||
<spacer name="verticalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="3">
|
||||
<item row="4" column="0" colspan="4">
|
||||
<widget class="QCheckBox" name="produce_circuit_cells_cb">
|
||||
<property name="text">
|
||||
<string>Produce cells for circuits</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QLineEdit" name="circuit_cell_prefix"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<item row="5" column="1">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Net cell name prefix</string>
|
||||
<string>Cell name prefix</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLineEdit" name="net_cell_prefix"/>
|
||||
</item>
|
||||
<item row="8" column="1" colspan="2">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>If this options is selected, each device will be represented by one cell made from the device name and the given prefix. Otherwise, device parts are exported as shapes inside the net.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0" colspan="3">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0" colspan="3">
|
||||
<item row="13" column="0" colspan="4">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
|
|
@ -106,21 +57,34 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Cell name prefix</string>
|
||||
<item row="14" column="0" colspan="4">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<item row="5" column="2" colspan="2">
|
||||
<widget class="QLineEdit" name="circuit_cell_prefix"/>
|
||||
</item>
|
||||
<item row="8" column="0" colspan="4">
|
||||
<widget class="QCheckBox" name="produce_device_cells_cb">
|
||||
<property name="text">
|
||||
<string>Cell name prefix</string>
|
||||
<string>Produce cells for devices</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="3">
|
||||
<item row="6" column="1" colspan="3">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>If this option is selected, the subcircuits on a net are represented by individual cells. Otherwise the net is exported as a whole into a single cell (flattened).</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="4">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
|
|
@ -136,17 +100,96 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="4" column="1" colspan="2">
|
||||
<widget class="QLabel" name="label">
|
||||
<item row="0" column="0" colspan="4">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>If this option is selected, the subcircuits on a net are represented by individual cells. Otherwise the net is exported as a whole into a single cell (flattened).</string>
|
||||
<string>This feature will export the nets to a new layout. This layout will contain the original hierarchy as far as required. Within each cell, that corresponds to a circuit, a cell is generated for each net. Each net has it's own hierarchy which can be tailored with the options below.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="3">
|
||||
<item row="9" column="1">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Cell name prefix</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2" colspan="2">
|
||||
<widget class="QLineEdit" name="net_cell_prefix"/>
|
||||
</item>
|
||||
<item row="12" column="0" colspan="3">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Starting layer number for unknown layers</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="10" column="1" colspan="3">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>If this options is selected, each device will be represented by one cell made from the device name and the given prefix. Otherwise, device parts are exported as shapes inside the net.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="2" colspan="2">
|
||||
<widget class="QLineEdit" name="device_cell_prefix"/>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Net cell name prefix</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="12" column="3">
|
||||
<widget class="QLineEdit" name="layernum">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0" colspan="4">
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
|
|
@ -162,8 +205,58 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="2" colspan="2">
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="net_propname"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="help_label">
|
||||
<property name="text">
|
||||
<string><html><body>(<a href="int:/about/variant_notation.xml">See here for the name notation</a>)</body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Net property name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>net_cell_prefix</tabstop>
|
||||
<tabstop>net_propname</tabstop>
|
||||
<tabstop>produce_circuit_cells_cb</tabstop>
|
||||
<tabstop>circuit_cell_prefix</tabstop>
|
||||
<tabstop>produce_device_cells_cb</tabstop>
|
||||
<tabstop>device_cell_prefix</tabstop>
|
||||
<tabstop>layernum</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@
|
|||
|
||||
#include "layNetExportDialog.h"
|
||||
#include "layPlugin.h"
|
||||
#include "layQtTools.h"
|
||||
|
||||
#include "tlExceptions.h"
|
||||
|
||||
#include "ui_NetExportDialog.h"
|
||||
|
||||
|
|
@ -31,10 +34,12 @@ namespace lay
|
|||
{
|
||||
|
||||
extern std::string cfg_l2ndb_net_cell_prefix;
|
||||
extern std::string cfg_l2ndb_net_propname;
|
||||
extern std::string cfg_l2ndb_circuit_cell_prefix;
|
||||
extern std::string cfg_l2ndb_produce_circuit_cells;
|
||||
extern std::string cfg_l2ndb_device_cell_prefix;
|
||||
extern std::string cfg_l2ndb_produce_device_cells;
|
||||
extern std::string cfg_l2ndb_start_layer_number;
|
||||
|
||||
|
||||
NetExportDialog::NetExportDialog (QWidget *parent)
|
||||
|
|
@ -42,6 +47,8 @@ NetExportDialog::NetExportDialog (QWidget *parent)
|
|||
{
|
||||
ui = new Ui::NetExportDialog ();
|
||||
ui->setupUi (this);
|
||||
|
||||
lay::activate_modal_help_links (ui->help_label);
|
||||
}
|
||||
|
||||
NetExportDialog::~NetExportDialog ()
|
||||
|
|
@ -62,6 +69,29 @@ NetExportDialog::net_prefix ()
|
|||
return tl::to_string (ui->net_cell_prefix->text ());
|
||||
}
|
||||
|
||||
void
|
||||
NetExportDialog::set_net_propname (const tl::Variant &net_propname)
|
||||
{
|
||||
if (net_propname.is_nil ()) {
|
||||
ui->net_propname->setText (QString ());
|
||||
} else {
|
||||
ui->net_propname->setText (tl::to_qstring (net_propname.to_parsable_string ()));
|
||||
}
|
||||
}
|
||||
|
||||
tl::Variant
|
||||
NetExportDialog::net_propname ()
|
||||
{
|
||||
std::string np = tl::to_string (ui->net_propname->text ());
|
||||
tl::Extractor ex (np.c_str ());
|
||||
tl::Variant v;
|
||||
if (! ex.at_end ()) {
|
||||
ex.read (v);
|
||||
ex.expect_end ();
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
void
|
||||
NetExportDialog::set_produce_circuit_cells (bool f)
|
||||
{
|
||||
|
|
@ -112,6 +142,30 @@ NetExportDialog::device_cell_prefix ()
|
|||
return tl::to_string (ui->device_cell_prefix->text ());
|
||||
}
|
||||
|
||||
void
|
||||
NetExportDialog::set_start_layer_number (int ln)
|
||||
{
|
||||
ui->layernum->setText (tl::to_qstring (tl::to_string (ln)));
|
||||
}
|
||||
|
||||
int
|
||||
NetExportDialog::start_layer_number ()
|
||||
{
|
||||
int ln = 0;
|
||||
tl::from_string (tl::to_string (ui->layernum->text ()), ln);
|
||||
return ln;
|
||||
}
|
||||
|
||||
void
|
||||
NetExportDialog::accept ()
|
||||
{
|
||||
BEGIN_PROTECTED
|
||||
start_layer_number ();
|
||||
net_propname ();
|
||||
QDialog::accept ();
|
||||
END_PROTECTED
|
||||
}
|
||||
|
||||
int
|
||||
NetExportDialog::exec (lay::PluginRoot *plugin_root)
|
||||
{
|
||||
|
|
@ -119,6 +173,10 @@ NetExportDialog::exec (lay::PluginRoot *plugin_root)
|
|||
plugin_root->config_get (cfg_l2ndb_net_cell_prefix, v);
|
||||
set_net_prefix (v);
|
||||
|
||||
tl::Variant var;
|
||||
plugin_root->config_get (cfg_l2ndb_net_propname, var);
|
||||
set_net_propname (var);
|
||||
|
||||
bool f = false;
|
||||
plugin_root->config_get (cfg_l2ndb_produce_circuit_cells, f);
|
||||
set_produce_circuit_cells (f);
|
||||
|
|
@ -135,10 +193,16 @@ NetExportDialog::exec (lay::PluginRoot *plugin_root)
|
|||
plugin_root->config_get (cfg_l2ndb_device_cell_prefix, v);
|
||||
set_device_cell_prefix (v);
|
||||
|
||||
int ln = 0;
|
||||
plugin_root->config_get (cfg_l2ndb_start_layer_number, ln);
|
||||
set_start_layer_number (ln);
|
||||
|
||||
int ret = QDialog::exec ();
|
||||
if (ret) {
|
||||
|
||||
plugin_root->config_set (cfg_l2ndb_net_cell_prefix, net_prefix ());
|
||||
plugin_root->config_set (cfg_l2ndb_net_propname, net_propname ());
|
||||
plugin_root->config_set (cfg_l2ndb_start_layer_number, tl::to_string (start_layer_number ()));
|
||||
plugin_root->config_set (cfg_l2ndb_produce_circuit_cells, tl::to_string (produce_circuit_cells ()));
|
||||
plugin_root->config_set (cfg_l2ndb_circuit_cell_prefix, circuit_cell_prefix ());
|
||||
plugin_root->config_set (cfg_l2ndb_produce_device_cells, tl::to_string (produce_device_cells ()));
|
||||
|
|
|
|||
|
|
@ -56,6 +56,9 @@ public:
|
|||
void set_net_prefix (const std::string &net_prefix);
|
||||
std::string net_prefix ();
|
||||
|
||||
void set_net_propname (const tl::Variant &net_propname);
|
||||
tl::Variant net_propname ();
|
||||
|
||||
void set_produce_circuit_cells (bool f);
|
||||
bool produce_circuit_cells ();
|
||||
|
||||
|
|
@ -68,8 +71,14 @@ public:
|
|||
void set_device_cell_prefix (const std::string &net_prefix);
|
||||
std::string device_cell_prefix ();
|
||||
|
||||
void set_start_layer_number (int ln);
|
||||
int start_layer_number ();
|
||||
|
||||
int exec (lay::PluginRoot *mp_plugin_root);
|
||||
|
||||
protected:
|
||||
void accept ();
|
||||
|
||||
private:
|
||||
Ui::NetExportDialog *ui;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ extern const std::string cfg_l2ndb_max_shapes_highlighted ("l2ndb-max-shapes-hig
|
|||
extern const std::string cfg_l2ndb_show_all ("l2ndb-show-all");
|
||||
extern const std::string cfg_l2ndb_window_state ("l2ndb-window-state");
|
||||
extern const std::string cfg_l2ndb_net_cell_prefix ("l2ndb-net-cell-prefix");
|
||||
extern const std::string cfg_l2ndb_net_propname ("l2ndb-net-propname");
|
||||
extern const std::string cfg_l2ndb_start_layer_number ("l2ndb-start-layer-number");
|
||||
extern const std::string cfg_l2ndb_circuit_cell_prefix ("l2ndb-circuit-cell-prefix");
|
||||
extern const std::string cfg_l2ndb_produce_circuit_cells ("l2ndb-produce-circuit-cells");
|
||||
extern const std::string cfg_l2ndb_device_cell_prefix ("l2ndb-device-cell-prefix");
|
||||
|
|
@ -340,7 +342,9 @@ public:
|
|||
options.push_back (std::pair<std::string, std::string> (cfg_l2ndb_marker_intensity, "50"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_l2ndb_show_all, "true"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_l2ndb_window_state, ""));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_l2ndb_net_propname, ""));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_l2ndb_net_cell_prefix, "NET_"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_l2ndb_start_layer_number, "1000"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_l2ndb_produce_circuit_cells, "false"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_l2ndb_circuit_cell_prefix, "CIRCUIT_"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_l2ndb_produce_device_cells, "false"));
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@
|
|||
#include "tlProgress.h"
|
||||
#include "dbLayoutToNetlist.h"
|
||||
#include "dbNetlistDeviceClasses.h"
|
||||
#include "dbCellMapping.h"
|
||||
#include "dbLayerMapping.h"
|
||||
|
||||
#include <QUrl>
|
||||
#include <QPainter>
|
||||
|
|
@ -2490,15 +2492,6 @@ NetlistBrowserPage::clear_markers ()
|
|||
mp_markers.clear ();
|
||||
}
|
||||
|
||||
void
|
||||
NetlistBrowserPage::export_all ()
|
||||
{
|
||||
std::auto_ptr<lay::NetExportDialog> dialog (new lay::NetExportDialog (this));
|
||||
if (dialog->exec (mp_plugin_root)) {
|
||||
// @@@
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NetlistBrowserPage::export_selected ()
|
||||
{
|
||||
|
|
@ -2508,5 +2501,73 @@ NetlistBrowserPage::export_selected ()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
NetlistBrowserPage::export_all ()
|
||||
{
|
||||
if (! mp_view || ! mp_database.get () || ! mp_database->internal_layout ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const db::Layout &source_layout = *mp_database->internal_layout ();
|
||||
if (source_layout.begin_top_down () == source_layout.end_top_cells ()) {
|
||||
// nothing to export
|
||||
return;
|
||||
}
|
||||
|
||||
const db::Cell &source_top = source_layout.cell (*source_layout.begin_top_down ());
|
||||
|
||||
std::auto_ptr<lay::NetExportDialog> dialog (new lay::NetExportDialog (this));
|
||||
if (dialog->exec (mp_plugin_root)) {
|
||||
|
||||
// NOTE: mp_view and database might get reset to 0 in create_layout
|
||||
lay::LayoutView *view = mp_view;
|
||||
db::LayoutToNetlist *database = mp_database.get ();
|
||||
|
||||
unsigned int cv_index = view->create_layout (true);
|
||||
db::Layout &target_layout = view->cellview (cv_index)->layout ();
|
||||
|
||||
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;
|
||||
{
|
||||
// create a layer mapping
|
||||
|
||||
std::set<unsigned int> layers_to_copy;
|
||||
const db::Connectivity &conn = database->connectivity ();
|
||||
for (db::Connectivity::layer_iterator layer = conn.begin_layers (); layer != conn.end_layers (); ++layer) {
|
||||
layers_to_copy.insert (*layer);
|
||||
}
|
||||
|
||||
int ln = dialog->start_layer_number ();
|
||||
|
||||
for (std::set<unsigned int>::const_iterator l = layers_to_copy.begin (); l != layers_to_copy.end (); ++l) {
|
||||
const db::LayerProperties &lp = source_layout.get_properties (*l);
|
||||
unsigned int tl;
|
||||
if (! lp.is_null ()) {
|
||||
tl = target_layout.insert_layer (lp);
|
||||
} else {
|
||||
tl = target_layout.insert_layer (db::LayerProperties (ln++, 0, database->name (*l)));
|
||||
}
|
||||
lm.insert (std::make_pair (tl, database->layer_by_index (*l)));
|
||||
}
|
||||
}
|
||||
|
||||
database->build_all_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,
|
||||
dialog->produce_circuit_cells () ? dialog->circuit_cell_prefix ().c_str () : 0,
|
||||
dialog->produce_device_cells () ? dialog->device_cell_prefix ().c_str () : 0);
|
||||
|
||||
view->zoom_fit ();
|
||||
view->max_hier ();
|
||||
view->add_missing_layers ();
|
||||
view->select_cell (target_top_index, cv_index);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ namespace lay
|
|||
|
||||
QObject *s_help_handler = 0;
|
||||
const char *s_help_slot = 0;
|
||||
const char *s_modal_help_slot = 0;
|
||||
|
||||
void activate_help_links (QLabel *label)
|
||||
{
|
||||
|
|
@ -50,10 +51,18 @@ void activate_help_links (QLabel *label)
|
|||
}
|
||||
}
|
||||
|
||||
void register_help_handler (QObject *object, const char *slot)
|
||||
void activate_modal_help_links (QLabel *label)
|
||||
{
|
||||
if (s_help_handler) {
|
||||
QObject::connect (label, SIGNAL (linkActivated (const QString &)), s_help_handler, s_modal_help_slot);
|
||||
}
|
||||
}
|
||||
|
||||
void register_help_handler (QObject *object, const char *slot, const char *modal_slot)
|
||||
{
|
||||
s_help_handler = object;
|
||||
s_help_slot = slot;
|
||||
s_modal_help_slot = modal_slot;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -53,9 +53,14 @@ LAYBASIC_PUBLIC void restore_dialog_state (QWidget *dialog, const std::string &s
|
|||
LAYBASIC_PUBLIC void activate_help_links (QLabel *label);
|
||||
|
||||
/**
|
||||
* @brief Register the help handler (object and slot)
|
||||
* @brief A utility function connecting a label's linkActivated event with the help browser (modal help dialogs)
|
||||
*/
|
||||
LAYBASIC_PUBLIC void register_help_handler (QObject *object, const char *slot);
|
||||
LAYBASIC_PUBLIC void activate_modal_help_links (QLabel *label);
|
||||
|
||||
/**
|
||||
* @brief Register the help handler (object and slots for non-modal and modal help dialogs)
|
||||
*/
|
||||
LAYBASIC_PUBLIC void register_help_handler (QObject *object, const char *slot, const char *modal_slot);
|
||||
|
||||
|
||||
} // namespace lay
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../../../lay/lay/layResources.qrc">
|
||||
<normaloff>:/clear.png</normaloff>:/clear.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
@ -140,7 +140,7 @@
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../../../lay/lay/layResources.qrc">
|
||||
<normaloff>:/down.png</normaloff>:/down.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
@ -167,7 +167,7 @@
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../../../lay/lay/layResources.qrc">
|
||||
<normaloff>:/add.png</normaloff>:/add.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
@ -181,7 +181,7 @@
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../../../lay/lay/layResources.qrc">
|
||||
<normaloff>:/up.png</normaloff>:/up.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
@ -270,7 +270,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../../lay/lay/layResources.qrc">:/right.png</pixmap>
|
||||
<pixmap resource="../../../../lay/lay/layResources.qrc">:/right.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -292,7 +292,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../../lay/lay/layResources.qrc">:/right.png</pixmap>
|
||||
<pixmap resource="../../../../lay/lay/layResources.qrc">:/right.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -318,7 +318,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../../lay/lay/layResources.qrc">:/right.png</pixmap>
|
||||
<pixmap resource="../../../../lay/lay/layResources.qrc">:/right.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -447,7 +447,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../../lay/lay/layResources.qrc">:/right.png</pixmap>
|
||||
<pixmap resource="../../../../lay/lay/layResources.qrc">:/right.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -493,7 +493,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../../lay/lay/layResources.qrc">:/right.png</pixmap>
|
||||
<pixmap resource="../../../../lay/lay/layResources.qrc">:/right.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -509,7 +509,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../../lay/lay/layResources.qrc">:/right.png</pixmap>
|
||||
<pixmap resource="../../../../lay/lay/layResources.qrc">:/right.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -525,7 +525,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../../lay/lay/layResources.qrc">:/right.png</pixmap>
|
||||
<pixmap resource="../../../../lay/lay/layResources.qrc">:/right.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -541,7 +541,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../../lay/lay/layResources.qrc">:/right.png</pixmap>
|
||||
<pixmap resource="../../../../lay/lay/layResources.qrc">:/right.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -585,7 +585,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../../lay/lay/layResources.qrc">:/right.png</pixmap>
|
||||
<pixmap resource="../../../../lay/lay/layResources.qrc">:/right.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -604,7 +604,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../../lay/lay/layResources.qrc">:/right.png</pixmap>
|
||||
<pixmap resource="../../../../lay/lay/layResources.qrc">:/right.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -641,7 +641,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../../lay/lay/layResources.qrc">:/right.png</pixmap>
|
||||
<pixmap resource="../../../../lay/lay/layResources.qrc">:/right.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -774,7 +774,7 @@
|
|||
<tabstop>read_all_cbx</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../../lay/lay/layResources.qrc"/>
|
||||
<include location="../../../../lay/lay/layResources.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in New Issue