Provide flat and hierarchical 'trace all nets' feature, added Netlist#flatten.

This commit is contained in:
Matthias Koefferlein 2019-09-06 23:13:21 +02:00
parent c7ee35a4e3
commit e2cc0c48b1
7 changed files with 52 additions and 5 deletions

View File

@ -396,6 +396,22 @@ void Netlist::flatten_circuit (Circuit *circuit)
delete circuit;
}
void Netlist::flatten ()
{
std::set<db::Circuit *> top_circuits;
size_t ntop = top_circuit_count ();
for (db::Netlist::top_down_circuit_iterator tc = begin_top_down (); tc != end_top_down () && ntop > 0; ++tc) {
top_circuits.insert (tc.operator-> ());
--ntop;
}
for (db::Netlist::bottom_up_circuit_iterator c = begin_bottom_up (); c != end_bottom_up(); ++c) {
if (top_circuits.find (c.operator-> ()) == top_circuits.end ()) {
flatten_circuit (c.operator-> ());
}
}
}
DeviceClass *Netlist::device_class_by_name (const std::string &name)
{
for (device_class_iterator d = begin_device_classes (); d != end_device_classes (); ++d) {

View File

@ -174,6 +174,11 @@ public:
*/
void flatten_circuit (Circuit *circuit);
/**
* @brief Flattens the netlist
*/
void flatten ();
/**
* @brief Begin iterator for the circuits of the netlist (non-const version)
*/

View File

@ -1388,6 +1388,10 @@ Class<db::Netlist> decl_dbNetlist ("db", "Netlist",
"A circuit with references (see \\has_refs?) should not be removed as the "
"subcircuits calling it would afterwards point to nothing."
) +
gsi::method ("flatten", &db::Netlist::flatten,
"@brief Flattens all circuits of the netlist\n"
"After calling this method, only the top circuits will remain."
) +
gsi::method ("flatten_circuit", &db::Netlist::flatten_circuit, gsi::arg ("circuit"),
"@brief Flattens a subcircuit\n"
"This method will substitute all instances (subcircuits) of the given circuit by it's "

View File

@ -1188,6 +1188,20 @@ TEST(20_FlattenSubCircuit)
" device NMOS $4 (S=$4,G=$2,D=OUT) (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0);\n"
"end;\n"
);
db::Netlist nl3;
nl3 = nl;
nl3.flatten ();
EXPECT_EQ (nl3.to_string (),
"circuit INV2 (IN=IN,$2=$2,OUT=OUT,$4=$4,$5=$5);\n"
" device PMOS $1 (S=$5,G=IN,D=$2) (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0);\n"
" device PMOS $2 (S=$5,G=$2,D=OUT) (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0);\n"
" device NMOS $3 (S=$4,G=IN,D=$2) (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0);\n"
" device NMOS $4 (S=$4,G=$2,D=OUT) (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0);\n"
"end;\n"
);
}
TEST(21_FlattenSubCircuit2)

View File

@ -559,13 +559,15 @@ NetTracerDialog::menu_activated (const std::string &symbol)
layer_stack_clicked ();
} else if (symbol == "lay::trace_all_nets") {
} else if (symbol == "lay::trace_all_nets" || symbol == "lay::trace_all_nets_flat") {
bool flat = symbol == "lay::trace_all_nets_flat";
const lay::CellView &cv = view ()->cellview (view ()->active_cellview_index ());
if (cv.is_valid ()) {
db::RecursiveShapeIterator si (cv->layout (), *cv.cell (), std::vector<unsigned int> ());
std::auto_ptr <db::LayoutToNetlist> l2ndb (new db::LayoutToNetlist (si));
trace_all_nets (l2ndb.get (), cv);
trace_all_nets (l2ndb.get (), cv, flat);
unsigned int l2ndb_index = view ()->add_l2ndb (l2ndb.release ());
view ()->open_l2ndb_browser (l2ndb_index, view ()->index_of_cellview (&cv));
}
@ -1658,7 +1660,7 @@ NetTracerDialog::clear_markers ()
}
void
NetTracerDialog::trace_all_nets (db::LayoutToNetlist *l2ndb, const lay::CellView &cv)
NetTracerDialog::trace_all_nets (db::LayoutToNetlist *l2ndb, const lay::CellView &cv, bool flat)
{
db::NetTracerData tracer_data;
if (! get_net_tracer_setup (cv, tracer_data)) {
@ -1668,6 +1670,10 @@ NetTracerDialog::trace_all_nets (db::LayoutToNetlist *l2ndb, const lay::CellView
tracer_data.configure_l2n (*l2ndb);
l2ndb->extract_netlist ();
if (flat) {
l2ndb->netlist ()->flatten ();
}
}
}

View File

@ -118,7 +118,7 @@ private:
void release_mouse ();
db::NetTracerNet *do_trace (const db::DBox &start_search_box, const db::DBox &stop_search_box, bool trace_path);
bool get_net_tracer_setup (const lay::CellView &cv, db::NetTracerData &data);
void trace_all_nets (db::LayoutToNetlist *l2ndb, const lay::CellView &cv);
void trace_all_nets (db::LayoutToNetlist *l2ndb, const lay::CellView &cv, bool flat);
};
}

View File

@ -69,7 +69,9 @@ public:
lay::PluginDeclaration::get_menu_entries (menu_entries);
menu_entries.push_back (lay::MenuEntry ("net_trace_group", "tools_menu.end"));
menu_entries.push_back (lay::MenuEntry ("lay::net_trace", "net_trace", "tools_menu.end", tl::to_string (QObject::tr ("Trace Net"))));
menu_entries.push_back (lay::MenuEntry ("lay::trace_all_nets", "trace_all_nets", "tools_menu.end", tl::to_string (QObject::tr ("Trace All Nets"))));
menu_entries.push_back (lay::MenuEntry ("", "trace_all_nets_menu", "tools_menu.end", tl::to_string (QObject::tr ("Trace All Nets")), true));
menu_entries.push_back (lay::MenuEntry ("lay::trace_all_nets", "trace_all_nets", "tools_menu.trace_all_nets_menu.end", tl::to_string (QObject::tr ("Hierarchical"))));
menu_entries.push_back (lay::MenuEntry ("lay::trace_all_nets_flat", "trace_all_nets_flat", "tools_menu.trace_all_nets_menu.end", tl::to_string (QObject::tr ("Flat"))));
menu_entries.push_back (lay::MenuEntry ("lay::edit_layer_stack", "edit_layer_stack", "tools_menu.end", tl::to_string (QObject::tr ("Edit Layer Stack"))));
}