mirror of https://github.com/KLayout/klayout.git
WIP: doc fixes, added Netlist::simplify as convenience method
This commit is contained in:
parent
621c3f74ed
commit
a1a0b62a10
|
|
@ -483,6 +483,14 @@ void Netlist::combine_devices ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Netlist::simplify ()
|
||||||
|
{
|
||||||
|
make_top_level_pins ();
|
||||||
|
purge ();
|
||||||
|
combine_devices ();
|
||||||
|
purge_nets ();
|
||||||
|
}
|
||||||
|
|
||||||
static std::string net2string (const db::Net *net)
|
static std::string net2string (const db::Net *net)
|
||||||
{
|
{
|
||||||
return net ? tl::to_word_or_quoted_string (net->expanded_name ()) : "(null)";
|
return net ? tl::to_word_or_quoted_string (net->expanded_name ()) : "(null)";
|
||||||
|
|
|
||||||
|
|
@ -452,6 +452,11 @@ public:
|
||||||
*/
|
*/
|
||||||
void purge ();
|
void purge ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Convenience method: simplify (purge, combine devices, ...)
|
||||||
|
*/
|
||||||
|
void simplify ();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Combine devices
|
* @brief Combine devices
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -1397,6 +1397,10 @@ Class<db::Netlist> decl_dbNetlist ("db", "Netlist",
|
||||||
"Floating nets can be created as effect of reconnections of devices or pins. "
|
"Floating nets can be created as effect of reconnections of devices or pins. "
|
||||||
"This method will eliminate all nets that make less than two connections."
|
"This method will eliminate all nets that make less than two connections."
|
||||||
) +
|
) +
|
||||||
|
gsi::method ("simplify", &db::Netlist::simplify,
|
||||||
|
"@brief Convience method that combines the simplification.\n"
|
||||||
|
"This method is a convenience method that runs \\make_top_level_pins, \\purge, \\combine_devices and \\purge_nets."
|
||||||
|
) +
|
||||||
gsi::method_ext ("read", &read_netlist, gsi::arg ("file"), gsi::arg ("reader"),
|
gsi::method_ext ("read", &read_netlist, gsi::arg ("file"), gsi::arg ("reader"),
|
||||||
"@brief Writes the netlist to the given file using the given reader object to parse the file\n"
|
"@brief Writes the netlist to the given file using the given reader object to parse the file\n"
|
||||||
"See \\NetlistSpiceReader for an example for a parser. "
|
"See \\NetlistSpiceReader for an example for a parser. "
|
||||||
|
|
@ -1873,7 +1877,7 @@ Class<db::NetlistSpiceReader> db_NetlistSpiceReader (db_NetlistReader, "db", "Ne
|
||||||
gsi::constructor ("new", &new_spice_reader,
|
gsi::constructor ("new", &new_spice_reader,
|
||||||
"@brief Creates a new reader.\n"
|
"@brief Creates a new reader.\n"
|
||||||
) +
|
) +
|
||||||
gsi::constructor ("new", &new_spice_reader2,
|
gsi::constructor ("new", &new_spice_reader2, gsi::arg ("delegate"),
|
||||||
"@brief Creates a new reader with a delegate.\n"
|
"@brief Creates a new reader with a delegate.\n"
|
||||||
),
|
),
|
||||||
"@brief Implements a netlist Reader for the SPICE format.\n"
|
"@brief Implements a netlist Reader for the SPICE format.\n"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,143 @@
|
||||||
|
# encoding: UTF-8
|
||||||
|
|
||||||
|
# KLayout Layout Viewer
|
||||||
|
# Copyright (C) 2006-2019 Matthias Koefferlein
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
if !$:.member?(File::dirname($0))
|
||||||
|
$:.push(File::dirname($0))
|
||||||
|
end
|
||||||
|
|
||||||
|
load("test_prologue.rb")
|
||||||
|
|
||||||
|
# For analysis
|
||||||
|
module RBA
|
||||||
|
class Netlist
|
||||||
|
attr_accessor :description
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class MyDelegate < RBA::NetlistSpiceReaderDelegate
|
||||||
|
|
||||||
|
def start(netlist)
|
||||||
|
netlist.description = "Read by MyDelegate"
|
||||||
|
end
|
||||||
|
|
||||||
|
def finish(netlist)
|
||||||
|
netlist.description = "Read by MyDelegate (sucessfully)"
|
||||||
|
end
|
||||||
|
|
||||||
|
def wants_subcircuit(name)
|
||||||
|
name == "HVNMOS" || name == "HVPMOS"
|
||||||
|
end
|
||||||
|
|
||||||
|
def element(circuit, el, name, model, value, nets, params)
|
||||||
|
|
||||||
|
if el != "X"
|
||||||
|
return super
|
||||||
|
end
|
||||||
|
|
||||||
|
if nets.size != 4
|
||||||
|
error("Subcircuit #{model} needs four nodes")
|
||||||
|
end
|
||||||
|
|
||||||
|
cls = circuit.netlist.device_class_by_name(model)
|
||||||
|
if ! cls
|
||||||
|
cls = RBA::DeviceClassMOS4Transistor::new
|
||||||
|
cls.name = model
|
||||||
|
circuit.netlist.add(cls)
|
||||||
|
end
|
||||||
|
|
||||||
|
device = circuit.create_device(cls, name)
|
||||||
|
|
||||||
|
[ "S", "G", "D", "B" ].each_with_index do |t,index|
|
||||||
|
device.connect_terminal(t, nets[index])
|
||||||
|
end
|
||||||
|
params.each do |p,value|
|
||||||
|
device.set_parameter(p, value * 1.5)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
class DBNetlistReaderTests_TestClass < TestBase
|
||||||
|
|
||||||
|
def test_1_Basic
|
||||||
|
|
||||||
|
nl = RBA::Netlist::new
|
||||||
|
|
||||||
|
input = File.join($ut_testsrc, "testdata", "algo", "nreader6.cir")
|
||||||
|
|
||||||
|
mydelegate = MyDelegate::new
|
||||||
|
reader = RBA::NetlistSpiceReader::new(mydelegate)
|
||||||
|
# the delegate is kept by the SPICE writer ..
|
||||||
|
mydelegate = nil
|
||||||
|
GC.start
|
||||||
|
nl.read(input, reader)
|
||||||
|
|
||||||
|
assert_equal(nl.description, "Read by MyDelegate (sucessfully)")
|
||||||
|
|
||||||
|
assert_equal(nl.to_s, <<"END")
|
||||||
|
circuit SUBCKT ($1=$1,$2=A,$3=VDD,$4=Z,$5=gnd,$6=gnd$1);
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
device HVNMOS $3 (S=gnd,G=$3,D=gnd,B=gnd$1) (L=1.695,W=3.18,AS=0,AD=0,PS=9,PD=9);
|
||||||
|
device HVNMOS $4 (S=gnd,G=$3,D=Z,B=gnd$1) (L=0.6,W=0.6,AS=0.285,AD=0.285,PS=1.74,PD=1.74);
|
||||||
|
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);
|
||||||
|
device RES $1 (A=A,B=Z) (R=100000,L=0,W=0,A=0,P=0);
|
||||||
|
end;
|
||||||
|
circuit .TOP ();
|
||||||
|
subcircuit SUBCKT SUBCKT ($1=(null),$2=(null),$3=(null),$4=(null),$5=VSS,$6=VSS);
|
||||||
|
end;
|
||||||
|
END
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_2_WithError
|
||||||
|
|
||||||
|
nl = RBA::Netlist::new
|
||||||
|
|
||||||
|
input = File.join($ut_testsrc, "testdata", "algo", "nreader6.cir")
|
||||||
|
|
||||||
|
mydelegate = MyDelegate::new
|
||||||
|
|
||||||
|
def mydelegate.element(circuit, el, name, model, value, nets, params)
|
||||||
|
self.error("Nothing implemented")
|
||||||
|
end
|
||||||
|
|
||||||
|
reader = RBA::NetlistSpiceReader::new(mydelegate)
|
||||||
|
# the delegate is kept by the SPICE writer ..
|
||||||
|
mydelegate = nil
|
||||||
|
GC.start
|
||||||
|
|
||||||
|
msg = "no error happened!"
|
||||||
|
begin
|
||||||
|
nl.read(input, reader)
|
||||||
|
rescue Exception => ex
|
||||||
|
msg = ex.message
|
||||||
|
end
|
||||||
|
assert_equal(msg.sub(input, "<INPUT>"), "Nothing implemented in <INPUT>, line 22 in Netlist::read")
|
||||||
|
|
||||||
|
assert_equal(nl.description, "Read by MyDelegate")
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
load("test_epilogue.rb")
|
||||||
|
|
||||||
|
|
||||||
Loading…
Reference in New Issue