mirror of https://github.com/KLayout/klayout.git
Merge branch 'master' of https://github.com/KLayout/klayout
This commit is contained in:
commit
915a27e67e
|
|
@ -344,6 +344,10 @@ void Circuit::remove_net (Net *net)
|
|||
|
||||
void Circuit::join_nets (Net *net, Net *with)
|
||||
{
|
||||
if (net == with || ! with) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (with->begin_terminals () != with->end_terminals ()) {
|
||||
db::Device *device = const_cast<db::Device *> (with->begin_terminals ()->device ());
|
||||
device->connect_terminal (with->begin_terminals ()->terminal_id (), net);
|
||||
|
|
@ -426,15 +430,21 @@ void Circuit::flatten_subcircuit (SubCircuit *subcircuit)
|
|||
|
||||
for (db::Circuit::const_net_iterator n = c->begin_nets (); n != c->end_nets (); ++n) {
|
||||
|
||||
// TODO: cannot join pins through subcircuits currently
|
||||
tl_assert (n->pin_count () <= 1);
|
||||
|
||||
db::Net *outside_net = 0;
|
||||
|
||||
if (n->pin_count () > 0) {
|
||||
|
||||
size_t pin_id = n->begin_pins ()->pin_id ();
|
||||
outside_net = subcircuit->net_for_pin (pin_id);
|
||||
for (db::Net::const_pin_iterator p = n->begin_pins (); p != n->end_pins (); ++p) {
|
||||
|
||||
size_t pin_id = p->pin_id ();
|
||||
|
||||
if (outside_net) {
|
||||
join_nets (outside_net, subcircuit->net_for_pin (pin_id));
|
||||
} else {
|
||||
outside_net = subcircuit->net_for_pin (pin_id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
|
|
|
|||
|
|
@ -419,7 +419,10 @@ bool NetlistSpiceReader::read_card ()
|
|||
|
||||
while (! ex.at_end ()) {
|
||||
std::string n = read_name (ex);
|
||||
m_global_nets.push_back (n);
|
||||
if (m_global_net_names.find (n) == m_global_net_names.end ()) {
|
||||
m_global_nets.push_back (n);
|
||||
m_global_net_names.insert (n);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (ex.test_without_case ("subckt")) {
|
||||
|
|
|
|||
|
|
@ -131,6 +131,7 @@ private:
|
|||
std::string m_stored_line;
|
||||
std::map<std::string, bool> m_captured;
|
||||
std::vector<std::string> m_global_nets;
|
||||
std::set<std::string> m_global_net_names;
|
||||
std::set<const db::Circuit *> m_circuits_read;
|
||||
|
||||
void push_stream (const std::string &path);
|
||||
|
|
|
|||
|
|
@ -422,3 +422,24 @@ TEST(11_ErrorOnCircuitRedefinition)
|
|||
EXPECT_EQ (tl::replaced (msg, path, "?"), "Redefinition of circuit SUBCKT in ?, line 20");
|
||||
}
|
||||
|
||||
TEST(12_IgnoreDuplicateGlobals)
|
||||
{
|
||||
db::Netlist nl;
|
||||
|
||||
std::string path = tl::combine_path (tl::combine_path (tl::combine_path (tl::testsrc (), "testdata"), "algo"), "nreader12.cir");
|
||||
|
||||
db::NetlistSpiceReader reader;
|
||||
tl::InputStream is (path);
|
||||
reader.read (is, nl);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit .TOP ();\n"
|
||||
" device RES $1 (A=VDD,B=GND) (R=1000,L=0,W=0,A=0,P=0);\n"
|
||||
" subcircuit FILLER_CAP '0' (VDD=VDD,GND=GND);\n"
|
||||
"end;\n"
|
||||
"circuit FILLER_CAP (VDD=VDD,GND=GND);\n"
|
||||
" device NMOS '0' (S=GND,G=VDD,D=GND,B=GND) (L=10,W=10,AS=0,AD=0,PS=0,PD=0);\n"
|
||||
"end;\n"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1337,9 +1337,97 @@ TEST(21_FlattenSubCircuit2)
|
|||
" device NMOS $1 (S=$1,G=$3,D=$2) (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0);\n"
|
||||
"end;\n"
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
TEST(22_BlankCircuit)
|
||||
TEST(22_FlattenSubCircuitPinsJoinNets)
|
||||
{
|
||||
db::Netlist nl;
|
||||
|
||||
db::DeviceClass *dc;
|
||||
|
||||
dc = new db::DeviceClassMOS3Transistor ();
|
||||
dc->set_name ("NMOS");
|
||||
nl.add_device_class (dc);
|
||||
|
||||
dc = new db::DeviceClassMOS3Transistor ();
|
||||
dc->set_name ("PMOS");
|
||||
nl.add_device_class (dc);
|
||||
|
||||
nl.from_string (
|
||||
"circuit RINGO (IN=IN,OSC=OSC,VSS=VSS,VDD=VDD);\n"
|
||||
" subcircuit INV2 INV2_SC1 (IN=$I8,$2=FB,OUT=OSC,$4=VSS,$5=VDD);\n"
|
||||
" subcircuit INV2 INV2_SC2 (IN=FB,$2=(null),OUT=$I8,$4=VSS,$5=VDD);\n"
|
||||
"end;\n"
|
||||
"circuit INV2 (IN=IN,$2=$2,OUT=OUT,$4=$4,$5=$5);\n"
|
||||
" subcircuit PTRANS SC1 ($1=$5,$2=$2,$3=IN);\n"
|
||||
" subcircuit NTRANS SC2 ($1=$4,$2=$2,$3=IN);\n"
|
||||
" subcircuit PTRANS SC3 ($1=$5,$2=OUT,$3=$2);\n"
|
||||
" subcircuit NTRANS SC4 ($1=$4,$2=OUT,$3=$2);\n"
|
||||
"end;\n"
|
||||
"circuit PTRANS ($1=$1,$2=$2,$3=$1);\n"
|
||||
" device PMOS $1 (S=$1,D=$2,G=$1) (L=0.25,W=0.95);\n"
|
||||
"end;\n"
|
||||
"circuit NTRANS ($1=$1,$2=$2,$3=$2);\n"
|
||||
" device NMOS $1 (S=$1,D=$2,G=$2) (L=0.25,W=0.95);\n"
|
||||
"end;\n"
|
||||
);
|
||||
|
||||
db::Netlist nl2;
|
||||
|
||||
nl2 = nl;
|
||||
nl2.flatten_circuit (nl2.circuit_by_name ("PTRANS"));
|
||||
|
||||
EXPECT_EQ (nl2.to_string (),
|
||||
"circuit RINGO (IN=IN,OSC=OSC,VSS=VSS,VDD=VDD);\n"
|
||||
" subcircuit INV2 INV2_SC1 (IN=$I8,$2=FB,OUT=OSC,$4=VSS,$5=VDD);\n"
|
||||
" subcircuit INV2 INV2_SC2 (IN=FB,$2=(null),OUT=$I8,$4=VSS,$5=VDD);\n"
|
||||
"end;\n"
|
||||
"circuit INV2 (IN=$5,$2=$5,OUT=OUT,$4=$4,$5=$5);\n"
|
||||
" device PMOS $1 (S=$5,G=$5,D=$5) (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0);\n"
|
||||
" device PMOS $2 (S=$5,G=$5,D=OUT) (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0);\n"
|
||||
" subcircuit NTRANS SC2 ($1=$4,$2=$5,$3=$5);\n"
|
||||
" subcircuit NTRANS SC4 ($1=$4,$2=OUT,$3=$5);\n"
|
||||
"end;\n"
|
||||
"circuit NTRANS ($1=$1,$2=$2,$3=$2);\n"
|
||||
" device NMOS $1 (S=$1,G=$2,D=$2) (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0);\n"
|
||||
"end;\n"
|
||||
);
|
||||
|
||||
nl2.flatten_circuit (nl2.circuit_by_name ("NTRANS"));
|
||||
|
||||
EXPECT_EQ (nl2.to_string (),
|
||||
"circuit RINGO (IN=IN,OSC=OSC,VSS=VSS,VDD=VDD);\n"
|
||||
" subcircuit INV2 INV2_SC1 (IN=$I8,$2=FB,OUT=OSC,$4=VSS,$5=VDD);\n"
|
||||
" subcircuit INV2 INV2_SC2 (IN=FB,$2=(null),OUT=$I8,$4=VSS,$5=VDD);\n"
|
||||
"end;\n"
|
||||
"circuit INV2 (IN=OUT,$2=OUT,OUT=OUT,$4=$4,$5=OUT);\n"
|
||||
" device PMOS $1 (S=OUT,G=OUT,D=OUT) (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0);\n"
|
||||
" device PMOS $2 (S=OUT,G=OUT,D=OUT) (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0);\n"
|
||||
" device NMOS $3 (S=$4,G=OUT,D=OUT) (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0);\n"
|
||||
" device NMOS $4 (S=$4,G=OUT,D=OUT) (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0);\n"
|
||||
"end;\n"
|
||||
);
|
||||
|
||||
nl2.flatten_circuit (nl2.circuit_by_name ("INV2"));
|
||||
|
||||
EXPECT_EQ (nl2.to_string (),
|
||||
"circuit RINGO (IN=IN,OSC=OSC,VSS=VSS,VDD=OSC);\n"
|
||||
" device PMOS $1 (S=OSC,G=OSC,D=OSC) (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0);\n"
|
||||
" device PMOS $2 (S=OSC,G=OSC,D=OSC) (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0);\n"
|
||||
" device NMOS $3 (S=VSS,G=OSC,D=OSC) (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0);\n"
|
||||
" device NMOS $4 (S=VSS,G=OSC,D=OSC) (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0);\n"
|
||||
" device PMOS $5 (S=OSC,G=OSC,D=OSC) (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0);\n"
|
||||
" device PMOS $6 (S=OSC,G=OSC,D=OSC) (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0);\n"
|
||||
" device NMOS $7 (S=VSS,G=OSC,D=OSC) (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0);\n"
|
||||
" device NMOS $8 (S=VSS,G=OSC,D=OSC) (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0);\n"
|
||||
"end;\n"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
TEST(23_BlankCircuit)
|
||||
{
|
||||
db::Netlist nl;
|
||||
|
||||
|
|
@ -1439,7 +1527,7 @@ TEST(22_BlankCircuit)
|
|||
);
|
||||
}
|
||||
|
||||
TEST(23_NetlistObject)
|
||||
TEST(24_NetlistObject)
|
||||
{
|
||||
db::NetlistObject nlo;
|
||||
nlo.set_property (1, "hello");
|
||||
|
|
@ -1526,7 +1614,7 @@ TEST(23_NetlistObject)
|
|||
EXPECT_EQ (pin3.property (1).to_string (), "hello");
|
||||
}
|
||||
|
||||
TEST(24_JoinNets)
|
||||
TEST(25_JoinNets)
|
||||
{
|
||||
db::Netlist nl;
|
||||
db::Circuit *c;
|
||||
|
|
@ -1575,7 +1663,7 @@ TEST(24_JoinNets)
|
|||
);
|
||||
}
|
||||
|
||||
TEST(25_JoinNets)
|
||||
TEST(26_JoinNets)
|
||||
{
|
||||
db::Netlist nl;
|
||||
db::Circuit *c;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
.global vdd gnd
|
||||
|
||||
X0 FILLER_CAP
|
||||
R$1 vdd gnd 1k
|
||||
|
||||
* should be ignored:
|
||||
.global vdd
|
||||
.global gnd
|
||||
|
||||
.subckt FILLER_CAP
|
||||
M0 gnd vdd gnd gnd NMOS W=10u L=10u
|
||||
.ends FILLER_CAP
|
||||
|
||||
Loading…
Reference in New Issue