From ab70c42c681dcb1651ca3394459749db2a943ef2 Mon Sep 17 00:00:00 2001
From: Matthias Koefferlein
+Example: +
# skips all MEMORY* circuits from compare
blank_circuit("MEMORY*")
@@ -317,7 +319,8 @@ Use this method andwhere in the script before the compare
Usage:
@@ -325,8 +328,17 @@ This method will force an equivalence between the net_a and net_b from circuit_a and circuit_b (circuit in the three-argument form is for both circuit_a and circuit_b).
In the four-argument form, the circuits can be either given by name or as Circuit -objects. In the three-argument form, the circuit has to be given by name. +objects. In the three-argument form, the circuits have to be given by name pattern. Nets can be either given by name or as Net objects. +In the two-argument form, the circuits and nets have to be given as name pattern. +
+"name pattern" are glob-style pattern - e.g. the following will identify the +all nets starting with "A" from the extracted netlist with the same net from +the schematic netlist for all circuits starting with "INV": +
+
+same_nets("INV*", "A*")
+
After using this function, the compare algorithm will consider these nets equivalent. Use this method to provide hints for the comparer in cases which are difficult to @@ -337,6 +349,18 @@ Names are case sensitive for layout-derived netlists and case-insensitive for SP
Use this method andwhere in the script before the compare call.
+Usage:
++This method is equivalent to same_nets, but requires identity of the given nets. +If the specified nets do not match, an error is reported. +
Usage:
diff --git a/src/lvs/lvs/built-in-macros/_lvs_engine.rb b/src/lvs/lvs/built-in-macros/_lvs_engine.rb index bb24407e3..3a0506516 100644 --- a/src/lvs/lvs/built-in-macros/_lvs_engine.rb +++ b/src/lvs/lvs/built-in-macros/_lvs_engine.rb @@ -115,10 +115,19 @@ module LVS # %LVS% # @name same_nets # @brief Establishes an equivalence between the nets - # @synopsis same_nets(circuit, net_a, net_b) + # @synopsis same_nets(circuit_pattern, net_pattern) + # @synopsis same_nets(circuit_pattern, net_a, net_b) # @synopsis same_nets(circuit_a, net_a, circuit_b, net_b) # See \Netter#same_nets for a description of that function. + # %LVS% + # @name same_nets! + # @brief Establishes an equivalence between the nets (must match) + # @synopsis same_nets!(circuit_pattern, net_pattern) + # @synopsis same_nets!(circuit_pattern, net_a, net_b) + # @synopsis same_nets!(circuit_a, net_a, circuit_b, net_b) + # See \Netter#same_nets! for a description of that function. + # %LVS% # @name same_circuits # @brief Establishes an equivalence between the circuits @@ -174,7 +183,7 @@ module LVS # @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 blank_circuit align same_nets same_circuits same_device_classes equivalent_pins min_caps max_res max_depth max_branch_complexity consider_net_names).each do |f| + %w(schematic compare join_symmetric_nets tolerance blank_circuit align same_nets same_nets! same_circuits same_device_classes equivalent_pins min_caps max_res max_depth max_branch_complexity consider_net_names).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 8e5aa1d63..4a25a1093 100644 --- a/src/lvs/lvs/built-in-macros/_lvs_netter.rb +++ b/src/lvs/lvs/built-in-macros/_lvs_netter.rb @@ -370,14 +370,24 @@ module LVS # %LVS% # @name same_nets # @brief Establishes an equivalence between the nets - # @synopsis same_nets(circuit, net_a, net_b) + # @synopsis same_nets(circuit_pattern, net_pattern) + # @synopsis same_nets(circuit_pattern, net_a, net_b) # @synopsis same_nets(circuit_a, net_a, circuit_b, net_b) # This method will force an equivalence between the net_a and net_b from circuit_a # and circuit_b (circuit in the three-argument form is for both circuit_a and circuit_b). - # + # # In the four-argument form, the circuits can be either given by name or as Circuit - # objects. In the three-argument form, the circuit has to be given by name. + # objects. In the three-argument form, the circuits have to be given by name pattern. # Nets can be either given by name or as Net objects. + # In the two-argument form, the circuits and nets have to be given as name pattern. + # + # "name pattern" are glob-style pattern - e.g. the following will identify the + # all nets starting with "A" from the extracted netlist with the same net from + # the schematic netlist for all circuits starting with "INV": + # + # @code + # same_nets("INV*", "A*") + # @/code # # After using this function, the compare algorithm will consider these nets equivalent. # Use this method to provide hints for the comparer in cases which are difficult to @@ -389,65 +399,125 @@ module LVS # Use this method andwhere in the script before the \compare call. def same_nets(*args) + _same_nets_impl(false, *args) + end - if args.size < 3 - raise("Too few arguments to 'same_nets' (need at least 3)") + # %LVS% + # @name same_nets! + # @brief Establishes an equivalence between the nets with matching requirement + # @synopsis same_nets!(circuit_pattern, net_pattern) + # @synopsis same_nets!(circuit_pattern, net_a, net_b) + # @synopsis same_nets!(circuit_a, net_a, circuit_b, net_b) + # This method is equivalent to \same_nets, but requires identity of the given nets. + # If the specified nets do not match, an error is reported. + + def same_nets!(*args) + _same_nets_impl(true, *args) + end + + def _same_nets_impl(force, *args) + + if args.size < 2 + raise("Too few arguments to 'same_nets' (need at least 2)") end if args.size > 4 raise("Too many arguments to 'same_nets' (need max 4)") end if args.size == 3 - ( ca, a, b ) = args - cb = ca + ( ca, a ) = args + cb = nil ca.is_a?(String) || raise("Circuit argument of 'same_nets' must be a string") + b = nil + a.is_a?(String) || raise("Net argument of 'same_nets' must be a string") + elsif args.size == 3 + ( ca, a, b ) = args + cb = nil + ca.is_a?(String) || raise("Circuit argument of 'same_nets' must be a string") + [ a, b ].each do |n| + n.is_a?(String) || n.is_a?(RBA::Net) || raise("Net arguments of 'same_nets' must be strings or Net objects") + end else ( ca, a, cb, b ) = args [ ca, cb ].each do |n| - n.is_a?(String) || n.is_a?(RBA::Net) || raise("Circuit arguments of 'same_nets' must be strings or Net objects") + n.is_a?(String) || n.is_a?(RBA::Circuit) || raise("Circuit arguments of 'same_nets' must be strings or Circuit objects") + end + [ a, b ].each do |n| + n.is_a?(String) || n.is_a?(RBA::Net) || raise("Net arguments of 'same_nets' must be strings or Net objects") end end - [ a, b ].each do |n| - n.is_a?(String) || n.is_a?(RBA::Net) || raise("Net arguments of 'same_nets' must be strings or Net objects") - end - - @comparer_config << lambda { |comparer| self._same_nets(comparer, ca, a, cb, b) } + @comparer_config << lambda { |comparer| self._same_nets(comparer, ca, a, cb, b, force) } end - def _same_nets(comparer, ca, a, cb, b) + def _same_nets(comparer, ca, a, cb, b, force) ( nl_a, nl_b ) = _ensure_two_netlists - if ca.is_a?(String) - circuit_a = nl_a.circuit_by_name(ca) + cs = !(nl_a.is_case_sensitive? && nl_b.is_case_sensitive?) + + if ca.is_a?(String) && !cb + + n2c = {} + nl_a.circuits_by_name(ca).each { |c| name = cs ? c.name.upcase : c.name; n2c[name] ||= [ nil, nil ]; n2c[name][0] = c } + nl_b.circuits_by_name(ca).each { |c| name = cs ? c.name.upcase : c.name; n2c[name] ||= [ nil, nil ]; n2c[name][1] = c } + + circuits = [] + n2c.keys.sort.each do |n| + if n2c[n][0] && n2c[n][1] + circuits << n2c[n] + end + end + else - circuit_a = ca - end - if cb.is_a?(String) - circuit_b = nl_b.circuit_by_name(cb) - else - circuit_b = cb - end + circuit_a = ca.is_a?(String) ? nl_a.circuit_by_name(ca) : ca + circuit_b = cb.is_a?(String) ? nl_b.circuit_by_name(cb) : cb - if circuit_a && circuit_b - - if a.is_a?(String) - net_a = circuit_a.net_by_name(a) || raise("Not a valid net name in extracted netlist in 'same_nets': #{a} (for circuit #{circuit_a})") - else - net_a = a + circuits = [] + if circuit_a && circuit_b + circuits << [ circuit_a, circuit_b ] end - if b.is_a?(String) - net_b = circuit_b.net_by_name(b) || raise("Not a valid net name in extracted netlist in 'same_nets': #{b} (for circuit #{circuit_b})") + end + + circuits.each do |circuit_a, circuit_b| + + if a.is_a?(String) && !b + + n2n = {} + circuit_a.nets_by_name(a).each { |n| name = cs ? n.name.upcase : n.name; n2n[name] ||= [ nil, nil ]; n2n[name][0] = n } + circuit_b.nets_by_name(a).each { |n| name = cs ? n.name.upcase : n.name; n2n[name] ||= [ nil, nil ]; n2n[name][1] = n } + + nets = [] + n2n.keys.sort.each do |n| + nets << n2n[n] + end + else - net_b = b + + if a.is_a?(String) + net_a = circuit_a.net_by_name(a) || raise("Not a valid net name in extracted netlist in 'same_nets': #{a} (for circuit #{circuit_a})") + else + net_a = a + end + + if b.is_a?(String) + net_b = circuit_b.net_by_name(b) || raise("Not a valid net name in extracted netlist in 'same_nets': #{b} (for circuit #{circuit_b})") + else + net_b = b + end + + nets = [] + if net_a && net_b + nets << [ net_a, net_b ] + end + end - if net_a && net_b - comparer.same_nets(net_a, net_b) + nets.each do |net_a, net_b| + comparer.same_nets(circuit_a, circuit_b, net_a, net_b, force) end end diff --git a/testdata/lvs/ringo_simple_net_and_circuit_equivalence.lvsdb.1 b/testdata/lvs/ringo_simple_net_and_circuit_equivalence.lvsdb.1 index a43d6f458..638555d57 100644 --- a/testdata/lvs/ringo_simple_net_and_circuit_equivalence.lvsdb.1 +++ b/testdata/lvs/ringo_simple_net_and_circuit_equivalence.lvsdb.1 @@ -881,6 +881,7 @@ xref( 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) diff --git a/testdata/lvs/ringo_simple_net_and_circuit_equivalence.lvsdb.2 b/testdata/lvs/ringo_simple_net_and_circuit_equivalence.lvsdb.2 index 04e80f7d8..a2b8e370d 100644 --- a/testdata/lvs/ringo_simple_net_and_circuit_equivalence.lvsdb.2 +++ b/testdata/lvs/ringo_simple_net_and_circuit_equivalence.lvsdb.2 @@ -881,6 +881,7 @@ xref( 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) diff --git a/testdata/ruby/dbNetlist.rb b/testdata/ruby/dbNetlist.rb index 7e5670fd0..392c9a3e8 100644 --- a/testdata/ruby/dbNetlist.rb +++ b/testdata/ruby/dbNetlist.rb @@ -63,6 +63,13 @@ class DBNetlist_TestClass < TestBase assert_equal(nl.circuit_by_cell_index(17).inspect, "nil") assert_equal(nl.circuit_by_name("DOESNOTEXIST").inspect, "nil") + assert_equal(nl.is_case_sensitive?, true) + assert_equal(nl.circuit_by_name("xyz").inspect, "nil") + nl.case_sensitive = false + assert_equal(nl.is_case_sensitive?, false) + assert_equal(nl.circuit_by_name("xyz").name, "XYZ") + nl.case_sensitive = true + cc = RBA::Circuit::new assert_equal(cc.dont_purge, false) cc.dont_purge = true @@ -103,6 +110,11 @@ class DBNetlist_TestClass < TestBase assert_equal(names, [ c.name, cc.name ]) assert_equal(nl.circuits_by_name("X*").collect { |x| x.name }, [ "XYZ" ]) + assert_equal(nl.circuits_by_name("x*").collect { |x| x.name }, []) + nl.case_sensitive = false + assert_equal(nl.circuits_by_name("X*").collect { |x| x.name }, [ "XYZ" ]) + assert_equal(nl.circuits_by_name("x*").collect { |x| x.name }, [ "XYZ" ]) + nl.case_sensitive = true assert_equal(nl.circuits_by_name("???").collect { |x| x.name }, [ "XYZ", "UVW" ]) assert_equal(nl.circuits_by_name("*").collect { |x| x.name }, [ "XYZ", "UVW" ]) assert_equal(nl.circuits_by_name("P*").collect { |x| x.name }, []) @@ -702,6 +714,11 @@ class DBNetlist_TestClass < TestBase assert_equal(c.net_by_name("DOESNOTEXIST").inspect, "nil") assert_equal(c.nets_by_name("DOESNOTEXIST").collect(&:name), []) + assert_equal(c.net_by_name("net1").inspect, "nil") + nl.case_sensitive = false + assert_equal(c.net_by_name("net1").name, "NET1") + nl.case_sensitive = true + net2 = c.create_net net2.name = "NET2" @@ -709,6 +726,11 @@ class DBNetlist_TestClass < TestBase c.each_net { |n| names << n.name } assert_equal(names, [ "NET1", "NET2" ]) assert_equal(c.nets_by_name("NET*").collect(&:name), ["NET1", "NET2"]) + assert_equal(c.nets_by_name("net*").collect(&:name), []) + nl.case_sensitive = false + assert_equal(c.nets_by_name("NET*").collect(&:name), ["NET1", "NET2"]) + assert_equal(c.nets_by_name("net*").collect(&:name), ["NET1", "NET2"]) + nl.case_sensitive = true assert_equal(net1.pin_count, 0) c.connect_pin(pina1, net1) diff --git a/testdata/ruby/dbNetlistCompare.rb b/testdata/ruby/dbNetlistCompare.rb index 58b3339ca..9fe3b704d 100644 --- a/testdata/ruby/dbNetlistCompare.rb +++ b/testdata/ruby/dbNetlistCompare.rb @@ -333,6 +333,8 @@ END assert_equal(logger.text(), <<"END") begin_circuit INV INV +match_nets VDD VDD +match_nets VSS VSS match_nets OUT OUT match_nets IN IN match_pins $0 $1 @@ -459,6 +461,8 @@ END assert_equal(logger.text, <<"END") begin_circuit BUF BUF +match_nets VDD VDD +match_nets VSS VSS match_nets OUT OUT match_nets INT $10 net_mismatch IN IN @@ -487,6 +491,8 @@ END assert_equal(logger.text, <<"END") begin_circuit BUF BUF +match_nets VDD VDD +match_nets VSS VSS match_nets OUT OUT match_nets IN IN match_ambiguous_nets INT $10 @@ -515,6 +521,8 @@ END assert_equal(logger.text, <<"END") begin_circuit BUF BUF +match_nets VDD VDD +match_nets VSS VSS match_nets OUT OUT match_nets INT $10 net_mismatch IN IN @@ -545,6 +553,8 @@ END assert_equal(logger.text, <<"END") begin_circuit BUF BUF +match_nets VDD VDD +match_nets VSS VSS match_nets OUT OUT match_nets IN IN match_ambiguous_nets INT $10 @@ -574,6 +584,8 @@ END assert_equal(logger.text, <<"END") begin_circuit BUF BUF +match_nets VDD VDD +match_nets VSS VSS match_nets OUT OUT match_nets IN IN match_ambiguous_nets INT $10 @@ -636,17 +648,20 @@ END # NOTE: adding this power hint makes the device class error harder to detect ca = nl1.circuit_by_name("BUF") cb = nl2.circuit_by_name("BUF") - comp.same_nets(ca.net_by_name("VDD"), cb.net_by_name("VDD")) - comp.same_nets(ca.net_by_name("VSS"), cb.net_by_name("VSS")) + comp.same_nets(ca.net_by_name("VDD"), cb.net_by_name("VDD"), false) + comp.same_nets(ca.net_by_name("VSS"), cb.net_by_name("VSS"), false) + comp.same_nets(ca.net_by_name("OUT"), cb.net_by_name("OUT"), false) good = comp.compare(nl1, nl2) assert_equal(logger.text, <<"END") begin_circuit BUF BUF +match_nets VDD VDD +match_nets VSS VSS +match_nets OUT OUT match_nets INT $10 match_nets IN IN net_mismatch INT2 $11 -net_mismatch OUT OUT match_pins $0 $1 match_pins $1 $3 match_pins $2 $0 @@ -666,6 +681,157 @@ END end + def test_6b + + nls1 = <<"END" +circuit BUF ($1=IN,$2=OUT,$3=VDD,$4=VSS); + device PMOS $1 (S=VDD,G=IN,D=INT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOS $2 (S=VSS,G=IN,D=INT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device PMOS $3 (S=VDD,G=INT,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOS $4 (S=VSS,G=INT,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device PMOS $5 (S=VDD,G=IN,D=INT2) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOS $6 (S=VSS,G=IN,D=INT2) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device PMOSB $7 (S=VDD,G=INT2,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOSB $8 (S=VSS,G=INT2,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); +end; +END + + nls2 = <<"END" +circuit BUF ($1=VDD,$2=IN,$3=VSS,$4=OUT); + device PMOS $1 (S=VDD,G=IN,D=$10) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device PMOS $2 (S=VDD,G=$10,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device PMOS $3 (S=VDD,G=IN,D=$11) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device PMOS $4 (S=VDD,G=$11,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOS $5 (S=$10,G=IN,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOS $6 (S=OUT,G=$10,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOS $7 (S=$11,G=IN,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOSB $8 (S=OUT,G=$11,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); +end; +END + + nl1 = RBA::Netlist::new + nl2 = RBA::Netlist::new + prep_nl(nl1, nls1) + prep_nl(nl2, nls2) + + logger = NetlistCompareTestLogger::new + comp = RBA::NetlistComparer::new(logger) + + # NOTE: adding this power hint makes the device class error harder to detect + ca = nl1.circuit_by_name("BUF") + cb = nl2.circuit_by_name("BUF") + comp.same_nets(ca.net_by_name("VDD"), cb.net_by_name("VDD"), true) + comp.same_nets(ca.net_by_name("VSS"), cb.net_by_name("VSS"), true) + comp.same_nets(ca.net_by_name("OUT"), cb.net_by_name("OUT"), true) + + good = comp.compare(nl1, nl2) + + assert_equal(logger.text, <<"END") +begin_circuit BUF BUF +net_mismatch VDD VDD +match_nets VSS VSS +net_mismatch OUT OUT +match_nets INT $10 +match_nets 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_with_different_device_classes $7 $4 +match_devices $2 $5 +match_devices $4 $6 +match_devices $6 $7 +match_devices $8 $8 +end_circuit BUF BUF NOMATCH +END + + assert_equal(good, false) + + end + + def test_6c + + nls1 = <<"END" +circuit BUF ($1=IN,$2=OUT,$3=VDD,$4=VSS); + device PMOS $1 (S=VDD,G=IN,D=INT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOS $2 (S=VSS,G=IN,D=INT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device PMOS $3 (S=VDD,G=INT,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOS $4 (S=VSS,G=INT,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device PMOS $5 (S=VDD,G=IN,D=INT2) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOS $6 (S=VSS,G=IN,D=INT2) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device PMOSB $7 (S=VDD,G=INT2,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOSB $8 (S=VSS,G=INT2,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); +end; +END + + nls2 = <<"END" +circuit BUF ($1=VDD,$2=IN,$3=VSS,$4=OUT); + device PMOS $1 (S=VDD,G=IN,D=$10) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device PMOS $2 (S=VDD,G=$10,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device PMOS $3 (S=VDD,G=IN,D=$11) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device PMOS $4 (S=VDD,G=$11,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOS $5 (S=$10,G=IN,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOS $6 (S=OUT,G=$10,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOS $7 (S=$11,G=IN,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOSB $8 (S=OUT,G=$11,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); +end; +END + + nl1 = RBA::Netlist::new + nl2 = RBA::Netlist::new + prep_nl(nl1, nls1) + prep_nl(nl2, nls2) + + logger = NetlistCompareTestLogger::new + comp = RBA::NetlistComparer::new(logger) + + # NOTE: adding this power hint makes the device class error harder to detect + ca = nl1.circuit_by_name("BUF") + cb = nl2.circuit_by_name("BUF") + comp.same_nets(ca, cb, ca.net_by_name("VDD"), cb.net_by_name("VDD"), true) + comp.same_nets(ca, cb, ca.net_by_name("VSS"), nil, false) + comp.same_nets(ca, cb, ca.net_by_name("OUT"), nil, true) + + good = comp.compare(nl1, nl2) + + assert_equal(logger.text, <<"END") +begin_circuit BUF BUF +net_mismatch VDD VDD +match_nets VSS (null) +net_mismatch OUT (null) +match_nets INT $10 +match_nets IN IN +net_mismatch INT2 (null) +net_mismatch (null) VSS +net_mismatch (null) OUT +net_mismatch (null) $11 +match_pins $0 $1 +match_pins $2 $0 +match_pins $1 (null) +match_pins $3 (null) +match_pins (null) $2 +match_pins (null) $3 +match_devices $1 $1 +device_mismatch $3 $2 +device_mismatch $5 $3 +device_mismatch (null) $4 +device_mismatch $6 $5 +device_mismatch $4 $6 +device_mismatch $2 $7 +device_mismatch (null) $8 +device_mismatch $7 (null) +device_mismatch $8 (null) +end_circuit BUF BUF NOMATCH +END + + assert_equal(good, false) + + end + def test_7 nls1 = <<"END" @@ -713,6 +879,8 @@ END assert_equal(logger.text, <<"END") begin_circuit BUF BUF +match_nets VDD VDD +match_nets VSS VSS net_mismatch INT $10 match_nets IN IN net_mismatch INT2 $11