WIP: live actions for netlist extraction - connect etc. are no longer delayed for better error messages

This commit is contained in:
Matthias Koefferlein 2019-06-24 19:41:02 +02:00
parent 624811d55e
commit 33bb85e4f3
1 changed files with 64 additions and 33 deletions

View File

@ -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%
@ -153,6 +161,8 @@ module DRC
# @/code # @/code
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")
@ -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 end
def ensure_l2n
@l2n || make_l2n
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