Merge pull request #329 from KLayout/dvb

Dvb
This commit is contained in:
Matthias Köfferlein 2019-09-09 18:30:34 +02:00 committed by GitHub
commit 9e30539476
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 97 additions and 12 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

@ -46,7 +46,7 @@
<pre>same_nets("LOGIC", "VDD", "VDD:P")</pre>
<p>
In this example it is assumed that the power net is labelled "VDD" in the
In this example it is assumed that the power net is labeled "VDD" in the
layout and called "VDD:P" in the schematic. Don't leave this statement in
the script for final verification as it may mask real errors.
</p>
@ -160,7 +160,8 @@ same_device_classes("NMOS_IN_LAYOUT", "NMOS_IN_SCHEMATIC")</pre>
</p>
<p>
In general, it's a good idea to include "align" before the "compare" step.
In general, it's a good idea to include "align" before "netlist.simplify" or
similar netlist manipulation and the "compare" step.
</p>
<p>

View File

@ -70,7 +70,7 @@ connect(metal2, metal2_labels)</pre>
<p>
If labels are connected to metal layers, their text strings will be used to assign
net names to the resulting nets. Ideally, one net is labelled with a single text
net names to the resulting nets. Ideally, one net is labeled with a single text
or with texts with the same text string. In this case, the net name will
be non-ambiguous. If multiple labels with different strings are present on a net,
the net name will be made from a combination of these names.

View File

@ -156,6 +156,9 @@ connect_global(nwell, "NWELL")
schematic("inv.cir")
align # flattens unpaired circuits
netlist.simplify # removes floating nets, combines devices
compare</pre>
<p>
@ -336,11 +339,35 @@ connect_global(nwell, "NWELL")</pre>
<p>
We have now provided all the essential inputs for the netlist formation.
We only have to specify the reference netlist:
We now have to specify the reference netlist:
</p>
<pre>schematic("inv.cir")</pre>
<p>
Two optional, but recommended steps are hierarchy alignment and extracted
netlist simplification:
</p>
<pre>align # flattens unpaired circuits
netlist.simplify # removes floating nets, combines devices
</pre>
<p>
"align" will remove circuits which are not present in the other netlist by
integrating their content into the parent cell. This will remove auxiliary cells
which are usually present in a layout but don't map to a schematic cell (e.g.
device PCells). "netlist.simplify" reduces the netlist by floating nets,
performs device combination (e.g. fingered transistors). This method will
also create pins from labeled nets in the top level circuit.
</p>
<p>
The order should be "align", then "netlist.simplify". Both have to happen before
"compare" to be effective. "align" is described in <link href="/manual/lvs_compare.xml"/>,
"netlist.simplify" in <link href="/manual/lvs_tweaks.xml"/>.
</p>
<p>
Finally after having set this up, we can trigger the compare step:
</p>
@ -498,6 +525,9 @@ connect_global(ptie, "SUBSTRATE")
schematic("inv2.cir")
align
netlist.simplify
compare</pre>
<p>

View File

@ -41,7 +41,7 @@
<p>
KLayout offers a function to create top-level pins using
a simple heuristics: for every named (i.e. labelled) net in the top level
a simple heuristics: for every named (i.e. labeled) net in the top level
circuit a pin will be created (<class_doc href="Netlist#make_top_level_pins"/>):
</p>
@ -199,9 +199,16 @@ netlist.purge_nets</pre>
<p>
<class_doc href="Netlist#simplify"/> is a wrapper for "make_top_level_pins",
"combine_devices" and "purge" in the recommended order:
"purge", "combine_devices" and "purge_nets" in this recommended order:
</p>
<pre>netlist.simplify</pre>
<p>
As a technical detail, "make_top_level_pins" is included in this sequence as with
pins, nets are not considered floating. So "purge_nets" will maintain pins for
labeled nets even if these nets are not connected to devices. This allows adding
optional pins while maintaining the top level circuit's interface.
</p>
</doc>

View File

@ -101,7 +101,7 @@
<li>Export all or selected nets to layout, save the netlist (with shapes) to a file, load it back from a file and manage
the netlist database. Use the "File" menu button in the right upper corner.
</li>
<li>Search for net names (if labelled) and circuits using the search edit box.
<li>Search for net names (if labeled) and circuits using the search edit box.
</li>
<li>Navigate through the history using the "back" and "forward" buttons at the top left.
</li>

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