mirror of https://github.com/KLayout/klayout.git
WIP: tests pass
This commit is contained in:
parent
49d3edd26a
commit
80fa7e47e2
|
|
@ -294,6 +294,8 @@ double NetlistSpiceReaderDelegate::read_atomic_value (tl::Extractor &ex, const s
|
|||
throw tl::Exception (tl::sprintf (tl::to_string (tr ("Expected number of variable name here: '...%s'")), ex.get ()));
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -840,6 +842,7 @@ struct ParametersLessFunction
|
|||
if (fabs (ia->second - ib->second) > avg * db::epsilon) {
|
||||
return ia->second < ib->second;
|
||||
}
|
||||
++ia, ++ib;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
@ -1003,6 +1006,7 @@ public:
|
|||
const std::string &file_path (int file_id) const;
|
||||
|
||||
const SpiceCachedCircuit *cached_circuit (const std::string &name) const;
|
||||
SpiceCachedCircuit *create_cached_circuit (const std::string &name);
|
||||
|
||||
private:
|
||||
NetlistSpiceReader *mp_reader;
|
||||
|
|
@ -1032,7 +1036,6 @@ private:
|
|||
void error (const std::string &msg);
|
||||
void warn (const std::string &msg);
|
||||
int file_id (const std::string &path);
|
||||
SpiceCachedCircuit *create_cached_circuit (const std::string &name);
|
||||
};
|
||||
|
||||
SpiceCircuitDict::SpiceCircuitDict (NetlistSpiceReader *reader, Netlist *netlist, NetlistSpiceReaderDelegate *delegate)
|
||||
|
|
@ -1323,6 +1326,8 @@ SpiceCircuitDict::ensure_circuit ()
|
|||
|
||||
// TODO: make top name configurable
|
||||
mp_circuit = new SpiceCachedCircuit (".TOP");
|
||||
m_cached_circuits.insert (std::make_pair (mp_circuit->name (), mp_circuit));
|
||||
|
||||
mp_anonymous_top_level_circuit = mp_circuit;
|
||||
|
||||
}
|
||||
|
|
@ -1373,12 +1378,18 @@ public:
|
|||
|
||||
SpiceNetlistBuilder (SpiceCircuitDict *dict, Netlist *netlist, NetlistSpiceReaderDelegate *delegate);
|
||||
|
||||
void set_strict (bool s)
|
||||
{
|
||||
m_strict = s;
|
||||
}
|
||||
|
||||
void build ();
|
||||
|
||||
private:
|
||||
const SpiceCircuitDict *mp_dict;
|
||||
SpiceCircuitDict *mp_dict;
|
||||
tl::weak_ptr<NetlistSpiceReaderDelegate> mp_delegate;
|
||||
Netlist *mp_netlist;
|
||||
bool m_strict;
|
||||
const SpiceCachedCircuit *mp_circuit;
|
||||
std::map<const SpiceCachedCircuit *, std::map<parameters_type, db::Circuit *, ParametersLessFunction> > m_circuits;
|
||||
db::Circuit *mp_netlist_circuit;
|
||||
|
|
@ -1402,7 +1413,7 @@ private:
|
|||
};
|
||||
|
||||
SpiceNetlistBuilder::SpiceNetlistBuilder (SpiceCircuitDict *dict, Netlist *netlist, NetlistSpiceReaderDelegate *delegate)
|
||||
: mp_dict (dict), mp_delegate (delegate), mp_netlist (netlist)
|
||||
: mp_dict (dict), mp_delegate (delegate), mp_netlist (netlist), m_strict (false)
|
||||
{
|
||||
mp_circuit = 0;
|
||||
mp_netlist_circuit = 0;
|
||||
|
|
@ -1499,28 +1510,32 @@ make_circuit_name (const std::string &name, const std::map<std::string, double>
|
|||
}
|
||||
res += p->first;
|
||||
res += "=";
|
||||
if (p->second < 0.5e-12) {
|
||||
res += tl::sprintf ("%.gF", p->second * 1e15);
|
||||
} else if (p->second < 0.5e-9) {
|
||||
res += tl::sprintf ("%.gP", p->second * 1e12);
|
||||
} else if (p->second < 0.5e-6) {
|
||||
res += tl::sprintf ("%.gN", p->second * 1e9);
|
||||
} else if (p->second < 0.5e-3) {
|
||||
res += tl::sprintf ("%.gU", p->second * 1e6);
|
||||
} else if (p->second < 0.5) {
|
||||
res += tl::sprintf ("%.gM", p->second * 1e3);
|
||||
} else if (p->second < 0.5e3) {
|
||||
res += tl::sprintf ("%.g", p->second);
|
||||
} else if (p->second < 0.5e6) {
|
||||
res += tl::sprintf ("%.gK", p->second * 1e-3);
|
||||
} else if (p->second < 0.5e9) {
|
||||
res += tl::sprintf ("%.gMEG", p->second * 1e-6);
|
||||
} else if (p->second < 0.5e12) {
|
||||
res += tl::sprintf ("%.gG", p->second * 1e-9);
|
||||
double va = fabs (p->second);
|
||||
if (va < 1e-15) {
|
||||
res += tl::sprintf ("%g", p->second);
|
||||
} else if (va < 0.1e-12) {
|
||||
res += tl::sprintf ("%gF", p->second * 1e15);
|
||||
} else if (va < 0.1e-9) {
|
||||
res += tl::sprintf ("%gP", p->second * 1e12);
|
||||
} else if (va < 0.1e-6) {
|
||||
res += tl::sprintf ("%gN", p->second * 1e9);
|
||||
} else if (va < 0.1e-3) {
|
||||
res += tl::sprintf ("%gU", p->second * 1e6);
|
||||
} else if (va< 0.1) {
|
||||
res += tl::sprintf ("%gM", p->second * 1e3);
|
||||
} else if (va < 0.1e3) {
|
||||
res += tl::sprintf ("%g", p->second);
|
||||
} else if (va < 0.1e6) {
|
||||
res += tl::sprintf ("%gK", p->second * 1e-3);
|
||||
} else if (va < 0.1e9) {
|
||||
res += tl::sprintf ("%gMEG", p->second * 1e-6);
|
||||
} else if (va < 0.1e12) {
|
||||
res += tl::sprintf ("%gG", p->second * 1e-9);
|
||||
} else {
|
||||
res += tl::sprintf ("%.g", p->second);
|
||||
res += tl::sprintf ("%g", p->second);
|
||||
}
|
||||
}
|
||||
res += ")";
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
@ -1554,7 +1569,8 @@ SpiceNetlistBuilder::build_circuit (const SpiceCachedCircuit *cc, const paramete
|
|||
|
||||
// produce the explicit pins
|
||||
for (auto i = mp_circuit->begin_pins (); i != mp_circuit->end_pins (); ++i) {
|
||||
db::Net *net = make_net (*i);
|
||||
std::string net_name = mp_delegate->translate_net_name (mp_netlist->normalize_name (*i));
|
||||
db::Net *net = make_net (net_name);
|
||||
// use the net name to name the pin (otherwise SPICE pins are always unnamed)
|
||||
size_t pin_id = i - mp_circuit->begin_pins ();
|
||||
if (! i->empty ()) {
|
||||
|
|
@ -1674,7 +1690,15 @@ SpiceNetlistBuilder::process_element (tl::Extractor &ex, const std::string &pref
|
|||
|
||||
const db::SpiceCachedCircuit *cc = mp_dict->cached_circuit (model);
|
||||
if (! cc) {
|
||||
error (tl::sprintf (tl::to_string (tr ("Subcircuit '%s' not found in netlist")), model));
|
||||
if (m_strict) {
|
||||
error (tl::sprintf (tl::to_string (tr ("Subcircuit '%s' not found in netlist")), model));
|
||||
} else {
|
||||
db::SpiceCachedCircuit *cc_nc = mp_dict->create_cached_circuit (model);
|
||||
cc = cc_nc;
|
||||
std::vector<std::string> pins;
|
||||
pins.resize (nn.size ());
|
||||
cc_nc->set_pins (pins);
|
||||
}
|
||||
}
|
||||
|
||||
if (cc->pin_count () != nn.size ()) {
|
||||
|
|
|
|||
|
|
@ -185,15 +185,19 @@ TEST(5_CircuitParameters)
|
|||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit SUBCKT ($1=$1,'A[5]<1>'='A[5]<1>','V42(%)'='V42(%)',Z=Z,GND=GND,GND$1=GND$1);\n"
|
||||
" subcircuit HVPMOS D_$1 ($1='V42(%)',$2=$3,$3=Z,$4=$1);\n"
|
||||
" subcircuit HVPMOS D_$2 ($1='V42(%)',$2='A[5]<1>',$3=$3,$4=$1);\n"
|
||||
" subcircuit HVNMOS D_$3 ($1=GND,$2=$3,$3=GND,$4=GND$1);\n"
|
||||
" subcircuit HVNMOS D_$4 ($1=GND,$2=$3,$3=Z,$4=GND$1);\n"
|
||||
" subcircuit HVNMOS D_$5 ($1=GND,$2='A[5]<1>',$3=$3,$4=GND$1);\n"
|
||||
" subcircuit 'HVPMOS(AD=0.18,AS=0.18,L=0.2,PD=2.16,PS=2.16,W=1)' D_$1 ($1='V42(%)',$2=$3,$3=Z,$4=$1);\n"
|
||||
" subcircuit 'HVPMOS(AD=0.18,AS=0.18,L=0.2,PD=2.16,PS=2.16,W=1)' D_$2 ($1='V42(%)',$2='A[5]<1>',$3=$3,$4=$1);\n"
|
||||
" subcircuit 'HVNMOS(AD=0,AS=0,L=1.13,PD=6,PS=6,W=2.12)' D_$3 ($1=GND,$2=$3,$3=GND,$4=GND$1);\n"
|
||||
" subcircuit 'HVNMOS(AD=0.19,AS=0.19,L=0.4,PD=1.16,PS=1.16,W=0.4)' D_$4 ($1=GND,$2=$3,$3=Z,$4=GND$1);\n"
|
||||
" subcircuit 'HVNMOS(AD=0.19,AS=0.19,L=0.4,PD=1.76,PS=1.76,W=0.4)' D_$5 ($1=GND,$2='A[5]<1>',$3=$3,$4=GND$1);\n"
|
||||
"end;\n"
|
||||
"circuit HVPMOS ($1=(null),$2=(null),$3=(null),$4=(null));\n"
|
||||
"circuit 'HVPMOS(AD=0.18,AS=0.18,L=0.2,PD=2.16,PS=2.16,W=1)' ($1=$0,$2=$0,$3=$0,$4=$0);\n"
|
||||
"end;\n"
|
||||
"circuit HVNMOS ($1=(null),$2=(null),$3=(null),$4=(null));\n"
|
||||
"circuit 'HVNMOS(AD=0,AS=0,L=1.13,PD=6,PS=6,W=2.12)' ($1=$0,$2=$0,$3=$0,$4=$0);\n"
|
||||
"end;\n"
|
||||
"circuit 'HVNMOS(AD=0.19,AS=0.19,L=0.4,PD=1.16,PS=1.16,W=0.4)' ($1=$0,$2=$0,$3=$0,$4=$0);\n"
|
||||
"end;\n"
|
||||
"circuit 'HVNMOS(AD=0.19,AS=0.19,L=0.4,PD=1.76,PS=1.76,W=0.4)' ($1=$0,$2=$0,$3=$0,$4=$0);\n"
|
||||
"end;\n"
|
||||
);
|
||||
}
|
||||
|
|
@ -262,6 +266,9 @@ TEST(6_ReaderWithDelegate)
|
|||
reader.read (is, nl);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit .TOP ();\n"
|
||||
" subcircuit SUBCKT SUBCKT ($1=IN,A=OUT,VDD=VDD,Z=Z,GND=VSS,GND$1=VSS);\n"
|
||||
"end;\n"
|
||||
"circuit SUBCKT ($1=$1,A=A,VDD=VDD,Z=Z,GND=GND,GND$1=GND$1);\n"
|
||||
" device HVPMOS $1 (S=VDD,G=$3,D=Z,B=$1) (L=0.3,W=1.5,AS=0.27,AD=0.27,PS=3.24,PD=3.24);\n"
|
||||
" device HVPMOS $2 (S=VDD,G=A,D=$3,B=$1) (L=0.3,W=1.5,AS=0.27,AD=0.27,PS=3.24,PD=3.24);\n"
|
||||
|
|
@ -270,9 +277,6 @@ TEST(6_ReaderWithDelegate)
|
|||
" device HVNMOS $5 (S=GND,G=A,D=$3,B=GND$1) (L=0.6,W=0.6,AS=0.285,AD=0.285,PS=2.64,PD=2.64);\n"
|
||||
" device RES $1 (A=A,B=Z) (R=100000,L=0,W=0,A=0,P=0);\n"
|
||||
"end;\n"
|
||||
"circuit .TOP ();\n"
|
||||
" subcircuit SUBCKT SUBCKT ($1=IN,A=OUT,VDD=VDD,Z=Z,GND=VSS,GND$1=VSS);\n"
|
||||
"end;\n"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -527,16 +531,16 @@ TEST(13_NoGlobalNetsIfNotUsed)
|
|||
" subcircuit C3 '3' (VDD=VDD,GND=GND);\n"
|
||||
" subcircuit C4 '4' (VDD=VDD,GND=GND);\n"
|
||||
"end;\n"
|
||||
"circuit C1 (VDD=VDD,GND=GND);\n"
|
||||
" subcircuit FILLER_CAP '1' (VDD=VDD,GND=GND);\n"
|
||||
" subcircuit DUMMY '2' ();\n"
|
||||
"end;\n"
|
||||
"circuit FILLER_CAP (VDD=VDD,GND=GND);\n"
|
||||
" device NMOS '1' (S=GND,G=VDD,D=GND,B=GND) (L=10,W=10,AS=0,AD=0,PS=0,PD=0);\n"
|
||||
"end;\n"
|
||||
"circuit DUMMY ();\n"
|
||||
" device NMOS '1' (S=A,G=A,D=A,B=B) (L=1,W=1,AS=0,AD=0,PS=0,PD=0);\n"
|
||||
"end;\n"
|
||||
"circuit C1 (VDD=VDD,GND=GND);\n"
|
||||
" subcircuit FILLER_CAP '1' (VDD=VDD,GND=GND);\n"
|
||||
" subcircuit DUMMY '2' ();\n"
|
||||
"end;\n"
|
||||
"circuit C2 ();\n"
|
||||
" subcircuit DUMMY '1' ();\n"
|
||||
"end;\n"
|
||||
|
|
@ -578,15 +582,19 @@ TEST(15_ContinuationWithBlanks)
|
|||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit SUBCKT ($1=$1,'A[5]<1>'='A[5]<1>','V42(%)'='V42(%)',Z=Z,GND=GND,GND$1=GND$1);\n"
|
||||
" subcircuit HVPMOS D_$1 ($1='V42(%)',$2=$3,$3=Z,$4=$1);\n"
|
||||
" subcircuit HVPMOS D_$2 ($1='V42(%)',$2='A[5]<1>',$3=$3,$4=$1);\n"
|
||||
" subcircuit HVNMOS D_$3 ($1=GND,$2=$3,$3=GND,$4=GND$1);\n"
|
||||
" subcircuit HVNMOS D_$4 ($1=GND,$2=$3,$3=Z,$4=GND$1);\n"
|
||||
" subcircuit HVNMOS D_$5 ($1=GND,$2='A[5]<1>',$3=$3,$4=GND$1);\n"
|
||||
" subcircuit 'HVPMOS(AD=0.18,AS=0.18,L=0.2,PD=2.16,PS=2.16,W=1)' D_$1 ($1='V42(%)',$2=$3,$3=Z,$4=$1);\n"
|
||||
" subcircuit 'HVPMOS(AD=0.18,AS=0.18,L=0.2,PD=2.16,PS=2.16,W=1)' D_$2 ($1='V42(%)',$2='A[5]<1>',$3=$3,$4=$1);\n"
|
||||
" subcircuit 'HVNMOS(AD=0,AS=0,L=1.13,PD=6,PS=6,W=2.12)' D_$3 ($1=GND,$2=$3,$3=GND,$4=GND$1);\n"
|
||||
" subcircuit 'HVNMOS(AD=0.19,AS=0.19,L=0.4,PD=1.16,PS=1.16,W=0.4)' D_$4 ($1=GND,$2=$3,$3=Z,$4=GND$1);\n"
|
||||
" subcircuit 'HVNMOS(AD=0.19,AS=0.19,L=0.4,PD=1.76,PS=1.76,W=0.4)' D_$5 ($1=GND,$2='A[5]<1>',$3=$3,$4=GND$1);\n"
|
||||
"end;\n"
|
||||
"circuit HVPMOS ($1=(null),$2=(null),$3=(null),$4=(null));\n"
|
||||
"circuit 'HVPMOS(AD=0.18,AS=0.18,L=0.2,PD=2.16,PS=2.16,W=1)' ($1=$0,$2=$0,$3=$0,$4=$0);\n"
|
||||
"end;\n"
|
||||
"circuit HVNMOS ($1=(null),$2=(null),$3=(null),$4=(null));\n"
|
||||
"circuit 'HVNMOS(AD=0,AS=0,L=1.13,PD=6,PS=6,W=2.12)' ($1=$0,$2=$0,$3=$0,$4=$0);\n"
|
||||
"end;\n"
|
||||
"circuit 'HVNMOS(AD=0.19,AS=0.19,L=0.4,PD=1.16,PS=1.16,W=0.4)' ($1=$0,$2=$0,$3=$0,$4=$0);\n"
|
||||
"end;\n"
|
||||
"circuit 'HVNMOS(AD=0.19,AS=0.19,L=0.4,PD=1.76,PS=1.76,W=0.4)' ($1=$0,$2=$0,$3=$0,$4=$0);\n"
|
||||
"end;\n"
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue