mirror of https://github.com/KLayout/klayout.git
Supporting remote must-connect connections
So far, must-connect connections had to be made one level up in the hierarchy or promoted further using labels and such. Now, must-connect connections can be made at any point up in the hierarchy.
This commit is contained in:
parent
856fe4a8d3
commit
45950f20d6
|
|
@ -473,69 +473,114 @@ void LayoutToNetlist::check_must_connect (const db::Circuit &c, const db::Net &a
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c.begin_refs () != c.end_refs ()) {
|
std::vector<const db::SubCircuit *> path;
|
||||||
|
check_must_connect_impl (c, a, b, c, a, b, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string path_msg (const std::vector<const db::SubCircuit *> &path, const db::Circuit &c_org)
|
||||||
|
{
|
||||||
|
if (path.empty ()) {
|
||||||
|
return std::string ();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string msg (".\n" + tl::to_string (tr ("Instance path: ")));
|
||||||
|
|
||||||
|
for (auto p = path.rbegin (); p != path.rend (); ++p) {
|
||||||
|
if (p != path.rbegin ()) {
|
||||||
|
msg += "/";
|
||||||
|
}
|
||||||
|
msg += (*p)->circuit ()->name () + ":" + (*p)->expanded_name () + "[" + (*p)->trans ().to_string () + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
msg += "/";
|
||||||
|
msg += c_org.name ();
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayoutToNetlist::check_must_connect_impl (const db::Circuit &c, const db::Net &a, const db::Net &b, const db::Circuit &c_org, const db::Net &a_org, const db::Net &b_org, std::vector<const db::SubCircuit *> &path)
|
||||||
|
{
|
||||||
|
if (c.begin_refs () != c.end_refs () && path.empty ()) {
|
||||||
|
|
||||||
if (a.begin_pins () == a.end_pins ()) {
|
if (a.begin_pins () == a.end_pins ()) {
|
||||||
db::LogEntryData error (db::Error, tl::sprintf (tl::to_string (tr ("Must-connect net %s is not connected to outside")), a.expanded_name ()));
|
db::LogEntryData error (db::Error, tl::sprintf (tl::to_string (tr ("Must-connect net %s is not connected to outside")), a_org.expanded_name ()));
|
||||||
error.set_cell_name (c.name ());
|
error.set_cell_name (c.name ());
|
||||||
error.set_category_name ("must-connect");
|
error.set_category_name ("must-connect");
|
||||||
log_entry (error);
|
log_entry (error);
|
||||||
}
|
}
|
||||||
if (b.begin_pins () == b.end_pins ()) {
|
if (b.begin_pins () == b.end_pins ()) {
|
||||||
db::LogEntryData error (db::Error, tl::sprintf (tl::to_string (tr ("Must-connect net %s is not connected to outside")), a.expanded_name ()));
|
db::LogEntryData error (db::Error, tl::sprintf (tl::to_string (tr ("Must-connect net %s is not connected to outside")), a_org.expanded_name ()));
|
||||||
error.set_cell_name (c.name ());
|
error.set_cell_name (c.name ());
|
||||||
error.set_category_name ("must-connect");
|
error.set_category_name ("must-connect");
|
||||||
log_entry (error);
|
log_entry (error);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (a.expanded_name () == b.expanded_name ()) {
|
} else if (c.begin_refs () == c.end_refs () || a.begin_pins () == a.end_pins () || b.begin_pins () == b.end_pins ()) {
|
||||||
db::LogEntryData warn (m_top_level_mode ? db::Error : db::Warning, tl::sprintf (tl::to_string (tr ("Must-connect nets %s must be connected further up in the hierarchy - this is an error at chip top level")), a.expanded_name ()));
|
|
||||||
warn.set_cell_name (c.name ());
|
if (a_org.expanded_name () == b_org.expanded_name ()) {
|
||||||
warn.set_category_name ("must-connect");
|
if (path.empty ()) {
|
||||||
log_entry (warn);
|
db::LogEntryData warn (m_top_level_mode ? db::Error : db::Warning, tl::sprintf (tl::to_string (tr ("Must-connect nets %s must be connected further up in the hierarchy - this is an error at chip top level")), a_org.expanded_name ()) + path_msg (path, c_org));
|
||||||
|
warn.set_cell_name (c.name ());
|
||||||
|
warn.set_category_name ("must-connect");
|
||||||
|
log_entry (warn);
|
||||||
|
} else {
|
||||||
|
db::LogEntryData warn (m_top_level_mode ? db::Error : db::Warning, tl::sprintf (tl::to_string (tr ("Must-connect nets %s of circuit %s must be connected further up in the hierarchy - this is an error at chip top level")), a_org.expanded_name (), c_org.name ()) + path_msg (path, c_org));
|
||||||
|
warn.set_cell_name (c.name ());
|
||||||
|
warn.set_geometry (subcircuit_geometry (*path.back (), internal_layout ()));
|
||||||
|
warn.set_category_name ("must-connect");
|
||||||
|
log_entry (warn);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
db::LogEntryData warn (m_top_level_mode ? db::Error : db::Warning, tl::sprintf (tl::to_string (tr ("Must-connect nets %s and %s must be connected further up in the hierarchy - this is an error at chip top level")), a.expanded_name (), b.expanded_name ()));
|
if (path.empty ()) {
|
||||||
warn.set_cell_name (c.name ());
|
db::LogEntryData warn (m_top_level_mode ? db::Error : db::Warning, tl::sprintf (tl::to_string (tr ("Must-connect nets %s and %s must be connected further up in the hierarchy - this is an error at chip top level")), a_org.expanded_name (), b_org.expanded_name ()) + path_msg (path, c_org));
|
||||||
warn.set_category_name ("must-connect");
|
warn.set_cell_name (c.name ());
|
||||||
log_entry (warn);
|
warn.set_category_name ("must-connect");
|
||||||
|
log_entry (warn);
|
||||||
|
} else {
|
||||||
|
db::LogEntryData warn (m_top_level_mode ? db::Error : db::Warning, tl::sprintf (tl::to_string (tr ("Must-connect nets %s and %s of circuit %s must be connected further up in the hierarchy - this is an error at chip top level")), a_org.expanded_name (), b_org.expanded_name (), c_org.name ()) + path_msg (path, c_org));
|
||||||
|
warn.set_cell_name (c.name ());
|
||||||
|
warn.set_geometry (subcircuit_geometry (*path.back (), internal_layout ()));
|
||||||
|
warn.set_category_name ("must-connect");
|
||||||
|
log_entry (warn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a.begin_pins () != a.end_pins () && b.begin_pins () != b.end_pins ()) {
|
if (a.begin_pins () != a.end_pins () && b.begin_pins () != b.end_pins ()) {
|
||||||
|
|
||||||
for (auto ref = c.begin_refs (); ref != c.end_refs (); ++ref) {
|
for (auto ref = c.begin_refs (); ref != c.end_refs (); ++ref) {
|
||||||
|
|
||||||
const db::SubCircuit &sc = *ref;
|
const db::SubCircuit &sc = *ref;
|
||||||
|
|
||||||
// TODO: consider the case of multiple pins on a net (rare)
|
// TODO: consider the case of multiple pins on a net (rare)
|
||||||
const db::Net *net_a = sc.net_for_pin (a.begin_pins ()->pin_id ());
|
const db::Net *net_a = sc.net_for_pin (a.begin_pins ()->pin_id ());
|
||||||
const db::Net *net_b = sc.net_for_pin (b.begin_pins ()->pin_id ());
|
const db::Net *net_b = sc.net_for_pin (b.begin_pins ()->pin_id ());
|
||||||
|
|
||||||
if (net_a == 0) {
|
if (net_a == 0) {
|
||||||
db::LogEntryData error (db::Error, tl::sprintf (tl::to_string (tr ("Must-connect net %s of circuit %s is not connected at all%s")), a.expanded_name (), c.name (), subcircuit_to_string (sc)));
|
db::LogEntryData error (db::Error, tl::sprintf (tl::to_string (tr ("Must-connect net %s of circuit %s is not connected at all%s")), a_org.expanded_name (), c_org.name (), subcircuit_to_string (sc)) + path_msg (path, c_org));
|
||||||
error.set_cell_name (sc.circuit ()->name ());
|
error.set_cell_name (sc.circuit ()->name ());
|
||||||
error.set_geometry (subcircuit_geometry (sc, internal_layout ()));
|
error.set_geometry (subcircuit_geometry (sc, internal_layout ()));
|
||||||
error.set_category_name ("must-connect");
|
error.set_category_name ("must-connect");
|
||||||
log_entry (error);
|
log_entry (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (net_b == 0) {
|
if (net_b == 0) {
|
||||||
db::LogEntryData error (db::Error, tl::sprintf (tl::to_string (tr ("Must-connect net %s of circuit %s is not connected at all%s")), b.expanded_name (), c.name (), subcircuit_to_string (sc)));
|
db::LogEntryData error (db::Error, tl::sprintf (tl::to_string (tr ("Must-connect net %s of circuit %s is not connected at all%s")), b_org.expanded_name (), c_org.name (), subcircuit_to_string (sc)) + path_msg (path, c_org));
|
||||||
error.set_cell_name (sc.circuit ()->name ());
|
error.set_cell_name (sc.circuit ()->name ());
|
||||||
error.set_geometry (subcircuit_geometry (sc, internal_layout ()));
|
error.set_geometry (subcircuit_geometry (sc, internal_layout ()));
|
||||||
error.set_category_name ("must-connect");
|
error.set_category_name ("must-connect");
|
||||||
log_entry (error);
|
log_entry (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (net_a && net_b && net_a != net_b) {
|
if (net_a && net_b && net_a != net_b) {
|
||||||
if (a.expanded_name () == b.expanded_name ()) {
|
path.push_back (&sc);
|
||||||
db::LogEntryData error (db::Error, tl::sprintf (tl::to_string (tr ("Must-connect nets %s of circuit %s are not connected%s")), a.expanded_name (), c.name (), subcircuit_to_string (sc)));
|
check_must_connect_impl (*sc.circuit (), *net_a, *net_b, c_org, a_org, b_org, path);
|
||||||
error.set_cell_name (sc.circuit ()->name ());
|
path.pop_back ();
|
||||||
error.set_geometry (subcircuit_geometry (sc, internal_layout ()));
|
|
||||||
error.set_category_name ("must-connect");
|
|
||||||
log_entry (error);
|
|
||||||
} else {
|
|
||||||
db::LogEntryData error (db::Error, tl::sprintf (tl::to_string (tr ("Must-connect nets %s and %s of circuit %s are not connected%s")), a.expanded_name (), b.expanded_name (), c.name (), subcircuit_to_string (sc)));
|
|
||||||
error.set_cell_name (sc.circuit ()->name ());
|
|
||||||
error.set_geometry (subcircuit_geometry (sc, internal_layout ()));
|
|
||||||
error.set_category_name ("must-connect");
|
|
||||||
log_entry (error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1041,6 +1041,7 @@ private:
|
||||||
void join_nets_from_pattern (db::Circuit &c, const tl::GlobPattern &p);
|
void join_nets_from_pattern (db::Circuit &c, const tl::GlobPattern &p);
|
||||||
void join_nets_from_pattern (db::Circuit &c, const std::set<std::string> &p);
|
void join_nets_from_pattern (db::Circuit &c, const std::set<std::string> &p);
|
||||||
void check_must_connect (const db::Circuit &c, const db::Net &a, const db::Net &b);
|
void check_must_connect (const db::Circuit &c, const db::Net &a, const db::Net &b);
|
||||||
|
void check_must_connect_impl (const db::Circuit &c, const db::Net &a, const db::Net &b, const db::Circuit &c_org, const db::Net &a_org, const db::Net &b_org, std::vector<const db::SubCircuit *> &path);
|
||||||
|
|
||||||
// implementation of NetlistManipulationCallbacks
|
// implementation of NetlistManipulationCallbacks
|
||||||
virtual size_t link_net_to_parent_circuit (const Net *subcircuit_net, Circuit *parent_circuit, const DCplxTrans &trans);
|
virtual size_t link_net_to_parent_circuit (const Net *subcircuit_net, Circuit *parent_circuit, const DCplxTrans &trans);
|
||||||
|
|
|
||||||
|
|
@ -289,6 +289,12 @@ TEST(31_MustConnect2)
|
||||||
run_test (_this, "must_connect2", "must_connect2.gds");
|
run_test (_this, "must_connect2", "must_connect2.gds");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Intermediate cell propagates must-connect pins
|
||||||
|
TEST(32_MustConnect3)
|
||||||
|
{
|
||||||
|
run_test (_this, "must_connect3", "must_connect3.gds");
|
||||||
|
}
|
||||||
|
|
||||||
// issue 1609
|
// issue 1609
|
||||||
TEST(40_DeviceExtractorErrors)
|
TEST(40_DeviceExtractorErrors)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ J(
|
||||||
G(l14 SUBSTRATE)
|
G(l14 SUBSTRATE)
|
||||||
H(W B('Must-connect nets GND must be connected further up in the hierarchy - this is an error at chip top level') C(INVCHAIN) X('must-connect'))
|
H(W B('Must-connect nets GND must be connected further up in the hierarchy - this is an error at chip top level') C(INVCHAIN) X('must-connect'))
|
||||||
H(W B('Must-connect nets R must be connected further up in the hierarchy - this is an error at chip top level') C(INVCHAIN) X('must-connect'))
|
H(W B('Must-connect nets R must be connected further up in the hierarchy - this is an error at chip top level') C(INVCHAIN) X('must-connect'))
|
||||||
H(E B('Must-connect nets R of circuit INV2 are not connected') C(INVCHAIN) X('must-connect') Q('(0,0;0,9.2;3,9.2;3,0)'))
|
H(W B('Must-connect nets R of circuit INV2 must be connected further up in the hierarchy - this is an error at chip top level.\nInstance path: INVCHAIN:$1[r0 *1 0,0]/INV2') C(INVCHAIN) X('must-connect') Q('(0,0;0,9.2;3,9.2;3,0)'))
|
||||||
K(PMOS MOS3)
|
K(PMOS MOS3)
|
||||||
K(NMOS MOS3)
|
K(NMOS MOS3)
|
||||||
D(D$PMOS PMOS
|
D(D$PMOS PMOS
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ J(
|
||||||
G(l14 SUBSTRATE)
|
G(l14 SUBSTRATE)
|
||||||
H(W B('Must-connect nets GND must be connected further up in the hierarchy - this is an error at chip top level') C(INVCHAIN) X('must-connect'))
|
H(W B('Must-connect nets GND must be connected further up in the hierarchy - this is an error at chip top level') C(INVCHAIN) X('must-connect'))
|
||||||
H(W B('Must-connect nets R must be connected further up in the hierarchy - this is an error at chip top level') C(INVCHAIN) X('must-connect'))
|
H(W B('Must-connect nets R must be connected further up in the hierarchy - this is an error at chip top level') C(INVCHAIN) X('must-connect'))
|
||||||
H(E B('Must-connect nets R of circuit INV2 are not connected') C(INVCHAIN) X('must-connect') Q('(0,0;0,9.2;3,9.2;3,0)'))
|
H(W B('Must-connect nets R of circuit INV2 must be connected further up in the hierarchy - this is an error at chip top level.\nInstance path: INVCHAIN:$1[r0 *1 0,0]/INV2') C(INVCHAIN) X('must-connect') Q('(0,0;0,9.2;3,9.2;3,0)'))
|
||||||
K(PMOS MOS3)
|
K(PMOS MOS3)
|
||||||
K(NMOS MOS3)
|
K(NMOS MOS3)
|
||||||
D(D$PMOS PMOS
|
D(D$PMOS PMOS
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ J(
|
||||||
G(l14 SUBSTRATE)
|
G(l14 SUBSTRATE)
|
||||||
H(W B('Must-connect nets VSSTOP must be connected further up in the hierarchy - this is an error at chip top level') C(TOP) X('must-connect'))
|
H(W B('Must-connect nets VSSTOP must be connected further up in the hierarchy - this is an error at chip top level') C(TOP) X('must-connect'))
|
||||||
H(W B('Must-connect nets VDD must be connected further up in the hierarchy - this is an error at chip top level') C(TOP) X('must-connect'))
|
H(W B('Must-connect nets VDD must be connected further up in the hierarchy - this is an error at chip top level') C(TOP) X('must-connect'))
|
||||||
H(E B('Must-connect nets VSS of circuit INV2 are not connected') C(INVCHAIN) X('must-connect') Q('(0,0;0,9.2;3,9.2;3,0)'))
|
H(W B('Must-connect nets VSS of circuit INV2 must be connected further up in the hierarchy - this is an error at chip top level.\nInstance path: INVCHAIN:$2[r0 *1 0,0]/INV2') C(INVCHAIN) X('must-connect') Q('(0,0;0,9.2;3,9.2;3,0)'))
|
||||||
K(PMOS MOS3)
|
K(PMOS MOS3)
|
||||||
K(NMOS MOS3)
|
K(NMOS MOS3)
|
||||||
D(D$PMOS PMOS
|
D(D$PMOS PMOS
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
* Extracted by KLayout
|
||||||
|
|
||||||
|
.SUBCKT TOP
|
||||||
|
X$2 \$1 \$I2 \$I1 \$I1 \$1.Q \$2 INV2
|
||||||
|
X$3 \$1.A \$I3 \$2 \$I3 \$I2 \$1 INVCHAIN
|
||||||
|
.ENDS TOP
|
||||||
|
|
||||||
|
.SUBCKT INVCHAIN IN IN2 VSS|VSS2|VSS2B OUT OUT2 VDD
|
||||||
|
X$1 VDD IN2 \$1 \$1 OUT2 VSS|VSS2|VSS2B INV2
|
||||||
|
X$2 VDD IN \$2 \$2 OUT VSS|VSS2|VSS2B INV2
|
||||||
|
.ENDS INVCHAIN
|
||||||
|
|
||||||
|
.SUBCKT INV2 VDD A1 A2 Q1 Q2 VSS
|
||||||
|
X$1 VSS VDD A2 Q2 INV
|
||||||
|
X$2 VSS VDD A1 Q1 INV
|
||||||
|
.ENDS INV2
|
||||||
|
|
||||||
|
.SUBCKT INV \$1 \$2 \$3 \$4
|
||||||
|
M$1 \$2 \$3 \$4 \$4 PMOS L=0.25U W=0.95U AS=0.73625P AD=0.73625P PS=3.45U
|
||||||
|
+ PD=3.45U
|
||||||
|
M$2 \$1 \$3 \$4 \$4 NMOS L=0.25U W=0.95U AS=0.73625P AD=0.73625P PS=3.45U
|
||||||
|
+ PD=3.45U
|
||||||
|
.ENDS INV
|
||||||
Binary file not shown.
|
|
@ -0,0 +1,142 @@
|
||||||
|
|
||||||
|
$lvs_test_source && source($lvs_test_source)
|
||||||
|
|
||||||
|
if $lvs_test_target_lvsdb
|
||||||
|
report_lvs($lvs_test_target_lvsdb)
|
||||||
|
else
|
||||||
|
report_lvs
|
||||||
|
end
|
||||||
|
|
||||||
|
# Implicit connection of the INV2
|
||||||
|
# VSS nets
|
||||||
|
connect_implicit("INV2", "VSS")
|
||||||
|
connect_implicit("TOP", "VSS*")
|
||||||
|
# Fix 1
|
||||||
|
connect_explicit("INVCHAIN", ["VSS2", "VSS2B", "VSS"])
|
||||||
|
connect_implicit("INVCHAIN", "VDD")
|
||||||
|
connect_explicit("TOP", ["VDD"])
|
||||||
|
|
||||||
|
ignore_extraction_errors(true)
|
||||||
|
|
||||||
|
writer = write_spice(true, false)
|
||||||
|
$lvs_test_target_cir && target_netlist($lvs_test_target_cir, writer, "Extracted by KLayout")
|
||||||
|
|
||||||
|
# needs this delegate because we use MOS3 which is not available in Spice
|
||||||
|
class SpiceReaderDelegate < RBA::NetlistSpiceReaderDelegate
|
||||||
|
|
||||||
|
# says we want to catch these subcircuits as devices
|
||||||
|
def wants_subcircuit(name)
|
||||||
|
name == "HVNMOS" || name == "HVPMOS"
|
||||||
|
end
|
||||||
|
|
||||||
|
# translate the element
|
||||||
|
def element(circuit, el, name, model, value, nets, params)
|
||||||
|
|
||||||
|
if el != "M"
|
||||||
|
# all other elements are left to the standard implementation
|
||||||
|
return super
|
||||||
|
end
|
||||||
|
|
||||||
|
if nets.size != 4
|
||||||
|
error("Device #{model} needs four nodes")
|
||||||
|
end
|
||||||
|
|
||||||
|
# provide a device class
|
||||||
|
cls = circuit.netlist.device_class_by_name(model)
|
||||||
|
if ! cls
|
||||||
|
cls = RBA::DeviceClassMOS3Transistor::new
|
||||||
|
cls.name = model
|
||||||
|
circuit.netlist.add(cls)
|
||||||
|
end
|
||||||
|
|
||||||
|
# create a device
|
||||||
|
device = circuit.create_device(cls, name)
|
||||||
|
|
||||||
|
# and configure the device
|
||||||
|
[ "S", "G", "D" ].each_with_index do |t,index|
|
||||||
|
device.connect_terminal(t, nets[index])
|
||||||
|
end
|
||||||
|
device.set_parameter("W", params["W"] * 1e6)
|
||||||
|
device.set_parameter("L", params["L"] * 1e6)
|
||||||
|
|
||||||
|
device
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
reader = RBA::NetlistSpiceReader::new(SpiceReaderDelegate::new)
|
||||||
|
schematic(File.basename(source.path, ".*") + ".sch", reader)
|
||||||
|
|
||||||
|
deep
|
||||||
|
|
||||||
|
# Drawing layers
|
||||||
|
|
||||||
|
nwell = input(1, 0)
|
||||||
|
active = input(2, 0)
|
||||||
|
poly = input(3, 0)
|
||||||
|
poly_lbl = input(3, 1)
|
||||||
|
diff_cont = input(4, 0)
|
||||||
|
poly_cont = input(5, 0)
|
||||||
|
metal1 = input(6, 0)
|
||||||
|
metal1_lbl = input(6, 1)
|
||||||
|
via1 = input(7, 0)
|
||||||
|
metal2 = input(8, 0)
|
||||||
|
metal2_lbl = input(8, 1)
|
||||||
|
|
||||||
|
# Bulk layer for terminal provisioning
|
||||||
|
|
||||||
|
bulk = polygon_layer
|
||||||
|
|
||||||
|
psd = nil
|
||||||
|
nsd = nil
|
||||||
|
|
||||||
|
# Computed layers
|
||||||
|
|
||||||
|
active_in_nwell = active & nwell
|
||||||
|
pactive = active_in_nwell
|
||||||
|
pgate = pactive & poly
|
||||||
|
psd = pactive - pgate
|
||||||
|
|
||||||
|
active_outside_nwell = active - nwell
|
||||||
|
nactive = active_outside_nwell
|
||||||
|
ngate = nactive & poly
|
||||||
|
nsd = nactive - ngate
|
||||||
|
|
||||||
|
# Device extraction
|
||||||
|
|
||||||
|
# PMOS transistor device extraction
|
||||||
|
extract_devices(mos3("PMOS"), { "SD" => psd, "G" => pgate,
|
||||||
|
"tS" => psd, "tD" => psd, "tG" => poly })
|
||||||
|
|
||||||
|
# NMOS transistor device extraction
|
||||||
|
extract_devices(mos3("NMOS"), { "SD" => nsd, "G" => ngate,
|
||||||
|
"tS" => nsd, "tD" => nsd, "tG" => poly })
|
||||||
|
|
||||||
|
# Define connectivity for netlist extraction
|
||||||
|
|
||||||
|
# Inter-layer
|
||||||
|
connect(psd, diff_cont)
|
||||||
|
connect(nsd, diff_cont)
|
||||||
|
connect(poly, poly_cont)
|
||||||
|
connect(diff_cont, metal1)
|
||||||
|
connect(poly_cont, metal1)
|
||||||
|
connect(metal1, via1)
|
||||||
|
connect(via1, metal2)
|
||||||
|
|
||||||
|
# attach labels
|
||||||
|
connect(poly, poly_lbl)
|
||||||
|
connect(metal1, metal1_lbl)
|
||||||
|
connect(metal2, metal2_lbl)
|
||||||
|
|
||||||
|
# Global
|
||||||
|
connect_global(bulk, "SUBSTRATE")
|
||||||
|
|
||||||
|
# Compare section
|
||||||
|
|
||||||
|
netlist.simplify
|
||||||
|
align
|
||||||
|
|
||||||
|
# Skip as we have errors ..
|
||||||
|
compare
|
||||||
|
|
||||||
|
|
@ -0,0 +1,482 @@
|
||||||
|
#%lvsdb-klayout
|
||||||
|
J(
|
||||||
|
W(TOP)
|
||||||
|
U(0.001)
|
||||||
|
L(l3 '3/0')
|
||||||
|
L(l11 '3/1')
|
||||||
|
L(l6 '4/0')
|
||||||
|
L(l7 '5/0')
|
||||||
|
L(l8 '6/0')
|
||||||
|
L(l12 '6/1')
|
||||||
|
L(l9 '7/0')
|
||||||
|
L(l10 '8/0')
|
||||||
|
L(l13 '8/1')
|
||||||
|
L(l14)
|
||||||
|
L(l2)
|
||||||
|
L(l5)
|
||||||
|
C(l3 l3 l11 l7)
|
||||||
|
C(l11 l3 l11)
|
||||||
|
C(l6 l6 l8 l2 l5)
|
||||||
|
C(l7 l3 l7 l8)
|
||||||
|
C(l8 l6 l7 l8 l12 l9)
|
||||||
|
C(l12 l8 l12)
|
||||||
|
C(l9 l8 l9 l10)
|
||||||
|
C(l10 l9 l10 l13)
|
||||||
|
C(l13 l10 l13)
|
||||||
|
C(l14 l14)
|
||||||
|
C(l2 l6 l2)
|
||||||
|
C(l5 l6 l5)
|
||||||
|
G(l14 SUBSTRATE)
|
||||||
|
K(PMOS MOS3)
|
||||||
|
K(NMOS MOS3)
|
||||||
|
D(D$PMOS PMOS
|
||||||
|
T(S
|
||||||
|
R(l2 (-900 -475) (775 950))
|
||||||
|
)
|
||||||
|
T(G
|
||||||
|
R(l3 (-125 -475) (250 950))
|
||||||
|
)
|
||||||
|
T(D
|
||||||
|
R(l2 (125 -475) (775 950))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
D(D$NMOS NMOS
|
||||||
|
T(S
|
||||||
|
R(l5 (-900 -475) (775 950))
|
||||||
|
)
|
||||||
|
T(G
|
||||||
|
R(l3 (-125 -475) (250 950))
|
||||||
|
)
|
||||||
|
T(D
|
||||||
|
R(l5 (125 -475) (775 950))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
X(INV
|
||||||
|
R((-1500 -800) (3000 4600))
|
||||||
|
N(1
|
||||||
|
R(l6 (290 -310) (220 220))
|
||||||
|
R(l6 (-220 180) (220 220))
|
||||||
|
R(l8 (-290 -690) (360 760))
|
||||||
|
R(l9 (-305 -705) (250 250))
|
||||||
|
R(l9 (-250 150) (250 250))
|
||||||
|
R(l10 (-2025 -775) (3000 900))
|
||||||
|
R(l5 (-1375 -925) (775 950))
|
||||||
|
)
|
||||||
|
N(2
|
||||||
|
R(l6 (290 2490) (220 220))
|
||||||
|
R(l6 (-220 180) (220 220))
|
||||||
|
R(l8 (-290 -690) (360 760))
|
||||||
|
R(l9 (-305 -705) (250 250))
|
||||||
|
R(l9 (-250 150) (250 250))
|
||||||
|
R(l10 (-2025 -775) (3000 900))
|
||||||
|
R(l2 (-1375 -925) (775 950))
|
||||||
|
)
|
||||||
|
N(3
|
||||||
|
R(l3 (-125 -250) (250 2500))
|
||||||
|
R(l3 (-250 -3050) (250 1600))
|
||||||
|
R(l3 (-250 1200) (250 1600))
|
||||||
|
)
|
||||||
|
N(4
|
||||||
|
R(l6 (-510 -310) (220 220))
|
||||||
|
R(l6 (-220 180) (220 220))
|
||||||
|
R(l6 (-220 2180) (220 220))
|
||||||
|
R(l6 (-220 180) (220 220))
|
||||||
|
R(l8 (-290 -3530) (360 2840))
|
||||||
|
R(l8 (-360 -2800) (360 760))
|
||||||
|
R(l8 (-360 2040) (360 760))
|
||||||
|
R(l2 (-680 -855) (775 950))
|
||||||
|
R(l5 (-775 -3750) (775 950))
|
||||||
|
)
|
||||||
|
P(1)
|
||||||
|
P(2)
|
||||||
|
P(3)
|
||||||
|
P(4)
|
||||||
|
D(1 D$PMOS
|
||||||
|
Y(0 2800)
|
||||||
|
E(L 0.25)
|
||||||
|
E(W 0.95)
|
||||||
|
E(AS 0.73625)
|
||||||
|
E(AD 0.73625)
|
||||||
|
E(PS 3.45)
|
||||||
|
E(PD 3.45)
|
||||||
|
T(S 4)
|
||||||
|
T(G 3)
|
||||||
|
T(D 2)
|
||||||
|
)
|
||||||
|
D(2 D$NMOS
|
||||||
|
Y(0 0)
|
||||||
|
E(L 0.25)
|
||||||
|
E(W 0.95)
|
||||||
|
E(AS 0.73625)
|
||||||
|
E(AD 0.73625)
|
||||||
|
E(PS 3.45)
|
||||||
|
E(PD 3.45)
|
||||||
|
T(S 4)
|
||||||
|
T(G 3)
|
||||||
|
T(D 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
X(INV2
|
||||||
|
R((0 0) (3000 9200))
|
||||||
|
N(1 I(VDD)
|
||||||
|
R(l10 (0 3150) (3000 2900))
|
||||||
|
R(l13 (-1890 -1450) (0 0))
|
||||||
|
)
|
||||||
|
N(2 I(A1)
|
||||||
|
R(l11 (1480 7110) (0 0))
|
||||||
|
)
|
||||||
|
N(3 I(A2)
|
||||||
|
R(l11 (1520 1950) (0 0))
|
||||||
|
)
|
||||||
|
N(4 I(Q1)
|
||||||
|
R(l12 (1920 7070) (0 0))
|
||||||
|
)
|
||||||
|
N(5 I(Q2)
|
||||||
|
R(l12 (1940 1950) (0 0))
|
||||||
|
)
|
||||||
|
N(6 I(VSS)
|
||||||
|
R(l13 (2680 8390) (0 0))
|
||||||
|
R(l13 (-30 -7640) (0 0))
|
||||||
|
)
|
||||||
|
P(1 I(VDD))
|
||||||
|
P(2 I(A1))
|
||||||
|
P(3 I(A2))
|
||||||
|
P(4 I(Q1))
|
||||||
|
P(5 I(Q2))
|
||||||
|
P(6 I(VSS))
|
||||||
|
X(1 INV M O(180) Y(1500 800)
|
||||||
|
P(0 6)
|
||||||
|
P(1 1)
|
||||||
|
P(2 3)
|
||||||
|
P(3 5)
|
||||||
|
)
|
||||||
|
X(2 INV O(180) Y(1500 8400)
|
||||||
|
P(0 6)
|
||||||
|
P(1 1)
|
||||||
|
P(2 2)
|
||||||
|
P(3 4)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
X(INVCHAIN
|
||||||
|
R((-915 -15) (10415 9215))
|
||||||
|
N(1
|
||||||
|
R(l3 (7340 1650) (2160 250))
|
||||||
|
R(l3 (-250 0) (250 4990))
|
||||||
|
R(l3 (-1605 0) (1605 250))
|
||||||
|
R(l7 (-1545 -250) (240 250))
|
||||||
|
R(l8 (-560 -375) (690 510))
|
||||||
|
)
|
||||||
|
N(2
|
||||||
|
R(l3 (1625 1835) (2160 250))
|
||||||
|
R(l3 (-250 0) (250 4990))
|
||||||
|
R(l3 (-1605 0) (1605 250))
|
||||||
|
R(l7 (-1545 -250) (240 250))
|
||||||
|
R(l8 (-560 -375) (690 510))
|
||||||
|
)
|
||||||
|
N(3 I(IN)
|
||||||
|
R(l3 (-90 6850) (1590 650))
|
||||||
|
R(l11 (-700 -350) (0 0))
|
||||||
|
)
|
||||||
|
N(4 I(IN2)
|
||||||
|
R(l3 (5665 6790) (1590 650))
|
||||||
|
R(l11 (-700 -350) (0 0))
|
||||||
|
)
|
||||||
|
N(5 I('VSS,VSS2,VSS2B')
|
||||||
|
R(l10 (-915 5290) (250 2960))
|
||||||
|
R(l10 (-250 0) (915 250))
|
||||||
|
R(l10 (-915 -7825) (915 250))
|
||||||
|
R(l10 (-915 0) (250 3145))
|
||||||
|
R(l13 (155 4305) (0 0))
|
||||||
|
R(l13 (8990 -255) (0 0))
|
||||||
|
R(l13 (25 -7115) (0 0))
|
||||||
|
)
|
||||||
|
N(6 I(OUT)
|
||||||
|
R(l12 (1890 2105) (0 0))
|
||||||
|
)
|
||||||
|
N(7 I(OUT2)
|
||||||
|
R(l12 (7730 2155) (0 0))
|
||||||
|
)
|
||||||
|
N(8 I(VDD)
|
||||||
|
R(l13 (8035 4540) (0 0))
|
||||||
|
R(l13 (-5735 60) (0 0))
|
||||||
|
)
|
||||||
|
P(3 I(IN))
|
||||||
|
P(4 I(IN2))
|
||||||
|
P(5 I('VSS,VSS2,VSS2B'))
|
||||||
|
P(6 I(OUT))
|
||||||
|
P(7 I(OUT2))
|
||||||
|
P(8 I(VDD))
|
||||||
|
X(1 INV2 Y(5780 -15)
|
||||||
|
P(0 8)
|
||||||
|
P(1 4)
|
||||||
|
P(2 1)
|
||||||
|
P(3 1)
|
||||||
|
P(4 7)
|
||||||
|
P(5 5)
|
||||||
|
)
|
||||||
|
X(2 INV2 Y(0 0)
|
||||||
|
P(0 8)
|
||||||
|
P(1 3)
|
||||||
|
P(2 2)
|
||||||
|
P(3 2)
|
||||||
|
P(4 6)
|
||||||
|
P(5 5)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
X(TOP
|
||||||
|
R((-305 350) (15415 9225))
|
||||||
|
N(1
|
||||||
|
R(l10 (3200 4800) (8800 400))
|
||||||
|
R(l10 (-5110 -425) (0 0))
|
||||||
|
R(l10 (-4295 30) (0 0))
|
||||||
|
R(l10 (9270 -80) (0 0))
|
||||||
|
)
|
||||||
|
N(2
|
||||||
|
R(l10 (-305 4435) (250 1220))
|
||||||
|
R(l10 (3665 -4655) (2780 400))
|
||||||
|
R(l10 (-2780 6900) (2815 440))
|
||||||
|
R(l10 (-710 -250) (0 0))
|
||||||
|
R(l10 (3675 -165) (1975 565))
|
||||||
|
R(l10 (-1975 -8190) (1975 575))
|
||||||
|
R(l10 (-1005 -255) (0 0))
|
||||||
|
)
|
||||||
|
N(3
|
||||||
|
R(l3 (12950 2130) (2160 250))
|
||||||
|
R(l3 (-250 0) (250 4990))
|
||||||
|
R(l3 (-1605 0) (1605 250))
|
||||||
|
R(l7 (-1545 -250) (240 250))
|
||||||
|
R(l8 (-560 -375) (690 510))
|
||||||
|
)
|
||||||
|
N(4
|
||||||
|
R(l3 (12100 7300) (640 530))
|
||||||
|
R(l7 (-540 -415) (270 250))
|
||||||
|
R(l8 (-1695 -250) (1695 250))
|
||||||
|
R(l8 (-4075 -5650) (2630 250))
|
||||||
|
R(l8 (-250 0) (250 5150))
|
||||||
|
)
|
||||||
|
N(5
|
||||||
|
R(l7 (6465 7325) (220 240))
|
||||||
|
R(l8 (-4100 -5365) (3125 250))
|
||||||
|
R(l8 (-250 0) (250 4860))
|
||||||
|
R(l8 (-250 0) (1225 250))
|
||||||
|
)
|
||||||
|
N(6 I($1.A)
|
||||||
|
R(l11 (975 7530) (0 0))
|
||||||
|
)
|
||||||
|
N(7 I($1.Q)
|
||||||
|
R(l12 (13260 2010) (0 0))
|
||||||
|
)
|
||||||
|
X(2 INV2 Y(11365 375)
|
||||||
|
P(0 1)
|
||||||
|
P(1 4)
|
||||||
|
P(2 3)
|
||||||
|
P(3 3)
|
||||||
|
P(4 7)
|
||||||
|
P(5 2)
|
||||||
|
)
|
||||||
|
X(3 INVCHAIN Y(610 365)
|
||||||
|
P(0 6)
|
||||||
|
P(1 5)
|
||||||
|
P(2 2)
|
||||||
|
P(3 5)
|
||||||
|
P(4 4)
|
||||||
|
P(5 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
H(
|
||||||
|
K(PMOS MOS3)
|
||||||
|
K(NMOS MOS3)
|
||||||
|
X(INV
|
||||||
|
N(1 I(VDD))
|
||||||
|
N(2 I(VSS))
|
||||||
|
N(3 I(A))
|
||||||
|
N(4 I(Q))
|
||||||
|
P(1 I(VDD))
|
||||||
|
P(2 I(VSS))
|
||||||
|
P(3 I(A))
|
||||||
|
P(4 I(Q))
|
||||||
|
D(1 PMOS
|
||||||
|
I($1)
|
||||||
|
E(L 0.25)
|
||||||
|
E(W 0.95)
|
||||||
|
E(AS 0)
|
||||||
|
E(AD 0)
|
||||||
|
E(PS 0)
|
||||||
|
E(PD 0)
|
||||||
|
T(S 1)
|
||||||
|
T(G 3)
|
||||||
|
T(D 4)
|
||||||
|
)
|
||||||
|
D(2 NMOS
|
||||||
|
I($3)
|
||||||
|
E(L 0.25)
|
||||||
|
E(W 0.95)
|
||||||
|
E(AS 0)
|
||||||
|
E(AD 0)
|
||||||
|
E(PS 0)
|
||||||
|
E(PD 0)
|
||||||
|
T(S 2)
|
||||||
|
T(G 3)
|
||||||
|
T(D 4)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
X(INV2
|
||||||
|
N(1 I(VDD))
|
||||||
|
N(2 I(VSS))
|
||||||
|
N(3 I(A1))
|
||||||
|
N(4 I(Q1))
|
||||||
|
N(5 I(A2))
|
||||||
|
N(6 I(Q2))
|
||||||
|
P(1 I(VDD))
|
||||||
|
P(2 I(VSS))
|
||||||
|
P(3 I(A1))
|
||||||
|
P(4 I(Q1))
|
||||||
|
P(5 I(A2))
|
||||||
|
P(6 I(Q2))
|
||||||
|
X(1 INV I($1)
|
||||||
|
P(0 1)
|
||||||
|
P(1 2)
|
||||||
|
P(2 3)
|
||||||
|
P(3 4)
|
||||||
|
)
|
||||||
|
X(2 INV I($2)
|
||||||
|
P(0 1)
|
||||||
|
P(1 2)
|
||||||
|
P(2 5)
|
||||||
|
P(3 6)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
X(INVCHAIN
|
||||||
|
N(1 I(VDD))
|
||||||
|
N(2 I(VSS))
|
||||||
|
N(3 I(A1))
|
||||||
|
N(4 I(Q1))
|
||||||
|
N(5 I(A2))
|
||||||
|
N(6 I(Q2))
|
||||||
|
N(7 I('1'))
|
||||||
|
N(8 I('2'))
|
||||||
|
P(1 I(VDD))
|
||||||
|
P(2 I(VSS))
|
||||||
|
P(3 I(A1))
|
||||||
|
P(4 I(Q1))
|
||||||
|
P(5 I(A2))
|
||||||
|
P(6 I(Q2))
|
||||||
|
X(1 INV2 I($2)
|
||||||
|
P(0 1)
|
||||||
|
P(1 2)
|
||||||
|
P(2 3)
|
||||||
|
P(3 7)
|
||||||
|
P(4 7)
|
||||||
|
P(5 4)
|
||||||
|
)
|
||||||
|
X(2 INV2 I($3)
|
||||||
|
P(0 1)
|
||||||
|
P(1 2)
|
||||||
|
P(2 5)
|
||||||
|
P(3 8)
|
||||||
|
P(4 8)
|
||||||
|
P(5 6)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
X(TOP
|
||||||
|
N(1 I(VDD))
|
||||||
|
N(2 I(VSS))
|
||||||
|
N(3 I(A))
|
||||||
|
N(4 I('1'))
|
||||||
|
N(5 I('3'))
|
||||||
|
N(6 I('2'))
|
||||||
|
N(7 I(Q))
|
||||||
|
X(1 INVCHAIN I($1)
|
||||||
|
P(0 1)
|
||||||
|
P(1 2)
|
||||||
|
P(2 3)
|
||||||
|
P(3 4)
|
||||||
|
P(4 4)
|
||||||
|
P(5 5)
|
||||||
|
)
|
||||||
|
X(2 INV2 I($2)
|
||||||
|
P(0 1)
|
||||||
|
P(1 2)
|
||||||
|
P(2 5)
|
||||||
|
P(3 6)
|
||||||
|
P(4 6)
|
||||||
|
P(5 7)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
Z(
|
||||||
|
X(INV INV 1
|
||||||
|
Z(
|
||||||
|
N(3 3 1)
|
||||||
|
N(4 4 1)
|
||||||
|
N(2 1 1)
|
||||||
|
N(1 2 1)
|
||||||
|
P(2 2 1)
|
||||||
|
P(3 3 1)
|
||||||
|
P(1 0 1)
|
||||||
|
P(0 1 1)
|
||||||
|
D(2 2 1)
|
||||||
|
D(1 1 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
X(INV2 INV2 1
|
||||||
|
Z(
|
||||||
|
N(2 3 1)
|
||||||
|
N(3 5 1)
|
||||||
|
N(4 4 1)
|
||||||
|
N(5 6 1)
|
||||||
|
N(1 1 1)
|
||||||
|
N(6 2 1)
|
||||||
|
P(1 2 1)
|
||||||
|
P(2 4 1)
|
||||||
|
P(3 3 1)
|
||||||
|
P(4 5 1)
|
||||||
|
P(0 0 1)
|
||||||
|
P(5 1 1)
|
||||||
|
X(2 1 1)
|
||||||
|
X(1 2 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
X(INVCHAIN INVCHAIN 1
|
||||||
|
L(
|
||||||
|
M(W B('Matching nets OUT vs. Q1 from an ambiguous group of nets'))
|
||||||
|
M(W B('Matching nets OUT2 vs. Q2 from an ambiguous group of nets'))
|
||||||
|
M(I B('Matching nets $2 vs. 1 following an ambiguous match'))
|
||||||
|
M(I B('Matching nets IN vs. A1 following an ambiguous match'))
|
||||||
|
M(I B('Matching nets $1 vs. 2 following an ambiguous match'))
|
||||||
|
M(I B('Matching nets IN2 vs. A2 following an ambiguous match'))
|
||||||
|
)
|
||||||
|
Z(
|
||||||
|
N(2 7 1)
|
||||||
|
N(1 8 1)
|
||||||
|
N(3 3 1)
|
||||||
|
N(4 5 1)
|
||||||
|
N(6 4 W)
|
||||||
|
N(7 6 W)
|
||||||
|
N(8 1 1)
|
||||||
|
N(5 2 1)
|
||||||
|
P(0 2 1)
|
||||||
|
P(1 4 1)
|
||||||
|
P(3 3 1)
|
||||||
|
P(4 5 1)
|
||||||
|
P(5 0 1)
|
||||||
|
P(2 1 1)
|
||||||
|
X(2 1 1)
|
||||||
|
X(1 2 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
X(TOP TOP 1
|
||||||
|
Z(
|
||||||
|
N(5 4 1)
|
||||||
|
N(3 6 1)
|
||||||
|
N(4 5 1)
|
||||||
|
N(1 1 1)
|
||||||
|
N(2 2 1)
|
||||||
|
N(6 3 1)
|
||||||
|
N(7 7 1)
|
||||||
|
X(2 2 1)
|
||||||
|
X(3 1 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
|
||||||
|
.SUBCKT TOP
|
||||||
|
X$1 VDD VSS A 1 1 3 INVCHAIN
|
||||||
|
X$2 VDD VSS 3 2 2 Q INV2
|
||||||
|
.ENDS TOP
|
||||||
|
|
||||||
|
* cell INVCHAIN
|
||||||
|
.SUBCKT INVCHAIN VDD VSS A1 Q1 A2 Q2
|
||||||
|
X$2 VDD VSS A1 1 1 Q1 INV2
|
||||||
|
X$3 VDD VSS A2 2 2 Q2 INV2
|
||||||
|
.ENDS INVCHAIN
|
||||||
|
|
||||||
|
* cell INV2
|
||||||
|
.SUBCKT INV2 VDD VSS A1 Q1 A2 Q2
|
||||||
|
X$1 VDD VSS A1 Q1 INV
|
||||||
|
X$2 VDD VSS A2 Q2 INV
|
||||||
|
.ENDS INV2
|
||||||
|
|
||||||
|
* cell INV
|
||||||
|
.SUBCKT INV VDD VSS A Q
|
||||||
|
M$1 VDD A Q VDD PMOS L=0.25U W=0.95U
|
||||||
|
M$3 VSS A Q VSS NMOS L=0.25U W=0.95U
|
||||||
|
.ENDS INV
|
||||||
|
|
||||||
Loading…
Reference in New Issue