Skip to content

Commit

Permalink
Enhancing LVS reader, Adding version check for gui lvs
Browse files Browse the repository at this point in the history
Signed-off-by: FaragElsayed2 <farag_agoor@mabrains.com>
  • Loading branch information
FaragElsayed2 committed May 15, 2024
1 parent a3b5a86 commit 83e408e
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 12 deletions.
36 changes: 31 additions & 5 deletions ihp-sg13g2/libs.tech/klayout/tech/lvs/rule_decks/custom_reader.lvs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,35 @@

# Custom reader for subcircuit models
class CustomReader < RBA::NetlistSpiceReaderDelegate
# Cleanup sch for R, C elements
def clean_sch(line, element)
line = line.delete('[]$\\/')
# Extracting parameters with values
valid_params = line.scan(/\b\w+=\S+\b/)
case element
when 'R'
# For 2 term res [<nets> <model> <params>]
num_terms = 3
when 'C'
# Determine number of terms based on component type
num_terms =
if line.downcase.include?('varicap')
5
elsif line.downcase.include?('rfcmim')
4
else
3
end
end
line_no_param = line.split(' ').take(num_terms).join(' ')
"#{line_no_param.strip} #{valid_params.join(' ')}"
end

# Override parse_element method to handle exceptions gracefully
def parse_element(line, element)
# Prep sch for R, C
line = clean_sch(line, element) if %w[R C].include?(element)

super
rescue StandardError
case element
Expand Down Expand Up @@ -265,13 +292,11 @@ class CustomReader < RBA::NetlistSpiceReaderDelegate

# Map parameters for a diode device.
def map_diode_params(device, model, params)
if model.downcase.include?('diodev') || model.downcase.include?('schottky') || model.downcase.include?('nmoscl')
device.set_parameter('m', params['M'] || 1.0)
else
unless model.downcase.include?('diodev') || model.downcase.include?('schottky') || model.downcase.include?('nmoscl')
device.set_parameter('A', (params['A'] || ((params['W'] || 0.0) * (params['L'] || 0.0))) * 1e12)
device.set_parameter('P', (params['P'] || (((params['W'] || 0.0) + (params['L'] || 0.0)) * 2)) * 1e6)
device.set_parameter('m', params['M'] || 1.0)
end
device.set_parameter('m', params['M'] || 1.0)
end

# Map parameters for a capacitor device.
Expand All @@ -293,7 +318,8 @@ class CustomReader < RBA::NetlistSpiceReaderDelegate
def map_resistor_params(device, model, params)
if model.downcase.include?('tap')
device.set_parameter('A', (params['A'] || ((params['W'] || 0.0) * (params['L'] || 0.0))) * 1e12)
device.set_parameter('P', (params['P'] || params['PERIM'] || (((params['W'] || 0.0) + (params['L'] || 0.0)) * 2)) * 1e6)
device.set_parameter('P',
(params['P'] || params['PERIM'] || (((params['W'] || 0.0) + (params['L'] || 0.0)) * 2)) * 1e6)
elsif RES_DEV.any? { |res| model.downcase.start_with?(res) }
device.set_parameter('w', (params['W'] || 0.0) * 1e6)
device.set_parameter('l', (params['L'] || 0.0) * 1e6)
Expand Down
5 changes: 3 additions & 2 deletions ihp-sg13g2/libs.tech/klayout/tech/lvs/run_lvs.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,12 +189,13 @@ def generate_klayout_switches(arguments, layout_path, netlist_path):
switches = dict()

if arguments["--run_mode"] in ["flat", "deep"]:
switches["run_mode"] = arguments["--run_mode"]
run_mode = arguments["--run_mode"]
else:
logging.error("Allowed klayout modes are (flat , deep) only")
exit()
exit(1)

switches = {
"run_mode": run_mode,
"no_net_names": "true" if arguments.get("--no_net_names") else "false",
"spice_comments": "true" if arguments.get("--spice_comments") else "false",
"net_only": "true" if arguments.get("--net_only") else "false",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*==========================================================================

.SUBCKT cap_cmim
C0 PLUS1 MINUS1 cap_cmim w=6.99u l=6.99u m=1
C0 PLUS1 MINUS1 $[cap_cmim] 74.620f w=6.99u l=6.99u m=1
C1 PLUS2 MINUS2 cap_cmim w=6.99u l=6.99u m=2
C2 PLUS3 MINUS3 cap_cmim w=6.99u l=6.99u m=3

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*==========================================================================

.SUBCKT lvsres
Rm1 net1 net2 lvsres l=1u w=5u
Rm2 net3 net4 lvsres l=1.5u w=5u
Rm3 net5 net6 lvsres length=1u width=6u
Rm1 net1 net2 $[lvsres] 20k l=1u w=5u
Rm2 net3 net4 lvsres \ l=1.5u w=5u
Rm3 net5 net6 lvsres / length=1u width=6u
.ENDS
24 changes: 24 additions & 0 deletions ihp-sg13g2/libs.tech/klayout/tech/macros/sg13g2_lvs.lylvs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
<text>

require 'yaml'
require 'open3'

# Load LVS options from a YAML file
#
Expand Down Expand Up @@ -82,6 +83,29 @@ def set_default_options(yaml_file_path)
default_options
end

# check klayout version
klayout_v, _ = Open3.capture2('klayout -b -v')
klayout_v = klayout_v.split("\n")[0]
klayout_v_list = []

if klayout_v.empty?
raise StandardError, "KLayout is not found. Please make sure KLayout is installed."
else
klayout_v_arr = klayout_v.split(" ")[-1].scan(/[^.]+/)
klayout_v_list = klayout_v_arr.map { |ele| ele.to_i }
end

if klayout_v_list.size &lt; 1 || klayout_v_list.size &gt; 3
raise StandardError, "Was not able to get KLayout version properly."
elsif klayout_v_list.size &gt;= 2 || klayout_v_list.size &lt;= 3
if klayout_v_list[1] &lt; 29
puts "Using this KLayout version has not been assessed. Limits are unknown."
raise StandardError, "Prerequisites at a minimum: KLayout 0.29.0"
end
end
puts "Your KLayout version is: #{klayout_v}"

# Get testing dir path
dir_path = File.dirname(File.expand_path(__FILE__))

## reading the loaded gds file path
Expand Down
27 changes: 26 additions & 1 deletion ihp-sg13g2/libs.tech/klayout/tech/macros/sg13g2_options.lym
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,35 @@
<text>
module SG13G2LVSOptions
require 'yaml'
require 'open3'
include RBA

# Main function to manage LVS options
def self.main
def self.main

# check klayout version
klayout_v, _ = Open3.capture2('klayout -b -v')
klayout_v = klayout_v.split("\n")[0]
klayout_v_list = []

if klayout_v.empty?
raise StandardError, "KLayout is not found. Please make sure KLayout is installed."
else
klayout_v_arr = klayout_v.split(" ")[-1].scan(/[^.]+/)
klayout_v_list = klayout_v_arr.map { |ele| ele.to_i }
end

if klayout_v_list.size &lt; 1 || klayout_v_list.size &gt; 3
raise StandardError, "Was not able to get KLayout version properly."
elsif klayout_v_list.size &gt;= 2 || klayout_v_list.size &lt;= 3
if klayout_v_list[1] &lt; 29
puts "Using this KLayout version has not been assessed. Limits are unknown."
raise StandardError, "Prerequisites at a minimum: KLayout 0.29.0"
end
end

puts "Your KLayout version is: #{klayout_v}"

# Construct the absolute path to the YAML file
yaml_file_path = "#{__dir__}/lvs_options.yml"

Expand Down

0 comments on commit 83e408e

Please sign in to comment.