WIP: make top level pins for named nets and netlist purging. Tests.

This commit is contained in:
Matthias Koefferlein 2018-12-29 20:50:35 +01:00
parent 54adb84e27
commit edbafae43e
4 changed files with 108 additions and 17 deletions

View File

@ -1446,6 +1446,53 @@ void Netlist::purge_nets ()
}
}
void Netlist::make_top_level_pins ()
{
size_t ntop = top_circuit_count ();
for (top_down_circuit_iterator c = begin_top_down (); c != end_top_down () && ntop > 0; ++c, --ntop) {
Circuit *circuit = *c;
if (circuit->pin_count () == 0) {
// create pins for the named nets and connect them
for (Circuit::net_iterator n = circuit->begin_nets (); n != circuit->end_nets (); ++n) {
if (! n->name ().empty () && n->terminal_count () + n->pin_count () > 0) {
Pin pin (n->name ());
pin = circuit->add_pin (pin);
circuit->connect_pin (pin.id (), n.operator-> ());
}
}
}
}
}
void Netlist::purge ()
{
// This locking is very important as we do not want to recompute the bottom-up list
// while iterating.
NetlistLocker locker (this);
for (bottom_up_circuit_iterator c = begin_bottom_up (); c != end_bottom_up (); ++c) {
Circuit *circuit = *c;
circuit->purge_nets ();
if (circuit->begin_nets () == circuit->end_nets ()) {
// No nets left: delete the subcircuits that refer to us and finally delete the circuit
while (circuit->begin_refs () != circuit->end_refs ()) {
delete circuit->begin_refs ().operator-> ();
}
delete circuit;
}
}
}
void Netlist::combine_devices ()
{
for (circuit_iterator c = begin_circuits (); c != end_circuits (); ++c) {

View File

@ -1984,6 +1984,23 @@ public:
*/
void purge_nets ();
/**
* @brief Creates pins for top-level circuits
*
* This method will turn all named nets of top-level circuits (such that are not
* referenced by subcircuits) into pins. This method can be used before purge to
* avoid that purge will remove nets which are directly connecting to subcircuits.
*/
void make_top_level_pins ();
/**
* @brief Purge unused nets, circuits and subcircuits
*
* This method will purge all nets which return "floating". Circuits which don't have any
* nets (or only floating ones) and removed. Their subcircuits are disconnected.
*/
void purge ();
/**
* @brief Combine devices
*

View File

@ -98,12 +98,6 @@ NetlistExtractor::extract_nets (const db::DeepShapeStore &dss, const db::Connect
net->set_cluster_id (*c);
circuit->add_net (net);
if (! clusters.is_root (*c)) {
// a non-root cluster makes a pin
size_t pin_id = make_pin (circuit, net);
c2p.insert (std::make_pair (*c, pin_id));
}
// make subcircuit connections (also make the subcircuits if required) from the connections of the clusters
make_and_connect_subcircuits (circuit, clusters, *c, net, subcircuits, circuits, pins_per_cluster, layout.dbu ());
@ -121,6 +115,12 @@ NetlistExtractor::extract_nets (const db::DeepShapeStore &dss, const db::Connect
}
}
if (! clusters.is_root (*c)) {
// a non-root cluster makes a pin
size_t pin_id = make_pin (circuit, net);
c2p.insert (std::make_pair (*c, pin_id));
}
}
}

View File

@ -480,17 +480,17 @@ TEST(1_DeviceAndNetExtraction)
// compare netlist as string
EXPECT_EQ (netlist2string (nl),
"Circuit RINGO ():\n"
" XINV2 $1 ($1=$I8,$2=FB,$3=OSC,$4=VSS,$5=VDD)\n"
" XINV2 $2 ($1=FB,$2=$I38,$3=$I19,$4=VSS,$5=VDD)\n"
" XINV2 $3 ($1=$I19,$2=$I39,$3=$I1,$4=VSS,$5=VDD)\n"
" XINV2 $4 ($1=$I1,$2=$I40,$3=$I2,$4=VSS,$5=VDD)\n"
" XINV2 $5 ($1=$I2,$2=$I41,$3=$I3,$4=VSS,$5=VDD)\n"
" XINV2 $6 ($1=$I3,$2=$I42,$3=$I4,$4=VSS,$5=VDD)\n"
" XINV2 $7 ($1=$I4,$2=$I43,$3=$I5,$4=VSS,$5=VDD)\n"
" XINV2 $8 ($1=$I5,$2=$I44,$3=$I6,$4=VSS,$5=VDD)\n"
" XINV2 $9 ($1=$I6,$2=$I45,$3=$I7,$4=VSS,$5=VDD)\n"
" XINV2 $10 ($1=$I7,$2=$I46,$3=$I8,$4=VSS,$5=VDD)\n"
"Circuit INV2 ($1=IN,$2=$2,$3=OUT,$4=$4,$5=$5):\n"
" XINV2 $1 (IN=$I8,$2=FB,OUT=OSC,$4=VSS,$5=VDD)\n"
" XINV2 $2 (IN=FB,$2=$I38,OUT=$I19,$4=VSS,$5=VDD)\n"
" XINV2 $3 (IN=$I19,$2=$I39,OUT=$I1,$4=VSS,$5=VDD)\n"
" XINV2 $4 (IN=$I1,$2=$I40,OUT=$I2,$4=VSS,$5=VDD)\n"
" XINV2 $5 (IN=$I2,$2=$I41,OUT=$I3,$4=VSS,$5=VDD)\n"
" XINV2 $6 (IN=$I3,$2=$I42,OUT=$I4,$4=VSS,$5=VDD)\n"
" XINV2 $7 (IN=$I4,$2=$I43,OUT=$I5,$4=VSS,$5=VDD)\n"
" XINV2 $8 (IN=$I5,$2=$I44,OUT=$I6,$4=VSS,$5=VDD)\n"
" XINV2 $9 (IN=$I6,$2=$I45,OUT=$I7,$4=VSS,$5=VDD)\n"
" XINV2 $10 (IN=$I7,$2=$I46,OUT=$I8,$4=VSS,$5=VDD)\n"
"Circuit INV2 (IN=IN,$2=$2,OUT=OUT,$4=$4,$5=$5):\n"
" DPMOS $1 (S=$2,G=IN,D=$5) [L=0.25,W=0.95,AS=0.49875,AD=0.26125]\n"
" DPMOS $2 (S=$5,G=$2,D=OUT) [L=0.25,W=0.95,AS=0.26125,AD=0.49875]\n"
" DNMOS $3 (S=$2,G=IN,D=$4) [L=0.25,W=0.95,AS=0.49875,AD=0.26125]\n"
@ -502,6 +502,33 @@ TEST(1_DeviceAndNetExtraction)
"Circuit TRANS ($1=$1,$2=$2,$3=$3):\n"
);
// doesn't do anything here, but we test that this does not destroy anything:
nl.combine_devices ();
// make pins for named nets of top-level circuits - this way they are not purged
nl.make_top_level_pins ();
nl.purge ();
// compare netlist as string
EXPECT_EQ (netlist2string (nl),
"Circuit RINGO (FB=FB,OSC=OSC,VSS=VSS,VDD=VDD):\n"
" XINV2 $1 (IN=$I8,$2=FB,OUT=OSC,$4=VSS,$5=VDD)\n"
" XINV2 $2 (IN=FB,$2=(null),OUT=$I19,$4=VSS,$5=VDD)\n"
" XINV2 $3 (IN=$I19,$2=(null),OUT=$I1,$4=VSS,$5=VDD)\n"
" XINV2 $4 (IN=$I1,$2=(null),OUT=$I2,$4=VSS,$5=VDD)\n"
" XINV2 $5 (IN=$I2,$2=(null),OUT=$I3,$4=VSS,$5=VDD)\n"
" XINV2 $6 (IN=$I3,$2=(null),OUT=$I4,$4=VSS,$5=VDD)\n"
" XINV2 $7 (IN=$I4,$2=(null),OUT=$I5,$4=VSS,$5=VDD)\n"
" XINV2 $8 (IN=$I5,$2=(null),OUT=$I6,$4=VSS,$5=VDD)\n"
" XINV2 $9 (IN=$I6,$2=(null),OUT=$I7,$4=VSS,$5=VDD)\n"
" XINV2 $10 (IN=$I7,$2=(null),OUT=$I8,$4=VSS,$5=VDD)\n"
"Circuit INV2 (IN=IN,$2=$2,OUT=OUT,$4=$4,$5=$5):\n"
" DPMOS $1 (S=$2,G=IN,D=$5) [L=0.25,W=0.95,AS=0.49875,AD=0.26125]\n"
" DPMOS $2 (S=$5,G=$2,D=OUT) [L=0.25,W=0.95,AS=0.26125,AD=0.49875]\n"
" DNMOS $3 (S=$2,G=IN,D=$4) [L=0.25,W=0.95,AS=0.49875,AD=0.26125]\n"
" DNMOS $4 (S=$4,G=$2,D=OUT) [L=0.25,W=0.95,AS=0.26125,AD=0.49875]\n"
);
// compare the collected test data
std::string au = tl::testsrc ();