From 8b73dffcfedc50aaf8f8120716102b78b89ce23b Mon Sep 17 00:00:00 2001
From: Matthias Koefferlein
Date: Thu, 27 Feb 2020 15:40:06 +0100
Subject: [PATCH 1/2] Implementation done. Added tests.
---
src/db/db/dbDeviceClass.cc | 8 +-
src/db/db/dbDeviceClass.h | 14 +-
src/db/db/gsiDeclDbNetlist.cc | 13 +
src/lvs/lvs/built-in-macros/_lvs_engine.rb | 9 +-
src/lvs/lvs/built-in-macros/_lvs_netter.rb | 54 ++
src/lvs/unit_tests/lvsSimpleTests.cc | 5 +
testdata/lvs/ringo_off_target.cir | 27 +
testdata/lvs/ringo_simple_with_tol.cir | 83 ++
testdata/lvs/ringo_simple_with_tol.lvs | 79 ++
testdata/lvs/ringo_simple_with_tol.lvsdb | 908 +++++++++++++++++++++
testdata/ruby/dbNetlistCompare.rb | 35 +-
11 files changed, 1226 insertions(+), 9 deletions(-)
create mode 100644 testdata/lvs/ringo_off_target.cir
create mode 100644 testdata/lvs/ringo_simple_with_tol.cir
create mode 100644 testdata/lvs/ringo_simple_with_tol.lvs
create mode 100644 testdata/lvs/ringo_simple_with_tol.lvsdb
diff --git a/src/db/db/dbDeviceClass.cc b/src/db/db/dbDeviceClass.cc
index 057c611d2..7d44e08f2 100644
--- a/src/db/db/dbDeviceClass.cc
+++ b/src/db/db/dbDeviceClass.cc
@@ -39,11 +39,13 @@ static int compare_parameters (double pa, double pb, double absolute, double rel
pa_min -= mean * relative;
pa_max += mean * relative;
- // NOTE: parameter values may be small (e.g. pF for caps) -> no epsilon
+ // NOTE: parameter values may be small (e.g. pF for caps) -> no fixed epsilon
- if (pa_max < pb) {
+ double eps = (fabs (pa_max) + fabs(pa_min)) * 0.5e-10;
+
+ if (pa_max < pb - eps) {
return -1;
- } else if (pa_min > pb) {
+ } else if (pa_min > pb + eps) {
return 1;
} else {
return 0;
diff --git a/src/db/db/dbDeviceClass.h b/src/db/db/dbDeviceClass.h
index b749528f8..e37b8f1f8 100644
--- a/src/db/db/dbDeviceClass.h
+++ b/src/db/db/dbDeviceClass.h
@@ -563,12 +563,22 @@ public:
*
* The device class takes ownership of the delegate.
*/
- virtual void set_parameter_compare_delegate (db::DeviceParameterCompareDelegate *delegate)
+ void set_parameter_compare_delegate (db::DeviceParameterCompareDelegate *delegate)
{
- delegate->keep (); // assume transfer of ownership for scripts
+ if (delegate) {
+ delegate->keep (); // assume transfer of ownership for scripts
+ }
mp_pc_delegate.reset (delegate);
}
+ /**
+ * @brief Gets the parameter compare delegate or null if no such delegate is registered
+ */
+ db::DeviceParameterCompareDelegate *parameter_compare_delegate ()
+ {
+ return mp_pc_delegate.get ();
+ }
+
private:
friend class Netlist;
diff --git a/src/db/db/gsiDeclDbNetlist.cc b/src/db/db/gsiDeclDbNetlist.cc
index 56fc451ea..a472236af 100644
--- a/src/db/db/gsiDeclDbNetlist.cc
+++ b/src/db/db/gsiDeclDbNetlist.cc
@@ -835,6 +835,11 @@ static void equal_parameters (db::DeviceClass *cls, db::EqualDeviceParameters *c
cls->set_parameter_compare_delegate (comparer);
}
+static db::EqualDeviceParameters *get_equal_parameters (db::DeviceClass *cls)
+{
+ return dynamic_cast (cls->parameter_compare_delegate ());
+}
+
Class decl_dbDeviceClass ("db", "DeviceClass",
gsi::method ("name", &db::DeviceClass::name,
"@brief Gets the name of the device class."
@@ -905,6 +910,12 @@ Class decl_dbDeviceClass ("db", "DeviceClass",
"An exception is thrown if there is no terminal with the given name. Use \\has_terminal to check "
"whether the name is a valid terminal name."
) +
+ gsi::method_ext ("equal_parameters", &get_equal_parameters,
+ "@brief Gets the device parameter comparer for netlist verification or nil if no comparer is registered.\n"
+ "See \\equal_parameters= for the setter.\n"
+ "\n"
+ "This getter has been introduced in version 0.26.4.\n"
+ ) +
gsi::method_ext ("equal_parameters=", &equal_parameters, gsi::arg ("comparer"),
"@brief Specifies a device parameter comparer for netlist verification.\n"
"By default, all devices are compared with all parameters. If you want to select only certain parameters "
@@ -912,6 +923,8 @@ Class decl_dbDeviceClass ("db", "DeviceClass",
"to the device class of one netlist. You can also chain multiple \\EqualDeviceParameters objects with the '+' operator "
"for specifying multiple parameters in the equality check.\n"
"\n"
+ "You can assign nil for the parameter comparer to remove it.\n"
+ "\n"
"In special cases, you can even implement a custom compare scheme by deriving your own comparer from the \\GenericDeviceParameterCompare class."
),
"@brief A class describing a specific type of device.\n"
diff --git a/src/lvs/lvs/built-in-macros/_lvs_engine.rb b/src/lvs/lvs/built-in-macros/_lvs_engine.rb
index 8186eb2eb..03bfbda7e 100644
--- a/src/lvs/lvs/built-in-macros/_lvs_engine.rb
+++ b/src/lvs/lvs/built-in-macros/_lvs_engine.rb
@@ -149,7 +149,14 @@ module LVS
# @synopsis max_depth(n)
# See \Netter#max_depth for a description of that function.
- %w(schematic compare align same_nets same_circuits same_device_classes equivalent_pins min_caps max_res max_depth max_branch_complexity).each do |f|
+ # %LVS%
+ # @name tolerance
+ # @brief Specifies compare tolerances for certain device parameters
+ # @synopsis tolerance(device_class_name, parameter_name, absolute_tolerance [, relative_tolerance])
+ # @synopsis tolerance(device_class_name, parameter_name [:absolute => absolute_tolerance,] [:relative => relative_tolerance,])
+ # See \Netter#tolerance for a description of that function.
+
+ %w(schematic compare align same_nets same_circuits same_device_classes equivalent_pins min_caps max_res max_depth max_branch_complexity tolerance).each do |f|
eval <<"CODE"
def #{f}(*args)
_netter.#{f}(*args)
diff --git a/src/lvs/lvs/built-in-macros/_lvs_netter.rb b/src/lvs/lvs/built-in-macros/_lvs_netter.rb
index ca5fcf5fa..44ba49000 100644
--- a/src/lvs/lvs/built-in-macros/_lvs_netter.rb
+++ b/src/lvs/lvs/built-in-macros/_lvs_netter.rb
@@ -98,6 +98,60 @@ module LVS
_l2n_data && @lvs
end
+ # %LVS%
+ # @name tolerance
+ # @brief Specifies compare tolerances for certain device parameters
+ # @synopsis tolerance(device_class_name, parameter_name, absolute_tolerance [, relative_tolerance])
+ # @synopsis tolerance(device_class_name, parameter_name [:absolute => absolute_tolerance,] [:relative => relative_tolerance,])
+ # Specifies a compare tolerance for a specific parameter on a given device class.
+ # The device class is the name of a device class in the extracted netlist.
+ # Tolerances can be given in absolute units or relative or both.
+ # The relative tolerance is given as a factor, so 0.1 is a 10% tolerance.
+ # Absolute and relative tolerances add, so specifying both allows for a larger
+ # deviation.
+
+ def tolerance(device_class_name, parameter_name, *args)
+
+ device_class_name.is_a?(String) || raise("Device class argument of 'tolerance' must be a string")
+ parameter_name.is_a?(String) || raise("Parameter name argument of 'tolerance' must be a string")
+
+ abs_tol = nil
+ rel_tol = nil
+ args.each do |a|
+ if a.is_a?(Hash)
+ a.keys.each do |k|
+ if k == :absolute
+ abs_tol = a[k].to_f
+ elsif k == :relative
+ rel_tol = a[k].to_f
+ else
+ raise("Unknown option #{k.to_s} in 'tolerance' (allowed options are: absolute, relative)")
+ end
+ end
+ elsif abs_tol == nil
+ abs_tol = a.to_f
+ elsif rel_tol == nil
+ rel_tol = a.to_f
+ else
+ raise("Too many arguments in 'tolerance' (max. 4)")
+ end
+ end
+
+ abs_tol ||= 0.0
+ rel_tol ||= 0.0
+
+ dc = netlist.device_class_by_name(device_class_name)
+ if dc && dc.has_parameter?(parameter_name)
+ ep = RBA::EqualDeviceParameters::new(dc.parameter_id(parameter_name), abs_tol, rel_tol)
+ if dc.equal_parameters == nil
+ dc.equal_parameters = ep
+ else
+ dc.equal_parameters += ep
+ end
+ end
+
+ end
+
# %LVS%
# @name align
# @brief Aligns the extracted netlist vs. the schematic
diff --git a/src/lvs/unit_tests/lvsSimpleTests.cc b/src/lvs/unit_tests/lvsSimpleTests.cc
index 7e08174c3..0b96e32c9 100644
--- a/src/lvs/unit_tests/lvsSimpleTests.cc
+++ b/src/lvs/unit_tests/lvsSimpleTests.cc
@@ -80,6 +80,11 @@ TEST(1_simple)
run_test (_this, "ringo_simple", "ringo.gds");
}
+TEST(1b_simple_with_tolerance)
+{
+ run_test (_this, "ringo_simple_with_tol", "ringo.gds");
+}
+
TEST(2_simple_io)
{
run_test (_this, "ringo_simple_io", "ringo.gds");
diff --git a/testdata/lvs/ringo_off_target.cir b/testdata/lvs/ringo_off_target.cir
new file mode 100644
index 000000000..a8a198cef
--- /dev/null
+++ b/testdata/lvs/ringo_off_target.cir
@@ -0,0 +1,27 @@
+
+.SUBCKT RINGO VSS VDD FB ENABLE OUT
+X$1 VDD 1 VSS VDD FB ENABLE VSS ND2X1
+X$2 VDD 2 VSS VDD 1 VSS INVX1
+X$3 VDD 3 VSS VDD 2 VSS INVX1
+X$4 VDD 4 VSS VDD 3 VSS INVX1
+X$5 VDD 5 VSS VDD 4 VSS INVX1
+X$6 VDD 6 VSS VDD 5 VSS INVX1
+X$7 VDD 7 VSS VDD 6 VSS INVX1
+X$8 VDD 8 VSS VDD 7 VSS INVX1
+X$9 VDD 9 VSS VDD 8 VSS INVX1
+X$10 VDD 10 VSS VDD 9 VSS INVX1
+X$11 VDD FB VSS VDD 10 VSS INVX1
+X$12 VDD OUT VSS VDD FB VSS INVX1
+.ENDS RINGO
+
+.SUBCKT ND2X1 VDD OUT VSS NWELL B A BULK
+M$1 OUT A VDD NWELL PMOS L=0.251U W=1.6U
+M$2 VDD B OUT NWELL PMOS L=0.25U W=1.5U
+M$3 VSS A 1 BULK NMOS L=0.26U W=1.00U
+M$4 1 B OUT BULK NMOS L=0.25U W=0.95U
+.ENDS ND2X1
+
+.SUBCKT INVX1 VDD OUT VSS NWELL IN BULK
+M$1 VDD IN OUT NWELL PMOS L=0.25U W=1.5U
+M$2 VSS IN OUT BULK NMOS L=0.25U W=0.95U
+.ENDS INVX1
diff --git a/testdata/lvs/ringo_simple_with_tol.cir b/testdata/lvs/ringo_simple_with_tol.cir
new file mode 100644
index 000000000..761afb771
--- /dev/null
+++ b/testdata/lvs/ringo_simple_with_tol.cir
@@ -0,0 +1,83 @@
+* Extracted by KLayout
+
+* cell RINGO
+* pin FB
+* pin VDD
+* pin OUT
+* pin ENABLE
+* pin VSS
+.SUBCKT RINGO 11 12 13 14 15
+* net 11 FB
+* net 12 VDD
+* net 13 OUT
+* net 14 ENABLE
+* net 15 VSS
+* cell instance $1 r0 *1 1.8,0
+X$1 12 1 15 12 11 14 15 ND2X1
+* cell instance $2 r0 *1 4.2,0
+X$2 12 2 15 12 1 15 INVX1
+* cell instance $3 r0 *1 6,0
+X$3 12 3 15 12 2 15 INVX1
+* cell instance $4 r0 *1 7.8,0
+X$4 12 4 15 12 3 15 INVX1
+* cell instance $5 r0 *1 9.6,0
+X$5 12 5 15 12 4 15 INVX1
+* cell instance $6 r0 *1 11.4,0
+X$6 12 6 15 12 5 15 INVX1
+* cell instance $7 r0 *1 13.2,0
+X$7 12 7 15 12 6 15 INVX1
+* cell instance $8 r0 *1 15,0
+X$8 12 8 15 12 7 15 INVX1
+* cell instance $9 r0 *1 16.8,0
+X$9 12 9 15 12 8 15 INVX1
+* cell instance $10 r0 *1 18.6,0
+X$10 12 10 15 12 9 15 INVX1
+* cell instance $11 r0 *1 20.4,0
+X$11 12 11 15 12 10 15 INVX1
+* cell instance $12 r0 *1 22.2,0
+X$12 12 13 15 12 11 15 INVX1
+.ENDS RINGO
+
+* cell INVX1
+* pin VDD
+* pin OUT
+* pin VSS
+* pin
+* pin IN
+* pin SUBSTRATE
+.SUBCKT INVX1 1 2 3 4 5 6
+* net 1 VDD
+* net 2 OUT
+* net 3 VSS
+* net 5 IN
+* net 6 SUBSTRATE
+* device instance $1 r0 *1 0.85,5.8 PMOS
+M$1 1 5 2 4 PMOS L=0.25U W=1.5U AS=0.6375P AD=0.6375P PS=3.85U PD=3.85U
+* device instance $2 r0 *1 0.85,2.135 NMOS
+M$2 3 5 2 6 NMOS L=0.25U W=0.95U AS=0.40375P AD=0.40375P PS=2.75U PD=2.75U
+.ENDS INVX1
+
+* cell ND2X1
+* pin VDD
+* pin OUT
+* pin VSS
+* pin
+* pin B
+* pin A
+* pin SUBSTRATE
+.SUBCKT ND2X1 1 2 3 4 5 6 7
+* net 1 VDD
+* net 2 OUT
+* net 3 VSS
+* net 5 B
+* net 6 A
+* net 7 SUBSTRATE
+* device instance $1 r0 *1 0.85,5.8 PMOS
+M$1 2 6 1 4 PMOS L=0.25U W=1.5U AS=0.6375P AD=0.3375P PS=3.85U PD=1.95U
+* device instance $2 r0 *1 1.55,5.8 PMOS
+M$2 1 5 2 4 PMOS L=0.25U W=1.5U AS=0.3375P AD=0.6375P PS=1.95U PD=3.85U
+* device instance $3 r0 *1 0.85,2.135 NMOS
+M$3 3 6 8 7 NMOS L=0.25U W=0.95U AS=0.40375P AD=0.21375P PS=2.75U PD=1.4U
+* device instance $4 r0 *1 1.55,2.135 NMOS
+M$4 8 5 2 7 NMOS L=0.25U W=0.95U AS=0.21375P AD=0.40375P PS=1.4U PD=2.75U
+.ENDS ND2X1
diff --git a/testdata/lvs/ringo_simple_with_tol.lvs b/testdata/lvs/ringo_simple_with_tol.lvs
new file mode 100644
index 000000000..5b2f6dcbd
--- /dev/null
+++ b/testdata/lvs/ringo_simple_with_tol.lvs
@@ -0,0 +1,79 @@
+
+source($lvs_test_source, "RINGO")
+
+report_lvs($lvs_test_target_lvsdb, true)
+
+target_netlist($lvs_test_target_cir, write_spice, "Extracted by KLayout")
+
+schematic("ringo_off_target.cir")
+
+deep
+
+# Drawing layers
+
+nwell = input(1, 0)
+active = input(2, 0)
+pplus = input(3, 0)
+nplus = input(4, 0)
+poly = input(5, 0)
+contact = input(8, 0)
+metal1 = input(9, 0)
+via1 = input(10, 0)
+metal2 = input(11, 0)
+
+# Bulk layer for terminal provisioning
+
+bulk = polygon_layer
+
+# Computed layers
+
+active_in_nwell = active & nwell
+pactive = active_in_nwell & pplus
+pgate = pactive & poly
+psd = pactive - pgate
+ntie = active_in_nwell & nplus
+
+active_outside_nwell = active - nwell
+nactive = active_outside_nwell & nplus
+ngate = nactive & poly
+nsd = nactive - ngate
+ptie = active_outside_nwell & pplus
+
+# Device extraction
+
+# PMOS transistor device extraction
+extract_devices(mos4("PMOS"), { "SD" => psd, "G" => pgate, "W" => nwell,
+ "tS" => psd, "tD" => psd, "tG" => poly, "tW" => nwell })
+
+# NMOS transistor device extraction
+extract_devices(mos4("NMOS"), { "SD" => nsd, "G" => ngate, "W" => bulk,
+ "tS" => nsd, "tD" => nsd, "tG" => poly, "tW" => bulk })
+
+# Define connectivity for netlist extraction
+
+# Inter-layer
+connect(psd, contact)
+connect(nsd, contact)
+connect(poly, contact)
+connect(ntie, contact)
+connect(nwell, ntie)
+connect(ptie, contact)
+connect(contact, metal1)
+connect(metal1, via1)
+connect(via1, metal2)
+
+# Global
+connect_global(bulk, "SUBSTRATE")
+connect_global(ptie, "SUBSTRATE")
+
+# Compare section
+
+tolerance("PMOS", "L", 0.001) # absolute
+tolerance("PMOS", "W", 0.01, 0.1) # relative + absolute
+tolerance("NMOS", "L", :absolute => 0.01)
+tolerance("NMOS", "W", :relative => 0.07)
+
+netlist.simplify
+
+compare
+
diff --git a/testdata/lvs/ringo_simple_with_tol.lvsdb b/testdata/lvs/ringo_simple_with_tol.lvsdb
new file mode 100644
index 000000000..9521ed1cb
--- /dev/null
+++ b/testdata/lvs/ringo_simple_with_tol.lvsdb
@@ -0,0 +1,908 @@
+#%lvsdb-klayout
+
+# Layout
+layout(
+ top(RINGO)
+ unit(0.001)
+
+ # Layer section
+ # This section lists the mask layers (drawing or derived) and their connections.
+
+ # Mask layers
+ layer(l3 '1/0')
+ layer(l4 '5/0')
+ layer(l8 '8/0')
+ layer(l11 '9/0')
+ layer(l12 '10/0')
+ layer(l13 '11/0')
+ layer(l7)
+ layer(l2)
+ layer(l9)
+ layer(l6)
+ layer(l10)
+
+ # Mask layer connectivity
+ connect(l3 l3 l9)
+ connect(l4 l4 l8)
+ connect(l8 l4 l8 l11 l2 l9 l6 l10)
+ connect(l11 l8 l11 l12)
+ connect(l12 l11 l12 l13)
+ connect(l13 l12 l13)
+ connect(l7 l7)
+ connect(l2 l8 l2)
+ connect(l9 l3 l8 l9)
+ connect(l6 l8 l6)
+ connect(l10 l8 l10)
+
+ # Global nets and connectivity
+ global(l7 SUBSTRATE)
+ global(l10 SUBSTRATE)
+
+ # Device class section
+ class(PMOS MOS4)
+ class(NMOS MOS4)
+
+ # Device abstracts section
+ # Device abstracts list the pin shapes of the devices.
+ device(D$PMOS PMOS
+ terminal(S
+ rect(l2 (-550 -750) (425 1500))
+ )
+ terminal(G
+ rect(l4 (-125 -750) (250 1500))
+ )
+ terminal(D
+ rect(l2 (125 -750) (450 1500))
+ )
+ terminal(B
+ rect(l3 (-125 -750) (250 1500))
+ )
+ )
+ device(D$PMOS$1 PMOS
+ terminal(S
+ rect(l2 (-575 -750) (450 1500))
+ )
+ terminal(G
+ rect(l4 (-125 -750) (250 1500))
+ )
+ terminal(D
+ rect(l2 (125 -750) (425 1500))
+ )
+ terminal(B
+ rect(l3 (-125 -750) (250 1500))
+ )
+ )
+ device(D$PMOS$2 PMOS
+ terminal(S
+ rect(l2 (-550 -750) (425 1500))
+ )
+ terminal(G
+ rect(l4 (-125 -750) (250 1500))
+ )
+ terminal(D
+ rect(l2 (125 -750) (425 1500))
+ )
+ terminal(B
+ rect(l3 (-125 -750) (250 1500))
+ )
+ )
+ device(D$NMOS NMOS
+ terminal(S
+ rect(l6 (-550 -475) (425 950))
+ )
+ terminal(G
+ rect(l4 (-125 -475) (250 950))
+ )
+ terminal(D
+ rect(l6 (125 -475) (450 950))
+ )
+ terminal(B
+ rect(l7 (-125 -475) (250 950))
+ )
+ )
+ device(D$NMOS$1 NMOS
+ terminal(S
+ rect(l6 (-575 -475) (450 950))
+ )
+ terminal(G
+ rect(l4 (-125 -475) (250 950))
+ )
+ terminal(D
+ rect(l6 (125 -475) (425 950))
+ )
+ terminal(B
+ rect(l7 (-125 -475) (250 950))
+ )
+ )
+ device(D$NMOS$2 NMOS
+ terminal(S
+ rect(l6 (-550 -475) (425 950))
+ )
+ terminal(G
+ rect(l4 (-125 -475) (250 950))
+ )
+ terminal(D
+ rect(l6 (125 -475) (425 950))
+ )
+ terminal(B
+ rect(l7 (-125 -475) (250 950))
+ )
+ )
+
+ # Circuit section
+ # Circuits are the hierarchical building blocks of the netlist.
+ circuit(ND2X1
+
+ # Circuit boundary
+ rect((-100 400) (2600 7600))
+
+ # Nets with their geometries
+ net(1 name(VDD)
+ rect(l8 (1110 5160) (180 180))
+ rect(l8 (-180 920) (180 180))
+ rect(l8 (-180 -730) (180 180))
+ rect(l11 (-240 -790) (300 1700))
+ rect(l11 (-1350 0) (2400 800))
+ rect(l11 (-1151 -401) (2 2))
+ rect(l2 (-276 -2151) (425 1500))
+ rect(l2 (-400 -1500) (425 1500))
+ )
+ net(2 name(OUT)
+ rect(l8 (1810 1770) (180 180))
+ rect(l8 (-180 370) (180 180))
+ rect(l8 (-1580 3760) (180 180))
+ rect(l8 (-180 -730) (180 180))
+ rect(l8 (-180 -730) (180 180))
+ rect(l8 (1220 920) (180 180))
+ rect(l8 (-180 -1280) (180 180))
+ rect(l8 (-180 370) (180 180))
+ polygon(l11 (-240 -4180) (0 1390) (490 0) (0 -300) (-190 0) (0 -1090))
+ rect(l11 (-110 1390) (300 1400))
+ polygon(l11 (-1890 0) (0 600) (300 0) (0 -300) (1590 0) (0 -300))
+ rect(l11 (-141 -501) (2 2))
+ rect(l11 (-1751 1099) (300 1400))
+ rect(l11 (1100 -1700) (300 300))
+ rect(l11 (-300 0) (300 1400))
+ rect(l2 (-1750 -1450) (425 1500))
+ rect(l2 (950 -1500) (425 1500))
+ rect(l6 (-425 -4890) (425 950))
+ )
+ net(3 name(VSS)
+ rect(l8 (410 1770) (180 180))
+ rect(l8 (-180 370) (180 180))
+ rect(l11 (-240 -1300) (300 1360))
+ rect(l11 (-650 -2160) (2400 800))
+ rect(l11 (-1151 -401) (2 2))
+ rect(l6 (-951 859) (425 950))
+ )
+ net(4
+ rect(l3 (-100 4500) (2600 3500))
+ )
+ net(5 name(B)
+ rect(l4 (1425 2860) (250 1940))
+ rect(l4 (-345 -950) (300 300))
+ rect(l4 (-205 650) (250 2000))
+ rect(l4 (-250 -2000) (250 2000))
+ rect(l4 (-250 -5390) (250 1450))
+ rect(l8 (-285 1050) (180 180))
+ rect(l11 (-71 -91) (2 2))
+ rect(l11 (-171 -151) (300 300))
+ )
+ net(6 name(A)
+ rect(l4 (725 2860) (250 1940))
+ rect(l4 (-325 -1850) (300 300))
+ rect(l4 (-225 1550) (250 2000))
+ rect(l4 (-250 -2000) (250 2000))
+ rect(l4 (-250 -5390) (250 1450))
+ rect(l8 (-265 150) (180 180))
+ rect(l11 (-91 -91) (2 2))
+ rect(l11 (-151 -151) (300 300))
+ )
+ net(7 name(SUBSTRATE))
+ net(8
+ rect(l6 (975 1660) (425 950))
+ rect(l6 (-400 -950) (425 950))
+ )
+
+ # Outgoing pins and their connections to nets
+ pin(1 name(VDD))
+ pin(2 name(OUT))
+ pin(3 name(VSS))
+ pin(4)
+ pin(5 name(B))
+ pin(6 name(A))
+ pin(7 name(SUBSTRATE))
+
+ # Devices and their connections
+ device(1 D$PMOS
+ location(850 5800)
+ param(L 0.25)
+ param(W 1.5)
+ param(AS 0.6375)
+ param(AD 0.3375)
+ param(PS 3.85)
+ param(PD 1.95)
+ terminal(S 2)
+ terminal(G 6)
+ terminal(D 1)
+ terminal(B 4)
+ )
+ device(2 D$PMOS$1
+ location(1550 5800)
+ param(L 0.25)
+ param(W 1.5)
+ param(AS 0.3375)
+ param(AD 0.6375)
+ param(PS 1.95)
+ param(PD 3.85)
+ terminal(S 1)
+ terminal(G 5)
+ terminal(D 2)
+ terminal(B 4)
+ )
+ device(3 D$NMOS
+ location(850 2135)
+ param(L 0.25)
+ param(W 0.95)
+ param(AS 0.40375)
+ param(AD 0.21375)
+ param(PS 2.75)
+ param(PD 1.4)
+ terminal(S 3)
+ terminal(G 6)
+ terminal(D 8)
+ terminal(B 7)
+ )
+ device(4 D$NMOS$1
+ location(1550 2135)
+ param(L 0.25)
+ param(W 0.95)
+ param(AS 0.21375)
+ param(AD 0.40375)
+ param(PS 1.4)
+ param(PD 2.75)
+ terminal(S 8)
+ terminal(G 5)
+ terminal(D 2)
+ terminal(B 7)
+ )
+
+ )
+ circuit(INVX1
+
+ # Circuit boundary
+ rect((-100 400) (2000 7600))
+
+ # Nets with their geometries
+ net(1 name(VDD)
+ rect(l8 (410 6260) (180 180))
+ rect(l8 (-180 -730) (180 180))
+ rect(l8 (-180 -730) (180 180))
+ rect(l11 (-240 -240) (300 1400))
+ rect(l11 (-650 300) (1800 800))
+ rect(l11 (-1450 -1100) (300 300))
+ rect(l11 (299 399) (2 2))
+ rect(l2 (-651 -2151) (425 1500))
+ )
+ net(2 name(OUT)
+ rect(l8 (1110 5160) (180 180))
+ rect(l8 (-180 920) (180 180))
+ rect(l8 (-180 -730) (180 180))
+ rect(l8 (-180 -4120) (180 180))
+ rect(l8 (-180 370) (180 180))
+ rect(l11 (-240 -790) (300 4790))
+ rect(l11 (-151 -2501) (2 2))
+ rect(l2 (-226 1049) (425 1500))
+ rect(l6 (-425 -4890) (425 950))
+ )
+ net(3 name(VSS)
+ rect(l8 (410 1770) (180 180))
+ rect(l8 (-180 370) (180 180))
+ rect(l11 (-240 -1300) (300 1360))
+ rect(l11 (-650 -2160) (1800 800))
+ rect(l11 (-851 -401) (2 2))
+ rect(l6 (-651 859) (425 950))
+ )
+ net(4
+ rect(l3 (-100 4500) (2000 3500))
+ )
+ net(5 name(IN)
+ rect(l4 (725 2860) (250 1940))
+ rect(l4 (-525 -1850) (300 300))
+ rect(l4 (-25 1550) (250 2000))
+ rect(l4 (-250 -2000) (250 2000))
+ rect(l4 (-250 -5390) (250 1450))
+ rect(l8 (-465 150) (180 180))
+ rect(l11 (-91 -91) (2 2))
+ rect(l11 (-151 -151) (300 300))
+ )
+ net(6 name(SUBSTRATE))
+
+ # Outgoing pins and their connections to nets
+ pin(1 name(VDD))
+ pin(2 name(OUT))
+ pin(3 name(VSS))
+ pin(4)
+ pin(5 name(IN))
+ pin(6 name(SUBSTRATE))
+
+ # Devices and their connections
+ device(1 D$PMOS$2
+ location(850 5800)
+ param(L 0.25)
+ param(W 1.5)
+ param(AS 0.6375)
+ param(AD 0.6375)
+ param(PS 3.85)
+ param(PD 3.85)
+ terminal(S 1)
+ terminal(G 5)
+ terminal(D 2)
+ terminal(B 4)
+ )
+ device(2 D$NMOS$2
+ location(850 2135)
+ param(L 0.25)
+ param(W 0.95)
+ param(AS 0.40375)
+ param(AD 0.40375)
+ param(PS 2.75)
+ param(PD 2.75)
+ terminal(S 3)
+ terminal(G 5)
+ terminal(D 2)
+ terminal(B 6)
+ )
+
+ )
+ circuit(RINGO
+
+ # Circuit boundary
+ rect((0 350) (25800 7650))
+
+ # Nets with their geometries
+ net(1
+ rect(l11 (4040 2950) (610 300))
+ )
+ net(2
+ rect(l11 (5550 2950) (900 300))
+ )
+ net(3
+ rect(l11 (7350 2950) (900 300))
+ )
+ net(4
+ rect(l11 (9150 2950) (900 300))
+ )
+ net(5
+ rect(l11 (10950 2950) (900 300))
+ )
+ net(6
+ rect(l11 (12750 2950) (900 300))
+ )
+ net(7
+ rect(l11 (14550 2950) (900 300))
+ )
+ net(8
+ rect(l11 (16350 2950) (900 300))
+ )
+ net(9
+ rect(l11 (18150 2950) (900 300))
+ )
+ net(10
+ rect(l11 (19950 2950) (900 300))
+ )
+ net(11 name(FB)
+ rect(l11 (21750 2950) (900 300))
+ rect(l11 (-19530 590) (320 320))
+ rect(l11 (17820 -320) (320 320))
+ rect(l12 (-18400 -260) (200 200))
+ rect(l12 (17940 -200) (200 200))
+ rect(l13 (-18040 -300) (17740 400))
+ rect(l13 (-17921 -201) (2 2))
+ rect(l13 (-221 -201) (400 400))
+ rect(l13 (17740 -400) (400 400))
+ )
+ net(12 name(VDD)
+ rect(l3 (500 4500) (1400 3500))
+ rect(l3 (-1900 -3500) (600 3500))
+ rect(l3 (23300 -3500) (1400 3500))
+ rect(l3 (-100 -3500) (600 3500))
+ rect(l8 (-24690 -1240) (180 180))
+ rect(l8 (-180 370) (180 180))
+ rect(l8 (-180 -1280) (180 180))
+ rect(l8 (23220 370) (180 180))
+ rect(l8 (-180 370) (180 180))
+ rect(l8 (-180 -1280) (180 180))
+ rect(l11 (-21741 859) (2 2))
+ rect(l11 (-2351 -451) (1200 800))
+ rect(l11 (-750 -1450) (300 1400))
+ rect(l11 (-101 -351) (2 2))
+ rect(l11 (-1251 -401) (600 800))
+ rect(l11 (23400 -800) (1200 800))
+ rect(l11 (-750 -1450) (300 1400))
+ rect(l11 (-101 -351) (2 2))
+ rect(l11 (549 -401) (600 800))
+ rect(l9 (-24850 -1500) (500 1500))
+ rect(l9 (22900 -1500) (500 1500))
+ )
+ net(13 name(OUT)
+ rect(l11 (23440 3840) (320 320))
+ rect(l12 (-260 -260) (200 200))
+ rect(l13 (-101 -101) (2 2))
+ rect(l13 (-201 -201) (400 400))
+ )
+ net(14 name(ENABLE)
+ rect(l11 (2440 2940) (320 320))
+ rect(l12 (-260 -260) (200 200))
+ rect(l13 (-101 -101) (2 2))
+ rect(l13 (-201 -201) (400 400))
+ )
+ net(15 name(VSS)
+ rect(l8 (1110 1610) (180 180))
+ rect(l8 (-180 -1280) (180 180))
+ rect(l8 (-180 370) (180 180))
+ rect(l8 (23220 370) (180 180))
+ rect(l8 (-180 -1280) (180 180))
+ rect(l8 (-180 370) (180 180))
+ rect(l11 (-21741 -391) (2 2))
+ rect(l11 (-1901 -401) (300 1400))
+ rect(l11 (-750 -1450) (1200 800))
+ rect(l11 (-551 -401) (2 2))
+ rect(l11 (-1251 -401) (600 800))
+ rect(l11 (23850 -750) (300 1400))
+ rect(l11 (-750 -1450) (1200 800))
+ rect(l11 (-551 -401) (2 2))
+ rect(l11 (549 -401) (600 800))
+ rect(l10 (-24850 -800) (500 1500))
+ rect(l10 (22900 -1500) (500 1500))
+ )
+
+ # Outgoing pins and their connections to nets
+ pin(11 name(FB))
+ pin(12 name(VDD))
+ pin(13 name(OUT))
+ pin(14 name(ENABLE))
+ pin(15 name(VSS))
+
+ # Subcircuits and their connections
+ circuit(1 ND2X1 location(1800 0)
+ pin(0 12)
+ pin(1 1)
+ pin(2 15)
+ pin(3 12)
+ pin(4 11)
+ pin(5 14)
+ pin(6 15)
+ )
+ circuit(2 INVX1 location(4200 0)
+ pin(0 12)
+ pin(1 2)
+ pin(2 15)
+ pin(3 12)
+ pin(4 1)
+ pin(5 15)
+ )
+ circuit(3 INVX1 location(6000 0)
+ pin(0 12)
+ pin(1 3)
+ pin(2 15)
+ pin(3 12)
+ pin(4 2)
+ pin(5 15)
+ )
+ circuit(4 INVX1 location(7800 0)
+ pin(0 12)
+ pin(1 4)
+ pin(2 15)
+ pin(3 12)
+ pin(4 3)
+ pin(5 15)
+ )
+ circuit(5 INVX1 location(9600 0)
+ pin(0 12)
+ pin(1 5)
+ pin(2 15)
+ pin(3 12)
+ pin(4 4)
+ pin(5 15)
+ )
+ circuit(6 INVX1 location(11400 0)
+ pin(0 12)
+ pin(1 6)
+ pin(2 15)
+ pin(3 12)
+ pin(4 5)
+ pin(5 15)
+ )
+ circuit(7 INVX1 location(13200 0)
+ pin(0 12)
+ pin(1 7)
+ pin(2 15)
+ pin(3 12)
+ pin(4 6)
+ pin(5 15)
+ )
+ circuit(8 INVX1 location(15000 0)
+ pin(0 12)
+ pin(1 8)
+ pin(2 15)
+ pin(3 12)
+ pin(4 7)
+ pin(5 15)
+ )
+ circuit(9 INVX1 location(16800 0)
+ pin(0 12)
+ pin(1 9)
+ pin(2 15)
+ pin(3 12)
+ pin(4 8)
+ pin(5 15)
+ )
+ circuit(10 INVX1 location(18600 0)
+ pin(0 12)
+ pin(1 10)
+ pin(2 15)
+ pin(3 12)
+ pin(4 9)
+ pin(5 15)
+ )
+ circuit(11 INVX1 location(20400 0)
+ pin(0 12)
+ pin(1 11)
+ pin(2 15)
+ pin(3 12)
+ pin(4 10)
+ pin(5 15)
+ )
+ circuit(12 INVX1 location(22200 0)
+ pin(0 12)
+ pin(1 13)
+ pin(2 15)
+ pin(3 12)
+ pin(4 11)
+ pin(5 15)
+ )
+
+ )
+)
+
+# Reference netlist
+reference(
+
+ # Device class section
+ class(PMOS MOS4)
+ class(NMOS MOS4)
+
+ # Circuit section
+ # Circuits are the hierarchical building blocks of the netlist.
+ circuit(ND2X1
+
+ # Nets
+ net(1 name(VDD))
+ net(2 name(OUT))
+ net(3 name(VSS))
+ net(4 name(NWELL))
+ net(5 name(B))
+ net(6 name(A))
+ net(7 name(BULK))
+ net(8 name('1'))
+
+ # Outgoing pins and their connections to nets
+ pin(1 name(VDD))
+ pin(2 name(OUT))
+ pin(3 name(VSS))
+ pin(4 name(NWELL))
+ pin(5 name(B))
+ pin(6 name(A))
+ pin(7 name(BULK))
+
+ # Devices and their connections
+ device(1 PMOS
+ name($1)
+ param(L 0.251)
+ param(W 1.6)
+ param(AS 0)
+ param(AD 0)
+ param(PS 0)
+ param(PD 0)
+ terminal(S 2)
+ terminal(G 6)
+ terminal(D 1)
+ terminal(B 4)
+ )
+ device(2 PMOS
+ name($2)
+ param(L 0.25)
+ param(W 1.5)
+ param(AS 0)
+ param(AD 0)
+ param(PS 0)
+ param(PD 0)
+ terminal(S 1)
+ terminal(G 5)
+ terminal(D 2)
+ terminal(B 4)
+ )
+ device(3 NMOS
+ name($3)
+ param(L 0.26)
+ param(W 1)
+ param(AS 0)
+ param(AD 0)
+ param(PS 0)
+ param(PD 0)
+ terminal(S 3)
+ terminal(G 6)
+ terminal(D 8)
+ terminal(B 7)
+ )
+ device(4 NMOS
+ name($4)
+ param(L 0.25)
+ param(W 0.95)
+ param(AS 0)
+ param(AD 0)
+ param(PS 0)
+ param(PD 0)
+ terminal(S 8)
+ terminal(G 5)
+ terminal(D 2)
+ terminal(B 7)
+ )
+
+ )
+ circuit(INVX1
+
+ # Nets
+ net(1 name(VDD))
+ net(2 name(OUT))
+ net(3 name(VSS))
+ net(4 name(NWELL))
+ net(5 name(IN))
+ net(6 name(BULK))
+
+ # Outgoing pins and their connections to nets
+ pin(1 name(VDD))
+ pin(2 name(OUT))
+ pin(3 name(VSS))
+ pin(4 name(NWELL))
+ pin(5 name(IN))
+ pin(6 name(BULK))
+
+ # Devices and their connections
+ device(1 PMOS
+ name($1)
+ param(L 0.25)
+ param(W 1.5)
+ param(AS 0)
+ param(AD 0)
+ param(PS 0)
+ param(PD 0)
+ terminal(S 1)
+ terminal(G 5)
+ terminal(D 2)
+ terminal(B 4)
+ )
+ device(2 NMOS
+ name($2)
+ param(L 0.25)
+ param(W 0.95)
+ param(AS 0)
+ param(AD 0)
+ param(PS 0)
+ param(PD 0)
+ terminal(S 3)
+ terminal(G 5)
+ terminal(D 2)
+ terminal(B 6)
+ )
+
+ )
+ circuit(RINGO
+
+ # Nets
+ net(1 name(VSS))
+ net(2 name(VDD))
+ net(3 name(FB))
+ net(4 name(ENABLE))
+ net(5 name(OUT))
+ net(6 name('1'))
+ net(7 name('2'))
+ net(8 name('3'))
+ net(9 name('4'))
+ net(10 name('5'))
+ net(11 name('6'))
+ net(12 name('7'))
+ net(13 name('8'))
+ net(14 name('9'))
+ net(15 name('10'))
+
+ # Outgoing pins and their connections to nets
+ pin(1 name(VSS))
+ pin(2 name(VDD))
+ pin(3 name(FB))
+ pin(4 name(ENABLE))
+ pin(5 name(OUT))
+
+ # Subcircuits and their connections
+ circuit(1 ND2X1 name($1)
+ pin(0 2)
+ pin(1 6)
+ pin(2 1)
+ pin(3 2)
+ pin(4 3)
+ pin(5 4)
+ pin(6 1)
+ )
+ circuit(2 INVX1 name($2)
+ pin(0 2)
+ pin(1 7)
+ pin(2 1)
+ pin(3 2)
+ pin(4 6)
+ pin(5 1)
+ )
+ circuit(3 INVX1 name($3)
+ pin(0 2)
+ pin(1 8)
+ pin(2 1)
+ pin(3 2)
+ pin(4 7)
+ pin(5 1)
+ )
+ circuit(4 INVX1 name($4)
+ pin(0 2)
+ pin(1 9)
+ pin(2 1)
+ pin(3 2)
+ pin(4 8)
+ pin(5 1)
+ )
+ circuit(5 INVX1 name($5)
+ pin(0 2)
+ pin(1 10)
+ pin(2 1)
+ pin(3 2)
+ pin(4 9)
+ pin(5 1)
+ )
+ circuit(6 INVX1 name($6)
+ pin(0 2)
+ pin(1 11)
+ pin(2 1)
+ pin(3 2)
+ pin(4 10)
+ pin(5 1)
+ )
+ circuit(7 INVX1 name($7)
+ pin(0 2)
+ pin(1 12)
+ pin(2 1)
+ pin(3 2)
+ pin(4 11)
+ pin(5 1)
+ )
+ circuit(8 INVX1 name($8)
+ pin(0 2)
+ pin(1 13)
+ pin(2 1)
+ pin(3 2)
+ pin(4 12)
+ pin(5 1)
+ )
+ circuit(9 INVX1 name($9)
+ pin(0 2)
+ pin(1 14)
+ pin(2 1)
+ pin(3 2)
+ pin(4 13)
+ pin(5 1)
+ )
+ circuit(10 INVX1 name($10)
+ pin(0 2)
+ pin(1 15)
+ pin(2 1)
+ pin(3 2)
+ pin(4 14)
+ pin(5 1)
+ )
+ circuit(11 INVX1 name($11)
+ pin(0 2)
+ pin(1 3)
+ pin(2 1)
+ pin(3 2)
+ pin(4 15)
+ pin(5 1)
+ )
+ circuit(12 INVX1 name($12)
+ pin(0 2)
+ pin(1 5)
+ pin(2 1)
+ pin(3 2)
+ pin(4 3)
+ pin(5 1)
+ )
+
+ )
+)
+
+# Cross reference
+xref(
+ circuit(INVX1 INVX1 match
+ xref(
+ net(4 4 match)
+ net(5 5 match)
+ net(2 2 match)
+ net(6 6 match)
+ net(1 1 match)
+ net(3 3 match)
+ pin(3 3 match)
+ pin(4 4 match)
+ pin(1 1 match)
+ pin(5 5 match)
+ pin(0 0 match)
+ pin(2 2 match)
+ device(2 2 match)
+ device(1 1 match)
+ )
+ )
+ circuit(ND2X1 ND2X1 match
+ xref(
+ net(8 8 mismatch)
+ net(4 4 match)
+ net(6 6 match)
+ net(5 5 match)
+ net(2 2 mismatch)
+ net(7 7 mismatch)
+ net(1 1 mismatch)
+ net(3 3 match)
+ pin(3 3 match)
+ pin(5 5 match)
+ pin(4 4 match)
+ pin(1 1 match)
+ pin(6 6 match)
+ pin(0 0 match)
+ pin(2 2 match)
+ device(3 3 match)
+ device(4 4 match)
+ device(1 1 match)
+ device(2 2 match)
+ )
+ )
+ circuit(RINGO RINGO match
+ xref(
+ net(1 6 match)
+ net(10 15 match)
+ net(2 7 match)
+ net(3 8 match)
+ net(4 9 match)
+ net(5 10 match)
+ net(6 11 match)
+ net(7 12 match)
+ net(8 13 match)
+ net(9 14 match)
+ net(14 4 match)
+ net(11 3 match)
+ net(13 5 match)
+ net(12 2 match)
+ net(15 1 match)
+ pin(3 3 match)
+ pin(0 2 match)
+ pin(2 4 match)
+ pin(1 1 match)
+ pin(4 0 match)
+ circuit(2 2 match)
+ circuit(3 3 match)
+ circuit(4 4 match)
+ circuit(5 5 match)
+ circuit(6 6 match)
+ circuit(7 7 match)
+ circuit(8 8 match)
+ circuit(9 9 match)
+ circuit(10 10 match)
+ circuit(11 11 match)
+ circuit(12 12 match)
+ circuit(1 1 match)
+ )
+ )
+)
diff --git a/testdata/ruby/dbNetlistCompare.rb b/testdata/ruby/dbNetlistCompare.rb
index be77f5bb4..a967fe665 100644
--- a/testdata/ruby/dbNetlistCompare.rb
+++ b/testdata/ruby/dbNetlistCompare.rb
@@ -508,10 +508,39 @@ END
assert_equal(good, true)
+ logger.clear
+ nl2.device_class_by_name("NMOS").equal_parameters = nil
+ assert_equal(nl2.device_class_by_name("NMOS").equal_parameters == nil, true)
+ good = comp.compare(nl1, nl2)
+
+ assert_equal(logger.text, <<"END")
+begin_circuit BUF BUF
+match_nets OUT OUT
+match_nets INT $10
+net_mismatch IN IN
+net_mismatch INT2 $11
+match_pins $0 $1
+match_pins $1 $3
+match_pins $2 $0
+match_pins $3 $2
+match_devices $1 $1
+match_devices $3 $2
+match_devices $5 $3
+match_devices $7 $4
+match_devices $2 $5
+match_devices $4 $6
+match_devices_with_different_parameters $6 $7
+match_devices $8 $8
+end_circuit BUF BUF NOMATCH
+END
+
+ assert_equal(good, false)
+
logger.clear
eqp = RBA::EqualDeviceParameters::new(RBA::DeviceClassMOS3Transistor::PARAM_W, 0.01, 0.0)
eqp = eqp + RBA::EqualDeviceParameters::new(RBA::DeviceClassMOS3Transistor::PARAM_L, 0.2, 0.0)
nl2.device_class_by_name("NMOS").equal_parameters = eqp
+ assert_equal(nl2.device_class_by_name("NMOS").equal_parameters == nil, false)
good = comp.compare(nl1, nl2)
assert_equal(logger.text, <<"END")
@@ -538,9 +567,9 @@ END
assert_equal(good, true)
logger.clear
- eqp = RBA::EqualDeviceParameters::new(RBA::DeviceClassMOS3Transistor::PARAM_W, 0.01, 0.0)
- eqp += RBA::EqualDeviceParameters::new(RBA::DeviceClassMOS3Transistor::PARAM_L, 0.2, 0.0)
- nl2.device_class_by_name("NMOS").equal_parameters = eqp
+ dc = nl2.device_class_by_name("NMOS")
+ dc.equal_parameters = RBA::EqualDeviceParameters::new(RBA::DeviceClassMOS3Transistor::PARAM_W, 0.01, 0.0)
+ dc.equal_parameters += RBA::EqualDeviceParameters::new(RBA::DeviceClassMOS3Transistor::PARAM_L, 0.2, 0.0)
good = comp.compare(nl1, nl2)
assert_equal(logger.text, <<"END")
From 78050b1e5f48a34e000f40c89ad254ad6756b33c Mon Sep 17 00:00:00 2001
From: Matthias Koefferlein
Date: Thu, 27 Feb 2020 17:30:23 +0100
Subject: [PATCH 2/2] Implemented #471: Updated doc.
---
src/lay/lay/doc/about/lvs_ref_global.xml | 10 +++
src/lay/lay/doc/about/lvs_ref_netter.xml | 15 +++++
src/lay/lay/doc/manual/lvs_compare.xml | 71 ++++++++++++++++++++++
src/lvs/lvs/built-in-macros/_lvs_engine.rb | 2 +-
src/lvs/lvs/built-in-macros/_lvs_netter.rb | 2 +-
5 files changed, 98 insertions(+), 2 deletions(-)
diff --git a/src/lay/lay/doc/about/lvs_ref_global.xml b/src/lay/lay/doc/about/lvs_ref_global.xml
index 970b72954..940f6af21 100644
--- a/src/lay/lay/doc/about/lvs_ref_global.xml
+++ b/src/lay/lay/doc/about/lvs_ref_global.xml
@@ -160,4 +160,14 @@ See Netter#same_nets for a des
See Netter#schematic for a description of that function.
+"tolerance" - Specifies compare tolerances for certain device parameters
+
+Usage:
+
+- tolerance(device_class_name, parameter_name, absolute_tolerance [, relative_tolerance])
+- tolerance(device_class_name, parameter_name [, :absolute => absolute_tolerance] [, :relative => relative_tolerance])
+
+
+See Netter#tolerance for a description of that function.
+
diff --git a/src/lay/lay/doc/about/lvs_ref_netter.xml b/src/lay/lay/doc/about/lvs_ref_netter.xml
index 3e22ca91d..b4a1c1b94 100644
--- a/src/lay/lay/doc/about/lvs_ref_netter.xml
+++ b/src/lay/lay/doc/about/lvs_ref_netter.xml
@@ -257,4 +257,19 @@ If no reader is provided, Spice format will be assumed. The reader object is a
Alternatively, a Netlist object can be given which is obtained from any other
source.
+"tolerance" - Specifies compare tolerances for certain device parameters
+
+Usage:
+
+- tolerance(device_class_name, parameter_name, absolute_tolerance [, relative_tolerance])
+- tolerance(device_class_name, parameter_name [, :absolute => absolute_tolerance] [, :relative => relative_tolerance])
+
+
+Specifies a compare tolerance for a specific parameter on a given device class.
+The device class is the name of a device class in the extracted netlist.
+Tolerances can be given in absolute units or relative or both.
+The relative tolerance is given as a factor, so 0.1 is a 10% tolerance.
+Absolute and relative tolerances add, so specifying both allows for a larger
+deviation.
+
diff --git a/src/lay/lay/doc/manual/lvs_compare.xml b/src/lay/lay/doc/manual/lvs_compare.xml
index 01dd882fc..211e5aa8a 100644
--- a/src/lay/lay/doc/manual/lvs_compare.xml
+++ b/src/lay/lay/doc/manual/lvs_compare.xml
@@ -81,6 +81,77 @@
same_device_classes("PMOS_IN_LAYOUT", "PMOS_IN_SCHEMATIC")
same_device_classes("NMOS_IN_LAYOUT", "NMOS_IN_SCHEMATIC")
+ Tolerances
+
+
+ When comparing device parameters, by default strict equivalence is required.
+ However, when drawing a device like a resistor, it's usually difficult to match
+ the exact value unless the resistor calibration is consistent with drawing grids and
+ the resistor geometry is not confined by design rule constraints.
+ So sometimes the target value or a device parameter can only be approximated in
+ the layout. This will by default lead to a mismatch.
+
+
+
+ The solution is to specify parameter tolerances. Tolerances can be specified
+ in an absolute or relative fashion. If an absolute tolerance is given, the layout
+ parameter may deviate from the target value by this tolerance either to
+ lower or higher values. So the unit of the tolerance is the same than the
+ unit of the parameter.
+
+
+
+ If a relative tolerance is given, the deviation is
+ computed from the target value times the tolerance. So the relative tolerance
+ is a factor and a value of 0.05 for example specifies an allowed deviation of
+ plus or minus 5%. Relative tolerances are unit-less.
+
+
+
+ It's also possible to specify both an absolute and a relative tolerance. In this
+ case, both tolerances add and the allowed deviation becomes larger.
+
+
+
+ To specify an absolute tolerance, use the tolerance function:
+
+
+ tolerance("NMOS", "L", 0.05)
+
+
+ The two arguments are the name of the device class and the name of the parameter
+ for which the tolerance will be applied. In the case above, a tolerance of 50nm (the
+ unit of L is micrometer) is applied to the length parameter of "NMOS" devices.
+
+
+
+ A relative tolerance is specified as an additonal forth parameter. You can set
+ the absolute tolerance to zero to specify only relative tolerances. This will
+ specify 1% tolerance for the "L" parameter of "NMOS" devices:
+
+
+ tolerance("NMOS", "L", 0.0, 0.01)
+
+
+ There is also a more explicit notation for the tolerance:
+
+
+ tolerance("NMOS", "L", :absolute => 0.05)
+tolerance("NMOS", "L", :relative => 0.01)
+
+
+ This notation is equivalent to the two forms above.
+
+
+
+ An absolute plus relative tolerance can be specified by giving both.
+ The following calls will give you 50nm absolute and 1% relative tolerance for the "L"
+ parameter of "NMOS" devices:
+
+
+ tolerance("NMOS", "L", 0.05, 0.01)
+tolerance("NMOS", "L", :absolute => 0.05, :relative => 0.01)
+
Pin swapping
diff --git a/src/lvs/lvs/built-in-macros/_lvs_engine.rb b/src/lvs/lvs/built-in-macros/_lvs_engine.rb
index f7b79467e..e1179f3a7 100644
--- a/src/lvs/lvs/built-in-macros/_lvs_engine.rb
+++ b/src/lvs/lvs/built-in-macros/_lvs_engine.rb
@@ -159,7 +159,7 @@ module LVS
# @name tolerance
# @brief Specifies compare tolerances for certain device parameters
# @synopsis tolerance(device_class_name, parameter_name, absolute_tolerance [, relative_tolerance])
- # @synopsis tolerance(device_class_name, parameter_name [:absolute => absolute_tolerance,] [:relative => relative_tolerance,])
+ # @synopsis tolerance(device_class_name, parameter_name [, :absolute => absolute_tolerance] [, :relative => relative_tolerance])
# See \Netter#tolerance for a description of that function.
%w(schematic compare join_symmetric_nets tolerance align same_nets same_circuits same_device_classes equivalent_pins min_caps max_res max_depth max_branch_complexity).each do |f|
diff --git a/src/lvs/lvs/built-in-macros/_lvs_netter.rb b/src/lvs/lvs/built-in-macros/_lvs_netter.rb
index 309d22ae5..ae27f99ea 100644
--- a/src/lvs/lvs/built-in-macros/_lvs_netter.rb
+++ b/src/lvs/lvs/built-in-macros/_lvs_netter.rb
@@ -102,7 +102,7 @@ module LVS
# @name tolerance
# @brief Specifies compare tolerances for certain device parameters
# @synopsis tolerance(device_class_name, parameter_name, absolute_tolerance [, relative_tolerance])
- # @synopsis tolerance(device_class_name, parameter_name [:absolute => absolute_tolerance,] [:relative => relative_tolerance,])
+ # @synopsis tolerance(device_class_name, parameter_name [, :absolute => absolute_tolerance] [, :relative => relative_tolerance])
# Specifies a compare tolerance for a specific parameter on a given device class.
# The device class is the name of a device class in the extracted netlist.
# Tolerances can be given in absolute units or relative or both.