mirror of https://github.com/KLayout/klayout.git
Put more amphasis on net names to resolve ambiguities
The problem was that with the floating test case, the ambiguity resolution sometimes assigned the wrong pins and floating pins/connected pins were swapped. One option is to make the ambiguity resolver consider the pin connection state when tenatively evaluating nodes. Another option is to put more emphasis on net names and use them for ambiguity resolution. This has helped here.
This commit is contained in:
parent
60ed0cdc89
commit
550e2622bf
|
|
@ -523,12 +523,13 @@ class NetGraph;
|
|||
struct CompareData
|
||||
{
|
||||
CompareData ()
|
||||
: other (0), max_depth (0), max_n_branch (0), logger (0), circuit_pin_mapper (0)
|
||||
: other (0), max_depth (0), max_n_branch (0), dont_consider_net_names (false), logger (0), circuit_pin_mapper (0)
|
||||
{ }
|
||||
|
||||
NetGraph *other;
|
||||
size_t max_depth;
|
||||
size_t max_n_branch;
|
||||
bool dont_consider_net_names;
|
||||
NetlistCompareLogger *logger;
|
||||
CircuitPinMapper *circuit_pin_mapper;
|
||||
};
|
||||
|
|
@ -1009,7 +1010,7 @@ public:
|
|||
* with a proposed identity. With "with_ambiguous", amiguities are resolved by trying
|
||||
* different combinations in tentative mode and deciding for one combination if possible.
|
||||
*/
|
||||
size_t derive_node_identities_from_node_set (const std::vector<const NetGraphNode *> &nodes, const std::vector<const NetGraphNode *> &other_nodes, size_t depth, size_t n_branch, TentativeNodeMapping *tentative, bool with_ambiguous, CompareData *data);
|
||||
size_t derive_node_identities_from_node_set (std::vector<const NetGraphNode *> &nodes, std::vector<const NetGraphNode *> &other_nodes, size_t depth, size_t n_branch, TentativeNodeMapping *tentative, bool with_ambiguous, CompareData *data);
|
||||
|
||||
private:
|
||||
std::vector<NetGraphNode> m_nodes;
|
||||
|
|
@ -1382,7 +1383,7 @@ NetGraphNode::edge_equal (const db::Net *a, const db::Net *b)
|
|||
*/
|
||||
struct NodeRange
|
||||
{
|
||||
NodeRange (size_t _num, std::vector<const NetGraphNode *>::const_iterator _n1, std::vector<const NetGraphNode *>::const_iterator _nn1, std::vector<const NetGraphNode *>::const_iterator _n2, std::vector<const NetGraphNode *>::const_iterator _nn2)
|
||||
NodeRange (size_t _num, std::vector<const NetGraphNode *>::iterator _n1, std::vector<const NetGraphNode *>::iterator _nn1, std::vector<const NetGraphNode *>::iterator _n2, std::vector<const NetGraphNode *>::iterator _nn2)
|
||||
: num (_num), n1 (_n1), nn1 (_nn1), n2 (_n2), nn2 (_nn2)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
|
|
@ -1394,7 +1395,7 @@ struct NodeRange
|
|||
}
|
||||
|
||||
size_t num;
|
||||
std::vector<const NetGraphNode *>::const_iterator n1, nn1, n2, nn2;
|
||||
std::vector<const NetGraphNode *>::iterator n1, nn1, n2, nn2;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
|
@ -1680,8 +1681,81 @@ NetGraph::derive_node_identities (size_t net_index, size_t depth, size_t n_branc
|
|||
return new_nodes;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
struct SortNodeByNet
|
||||
{
|
||||
public:
|
||||
bool operator() (const NetGraphNode *a, const NetGraphNode *b) const
|
||||
{
|
||||
tl_assert (a->net () && b->net ());
|
||||
return a->net ()->name () < b->net ()->name ();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
static void sort_node_range_by_best_match (NodeRange &nr)
|
||||
{
|
||||
std::stable_sort (nr.n1, nr.nn1, SortNodeByNet ());
|
||||
std::stable_sort (nr.n2, nr.nn2, SortNodeByNet ());
|
||||
|
||||
std::vector<const NetGraphNode *> nomatch1, nomatch2;
|
||||
nomatch1.reserve (nr.nn1 - nr.n1);
|
||||
nomatch2.reserve (nr.nn2 - nr.n2);
|
||||
|
||||
std::vector<const NetGraphNode *>::const_iterator i = nr.n1, j = nr.n2;
|
||||
std::vector<const NetGraphNode *>::iterator iw = nr.n1, jw = nr.n2;
|
||||
|
||||
SortNodeByNet compare;
|
||||
|
||||
while (i != nr.nn1 || j != nr.nn2) {
|
||||
if (j == nr.nn2) {
|
||||
nomatch1.push_back (*i);
|
||||
++i;
|
||||
} else if (i == nr.nn1) {
|
||||
nomatch2.push_back (*j);
|
||||
++j;
|
||||
} else if (compare (*i, *j)) {
|
||||
nomatch1.push_back (*i);
|
||||
++i;
|
||||
} else if (compare (*j, *i)) {
|
||||
nomatch2.push_back (*j);
|
||||
++j;
|
||||
} else {
|
||||
if (iw != i) {
|
||||
*iw = *i;
|
||||
}
|
||||
++iw, ++i;
|
||||
if (jw != j) {
|
||||
*jw = *j;
|
||||
}
|
||||
++jw, ++j;
|
||||
}
|
||||
}
|
||||
|
||||
tl_assert (iw + nomatch1.size () == nr.nn1);
|
||||
tl_assert (jw + nomatch2.size () == nr.nn2);
|
||||
|
||||
for (i = nomatch1.begin (); i != nomatch1.end (); ++i) {
|
||||
*iw++ = *i;
|
||||
}
|
||||
for (j = nomatch2.begin (); j != nomatch2.end (); ++j) {
|
||||
*jw++ = *j;
|
||||
}
|
||||
}
|
||||
|
||||
static bool net_names_are_different (const db::Net *a, const db::Net *b)
|
||||
{
|
||||
if (! a || ! b || a->name ().empty () || b->name ().empty ()) {
|
||||
return false;
|
||||
} else {
|
||||
return (a->name () != b->name ());
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
NetGraph::derive_node_identities_from_node_set (const std::vector<const NetGraphNode *> &nodes, const std::vector<const NetGraphNode *> &other_nodes, size_t depth, size_t n_branch, TentativeNodeMapping *tentative, bool with_ambiguous, CompareData *data)
|
||||
NetGraph::derive_node_identities_from_node_set (std::vector<const NetGraphNode *> &nodes, std::vector<const NetGraphNode *> &other_nodes, size_t depth, size_t n_branch, TentativeNodeMapping *tentative, bool with_ambiguous, CompareData *data)
|
||||
{
|
||||
#if defined(PRINT_DEBUG_NETCOMPARE)
|
||||
std::string indent;
|
||||
|
|
@ -1757,8 +1831,8 @@ NetGraph::derive_node_identities_from_node_set (const std::vector<const NetGraph
|
|||
|
||||
std::vector<NodeRange> node_ranges;
|
||||
|
||||
std::vector<const NetGraphNode *>::const_iterator n1 = nodes.begin ();
|
||||
std::vector<const NetGraphNode *>::const_iterator n2 = other_nodes.begin ();
|
||||
std::vector<const NetGraphNode *>::iterator n1 = nodes.begin ();
|
||||
std::vector<const NetGraphNode *>::iterator n2 = other_nodes.begin ();
|
||||
|
||||
while (n1 != nodes.end () && n2 != other_nodes.end ()) {
|
||||
|
||||
|
|
@ -1778,7 +1852,7 @@ NetGraph::derive_node_identities_from_node_set (const std::vector<const NetGraph
|
|||
continue;
|
||||
}
|
||||
|
||||
std::vector<const NetGraphNode *>::const_iterator nn1 = n1, nn2 = n2;
|
||||
std::vector<const NetGraphNode *>::iterator nn1 = n1, nn2 = n2;
|
||||
|
||||
size_t num = 1;
|
||||
++nn1;
|
||||
|
|
@ -1853,6 +1927,16 @@ NetGraph::derive_node_identities_from_node_set (const std::vector<const NetGraph
|
|||
|
||||
if (! (*nr->n1)->has_other () && ! (*nr->n2)->has_other ()) {
|
||||
|
||||
// in tentative mode, reject this choice if both nets are named and
|
||||
// their names differ -> this favors net matching by name
|
||||
|
||||
if (tentative && ! data->dont_consider_net_names && net_names_are_different ((*nr->n1)->net (), (*nr->n2)->net ())) {
|
||||
#if defined(PRINT_DEBUG_NETCOMPARE)
|
||||
tl::info << indent << "rejecting pair as names are not identical: " << (*nr->n1)->net ()->expanded_name () << " vs. " << (*nr->n2)->net ()->expanded_name ();
|
||||
#endif
|
||||
return std::numeric_limits<size_t>::max ();
|
||||
}
|
||||
|
||||
// A single candiate: just take this one -> this may render
|
||||
// inexact matches, but further propagates net pairing
|
||||
|
||||
|
|
@ -1909,10 +1993,17 @@ NetGraph::derive_node_identities_from_node_set (const std::vector<const NetGraph
|
|||
#if defined(PRINT_DEBUG_NETCOMPARE)
|
||||
tl::info << indent << "analyzing ambiguity group with " << nr->num << " members";
|
||||
#endif
|
||||
|
||||
// sort the ambiguity group such that net names
|
||||
|
||||
std::vector<std::pair<const NetGraphNode *, const NetGraphNode *> > pairs;
|
||||
tl::equivalence_clusters<const NetGraphNode *> equivalent_other_nodes;
|
||||
std::set<const NetGraphNode *> seen;
|
||||
|
||||
if (! data->dont_consider_net_names) {
|
||||
sort_node_range_by_best_match (*nr);
|
||||
}
|
||||
|
||||
for (std::vector<const NetGraphNode *>::const_iterator i1 = nr->n1; i1 != nr->nn1; ++i1) {
|
||||
|
||||
if ((*i1)->has_other ()) {
|
||||
|
|
@ -2061,6 +2152,8 @@ NetlistComparer::NetlistComparer (NetlistCompareLogger *logger)
|
|||
|
||||
m_max_depth = 8;
|
||||
m_max_n_branch = 100;
|
||||
|
||||
m_dont_consider_net_names = false;
|
||||
}
|
||||
|
||||
NetlistComparer::~NetlistComparer ()
|
||||
|
|
@ -2617,6 +2710,7 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2,
|
|||
data.other = &g2;
|
||||
data.max_depth = m_max_depth;
|
||||
data.max_n_branch = m_max_n_branch;
|
||||
data.dont_consider_net_names = m_dont_consider_net_names;
|
||||
data.circuit_pin_mapper = &circuit_pin_mapper;
|
||||
data.logger = mp_logger;
|
||||
|
||||
|
|
@ -2669,6 +2763,7 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2,
|
|||
data.other = &g2;
|
||||
data.max_depth = m_max_depth;
|
||||
data.max_n_branch = m_max_n_branch;
|
||||
data.dont_consider_net_names = m_dont_consider_net_names;
|
||||
data.circuit_pin_mapper = &circuit_pin_mapper;
|
||||
data.logger = mp_logger;
|
||||
|
||||
|
|
|
|||
|
|
@ -245,6 +245,23 @@ public:
|
|||
return m_max_depth;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a value indicating whether not to consider net names
|
||||
* This feature is mainly intended for testing.
|
||||
*/
|
||||
void set_dont_consider_net_names (bool f)
|
||||
{
|
||||
m_dont_consider_net_names = f;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets a value indicating whether not to consider net names
|
||||
*/
|
||||
bool dont_consider_net_names () const
|
||||
{
|
||||
return m_dont_consider_net_names;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the maximum branch complexity
|
||||
*
|
||||
|
|
@ -308,6 +325,7 @@ protected:
|
|||
double m_res_threshold;
|
||||
size_t m_max_n_branch;
|
||||
size_t m_max_depth;
|
||||
bool m_dont_consider_net_names;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1661,6 +1661,7 @@ TEST(11_MismatchingSubcircuits)
|
|||
|
||||
NetlistCompareTestLogger logger;
|
||||
db::NetlistComparer comp (&logger);
|
||||
comp.set_dont_consider_net_names (true);
|
||||
|
||||
bool good = comp.compare (&nl1, &nl2);
|
||||
|
||||
|
|
@ -1696,6 +1697,7 @@ TEST(11_MismatchingSubcircuits)
|
|||
|
||||
db::NetlistCrossReference xref;
|
||||
db::NetlistComparer comp_xref (&xref);
|
||||
comp_xref.set_dont_consider_net_names (true);
|
||||
|
||||
good = comp_xref.compare (&nl1, &nl2);
|
||||
|
||||
|
|
@ -2521,6 +2523,7 @@ TEST(17_InherentlyAmbiguousDecoder)
|
|||
NetlistCompareTestLogger logger;
|
||||
db::NetlistComparer comp (&logger);
|
||||
comp.equivalent_pins (nl2.circuit_by_name ("NAND"), 0, 1);
|
||||
comp.set_dont_consider_net_names (true);
|
||||
|
||||
bool good = comp.compare (&nl1, &nl2);
|
||||
|
||||
|
|
@ -2572,7 +2575,61 @@ TEST(17_InherentlyAmbiguousDecoder)
|
|||
|
||||
EXPECT_EQ (good, true);
|
||||
|
||||
comp.set_dont_consider_net_names (false);
|
||||
|
||||
logger.clear ();
|
||||
good = comp.compare (&nl1, &nl2);
|
||||
|
||||
EXPECT_EQ (logger.text (),
|
||||
"begin_circuit NAND NAND\n"
|
||||
"match_nets VSS VSS\n"
|
||||
"match_nets INT INT\n"
|
||||
"match_nets OUT OUT\n"
|
||||
"match_nets VDD VDD\n"
|
||||
"match_nets B B\n"
|
||||
"match_nets A A\n"
|
||||
"match_pins $0 $0\n"
|
||||
"match_pins $1 $1\n"
|
||||
"match_pins $2 $2\n"
|
||||
"match_pins $3 $3\n"
|
||||
"match_pins $4 $4\n"
|
||||
"match_devices $1 $1\n"
|
||||
"match_devices $2 $2\n"
|
||||
"match_devices $3 $3\n"
|
||||
"match_devices $4 $4\n"
|
||||
"end_circuit NAND NAND MATCH\n"
|
||||
"begin_circuit DECODER DECODER\n"
|
||||
"match_nets VSS VSS\n"
|
||||
"match_nets VDD VDD\n"
|
||||
"match_nets NQ0 NQ0\n"
|
||||
"match_nets NQ1 NQ1\n"
|
||||
"match_nets NQ2 NQ2\n"
|
||||
"match_nets NQ3 NQ3\n"
|
||||
"match_ambiguous_nets NA NA\n"
|
||||
"match_ambiguous_nets NB NB\n"
|
||||
"match_nets B B\n"
|
||||
"match_nets A A\n"
|
||||
"match_pins $0 $1\n"
|
||||
"match_pins $1 $0\n"
|
||||
"match_pins $2 $2\n"
|
||||
"match_pins $3 $3\n"
|
||||
"match_pins $4 $4\n"
|
||||
"match_pins $5 $5\n"
|
||||
"match_pins $6 $6\n"
|
||||
"match_pins $7 $7\n"
|
||||
"match_subcircuits $1 $1\n"
|
||||
"match_subcircuits $2 $2\n"
|
||||
"match_subcircuits $4 $3\n"
|
||||
"match_subcircuits $6 $4\n"
|
||||
"match_subcircuits $3 $5\n"
|
||||
"match_subcircuits $5 $6\n"
|
||||
"end_circuit DECODER DECODER MATCH"
|
||||
);
|
||||
|
||||
EXPECT_EQ (good, true);
|
||||
|
||||
logger.clear ();
|
||||
comp.set_dont_consider_net_names (true);
|
||||
comp.same_nets (nl1.circuit_by_name ("DECODER")->net_by_name ("A"), nl2.circuit_by_name ("DECODER")->net_by_name ("A"));
|
||||
good = comp.compare (&nl1, &nl2);
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
#include "lymMacro.h"
|
||||
#include "tlFileUtils.h"
|
||||
|
||||
void run_test (tl::TestBase *_this, const std::string &suffix, const std::string &layout, bool with_l2n = false)
|
||||
void run_test (tl::TestBase *_this, const std::string &suffix, const std::string &layout, bool with_l2n = false, const std::string &top = std::string ())
|
||||
{
|
||||
std::string rs = tl::testsrc ();
|
||||
rs += "/testdata/lvs/" + suffix + ".lvs";
|
||||
|
|
@ -57,7 +57,8 @@ void run_test (tl::TestBase *_this, const std::string &suffix, const std::string
|
|||
"$lvs_test_target_lvsdb = '%s'\n"
|
||||
"$lvs_test_target_cir = '%s'\n"
|
||||
"$lvs_test_target_l2n = '%s'\n"
|
||||
, src, output_lvsdb, output_cir, output_l2n)
|
||||
"$lvs_test_top = '%s'\n"
|
||||
, src, output_lvsdb, output_cir, output_l2n, top)
|
||||
);
|
||||
config.set_interpreter (lym::Macro::Ruby);
|
||||
EXPECT_EQ (config.run (), 0);
|
||||
|
|
@ -148,3 +149,8 @@ TEST(15_simple_dummy_device)
|
|||
{
|
||||
run_test (_this, "ringo_simple_dummy_device", "ringo_dummy_device.gds");
|
||||
}
|
||||
|
||||
TEST(16_floating)
|
||||
{
|
||||
run_test (_this, "floating", "floating.gds", false, "TOP");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
* Extracted by KLayout
|
||||
|
||||
* cell TOP
|
||||
* pin A
|
||||
* pin C
|
||||
* pin SUBSTRATE
|
||||
.SUBCKT TOP 2 3 4
|
||||
* net 2 A
|
||||
* net 3 C
|
||||
* net 4 SUBSTRATE
|
||||
* cell instance $1 r0 *1 0,0
|
||||
X$1 2 3 1 6 4 DINV
|
||||
* cell instance $2 r0 *1 3.6,0
|
||||
X$2 5 6 1 4 INVX1
|
||||
.ENDS TOP
|
||||
|
||||
* cell DINV
|
||||
* pin A<1>
|
||||
* pin A<2>
|
||||
* pin B<2>
|
||||
* pin VDD
|
||||
* pin VSS
|
||||
.SUBCKT DINV 1 2 3 5 6
|
||||
* net 1 A<1>
|
||||
* net 2 A<2>
|
||||
* net 3 B<2>
|
||||
* net 4 B<1>
|
||||
* net 5 VDD
|
||||
* net 6 VSS
|
||||
* cell instance $1 r0 *1 0,0
|
||||
X$1 4 5 1 6 INVX1
|
||||
* cell instance $2 r0 *1 1.8,0
|
||||
X$2 3 5 2 6 INVX1
|
||||
.ENDS DINV
|
||||
|
||||
* cell INVX1
|
||||
* pin OUT
|
||||
* pin VDD
|
||||
* pin IN
|
||||
* pin VSS
|
||||
.SUBCKT INVX1 1 2 3 4
|
||||
* net 1 OUT
|
||||
* net 2 VDD
|
||||
* net 3 IN
|
||||
* net 4 VSS
|
||||
* device instance $1 r0 *1 0.85,2.135 NMOS
|
||||
M$1 4 3 1 4 NMOS L=0.25U W=0.95U AS=0.40375P AD=0.40375P PS=2.75U PD=2.75U
|
||||
* device instance $2 r0 *1 0.85,5.8 PMOS
|
||||
M$2 2 3 1 2 PMOS L=0.25U W=1.5U AS=0.6375P AD=0.6375P PS=3.85U PD=3.85U
|
||||
.ENDS INVX1
|
||||
Binary file not shown.
|
|
@ -0,0 +1,75 @@
|
|||
|
||||
source($lvs_test_source, $lvs_test_top)
|
||||
|
||||
report_lvs($lvs_test_target_lvsdb, true)
|
||||
|
||||
target_netlist($lvs_test_target_cir, write_spice, "Extracted by KLayout")
|
||||
|
||||
schematic("floating_ref.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
|
||||
|
||||
netlist.simplify
|
||||
align
|
||||
|
||||
compare
|
||||
|
||||
|
|
@ -0,0 +1,454 @@
|
|||
#%lvsdb-klayout
|
||||
|
||||
# Layout
|
||||
layout(
|
||||
top(TOP)
|
||||
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 '5/0')
|
||||
layer(l13 '5/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) (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) (425 950))
|
||||
)
|
||||
terminal(B
|
||||
rect(l7 (-125 -475) (250 950))
|
||||
)
|
||||
)
|
||||
|
||||
# Circuit section
|
||||
# Circuits are the hierarchical building blocks of the netlist.
|
||||
circuit(INVX1
|
||||
|
||||
# Circuit boundary
|
||||
rect((-100 400) (2000 7600))
|
||||
|
||||
# Nets with their geometries
|
||||
net(1 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(2 name(VDD)
|
||||
rect(l3 (-100 4500) (2000 3500))
|
||||
rect(l8 (-1090 -890) (180 180))
|
||||
rect(l8 (-580 -1030) (180 180))
|
||||
rect(l8 (-180 -730) (180 180))
|
||||
rect(l8 (-180 -730) (180 180))
|
||||
rect(l11 (-590 1460) (1800 800))
|
||||
rect(l11 (-1050 -550) (300 300))
|
||||
rect(l11 (-700 -850) (300 300))
|
||||
rect(l11 (299 499) (2 2))
|
||||
rect(l11 (-601 -2201) (300 1400))
|
||||
rect(l2 (-350 -1450) (425 1500))
|
||||
rect(l9 (-75 450) (500 500))
|
||||
)
|
||||
net(3 name(IN)
|
||||
rect(l4 (725 2860) (250 1940))
|
||||
rect(l4 (-525 -1850) (300 300))
|
||||
rect(l4 (-25 -1840) (250 1450))
|
||||
rect(l4 (-250 1940) (250 2000))
|
||||
rect(l4 (-250 -2000) (250 2000))
|
||||
rect(l8 (-465 -3790) (180 180))
|
||||
rect(l11 (-91 -91) (2 2))
|
||||
rect(l11 (-151 -151) (300 300))
|
||||
)
|
||||
net(4 name(VSS)
|
||||
rect(l8 (810 710) (180 180))
|
||||
rect(l8 (-580 880) (180 180))
|
||||
rect(l8 (-180 370) (180 180))
|
||||
rect(l11 (-590 -2100) (1800 800))
|
||||
rect(l11 (-1050 -550) (300 300))
|
||||
rect(l11 (-101 -151) (2 2))
|
||||
rect(l11 (-601 399) (300 1360))
|
||||
rect(l6 (-350 -900) (425 950))
|
||||
rect(l10 (-75 -2010) (500 400))
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(1 name(OUT))
|
||||
pin(2 name(VDD))
|
||||
pin(3 name(IN))
|
||||
pin(4 name(VSS))
|
||||
|
||||
# Devices and their connections
|
||||
device(1 D$NMOS
|
||||
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 4)
|
||||
terminal(G 3)
|
||||
terminal(D 1)
|
||||
terminal(B 4)
|
||||
)
|
||||
device(2 D$PMOS
|
||||
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 2)
|
||||
terminal(G 3)
|
||||
terminal(D 1)
|
||||
terminal(B 2)
|
||||
)
|
||||
|
||||
)
|
||||
circuit(DINV
|
||||
|
||||
# Circuit boundary
|
||||
rect((-100 400) (3800 7600))
|
||||
|
||||
# Nets with their geometries
|
||||
net(1 name('A<1>')
|
||||
rect(l8 (510 3010) (180 180))
|
||||
rect(l11 (-91 -91) (2 2))
|
||||
)
|
||||
net(2 name('A<2>')
|
||||
rect(l8 (2310 3010) (180 180))
|
||||
rect(l11 (-91 -91) (2 2))
|
||||
)
|
||||
net(3 name('B<2>')
|
||||
rect(l11 (2999 3999) (2 2))
|
||||
rect(l2 (-226 1049) (425 1500))
|
||||
rect(l6 (-425 -4890) (425 950))
|
||||
)
|
||||
net(4 name('B<1>')
|
||||
rect(l11 (1199 3999) (2 2))
|
||||
rect(l2 (-226 1049) (425 1500))
|
||||
rect(l6 (-425 -4890) (425 950))
|
||||
)
|
||||
net(5 name(VDD)
|
||||
rect(l11 (1799 7199) (2 2))
|
||||
rect(l2 (299 -2151) (425 1500))
|
||||
rect(l2 (-2225 -1500) (425 1500))
|
||||
)
|
||||
net(6 name(VSS)
|
||||
rect(l11 (1799 799) (2 2))
|
||||
rect(l6 (299 859) (425 950))
|
||||
rect(l6 (-2225 -950) (425 950))
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(1 name('A<1>'))
|
||||
pin(2 name('A<2>'))
|
||||
pin(3 name('B<2>'))
|
||||
pin(5 name(VDD))
|
||||
pin(6 name(VSS))
|
||||
|
||||
# Subcircuits and their connections
|
||||
circuit(1 INVX1 location(0 0)
|
||||
pin(0 4)
|
||||
pin(1 5)
|
||||
pin(2 1)
|
||||
pin(3 6)
|
||||
)
|
||||
circuit(2 INVX1 location(1800 0)
|
||||
pin(0 3)
|
||||
pin(1 5)
|
||||
pin(2 2)
|
||||
pin(3 6)
|
||||
)
|
||||
|
||||
)
|
||||
circuit(TOP
|
||||
|
||||
# Circuit boundary
|
||||
rect((-100 400) (5600 7600))
|
||||
|
||||
# Nets with their geometries
|
||||
net(1
|
||||
rect(l8 (4110 3010) (180 180))
|
||||
rect(l11 (-1190 -240) (950 300))
|
||||
rect(l2 (-1275 1800) (425 1500))
|
||||
rect(l6 (-425 -4890) (425 950))
|
||||
)
|
||||
net(2 name(A)
|
||||
rect(l8 (510 3010) (180 180))
|
||||
rect(l11 (-91 -91) (2 2))
|
||||
)
|
||||
net(3 name(C)
|
||||
rect(l8 (2310 3010) (180 180))
|
||||
rect(l11 (-91 -91) (2 2))
|
||||
)
|
||||
net(4 name(SUBSTRATE)
|
||||
rect(l6 (3900 1660) (425 950))
|
||||
rect(l6 (-2225 -950) (425 950))
|
||||
rect(l6 (-2225 -950) (425 950))
|
||||
)
|
||||
net(5
|
||||
rect(l2 (4575 5050) (425 1500))
|
||||
rect(l6 (-425 -4890) (425 950))
|
||||
)
|
||||
net(6
|
||||
rect(l2 (3900 5050) (425 1500))
|
||||
rect(l2 (-2225 -1500) (425 1500))
|
||||
rect(l2 (-2225 -1500) (425 1500))
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(2 name(A))
|
||||
pin(3 name(C))
|
||||
pin(4 name(SUBSTRATE))
|
||||
|
||||
# Subcircuits and their connections
|
||||
circuit(1 DINV location(0 0)
|
||||
pin(0 2)
|
||||
pin(1 3)
|
||||
pin(2 1)
|
||||
pin(3 6)
|
||||
pin(4 4)
|
||||
)
|
||||
circuit(2 INVX1 location(3600 0)
|
||||
pin(0 5)
|
||||
pin(1 6)
|
||||
pin(2 1)
|
||||
pin(3 4)
|
||||
)
|
||||
|
||||
)
|
||||
)
|
||||
|
||||
# Reference netlist
|
||||
reference(
|
||||
|
||||
# Device class section
|
||||
class(NMOS MOS4)
|
||||
class(PMOS MOS4)
|
||||
|
||||
# Circuit section
|
||||
# Circuits are the hierarchical building blocks of the netlist.
|
||||
circuit(INVX1
|
||||
|
||||
# Nets
|
||||
net(1 name(A))
|
||||
net(2 name(Z))
|
||||
net(3 name(VDD))
|
||||
net(4 name(VSS))
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(1 name(A))
|
||||
pin(2 name(Z))
|
||||
pin(3 name(VDD))
|
||||
pin(4 name(VSS))
|
||||
|
||||
# Devices and their connections
|
||||
device(1 NMOS
|
||||
name('0')
|
||||
param(L 0.25)
|
||||
param(W 0.95)
|
||||
param(AS 0)
|
||||
param(AD 0)
|
||||
param(PS 0)
|
||||
param(PD 0)
|
||||
terminal(S 2)
|
||||
terminal(G 1)
|
||||
terminal(D 4)
|
||||
terminal(B 4)
|
||||
)
|
||||
device(2 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 2)
|
||||
terminal(G 1)
|
||||
terminal(D 3)
|
||||
terminal(B 3)
|
||||
)
|
||||
|
||||
)
|
||||
circuit(DINV
|
||||
|
||||
# Nets
|
||||
net(1 name('A<1>'))
|
||||
net(2 name('A<2>'))
|
||||
net(3 name('B<1>'))
|
||||
net(4 name('B<2>'))
|
||||
net(5 name(VDD))
|
||||
net(6 name(VSS))
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(1 name('A<1>'))
|
||||
pin(2 name('A<2>'))
|
||||
pin(3 name('B<1>'))
|
||||
pin(4 name('B<2>'))
|
||||
pin(5 name(VDD))
|
||||
pin(6 name(VSS))
|
||||
|
||||
# Subcircuits and their connections
|
||||
circuit(1 INVX1 name(A)
|
||||
pin(0 1)
|
||||
pin(1 3)
|
||||
pin(2 5)
|
||||
pin(3 6)
|
||||
)
|
||||
circuit(2 INVX1 name(B)
|
||||
pin(0 2)
|
||||
pin(1 4)
|
||||
pin(2 5)
|
||||
pin(3 6)
|
||||
)
|
||||
|
||||
)
|
||||
circuit(TOP
|
||||
|
||||
# Nets
|
||||
net(1 name(A))
|
||||
net(2 name(C))
|
||||
net(3 name(D))
|
||||
net(4 name(VDD))
|
||||
net(5 name(VSS))
|
||||
net(6 name(B))
|
||||
net(7 name(E))
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(1 name(A))
|
||||
pin(2 name(C))
|
||||
pin(3 name(D))
|
||||
pin(4 name(VDD))
|
||||
pin(5 name(VSS))
|
||||
|
||||
# Subcircuits and their connections
|
||||
circuit(1 DINV name('0')
|
||||
pin(0 1)
|
||||
pin(1 2)
|
||||
pin(2 6)
|
||||
pin(3 7)
|
||||
pin(4 4)
|
||||
pin(5 5)
|
||||
)
|
||||
circuit(2 INVX1 name('1')
|
||||
pin(0 7)
|
||||
pin(1 3)
|
||||
pin(2 4)
|
||||
pin(3 5)
|
||||
)
|
||||
|
||||
)
|
||||
)
|
||||
|
||||
# Cross reference
|
||||
xref(
|
||||
circuit(DINV DINV match
|
||||
xref(
|
||||
net(1 1 match)
|
||||
net(2 2 match)
|
||||
net(4 3 warning)
|
||||
net(3 4 warning)
|
||||
net(5 5 match)
|
||||
net(6 6 match)
|
||||
pin(() 2 match)
|
||||
pin(0 0 match)
|
||||
pin(1 1 match)
|
||||
pin(2 3 match)
|
||||
pin(3 4 match)
|
||||
pin(4 5 match)
|
||||
circuit(1 1 match)
|
||||
circuit(2 2 match)
|
||||
)
|
||||
)
|
||||
circuit(INVX1 INVX1 match
|
||||
xref(
|
||||
net(3 1 match)
|
||||
net(1 2 match)
|
||||
net(2 3 match)
|
||||
net(4 4 match)
|
||||
pin(2 0 match)
|
||||
pin(0 1 match)
|
||||
pin(1 2 match)
|
||||
pin(3 3 match)
|
||||
device(1 1 match)
|
||||
device(2 2 match)
|
||||
)
|
||||
)
|
||||
circuit(TOP TOP match
|
||||
xref(
|
||||
net(5 3 match)
|
||||
net(1 7 match)
|
||||
net(6 4 match)
|
||||
net(2 1 match)
|
||||
net(3 2 match)
|
||||
net(4 5 match)
|
||||
pin(() 2 match)
|
||||
pin(() 3 match)
|
||||
pin(0 0 match)
|
||||
pin(1 1 match)
|
||||
pin(2 4 match)
|
||||
circuit(1 1 match)
|
||||
circuit(2 2 match)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
.global VDD VSS
|
||||
|
||||
.subckt TOP A C D
|
||||
X0 A C B E DINV
|
||||
X1 E D INVX1
|
||||
.ends
|
||||
|
||||
.subckt DINV A<1> A<2> B<1> B<2>
|
||||
XA A<1> B<1> INVX1
|
||||
XB A<2> B<2> INVX1
|
||||
.ends
|
||||
|
||||
.subckt INVX1 A Z
|
||||
M0 Z A VSS VSS NMOS W=0.95U L=0.25U
|
||||
M1 Z A VDD VDD PMOS W=1.5U L=0.25U
|
||||
.ends
|
||||
|
|
@ -530,13 +530,13 @@ xref(
|
|||
net(8 4 match)
|
||||
net(5 3 match)
|
||||
net(7 5 match)
|
||||
net(6 1 warning)
|
||||
net(9 2 warning)
|
||||
net(6 2 warning)
|
||||
net(9 1 warning)
|
||||
pin(3 3 match)
|
||||
pin(0 2 match)
|
||||
pin(2 4 match)
|
||||
pin(1 0 match)
|
||||
pin(4 1 match)
|
||||
pin(1 1 match)
|
||||
pin(4 0 match)
|
||||
circuit(2 2 match)
|
||||
circuit(3 3 match)
|
||||
circuit(17 4 match)
|
||||
|
|
|
|||
Loading…
Reference in New Issue