mirror of https://github.com/KLayout/klayout.git
Small enhancements for Spice reader
- Detects recursive subcircuit calls now - Dismisses empty top level circuit which happened to be created when there were not top level elements and control statements were present (such as .param)
This commit is contained in:
parent
e8ecaa6472
commit
cba126e9ee
|
|
@ -644,6 +644,11 @@ void Circuit::set_pin_ref_for_pin (size_t pin_id, Net::pin_iterator iter)
|
|||
m_pin_refs [pin_id] = iter;
|
||||
}
|
||||
|
||||
bool Circuit::is_empty () const
|
||||
{
|
||||
return m_nets.empty () && m_pins.empty () && m_devices.empty () && m_subcircuits.empty ();
|
||||
}
|
||||
|
||||
void Circuit::blank ()
|
||||
{
|
||||
tl_assert (netlist () != 0);
|
||||
|
|
|
|||
|
|
@ -759,6 +759,11 @@ public:
|
|||
*/
|
||||
void blank ();
|
||||
|
||||
/**
|
||||
* @brief Gets a value indicating whether the circuit is empty
|
||||
*/
|
||||
bool is_empty () const;
|
||||
|
||||
/**
|
||||
* @brief Generate memory statistics
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -943,6 +943,12 @@ SpiceNetlistBuilder::circuit_for (const SpiceCachedCircuit *cc, const parameters
|
|||
if (cp == c->second.end ()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// a null pointer indicates that we are currently defining this circuit
|
||||
if (cp->second == 0) {
|
||||
error (tl::sprintf (tl::to_string (tr ("Subcircuit '%s' called recursively")), cc->name ()));
|
||||
}
|
||||
|
||||
return cp->second;
|
||||
}
|
||||
|
||||
|
|
@ -1055,7 +1061,8 @@ SpiceNetlistBuilder::build_circuit (const SpiceCachedCircuit *cc, const paramete
|
|||
c->set_name (make_circuit_name (cc->name (), pv));
|
||||
}
|
||||
|
||||
register_circuit_for (cc, pv, c, anonymous_top_level);
|
||||
// pre-register the circuit - allows detecting recursive calls
|
||||
register_circuit_for (cc, pv, 0, false);
|
||||
|
||||
std::unique_ptr<std::map<std::string, db::Net *> > n2n (mp_nets_by_name.release ());
|
||||
mp_nets_by_name.reset (0);
|
||||
|
|
@ -1095,6 +1102,14 @@ SpiceNetlistBuilder::build_circuit (const SpiceCachedCircuit *cc, const paramete
|
|||
std::swap (c, mp_netlist_circuit);
|
||||
std::swap (vars, m_variables);
|
||||
|
||||
// final registration if required
|
||||
if (! anonymous_top_level || ! c->is_empty ()) {
|
||||
register_circuit_for (cc, pv, c, anonymous_top_level);
|
||||
} else {
|
||||
mp_netlist->remove_circuit (c);
|
||||
c = 0;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -880,6 +880,40 @@ TEST(23_endl)
|
|||
);
|
||||
}
|
||||
|
||||
TEST(24_recursive_calls)
|
||||
{
|
||||
db::Netlist nl;
|
||||
|
||||
std::string path = tl::combine_path (tl::combine_path (tl::testdata (), "algo"), "nreader24.cir");
|
||||
|
||||
db::NetlistSpiceReader reader;
|
||||
tl::InputStream is (path);
|
||||
|
||||
try {
|
||||
reader.read (is, nl);
|
||||
EXPECT_EQ (false, true);
|
||||
} catch (tl::Exception &ex) {
|
||||
EXPECT_EQ (ex.msg (), "Subcircuit 'C1' called recursively in /home/matthias/klayout/master/testdata/algo/nreader24.cir, line 8");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(25_dismiss_top_level)
|
||||
{
|
||||
db::Netlist nl;
|
||||
|
||||
std::string path = tl::combine_path (tl::combine_path (tl::testdata (), "algo"), "nreader25.cir");
|
||||
|
||||
db::NetlistSpiceReader reader;
|
||||
tl::InputStream is (path);
|
||||
reader.read (is, nl);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit TOP (A=A,B=B);\n"
|
||||
" device NMOS '1' (S=A,G=B,D=A,B=B) (L=100,W=100,AS=0,AD=0,PS=0,PD=0);\n"
|
||||
"end;\n"
|
||||
);
|
||||
}
|
||||
|
||||
TEST(100_ExpressionParser)
|
||||
{
|
||||
std::map<std::string, tl::Variant> vars;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
* Testing recursive call detection
|
||||
|
||||
.subckt c1 a b
|
||||
x1 a b c2
|
||||
.end
|
||||
|
||||
.subckt c2 a b
|
||||
x1 a b c1
|
||||
.ends
|
||||
|
||||
xtop vdd vss c2
|
||||
|
||||
.end
|
||||
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
* Test: dismiss empty top level circuit
|
||||
|
||||
.subckt top a b
|
||||
m1 a b a b nmos
|
||||
.ends
|
||||
|
||||
* this triggered generation of a top level circuit
|
||||
.param p1 17
|
||||
|
||||
.end
|
||||
|
||||
Loading…
Reference in New Issue