mirror of https://github.com/KLayout/klayout.git
WIP: live actions for netlist extraction - connect etc. are no longer delayed for better error messages
This commit is contained in:
parent
624811d55e
commit
33bb85e4f3
|
|
@ -68,7 +68,9 @@ module DRC
|
||||||
|
|
||||||
def initialize(engine)
|
def initialize(engine)
|
||||||
@engine = engine
|
@engine = engine
|
||||||
clear_connections
|
@netlisted = false
|
||||||
|
@connect_implicit = ""
|
||||||
|
@l2n = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
# %DRC%
|
# %DRC%
|
||||||
|
|
@ -90,13 +92,16 @@ module DRC
|
||||||
# can be cleared with \clear_connections.
|
# can be cleared with \clear_connections.
|
||||||
|
|
||||||
def connect(a, b)
|
def connect(a, b)
|
||||||
|
|
||||||
a.is_a?(DRC::DRCLayer) || raise("First argument of Netter#connect must be a layer")
|
a.is_a?(DRC::DRCLayer) || raise("First argument of Netter#connect must be a layer")
|
||||||
b.is_a?(DRC::DRCLayer) || raise("Second argument of Netter#connect must be a layer")
|
b.is_a?(DRC::DRCLayer) || raise("Second argument of Netter#connect must be a layer")
|
||||||
a.requires_region("Netter#connect (first argument)")
|
a.requires_region("Netter#connect (first argument)")
|
||||||
b.requires_region("Netter#connect (second argument)")
|
b.requires_region("Netter#connect (second argument)")
|
||||||
[ a, b ].each { |l| @layers[l.data.data_id] = l.data }
|
|
||||||
@connections << [ a, b ].collect { |l| l.data.data_id }
|
register_layer(a.data)
|
||||||
modified
|
register_layer(b.data)
|
||||||
|
@l2n.connect(a.data, b.data)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# %DRC%
|
# %DRC%
|
||||||
|
|
@ -109,10 +114,13 @@ module DRC
|
||||||
# to shapes belonging to tie-down diodes.
|
# to shapes belonging to tie-down diodes.
|
||||||
|
|
||||||
def connect_global(l, name)
|
def connect_global(l, name)
|
||||||
|
|
||||||
l.is_a?(DRC::DRCLayer) || raise("Layer argument of Netter#connect_global must be a layer")
|
l.is_a?(DRC::DRCLayer) || raise("Layer argument of Netter#connect_global must be a layer")
|
||||||
l.requires_region("Netter#connect_global (layer argument)")
|
l.requires_region("Netter#connect_global (layer argument)")
|
||||||
@layers[l.data.data_id] = l.data
|
|
||||||
@global_connections << [ l.data.data_id, name.to_s ]
|
register_layer(l.data)
|
||||||
|
@l2n.connect_global(l.data, name)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# %DRC%
|
# %DRC%
|
||||||
|
|
@ -154,6 +162,8 @@ module DRC
|
||||||
|
|
||||||
def extract_devices(devex, layer_selection)
|
def extract_devices(devex, layer_selection)
|
||||||
|
|
||||||
|
ensure_l2n
|
||||||
|
|
||||||
devex.is_a?(RBA::DeviceExtractorBase) || raise("First argument of Netter#extract_devices must be a device extractor instance in the two-arguments form")
|
devex.is_a?(RBA::DeviceExtractorBase) || raise("First argument of Netter#extract_devices must be a device extractor instance in the two-arguments form")
|
||||||
|
|
||||||
layer_selection.is_a?(Hash) || raise("Second argument of Netter#extract_devices must be a hash")
|
layer_selection.is_a?(Hash) || raise("Second argument of Netter#extract_devices must be a hash")
|
||||||
|
|
@ -161,12 +171,11 @@ module DRC
|
||||||
ls = {}
|
ls = {}
|
||||||
layer_selection.each do |n,l|
|
layer_selection.each do |n,l|
|
||||||
l.requires_region("Netter#extract_devices (#{n} layer)")
|
l.requires_region("Netter#extract_devices (#{n} layer)")
|
||||||
@layers[l.data.data_id] = l.data
|
register_layer(l.data)
|
||||||
ls[n.to_s] = l.data
|
ls[n.to_s] = l.data
|
||||||
end
|
end
|
||||||
|
|
||||||
@devices_to_extract << [ devex, ls ]
|
@engine._cmd(@l2n, :extract_devices, devex, ls)
|
||||||
modified
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -177,12 +186,10 @@ module DRC
|
||||||
# See \connect for more details.
|
# See \connect for more details.
|
||||||
|
|
||||||
def clear_connections
|
def clear_connections
|
||||||
@devices_to_extract = []
|
@netlisted = false
|
||||||
@connections = []
|
|
||||||
@global_connections = []
|
|
||||||
@layers = {}
|
|
||||||
@connect_implicit = ""
|
@connect_implicit = ""
|
||||||
modified
|
@l2n && @l2n._destroy
|
||||||
|
@l2n = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
# %DRC%
|
# %DRC%
|
||||||
|
|
@ -207,8 +214,16 @@ module DRC
|
||||||
# on "clear_connections".
|
# on "clear_connections".
|
||||||
|
|
||||||
def connect_implicit(arg)
|
def connect_implicit(arg)
|
||||||
@connect_implicit = arg
|
|
||||||
modified
|
cleanup
|
||||||
|
|
||||||
|
if arg != @connect_implicit
|
||||||
|
if @connect_implicit != "" && arg != ""
|
||||||
|
raise("connect_implicit can only be used once")
|
||||||
|
end
|
||||||
|
@connect_implicit = arg
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# %DRC%
|
# %DRC%
|
||||||
|
|
@ -308,8 +323,7 @@ module DRC
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@l2n || make_l2n
|
DRC::DRCLayer::new(@engine, @engine._cmd(l2n_data, :antenna_check, gate.data, metal.data, ratio, dl))
|
||||||
DRC::DRCLayer::new(@engine, @engine._cmd(@l2n, :antenna_check, gate.data, metal.data, ratio, dl))
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -321,8 +335,17 @@ module DRC
|
||||||
# the netter object.
|
# the netter object.
|
||||||
|
|
||||||
def l2n_data
|
def l2n_data
|
||||||
@l2n || make_l2n
|
|
||||||
|
ensure_l2n
|
||||||
|
|
||||||
|
# run extraction in a timed environment
|
||||||
|
if ! @netlisted
|
||||||
|
@engine._cmd(@l2n, :extract_netlist, @connect_implicit)
|
||||||
|
@netlisted = true
|
||||||
|
end
|
||||||
|
|
||||||
@l2n
|
@l2n
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# %DRC%
|
# %DRC%
|
||||||
|
|
@ -339,8 +362,6 @@ module DRC
|
||||||
|
|
||||||
def _finish
|
def _finish
|
||||||
clear_connections
|
clear_connections
|
||||||
# cleans up the L2N object
|
|
||||||
modified
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def _take_l2n_data
|
def _take_l2n_data
|
||||||
|
|
@ -351,13 +372,18 @@ module DRC
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def modified
|
def cleanup
|
||||||
@l2n && @l2n._destroy
|
@netlisted && clear_connections
|
||||||
@l2n = nil
|
end
|
||||||
|
|
||||||
|
def ensure_l2n
|
||||||
|
@l2n || make_l2n
|
||||||
end
|
end
|
||||||
|
|
||||||
def make_l2n
|
def make_l2n
|
||||||
|
|
||||||
|
@layers = {}
|
||||||
|
|
||||||
if @engine._dss
|
if @engine._dss
|
||||||
# TODO: check whether all layers are deep and come from the dss and layout index,
|
# TODO: check whether all layers are deep and come from the dss and layout index,
|
||||||
# then use this layout index. This will remove the need for this check:
|
# then use this layout index. This will remove the need for this check:
|
||||||
|
|
@ -368,19 +394,24 @@ module DRC
|
||||||
@l2n = RBA::LayoutToNetlist::new(layout.top_cell.name, layout.dbu)
|
@l2n = RBA::LayoutToNetlist::new(layout.top_cell.name, layout.dbu)
|
||||||
end
|
end
|
||||||
|
|
||||||
@layers.each { |id,l| @l2n.register(l, "l" + id.to_s) }
|
end
|
||||||
|
|
||||||
@devices_to_extract.each do |devex,ls|
|
def register_layer(data)
|
||||||
@engine._cmd(@l2n, :extract_devices, devex, ls)
|
|
||||||
|
id = data.data_id
|
||||||
|
|
||||||
|
if @layers[id]
|
||||||
|
# already registered
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@layers.each { |id,l| @l2n.connect(l) }
|
ensure_l2n
|
||||||
@connections.each { |a,b| @l2n.connect(@layers[a], @layers[b]) }
|
|
||||||
@global_connections.each { |l,n| @l2n.connect_global(@layers[l], n) }
|
|
||||||
|
|
||||||
# run extraction in a timed environment
|
@layers[id] = data
|
||||||
@engine._cmd(@l2n, :extract_netlist, @connect_implicit)
|
|
||||||
@l2n
|
# every layer gets registered and intra-layer connections are made
|
||||||
|
@l2n.register(data, "l" + id.to_s)
|
||||||
|
@l2n.connect(data)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue