Netlist browser: Paths for probing, cell contexts for highlighting, probe_net with initial circuit (not just top one)

This commit is contained in:
Matthias Koefferlein 2020-07-14 23:06:26 +02:00
parent a10d56e6b6
commit be5f03b1f4
6 changed files with 98 additions and 34 deletions

View File

@ -1041,9 +1041,9 @@ LayoutToNetlist::build_nets (const std::vector<const db::Net *> *nets, const db:
}
}
db::Net *LayoutToNetlist::probe_net (const db::Region &of_region, const db::DPoint &point, std::vector<db::SubCircuit *> *sc_path_out)
db::Net *LayoutToNetlist::probe_net (const db::Region &of_region, const db::DPoint &point, std::vector<db::SubCircuit *> *sc_path_out, db::Circuit *initial_circuit)
{
return probe_net (of_region, db::CplxTrans (internal_layout ()->dbu ()).inverted () * point, sc_path_out);
return probe_net (of_region, db::CplxTrans (internal_layout ()->dbu ()).inverted () * point, sc_path_out, initial_circuit);
}
size_t LayoutToNetlist::search_net (const db::ICplxTrans &trans, const db::Cell *cell, const db::local_cluster<db::NetShape> &test_cluster, std::vector<db::InstElement> &rev_inst_path)
@ -1077,7 +1077,7 @@ size_t LayoutToNetlist::search_net (const db::ICplxTrans &trans, const db::Cell
return 0;
}
db::Net *LayoutToNetlist::probe_net (const db::Region &of_region, const db::Point &point, std::vector<db::SubCircuit *> *sc_path_out)
db::Net *LayoutToNetlist::probe_net (const db::Region &of_region, const db::Point &point, std::vector<db::SubCircuit *> *sc_path_out, db::Circuit *initial_circuit)
{
if (! m_netlist_extracted) {
throw tl::Exception (tl::to_string (tr ("The netlist has not been extracted yet")));
@ -1089,6 +1089,14 @@ db::Net *LayoutToNetlist::probe_net (const db::Region &of_region, const db::Poin
unsigned int layer = layer_of (of_region);
const db::Cell *top_cell = internal_top_cell ();
if (initial_circuit && internal_layout ()->is_valid_cell_index (initial_circuit->cell_index ())) {
top_cell = &internal_layout ()->cell (initial_circuit->cell_index ());
}
if (! top_cell) {
return 0;
}
// Prepare a test cluster
db::Box box (point - db::Vector (1, 1), point + db::Vector (1, 1));
db::GenericRepository sr;
@ -1097,7 +1105,7 @@ db::Net *LayoutToNetlist::probe_net (const db::Region &of_region, const db::Poin
std::vector<db::InstElement> inst_path;
size_t cluster_id = search_net (db::ICplxTrans (), internal_top_cell (), test_cluster, inst_path);
size_t cluster_id = search_net (db::ICplxTrans (), top_cell, test_cluster, inst_path);
if (cluster_id > 0) {
// search_net delivers the path in reverse order
@ -1105,7 +1113,7 @@ db::Net *LayoutToNetlist::probe_net (const db::Region &of_region, const db::Poin
std::vector<db::cell_index_type> cell_indexes;
cell_indexes.reserve (inst_path.size () + 1);
cell_indexes.push_back (internal_top_cell ()->cell_index ());
cell_indexes.push_back (top_cell->cell_index ());
for (std::vector<db::InstElement>::const_iterator i = inst_path.begin (); i != inst_path.end (); ++i) {
cell_indexes.push_back (i->inst_ptr.cell_index ());
}

View File

@ -713,7 +713,7 @@ public:
* The subcircuit path leading to the topmost net is stored in *sc_path_out if this
* pointer is non-null.
*/
db::Net *probe_net (const db::Region &of_region, const db::DPoint &point, std::vector<SubCircuit *> *sc_path_out = 0);
db::Net *probe_net (const db::Region &of_region, const db::DPoint &point, std::vector<SubCircuit *> *sc_path_out = 0, Circuit *initial_circuit = 0);
/**
* @brief Finds the net by probing a specific location on the given layer
@ -721,7 +721,7 @@ public:
* This variant accepts a database-unit location. The location is given in the
* coordinate space of the initial cell.
*/
db::Net *probe_net (const db::Region &of_region, const db::Point &point, std::vector<SubCircuit *> *sc_path_out = 0);
db::Net *probe_net (const db::Region &of_region, const db::Point &point, std::vector<SubCircuit *> *sc_path_out = 0, Circuit *initial_circuit = 0);
/**
* @brief Runs an antenna check on the extracted clusters

View File

@ -543,7 +543,7 @@ Class<db::LayoutToNetlist> decl_dbLayoutToNetlist ("db", "LayoutToNetlist",
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 &, std::vector<db::SubCircuit *> *)) &db::LayoutToNetlist::probe_net, gsi::arg ("of_layer"), gsi::arg ("point"), gsi::arg ("sc_path_out", (std::vector<db::SubCircuit *> *) 0, "nil"),
gsi::method ("probe_net", (db::Net *(db::LayoutToNetlist::*) (const db::Region &, const db::DPoint &, std::vector<db::SubCircuit *> *, db::Circuit *)) &db::LayoutToNetlist::probe_net, gsi::arg ("of_layer"), gsi::arg ("point"), gsi::arg ("sc_path_out", (std::vector<db::SubCircuit *> *) 0, "nil"), gsi::arg ("initial_circuit", (db::Circuit *) 0, "nil"),
"@brief Finds the net by probing a specific location on the given layer\n"
"\n"
"This method will find a net looking at the given layer at the specific position.\n"
@ -551,9 +551,12 @@ Class<db::LayoutToNetlist> decl_dbLayoutToNetlist ("db", "LayoutToNetlist",
"in the specified location. The function will report the topmost net from far above the\n"
"hierarchy of circuits as possible.\n"
"\n"
"If \\initial_circuit is given, the probing will start from this circuit and from the "
"cell this circuit represents. By default, the probing will start from the top circuit.\n"
"\n"
"If no net is found at all, 0 is returned.\n"
"\n"
"It is recommended to use \\probe on the netlist right after extraction.\n"
"It is recommended to use \\probe_net on the netlist right after extraction.\n"
"Optimization functions such as \\Netlist#purge will remove parts of the net which means\n"
"shape to net probing may no longer work for these nets.\n"
"\n"
@ -565,7 +568,7 @@ Class<db::LayoutToNetlist> decl_dbLayoutToNetlist ("db", "LayoutToNetlist",
"\n"
"The \\sc_path_out parameter has been added in version 0.27.\n"
) +
gsi::method ("probe_net", (db::Net *(db::LayoutToNetlist::*) (const db::Region &, const db::Point &, std::vector<db::SubCircuit *> *)) &db::LayoutToNetlist::probe_net, gsi::arg ("of_layer"), gsi::arg ("point"), gsi::arg ("sc_path_out", (std::vector<db::SubCircuit *> *) 0, "nil"),
gsi::method ("probe_net", (db::Net *(db::LayoutToNetlist::*) (const db::Region &, const db::Point &, std::vector<db::SubCircuit *> *, db::Circuit *)) &db::LayoutToNetlist::probe_net, gsi::arg ("of_layer"), gsi::arg ("point"), gsi::arg ("sc_path_out", (std::vector<db::SubCircuit *> *) 0, "nil"), gsi::arg ("initial_circuit", (db::Circuit *) 0, "nil"),
"@brief Finds the net by probing a specific location on the given layer\n"
"See the description of the other \\probe_net variant.\n"
"This variant accepts a database-unit location. The location is given in the\n"

View File

@ -307,41 +307,54 @@ NetlistBrowserDialog::probe_net (const db::DPoint &p, bool trace_path)
}
db::Net *net = 0;
db::Circuit *root = 0;
std::vector<db::SubCircuit *> sc_path;
db::LayoutToNetlist *l2ndb = view ()->get_l2ndb (m_l2n_index);
if (l2ndb) {
// determines the corresponding layer inside the database and probe the net from this region and the
// start point.
root = l2ndb->netlist ()->circuit_by_name (cv->layout ().cell_name (cv.cell_index ()));
if (root) {
std::vector<db::Region *> regions;
// determines the corresponding layer inside the database and probe the net from this region and the
// start point.
const db::Connectivity &conn = l2ndb->connectivity ();
for (db::Connectivity::layer_iterator layer = conn.begin_layers (); layer != conn.end_layers (); ++layer) {
db::LayerProperties lp = l2ndb->internal_layout ()->get_properties (*layer);
if (! lp.is_null ()) {
db::Region *region = l2ndb->layer_by_index (*layer);
if (lp == cv->layout ().get_properties (start_layer)) {
// a matching original layer is looked up with higher prio
regions.insert (regions.begin (), region);
} else {
regions.push_back (region);
std::vector<db::Region *> regions;
const db::Connectivity &conn = l2ndb->connectivity ();
for (db::Connectivity::layer_iterator layer = conn.begin_layers (); layer != conn.end_layers (); ++layer) {
db::LayerProperties lp = l2ndb->internal_layout ()->get_properties (*layer);
if (! lp.is_null ()) {
db::Region *region = l2ndb->layer_by_index (*layer);
if (lp == cv->layout ().get_properties (start_layer)) {
// a matching original layer is looked up with higher prio
regions.insert (regions.begin (), region);
} else {
regions.push_back (region);
}
}
}
}
// probe the net
// probe the net
for (std::vector<db::Region *>::const_iterator r = regions.begin (); r != regions.end () && !net; ++r) {
sc_path.clear ();
net = l2ndb->probe_net (**r, start_point, &sc_path, root);
}
for (std::vector<db::Region *>::const_iterator r = regions.begin (); r != regions.end () && !net; ++r) {
sc_path.clear ();
net = l2ndb->probe_net (**r, start_point, &sc_path);
}
}
// select the net if one was found
browser_page->select_net (net);
lay::NetlistObjectPath path;
if (net) {
path.root = root;
path.net = net;
path.path = lay::NetlistObjectPath::path_type (sc_path.begin (), sc_path.end ());
}
browser_page->select_path (path);
// emits the probe event
probe_event (net, sc_path);

View File

@ -369,6 +369,18 @@ NetlistBrowserPage::select_net (const db::Net *net)
}
}
void
NetlistBrowserPage::select_path (const lay::NetlistObjectsPath &path)
{
if (path.is_null ()) {
directory_tree->clearSelection ();
} else {
NetlistBrowserModel *model = dynamic_cast<NetlistBrowserModel *> (directory_tree->model ());
tl_assert (model != 0);
directory_tree->setCurrentIndex (model->index_from_path (path));
}
}
std::vector<const db::Net *>
NetlistBrowserPage::selected_nets ()
{
@ -946,13 +958,20 @@ NetlistBrowserPage::adjust_view ()
return;
}
const db::Layout &original_layout = mp_view->cellview (m_cv_index)->layout ();
const db::Circuit *top_circuit = mp_database->netlist ()->circuit_by_name (original_layout.cell_name (mp_view->cellview (m_cv_index).cell_index ()));
const db::Circuit *circuit = m_current_path.root.first;
if (! circuit) {
return;
}
const db::Layout *layout = mp_database->internal_layout ();
const db::Cell *cell = mp_database->internal_top_cell ();
const db::Cell *cell = (top_circuit && layout->is_valid_cell_index (top_circuit->cell_index ()) ? &layout->cell (top_circuit->cell_index ()) : mp_database->internal_top_cell ());
if (! layout || ! cell) {
return;
}
const db::Circuit *circuit = m_current_path.root.first;
db::DCplxTrans trans;
if (circuit) {
@ -1232,16 +1251,21 @@ NetlistBrowserPage::update_highlights ()
}
const db::Layout &original_layout = mp_view->cellview (m_cv_index)->layout ();
const db::Circuit *top_circuit = mp_database->netlist ()->circuit_by_name (original_layout.cell_name (mp_view->cellview (m_cv_index).cell_index ()));
const db::Circuit *circuit = m_current_path.root.first;
if (! circuit) {
return;
}
const db::Layout *layout = mp_database->internal_layout ();
const db::Cell *cell = mp_database->internal_top_cell ();
const db::Cell *cell = (top_circuit && layout->is_valid_cell_index (top_circuit->cell_index ()) ? &layout->cell (top_circuit->cell_index ()) : mp_database->internal_top_cell ());
if (! layout || ! cell) {
return;
}
// compute the transformation supplied by the path
// computes the transformation supplied by the path
const db::Circuit *circuit = m_current_path.root.first;
db::DCplxTrans trans;
if (circuit) {

View File

@ -106,6 +106,22 @@ public:
*/
void select_net (const db::Net *net);
/**
* @brief Selects a netlist object (a circuit, a subcircuit, a net or a device)
*/
void select_path (const lay::NetlistObjectPath &path)
{
select_path (lay::NetlistObjectsPath::from_first (path));
}
/**
* @brief Selects a netlist object (a circuit, a subcircuit, a net or a device)
*
* This variant allows specifying a paired path using either an object from the first,
* the second netlist of both.
*/
void select_path (const lay::NetlistObjectsPath &path);
/**
* @brief Set the window type and window dimensions
*/