From dc526132c0be6149b6a252942003368c70ad7120 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 27 May 2024 19:02:53 +0200 Subject: [PATCH] Part 3 of issue #1719 New LVS/DRC functions: "name" and "name_prefix" to control what layer names are used. "name" needs to be used explicitly and before a layer is used (and gets auto-assigned a name). --- src/drc/drc/built-in-macros/_drc_engine.rb | 14 ++++ src/drc/drc/built-in-macros/_drc_netter.rb | 91 +++++++++++++++++++--- 2 files changed, 94 insertions(+), 11 deletions(-) diff --git a/src/drc/drc/built-in-macros/_drc_engine.rb b/src/drc/drc/built-in-macros/_drc_engine.rb index 14a384a1a..765fc4215 100644 --- a/src/drc/drc/built-in-macros/_drc_engine.rb +++ b/src/drc/drc/built-in-macros/_drc_engine.rb @@ -2394,6 +2394,18 @@ CODE # @synopsis extract_devices(extractor_class, name, layer_hash) # See \Netter#extract_devices for a description of that function. + # %DRC% + # @name name + # @brief Assigns a name to a layer for reference in the LVS database + # @synopsis name(layer, name) + # See \Netter#name for a description of that function. + + # %DRC% + # @name name_prefix + # @brief Specifies the layer name prefix for auto-generated layer names + # @synopsis name_prefix(prefix) + # See \Netter#name_prefix for a description of that function. + # %DRC% # @name netlist # @brief Obtains the extracted netlist from the default \Netter @@ -2408,6 +2420,8 @@ CODE connect_global soft_connect soft_connect_global + name_prefix + name connect_implicit connect_explicit device_scaling diff --git a/src/drc/drc/built-in-macros/_drc_netter.rb b/src/drc/drc/built-in-macros/_drc_netter.rb index 627dd85a9..4a3b023f9 100644 --- a/src/drc/drc/built-in-macros/_drc_netter.rb +++ b/src/drc/drc/built-in-macros/_drc_netter.rb @@ -68,6 +68,7 @@ module DRC @post_extract_config = [] @l2n = nil @lnum = 0 + @name_prefix = "l" @device_scaling = 1.0 @ignore_extraction_errors = false @top_level = false @@ -106,8 +107,8 @@ module DRC a.requires_texts_or_region b.requires_texts_or_region - register_layer(a.data) - register_layer(b.data) + _register_layer(a.data, "connect") + _register_layer(b.data, "connect") a.data.is_a?(RBA::Region) && @l2n.connect(a.data) b.data.is_a?(RBA::Region) && @l2n.connect(b.data) @l2n.connect(a.data, b.data) @@ -150,8 +151,8 @@ module DRC a.requires_texts_or_region b.requires_texts_or_region - register_layer(a.data) - register_layer(b.data) + _register_layer(a.data, "soft_connect") + _register_layer(b.data, "soft_connect") # soft connections imply hard intra-layer connections a.data.is_a?(RBA::Region) && @l2n.connect(a.data) b.data.is_a?(RBA::Region) && @l2n.connect(b.data) @@ -177,7 +178,7 @@ module DRC l.is_a?(DRC::DRCLayer) || raise("Layer argument must be a layer") l.requires_texts_or_region - register_layer(l.data) + _register_layer(l.data, "connect_global") l.data.is_a?(RBA::Region) && @l2n.connect(l.data) @l2n.connect_global(l.data, name) @@ -204,7 +205,7 @@ module DRC l.is_a?(DRC::DRCLayer) || raise("Layer argument must be a layer") l.requires_texts_or_region - register_layer(l.data) + _register_layer(l.data, "soft_connect_global") l.data.is_a?(RBA::Region) && @l2n.connect(l.data) @l2n.soft_connect_global(l.data, name) @@ -282,7 +283,7 @@ module DRC layer_selection.keys.sort.each do |n| l = layer_selection[n] l.requires_texts_or_region - register_layer(l.data) + _register_layer(l.data, "extract_devices") ls[n.to_s] = l.data end @@ -294,6 +295,70 @@ module DRC end + # %DRC% + # @name name + # @brief Assigns a name to a layer + # @synopsis name(layer, name) + # Layer names are listed in the LayoutToNetlist (L2N) or LVS database. They + # are used to identify the layers, the net or device terminal geometries are + # on. It is usual to have computed layers, so it is necessary to indicate the + # purpose of the layer for later reuse of the geometries. + # + # It is a good practice to assign names to computed and original layers, + # for example: + # + # @code + # poly = input(...) + # poly_resistor = input(...) + # + # poly_wiring = poly - poly_resistor + # name(poly_wiring, "poly_wiring") + # @/code + # + # Names must be assigned before the layers are used for the first time + # in \connect, \soft_connect, \connect_global, \soft_connect_global and + # extract_devices statements. + # + # If layers are not named, they will be given a name made from the + # \name_prefix and an incremental number when the layer is used for the + # first time. + # + # \name can only be used once on a layer and the layer names must be + # unique (not taken by another layer). + + # %DRC% + # @name name_prefix + # @brief Specifies the name prefix for auto-generated layer names + # @synopsis name_prefix(prefix) + # See \\name for details. The default prefix is "l". + + def name(l, name) + + @engine._context("name") do + + l.is_a?(DRC::DRCLayer) || raise("First argument must be a layer") + (name.is_a?(String) && name != "") || raise("Second argument must be a non-empty string") + + id = l.data.data_id + + if @layers && @layers[id] + # already registered + if @layers[id][1] != name + raise("Layer already registered with name #{@layers[id][1]} in context: #{@layers[id][2]}") + end + return + end + + self._register_layer(l.data, "name", name) + + end + + end + + def name_prefix(prefix) + @name_prefix = prefix.to_s + end + # %DRC% # @name device_scaling # @brief Specifies a dimension scale factor for the geometrical device properties @@ -792,7 +857,7 @@ module DRC end - def register_layer(data) + def _register_layer(data, context, name = nil) id = data.data_id ensure_data @@ -802,11 +867,15 @@ module DRC return end - @layers[id] = data - @lnum += 1 + if !name + @lnum += 1 + name = @name_prefix + @lnum.to_s + end + + @layers[id] = [ data, name, context ] # every layer gets registered and intra-layer connections are made - @l2n.register(data, "l" + @lnum.to_s) + @l2n.register(data, name) end