mirror of https://github.com/KLayout/klayout.git
Updated a test.
This commit is contained in:
parent
9f295523e4
commit
6ceac2c6ba
|
|
@ -1790,6 +1790,14 @@ CODE
|
||||||
# @synopsis connect_implicit(cell_pattern, label_pattern)
|
# @synopsis connect_implicit(cell_pattern, label_pattern)
|
||||||
# See \Netter#connect_implicit for a description of that function.
|
# See \Netter#connect_implicit for a description of that function.
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name connect_explicit
|
||||||
|
# @brief Specifies explicit net connections
|
||||||
|
# @synopsis connect_explicit(net_names)
|
||||||
|
# @synopsis connect_explicit(cell_pattern, net_names)
|
||||||
|
# See \Netter#connect_explicit for a description of that function.
|
||||||
|
# Net names is an array (use square brackets to list the net names).
|
||||||
|
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name antenna_check
|
# @name antenna_check
|
||||||
# @brief Performs an antenna check
|
# @brief Performs an antenna check
|
||||||
|
|
@ -1828,6 +1836,7 @@ CODE
|
||||||
connect
|
connect
|
||||||
connect_global
|
connect_global
|
||||||
connect_implicit
|
connect_implicit
|
||||||
|
connect_explicit
|
||||||
device_scaling
|
device_scaling
|
||||||
extract_devices
|
extract_devices
|
||||||
l2n_data
|
l2n_data
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,8 @@ module DRC
|
||||||
@netlisted = false
|
@netlisted = false
|
||||||
@connect_implicit = []
|
@connect_implicit = []
|
||||||
@connect_implicit_per_cell = {}
|
@connect_implicit_per_cell = {}
|
||||||
|
@connect_explicit = []
|
||||||
|
@connect_explicit_per_cell = {}
|
||||||
@l2n = nil
|
@l2n = nil
|
||||||
@lnum = 0
|
@lnum = 0
|
||||||
@device_scaling = 1.0
|
@device_scaling = 1.0
|
||||||
|
|
@ -241,6 +243,8 @@ module DRC
|
||||||
@netlisted = false
|
@netlisted = false
|
||||||
@connect_implicit = []
|
@connect_implicit = []
|
||||||
@connect_implicit_per_cell = {}
|
@connect_implicit_per_cell = {}
|
||||||
|
@connect_explicit = []
|
||||||
|
@connect_explicit_per_cell = {}
|
||||||
_clear_data
|
_clear_data
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -286,6 +290,67 @@ module DRC
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name connect_explicit
|
||||||
|
# @brief Specifies a list of net names for nets to connect explicitly
|
||||||
|
# @synopsis connect_explicit(net_names)
|
||||||
|
# @synopsis connect_explicit(cell_pattern, net_names)
|
||||||
|
# Use this method to explicitly connect nets even if there is no physical connection.
|
||||||
|
# As this breaks with the concept of physical verification, this feature should be used
|
||||||
|
# with care.
|
||||||
|
#
|
||||||
|
# The first version of this function will connect all nets listed in the "net_names" array
|
||||||
|
# in the top level cell. The second version takes a cell name pattern and connects all nets listed
|
||||||
|
# in "net_names" for cells matching this pattern.
|
||||||
|
#
|
||||||
|
# A use case for this method is the following: consider a set of standard cells. These do not have a bulk
|
||||||
|
# or n-well pin in the schematics. They also do not have build in tie-down diodes for the
|
||||||
|
# substrate connections. In this case there is a build-in discrepancy between the
|
||||||
|
# schematics and the layout: bulk and VSS are separate nets within the layout, but the
|
||||||
|
# schematic does not list them as separate. The solution is to make an explicit connection
|
||||||
|
# between VDD and n-well and VSS and bulk, provided VDD and VSS are properly labelled as "VDD" and "VSS"
|
||||||
|
# and n-well and bulk are accessible as named nets (for bulk you can use "connect_global").
|
||||||
|
#
|
||||||
|
# The following code will establish an explicit connection for all cells called "INV.." between
|
||||||
|
# BULK and VSS nets:
|
||||||
|
#
|
||||||
|
# @code
|
||||||
|
# connect_global(bulk, "BULK")
|
||||||
|
# ...
|
||||||
|
# connect_explicit("INV*", [ "BULK", "VSS" ])
|
||||||
|
# @/code
|
||||||
|
#
|
||||||
|
# Explicit connections also imply implicit connections between different parts of
|
||||||
|
# one of the nets. In the example before, "VSS" pieces without a physical connection
|
||||||
|
# will also be connected.
|
||||||
|
#
|
||||||
|
# When you use explicit connections you should make sure by other ways that the connection
|
||||||
|
# is made physically. For example, for the bulk/n-well pin example above, by enforcing at least one
|
||||||
|
# tie-down diode per n-well island and in the substrate by means of a DRC rule.
|
||||||
|
#
|
||||||
|
# The explicit connections are applied on the next net extraction and cleared
|
||||||
|
# on "clear_connections".
|
||||||
|
|
||||||
|
def connect_explicit(arg1, arg2 = nil)
|
||||||
|
|
||||||
|
@engine._context("connect_explicit") do
|
||||||
|
|
||||||
|
cleanup
|
||||||
|
if arg2
|
||||||
|
arg2.is_a?(Array) || raise("The second argument has to be an array of strings")
|
||||||
|
arg2.find { |a| !a.is_a?(String) } && raise("The second argument has to be an array of strings")
|
||||||
|
arg1.is_a?(String) || raise("The first argument has to be a string")
|
||||||
|
@connect_explicit_per_cell[arg1] ||= []
|
||||||
|
@connect_explicit_per_cell[arg1] << arg2
|
||||||
|
else
|
||||||
|
arg1.is_a?(String) || raise("The argument has to be a string")
|
||||||
|
@connect_explicit << arg1
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @brief Performs an antenna check
|
# @brief Performs an antenna check
|
||||||
# @name antenna_check
|
# @name antenna_check
|
||||||
|
|
@ -481,16 +546,29 @@ module DRC
|
||||||
# run extraction in a timed environment
|
# run extraction in a timed environment
|
||||||
if ! @netlisted
|
if ! @netlisted
|
||||||
|
|
||||||
# build a glob expression from the parts
|
# configure implicit net connections
|
||||||
expr = _join_glob_pattern(@connect_implicit)
|
@l2n.clear_join_net_names
|
||||||
|
@connect_implicit.each do |label_pattern|
|
||||||
# build cell-pattern specific glob expressions from the parts
|
@l2n.join_net_names(label_pattern)
|
||||||
per_cell_expr = {}
|
end
|
||||||
@connect_implicit_per_cell.each do |cell_pattern,label_pattern|
|
@connect_implicit_per_cell.each do |cell_pattern,label_pattern|
|
||||||
per_cell_expr[cell_pattern] = _join_glob_pattern(label_pattern)
|
label_pattern.each do |lp|
|
||||||
|
@l2n.join_net_names(cell_pattern, lp)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@engine._cmd(@l2n, :extract_netlist, expr, per_cell_expr)
|
# configure explicit net connections
|
||||||
|
@l2n.clear_join_nets
|
||||||
|
@connect_explicit.each do |names|
|
||||||
|
@l2n.join_nets(names)
|
||||||
|
end
|
||||||
|
@connect_explicit_per_cell.each do |cell_pattern,name_lists|
|
||||||
|
name_lists.each do |names|
|
||||||
|
@l2n.join_nets(cell_pattern, names)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@engine._cmd(@l2n, :extract_netlist)
|
||||||
@netlisted = true
|
@netlisted = true
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
@ -548,18 +626,6 @@ module DRC
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def _join_glob_pattern(exprs)
|
|
||||||
|
|
||||||
if exprs.size > 1
|
|
||||||
expr = "{" + exprs.join(",") + "}"
|
|
||||||
else
|
|
||||||
expr = exprs[0] || ""
|
|
||||||
end
|
|
||||||
|
|
||||||
expr
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
def _make_data
|
def _make_data
|
||||||
|
|
||||||
if @engine._dss
|
if @engine._dss
|
||||||
|
|
|
||||||
|
|
@ -330,10 +330,10 @@ TEST (2)
|
||||||
EXPECT_EQ (model->rowCount (inv2Net0TerminalIndex), 4);
|
EXPECT_EQ (model->rowCount (inv2Net0TerminalIndex), 4);
|
||||||
EXPECT_EQ (model->parent (inv2Net0TerminalIndex) == inv2Net0Index, true);
|
EXPECT_EQ (model->parent (inv2Net0TerminalIndex) == inv2Net0Index, true);
|
||||||
// .. whose second terminal is gate
|
// .. whose second terminal is gate
|
||||||
EXPECT_EQ (tl::to_string (model->data (model->index (1, 0, inv2Net0TerminalIndex), Qt::UserRole).toString ()), "G|G|IN|2");
|
EXPECT_EQ (tl::to_string (model->data (model->index (1, 0, inv2Net0TerminalIndex), Qt::UserRole).toString ()), "D|D|VDD|5");
|
||||||
EXPECT_EQ (tl::to_string (model->data (model->index (1, 0, inv2Net0TerminalIndex), Qt::DisplayRole).toString ()), "G");
|
EXPECT_EQ (tl::to_string (model->data (model->index (1, 0, inv2Net0TerminalIndex), Qt::DisplayRole).toString ()), "D");
|
||||||
EXPECT_EQ (tl::to_string (model->data (model->index (1, 2, inv2Net0TerminalIndex), Qt::DisplayRole).toString ()), "IN (3)");
|
EXPECT_EQ (tl::to_string (model->data (model->index (1, 2, inv2Net0TerminalIndex), Qt::DisplayRole).toString ()), "VDD (2)");
|
||||||
EXPECT_EQ (tl::to_string (model->data (model->index (1, 3, inv2Net0TerminalIndex), Qt::DisplayRole).toString ()), "2 (3)");
|
EXPECT_EQ (tl::to_string (model->data (model->index (1, 3, inv2Net0TerminalIndex), Qt::DisplayRole).toString ()), "5 (2)");
|
||||||
|
|
||||||
// The Pin
|
// The Pin
|
||||||
EXPECT_EQ (tl::to_string (model->data (model->index (1, 0, inv2Net0Index), Qt::UserRole).toString ()), "");
|
EXPECT_EQ (tl::to_string (model->data (model->index (1, 0, inv2Net0Index), Qt::UserRole).toString ()), "");
|
||||||
|
|
|
||||||
|
|
@ -161,3 +161,9 @@ TEST(18_private)
|
||||||
run_test (_this, "test_18.lvs", "test_18.cir.gz", "test_18.gds.gz", true);
|
run_test (_this, "test_18.lvs", "test_18.cir.gz", "test_18.gds.gz", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(19_private)
|
||||||
|
{
|
||||||
|
// test_is_long_runner ();
|
||||||
|
run_test (_this, "test_19.lvs", "test_19.cir.gz", "test_19.gds.gz", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue