Introducing cheats for LVS/device extraction/booleans

This commit is contained in:
Matthias Koefferlein 2019-10-16 18:59:38 +02:00
parent a3b2e3a154
commit 9e1c8b44c7
3 changed files with 256 additions and 8 deletions

View File

@ -1120,6 +1120,108 @@ module DRC
@def_source = layout.clip(*args)
nil
end
# %DRC%
# @name cheat
# @brief Hierarchy cheats
# @synopsis cheat(args) { block }
#
# Hierarchy cheats can be used in deep mode to shortcut hierarchy evaluation
# for certain cells and consider their local configuration only.
# Cheats are useful for example when dealing with memory arrays. Often
# such arrays are build from unit cells and those often overlap with their
# neighbors. Now, if the hierarchical engine encounters such a situation, it
# will first analyse all these interactions (which can be expensive) and then
# it may come to the conclusion that boundary instances need to be handled
# differently than inside instances. This in turn might lead to propagation of
# shapes and in an LVS context to device externalisation: because some devices
# might have different parameters for boundary cells than for inside cells, the
# device instances can no longer be kept inside the unit cell. Specifically for
# memory arrays, this is not desired as eventually this leads to flattening
# of the whole array.
#
# The solution is to cheat: provided the unit cell is fully fledged and neighbors
# do not disturb the unit cell's configuration in critical ways, the unit cell
# can be treated as being isolated and results are put together in the usual way.
#
# Cheats can be applied on layout operations - specifically booleans - and device
# extraction operations. Cheats are only effective in \deep mode.
#
# For booleans, a cheat means that the cheating cell's boolean results are computed
# locally and are combined afterwards. A cheat is introduced this way:
#
# @code
# deep
#
# l1 = input(1, 0)
# l2 = input(2, 0)
#
# # usual booleans
# l1and2 = l1 & l2
#
# # will compute "UNIT_CELL" isolated and everything else in normal hierarchical mode:
# l1minus2 = cheat("UNIT_CELL) { l1 - l2 }
# @/code
#
# The cheat block can also be wrapped in do .. end statements and can return multiple
# layer objects:
#
# @code
# deep
#
# l1 = input(1, 0)
# l2 = input(2, 0)
#
# # computes both AND and NOT of l1 and l2 with cheating for "UNIT_CELL"
# l1and2, l1minus2 = cheat("UNIT_CELL) do
# [ l1 & l2, l1 - l2 ]
# end
# @/code
#
# (Technically, the cheat code block is a Ruby Proc and cannot create variables
# outside it's scope. Hence the results of this code block have to be passed
# through the "cheat" method).
#
# To apply cheats for device extraction, use the following scheme:
#
# @code
# deep
#
# poly = input(1, 0)
# active = input(2, 0)
#
# sd = active - poly
# gate = active & poly
#
# # device extraction with cheating for "UNIT_CELL":
# cheat("UNIT_CELL") do
# extract_devices(mos3("NMOS"), { "SD" => sd, "G" => gate, "tS" => sd, "tD" => sd, "tG" => poly }
# end
# @/code
#
# The argument to the cheat method is a list of cell name pattern (glob-style
# pattern). For example:
#
# @code
# cheat("UNIT_CELL*") { ... }
# cheat("UNIT_CELL1", "UNIT_CELL2") { ... }
# cheat("UNIT_CELL{1,2}") { ... }
# @/code
#
# For LVS applications, it's usually sufficient to cheat in the device extraction step.
# Cheats have been introduced in version 0.26.1.
def cheat(*args, &block)
if _dss
_dss.push_state
args.flatten.each { |a| _dss.add_breakout_cells(a.to_s) }
ret = block.call
_dss.pop_state
else
ret = block.call
end
ret
end
# make some DRCLayer methods available as functions
# for the engine

View File

@ -92,6 +92,98 @@ cell("MACRO")
l1 = input(1, 0)
</pre>
</p>
<h2>"cheat" - Hierarchy cheats</h2>
<keyword name="cheat"/>
<a name="cheat"/><p>Usage:</p>
<ul>
<li><tt>cheat(args) { block }</tt></li>
</ul>
<p>
Hierarchy cheats can be used in deep mode to shortcut hierarchy evaluation
for certain cells and consider their local configuration only.
Cheats are useful for example when dealing with memory arrays. Often
such arrays are build from unit cells and those often overlap with their
neighbors. Now, if the hierarchical engine encounters such a situation, it
will first analyse all these interactions (which can be expensive) and then
it may come to the conclusion that boundary instances need to be handled
differently than inside instances. This in turn might lead to propagation of
shapes and in an LVS context to device externalisation: because some devices
might have different parameters for boundary cells than for inside cells, the
device instances can no longer be kept inside the unit cell. Specifically for
memory arrays, this is not desired as eventually this leads to flattening
of the whole array.
</p><p>
The solution is to cheat: provided the unit cell is fully fledged and neighbors
do not disturb the unit cell's configuration in critical ways, the unit cell
can be treated as being isolated and results are put together in the usual way.
</p><p>
Cheats can be applied on layout operations - specifically booleans - and device
extraction operations. Cheats are only effective in <a href="#deep">deep</a> mode.
</p><p>
For booleans, a cheat means that the cheating cell's boolean results are computed
locally and are combined afterwards. A cheat is introduced this way:
</p><p>
<pre>
deep
l1 = input(1, 0)
l2 = input(2, 0)
# usual booleans
l1and2 = l1 &amp; l2
# will compute "UNIT_CELL" isolated and everything else in normal hierarchical mode:
l1minus2 = cheat("UNIT_CELL) { l1 - l2 }
</pre>
</p><p>
The cheat block can also be wrapped in do .. end statements and can return multiple
layer objects:
</p><p>
<pre>
deep
l1 = input(1, 0)
l2 = input(2, 0)
# computes both AND and NOT of l1 and l2 with cheating for "UNIT_CELL"
l1and2, l1minus2 = cheat("UNIT_CELL) do
[ l1 &amp; l2, l1 - l2 ]
end
</pre>
</p><p>
(Technically, the check code block is a Ruby Proc and cannot create variables
outside it's scope. Hence the results of this code block have to be passed
through the "cheat" method).
</p><p>
To apply cheats for device extraction, use the following scheme:
</p><p>
<pre>
deep
poly = input(1, 0)
active = input(2, 0)
sd = active - poly
gate = active &amp; poly
# device extraction with cheating for "UNIT_CELL":
cheat("UNIT_CELL") do
extract_devices(mos3("NMOS"), { "SD" =&gt; sd, "G" =&gt; gate, "tS" =&gt; sd, "tD" =&gt; sd, "tG" =&gt; poly }
end
</pre>
</p><p>
The argument to the cheat method is a list of cell name pattern (glob-style
pattern). For example:
</p><p>
<pre>
cheat("UNIT_CELL*") { ... }
cheat("UNIT_CELL1", "UNIT_CELL2") { ... }
cheat("UNIT_CELL{1,2}") { ... }
</pre>
</p><p>
For LVS applications, it's usually sufficient to cheat in the device extraction step.
Cheats have been introduced in version 0.26.1.
</p>
<h2>"clear_connections" - Clears all connections stored so far</h2>
<keyword name="clear_connections"/>
<a name="clear_connections"/><p>Usage:</p>

View File

@ -735,7 +735,7 @@ This method is available for edge layers. The argument must be a polygon layer.
</ul>
<p>
This method selects all shapes or regions from self which touch or overlap shapes from the other
region. If self is in raw mode (see <a href="#raw">raw</a>), coherent regions are selected from self,
region. Unless self is in raw mode (see <a href="#raw">raw</a>), coherent regions are selected from self,
otherwise individual shapes are selected.
It returns a new layer containing the selected shapes. A version which modifies self
is <a href="#select_interacting">select_interacting</a>.
@ -1085,7 +1085,7 @@ The following image shows the effect of the "not_inside" method (input1: red, in
</ul>
<p>
This method selects all shapes or regions from self which do not touch or overlap shapes from the other
region. If self is in raw mode (see <a href="#raw">raw</a>), coherent regions are selected from self,
region. Unless self is in raw mode (see <a href="#raw">raw</a>), coherent regions are selected from self,
otherwise individual shapes are selected.
It returns a new layer containing the selected shapes. A version which modifies self
is <a href="#select_not_interacting">select_not_interacting</a>.
@ -1134,7 +1134,7 @@ The following image shows the effect of the "not_outside" method (input1: red, i
</ul>
<p>
This method selects all shapes or regions from self which do not overlap shapes from the other
region. If self is in raw mode (see <a href="#raw">raw</a>), coherent regions are selected from self,
region. Unless self is in raw mode (see <a href="#raw">raw</a>), coherent regions are selected from self,
otherwise individual shapes are selected.
</p><p>
The "not_overlapping" method is equivalent to the <a href="#outside">outside</a> method. It is provided
@ -1322,7 +1322,7 @@ The following images show the effect of the overlap check (layer1: red, layer2:
</ul>
<p>
This method selects all shapes or regions from self which overlap shapes from the other
region. If self is in raw mode (see <a href="#raw">raw</a>), coherent regions are selected from self,
region. Unless self is in raw mode (see <a href="#raw">raw</a>), coherent regions are selected from self,
otherwise individual shapes are selected.
It returns a new layer containing the selected shapes. A version which modifies self
is <a href="#select_overlapping">select_overlapping</a>.
@ -1372,6 +1372,60 @@ parameter is 0, special edge pairs with an area of 0 will be dropped.
<ul>
<li><tt>layer.polygons?</tt></li>
</ul>
<h2>"pull_inside" - Selects shapes or regions of other which are inside polygons from the this region</h2>
<keyword name="pull_inside"/>
<a name="pull_inside"/><p>Usage:</p>
<ul>
<li><tt>layer.pull_inside(other)</tt></li>
</ul>
<p>
This method selects all shapes or regions from other which are inside polygons from this
region. Unless other is in raw mode (see <a href="#raw">raw</a>), coherent regions are selected from other,
otherwise individual shapes are selected.
</p><p>
The functionality is similar to select_inside, but chosing shapes from other rather
than from self. Because in deep mode the hierarchy reference comes from self, this method
provides a way to pull shapes from other to the hierarchy to self.
</p><p>
This method is available for polygon layers. Other needs to be a polygon layer too.
</p>
<h2>"pull_interacting" - Selects shapes or edges of other which touch or overlap shapes from the this region</h2>
<keyword name="pull_interacting"/>
<a name="pull_interacting"/><p>Usage:</p>
<ul>
<li><tt>layer.pull_interacting(other)</tt></li>
</ul>
<p>
This method selects all shapes or regions from other which touch or overlap shapes from this
region. Unless other is in raw mode (see <a href="#raw">raw</a>), coherent regions are selected from other,
otherwise individual shapes are selected.
</p><p>
The functionality is similar to select_interacting, but chosing shapes from other rather
than from self. Because in deep mode the hierarchy reference comes from self, this method
provides a way to pull shapes from other to the hierarchy to self.
</p><p>
This method will neither modify self nor other.
</p><p>
This method is available for polygon layers. Other can be an edge or polygon layer.
Edges or polygons can be selected with respect to polygons of self.
</p>
<h2>"pull_overlapping" - Selects shapes or regions of other which overlap shapes from the this region</h2>
<keyword name="pull_overlapping"/>
<a name="pull_overlapping"/><p>Usage:</p>
<ul>
<li><tt>layer.pull_overlapping(other)</tt></li>
</ul>
<p>
This method selects all shapes or regions from other which overlap shapes from this
region. Unless other is in raw mode (see <a href="#raw">raw</a>), coherent regions are selected from other,
otherwise individual shapes are selected.
</p><p>
The functionality is similar to select_overlapping, but chosing shapes from other rather
than from self. Because in deep mode the hierarchy reference comes from self, this method
provides a way to pull shapes from other to the hierarchy to self.
</p><p>
This method is available for polygon layers. Other needs to be a polygon layer too.
</p>
<h2>"raw" - Marks a layer as raw</h2>
<keyword name="raw"/>
<a name="raw"/><p>Usage:</p>
@ -1562,7 +1616,7 @@ This method is available for polygon layers.
</ul>
<p>
This method selects all shapes or regions from self which touch or overlap shapes from the other
region. If self is in raw mode (see <a href="#raw">raw</a>), coherent regions are selected from self,
region. Unless self is in raw mode (see <a href="#raw">raw</a>), coherent regions are selected from self,
otherwise individual shapes are selected.
It modifies self to contain the selected shapes. A version which does not modify self
is <a href="#interacting">interacting</a>.
@ -1595,7 +1649,7 @@ This method is available for polygon layers.
</ul>
<p>
This method selects all shapes or regions from self which do not touch or overlap shapes from the other
region. If self is in raw mode (see <a href="#raw">raw</a>), coherent regions are selected from self,
region. Unless self is in raw mode (see <a href="#raw">raw</a>), coherent regions are selected from self,
otherwise individual shapes are selected.
It modifies self to contain the selected shapes. A version which does not modify self
is <a href="#not_interacting">not_interacting</a>.
@ -1628,7 +1682,7 @@ This method is available for polygon layers.
</ul>
<p>
This method selects all shapes or regions from self which do not overlap shapes from the other
region. If self is in raw mode (see <a href="#raw">raw</a>), coherent regions are selected from self,
region. Unless self is in raw mode (see <a href="#raw">raw</a>), coherent regions are selected from self,
otherwise individual shapes are selected.
It modifies self to contain the selected shapes. A version which does not modify self
is <a href="#not_overlapping">not_overlapping</a>.
@ -1661,7 +1715,7 @@ This method is available for polygon layers.
</ul>
<p>
This method selects all shapes or regions from self which overlap shapes from the other
region. If self is in raw mode (see <a href="#raw">raw</a>), coherent regions are selected from self,
region. Unless self is in raw mode (see <a href="#raw">raw</a>), coherent regions are selected from self,
otherwise individual shapes are selected.
It modifies self to contain the selected shapes. A version which does not modify self
is <a href="#overlapping">overlapping</a>.