jfreeze-ruby-gdsii 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.txt +6 -0
- data/LICENSE.txt +20 -0
- data/README.txt +113 -0
- data/Rakefile +30 -0
- data/bin/rgds-debug +43 -0
- data/bin/rgds-dump +38 -0
- data/bin/rgds-join +98 -0
- data/bin/rgds-layers +53 -0
- data/bin/rgds-sremove +136 -0
- data/bin/rgds-ssplit +113 -0
- data/bin/rgds-stats +134 -0
- data/bin/rgds-structs +41 -0
- data/bin/rgds-tree +167 -0
- data/bin/rgds2rb +99 -0
- data/lib/gdsii.rb +137 -0
- data/lib/gdsii/aref.rb +243 -0
- data/lib/gdsii/bnf.rb +309 -0
- data/lib/gdsii/boundary.rb +53 -0
- data/lib/gdsii/box.rb +65 -0
- data/lib/gdsii/byte_order.rb +36 -0
- data/lib/gdsii/element.rb +172 -0
- data/lib/gdsii/group.rb +98 -0
- data/lib/gdsii/library.rb +518 -0
- data/lib/gdsii/mixins.rb +378 -0
- data/lib/gdsii/node.rb +65 -0
- data/lib/gdsii/path.rb +169 -0
- data/lib/gdsii/property.rb +108 -0
- data/lib/gdsii/record.rb +606 -0
- data/lib/gdsii/record/consts.rb +384 -0
- data/lib/gdsii/record/datatypes/ascii.rb +145 -0
- data/lib/gdsii/record/datatypes/bitarray.rb +101 -0
- data/lib/gdsii/record/datatypes/data.rb +111 -0
- data/lib/gdsii/record/datatypes/int2.rb +67 -0
- data/lib/gdsii/record/datatypes/int4.rb +65 -0
- data/lib/gdsii/record/datatypes/nodata.rb +60 -0
- data/lib/gdsii/record/datatypes/real4.rb +51 -0
- data/lib/gdsii/record/datatypes/real8.rb +120 -0
- data/lib/gdsii/sref.rb +61 -0
- data/lib/gdsii/strans.rb +133 -0
- data/lib/gdsii/structure.rb +352 -0
- data/lib/gdsii/text.rb +203 -0
- data/pkg/ruby-gdsii.gem +46 -0
- data/samples/hello.gds +0 -0
- data/samples/hello.out.rb +84 -0
- data/samples/hello.rb +94 -0
- data/test/baseline/dcp1.gds +0 -0
- data/test/baseline/h_write.gds +0 -0
- data/test/h_pthru.rb +22 -0
- data/test/h_write.rb +117 -0
- data/test/hs_pthru.rb +31 -0
- data/test/l_pthru.rb +23 -0
- data/test/test_gds_group.rb +379 -0
- data/test/test_gds_record.rb +99 -0
- metadata +117 -0
data/bin/rgds-ssplit
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
##############################################################################
|
3
|
+
#
|
4
|
+
# == gdsssplit.rb
|
5
|
+
#
|
6
|
+
# Splits a GDSII file into separate GDSII files. A separate GDSII file will
|
7
|
+
# be created for each structure in the original GDSII file and the new GDSII
|
8
|
+
# files will be named after their structure name. At this time there are
|
9
|
+
# NO sref or aref intelligence (i.e. no hierarchy dependency checking) - so
|
10
|
+
# only one structure will exist per file.
|
11
|
+
#
|
12
|
+
# === Author
|
13
|
+
#
|
14
|
+
# James D. Masters (james.d.masters@gmail.com)
|
15
|
+
#
|
16
|
+
# === History
|
17
|
+
#
|
18
|
+
# * 03/26/2007 (jdm): Initial version
|
19
|
+
#
|
20
|
+
##############################################################################
|
21
|
+
|
22
|
+
|
23
|
+
require 'getoptlong'
|
24
|
+
require 'gdsii'
|
25
|
+
include Gdsii
|
26
|
+
|
27
|
+
# Build usage message
|
28
|
+
usage = "
|
29
|
+
Splits a GDSII file into separate GDSII files. A separate GDSII file will
|
30
|
+
be created for each structure in the original GDSII file and the new GDSII
|
31
|
+
files will be named after their structure name. At this time there are
|
32
|
+
NO sref or aref intelligence (i.e. no hierarchy dependency checking) - so
|
33
|
+
only one structure will exist per file.
|
34
|
+
|
35
|
+
Usage: #{File.basename($PROGRAM_NAME)} [options] <gds-file> <output-dir>
|
36
|
+
|
37
|
+
Options:
|
38
|
+
|
39
|
+
-s, --structs Specify structure(s) in a space separated list to extract.
|
40
|
+
The default behavior is to extract all structures.
|
41
|
+
-f, --force Force overwritting of GDSII files in the output directory
|
42
|
+
if a file by the same name exists.
|
43
|
+
-e, --extension Specify the output file GDSII extension to use. Default
|
44
|
+
is 'gds'.
|
45
|
+
-h, --help Displays this usage message.
|
46
|
+
|
47
|
+
"
|
48
|
+
|
49
|
+
# Get command-line arguments
|
50
|
+
force = false
|
51
|
+
structs = []
|
52
|
+
ext = 'gds'
|
53
|
+
|
54
|
+
opts = GetoptLong.new(
|
55
|
+
['--structs', '-s', GetoptLong::OPTIONAL_ARGUMENT],
|
56
|
+
['--force', '-f', GetoptLong::OPTIONAL_ARGUMENT|GetoptLong::NO_ARGUMENT],
|
57
|
+
['--extension', '-e', GetoptLong::OPTIONAL_ARGUMENT|GetoptLong::NO_ARGUMENT],
|
58
|
+
['--help', '-h', GetoptLong::OPTIONAL_ARGUMENT|GetoptLong::NO_ARGUMENT]
|
59
|
+
)
|
60
|
+
|
61
|
+
opts.each do |option, argument|
|
62
|
+
case option
|
63
|
+
when '--help' : abort usage
|
64
|
+
when '--structs' : structs = argument.split(/\s+/)
|
65
|
+
when '--extension' : ext = argument
|
66
|
+
when '--force' : force = true
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Get GDSII file and output directory from command line
|
71
|
+
gds_file, output_dir = ARGV
|
72
|
+
unless gds_file and output_dir
|
73
|
+
abort usage
|
74
|
+
end
|
75
|
+
|
76
|
+
# Check that GDSII file is readable and that output dir is writable
|
77
|
+
unless File.readable? gds_file
|
78
|
+
abort "\nGDSII file does not exist or is not readable: #{gds_file}\n\n" + usage
|
79
|
+
end
|
80
|
+
|
81
|
+
# Check that output directory is writable
|
82
|
+
unless File.directory? output_dir and File.writable? output_dir
|
83
|
+
abort "\nOutput directory is not writable: #{output_dir}\n\n" + usage
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
# Read the GDSII file and write out resulting GDSII files
|
88
|
+
File.open(gds_file, 'rb') do |inf|
|
89
|
+
Library.read_header(inf) do |lib|
|
90
|
+
Structure.read_each_header(inf) do |struct|
|
91
|
+
if structs.empty? or structs.member?(struct.name)
|
92
|
+
# write lib & structure header to file
|
93
|
+
file_name = "#{output_dir}/#{struct.name}.#{ext}"
|
94
|
+
if File.exists? file_name and not force
|
95
|
+
warn "WARNING: #{file_name} already exists; use --force to override"
|
96
|
+
else
|
97
|
+
# open the file
|
98
|
+
File.open(file_name, 'wb') do |outf|
|
99
|
+
lib.write_header(outf)
|
100
|
+
struct.write_header(outf)
|
101
|
+
Element.read_each(inf) {|element| element.write(outf)}
|
102
|
+
struct.write_footer(outf)
|
103
|
+
lib.write_footer(outf)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
else
|
107
|
+
# structure not on list; skip to next
|
108
|
+
Structure.seek_next(inf)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
data/bin/rgds-stats
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
##############################################################################
|
3
|
+
#
|
4
|
+
# == gdsstats.rb
|
5
|
+
#
|
6
|
+
# Dumps statistical information from a GDSII file.
|
7
|
+
#
|
8
|
+
# === Author
|
9
|
+
#
|
10
|
+
# James D. Masters (james.d.masters@gmail.com)
|
11
|
+
#
|
12
|
+
# === History
|
13
|
+
#
|
14
|
+
# * 03/26/2007 (jdm): Initial version
|
15
|
+
#
|
16
|
+
##############################################################################
|
17
|
+
|
18
|
+
|
19
|
+
require 'getoptlong'
|
20
|
+
require 'gdsii/record.rb'
|
21
|
+
include Gdsii
|
22
|
+
|
23
|
+
# Build usage message
|
24
|
+
usage = "
|
25
|
+
Dumps statistical information from a GDSII file.
|
26
|
+
|
27
|
+
Usage: #{File.basename($PROGRAM_NAME)} [options] <gds-file>
|
28
|
+
|
29
|
+
Options:
|
30
|
+
|
31
|
+
-s, --structs Specify structure(s) in a space separated list to process.
|
32
|
+
The default behavior is to process all structures.
|
33
|
+
-h, --help Displays this usage message.
|
34
|
+
|
35
|
+
"
|
36
|
+
|
37
|
+
# Get command-line arguments
|
38
|
+
structs = []
|
39
|
+
|
40
|
+
opts = GetoptLong.new(
|
41
|
+
['--structs', '-s', GetoptLong::OPTIONAL_ARGUMENT],
|
42
|
+
['--help', '-h', GetoptLong::OPTIONAL_ARGUMENT|GetoptLong::NO_ARGUMENT]
|
43
|
+
)
|
44
|
+
|
45
|
+
opts.each do |option, argument|
|
46
|
+
case option
|
47
|
+
when '--help' : abort usage
|
48
|
+
when '--structs' : structs = argument.split(/\s+/)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Get GDSII file directory from command line
|
53
|
+
unless (gds_file = ARGV[0])
|
54
|
+
abort usage
|
55
|
+
end
|
56
|
+
|
57
|
+
# Read the GDSII file and write out resulting GDSII files
|
58
|
+
File.open(gds_file, 'rb') do |inf|
|
59
|
+
|
60
|
+
# Set statistics hashes:
|
61
|
+
# lib_stats = Hash.new {|h,k| h[k] = 0}
|
62
|
+
str_stats = Hash.new {|h,k| h[k] = Hash.new {|h2,k2| h2[k2] = 0}}
|
63
|
+
|
64
|
+
# Set parse flags
|
65
|
+
strname = nil
|
66
|
+
dt_cxt = nil
|
67
|
+
layer = nil
|
68
|
+
|
69
|
+
# Read each record in the GDSII file
|
70
|
+
Record.read_each(inf) do |record|
|
71
|
+
|
72
|
+
type = record.type
|
73
|
+
|
74
|
+
case type
|
75
|
+
when GRT_STRNAME
|
76
|
+
# New structure definition... print header
|
77
|
+
strname = record.data_value
|
78
|
+
if structs.empty? or structs.member?(strname)
|
79
|
+
puts
|
80
|
+
puts '#' * 78
|
81
|
+
puts
|
82
|
+
puts "STRUCTURE: #{strname}"
|
83
|
+
# lib_stats[type] += 1
|
84
|
+
end
|
85
|
+
when GRT_SREF, GRT_AREF
|
86
|
+
# increment count for sref, aref, text, node, box
|
87
|
+
str_stats[nil][type] += 1
|
88
|
+
when GRT_BOUNDARY
|
89
|
+
# set datatype context to BOUNDARY
|
90
|
+
dt_cxt = type
|
91
|
+
when GRT_PATH
|
92
|
+
# set datatype context to PATH
|
93
|
+
dt_cxt = type
|
94
|
+
when GRT_LAYER
|
95
|
+
# capture the layer number - record when context is reached
|
96
|
+
layer = record.data_value
|
97
|
+
when GRT_DATATYPE, GRT_TEXTTYPE, GRT_NODETYPE, GRT_BOXTYPE
|
98
|
+
# record the layer for the given layer context
|
99
|
+
datatype = record.data_value
|
100
|
+
rec_num = (dt_cxt) ? dt_cxt : type
|
101
|
+
str_stats[[layer, datatype]][rec_num] += 1
|
102
|
+
dt_cxt = nil
|
103
|
+
when GRT_ENDSTR
|
104
|
+
# end structure definition
|
105
|
+
if structs.empty? or structs.member?(strname)
|
106
|
+
puts
|
107
|
+
printf("SRefs: %-12d\n", str_stats[nil][GRT_SREF])
|
108
|
+
printf("ARefs: %-12d\n", str_stats[nil][GRT_AREF])
|
109
|
+
puts
|
110
|
+
puts "Layer Type # Bnd # Path # Text # Box # Node"
|
111
|
+
puts '-' * 78
|
112
|
+
|
113
|
+
# Show layer information
|
114
|
+
layers = str_stats.keys.compact.sort {|a, b| (a[0] <=> b[0]) <=> (a[1] <=> b[1])}
|
115
|
+
layers.each do |layer|
|
116
|
+
printf("%-6d %-6d %11d %11d %11d %11d %11d\n",
|
117
|
+
layer[0],
|
118
|
+
layer[1],
|
119
|
+
str_stats[layer][GRT_BOUNDARY],
|
120
|
+
str_stats[layer][GRT_PATH],
|
121
|
+
str_stats[layer][GRT_TEXTTYPE],
|
122
|
+
str_stats[layer][GRT_BOXTYPE],
|
123
|
+
str_stats[layer][GRT_NODETYPE]
|
124
|
+
)
|
125
|
+
end
|
126
|
+
puts
|
127
|
+
end
|
128
|
+
str_stats.delete_if {|key,value| true}
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
|
data/bin/rgds-structs
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
##############################################################################
|
3
|
+
#
|
4
|
+
# == gdsstructs.rb
|
5
|
+
#
|
6
|
+
#
|
7
|
+
# === Author
|
8
|
+
#
|
9
|
+
# James D. Masters (james.d.masters@gmail.com)
|
10
|
+
#
|
11
|
+
# === History
|
12
|
+
#
|
13
|
+
# * 03/26/2007 (jdm): Initial version
|
14
|
+
#
|
15
|
+
##############################################################################
|
16
|
+
|
17
|
+
|
18
|
+
require 'getoptlong'
|
19
|
+
require 'gdsii/record.rb'
|
20
|
+
include Gdsii
|
21
|
+
|
22
|
+
# Build usage message
|
23
|
+
if (file_name = ARGV[0]).nil? then
|
24
|
+
abort "
|
25
|
+
Dumps a of structure names defined in the GDSII file.
|
26
|
+
|
27
|
+
Usage: #{File.basename($PROGRAM_NAME)} <gds-file>
|
28
|
+
|
29
|
+
"
|
30
|
+
end
|
31
|
+
|
32
|
+
# Extract the structure names from the GDSII file
|
33
|
+
File.open(file_name, 'rb') do |file|
|
34
|
+
while (record = Record.read(file)) do
|
35
|
+
if record.is_strname?
|
36
|
+
puts record.data_value
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
|
data/bin/rgds-tree
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
##############################################################################
|
3
|
+
#
|
4
|
+
# == gdstree.rb
|
5
|
+
#
|
6
|
+
# Dumps a hierarchy tree of structures used within a given GDSII file.
|
7
|
+
#
|
8
|
+
# === Author
|
9
|
+
#
|
10
|
+
# James D. Masters (james.d.masters@gmail.com)
|
11
|
+
#
|
12
|
+
# === History
|
13
|
+
#
|
14
|
+
# * 03/27/2007 (jdm): Initial version
|
15
|
+
#
|
16
|
+
#
|
17
|
+
##############################################################################
|
18
|
+
|
19
|
+
|
20
|
+
require 'getoptlong'
|
21
|
+
require 'gdsii/record.rb'
|
22
|
+
include Gdsii
|
23
|
+
|
24
|
+
# Build usage message
|
25
|
+
program = File.basename($PROGRAM_NAME)
|
26
|
+
usage = "
|
27
|
+
Dumps a hierarchy tree of structures used within a given GDSII file.
|
28
|
+
|
29
|
+
Usage: #{File.basename($PROGRAM_NAME)} [options] <gds-file>
|
30
|
+
|
31
|
+
Options:
|
32
|
+
|
33
|
+
-t, --top-structs Explicitly specify the top structure name(s) to use in
|
34
|
+
the tree. The default behavior is to identify the top
|
35
|
+
structure(s) in the hierarchy automatically.
|
36
|
+
-c, --inst-counts Include instantiation counts in the tree.
|
37
|
+
-b, --broken-refs Indicate how broken references are handled. Possible values
|
38
|
+
are 'annotate' or 'prune'. The default behavior is to
|
39
|
+
ignore broken references.
|
40
|
+
-d, --delimiter Set hierarchy delimiter (default is '/').
|
41
|
+
-h, --help Displays this usage message.
|
42
|
+
|
43
|
+
Examples:
|
44
|
+
|
45
|
+
ruby #{program} design.gds
|
46
|
+
ruby #{program} --delimiter . design.gds
|
47
|
+
ruby #{program} --inst-counts design.gds
|
48
|
+
ruby #{program} --top-structs 'mytop othertop' --broken-refs annotate
|
49
|
+
|
50
|
+
"
|
51
|
+
|
52
|
+
# Get command-line arguments
|
53
|
+
top_structs = []
|
54
|
+
show_inst_counts = false
|
55
|
+
broken_refs = nil
|
56
|
+
delimiter = '/'
|
57
|
+
|
58
|
+
opts = GetoptLong.new(
|
59
|
+
['--top-structs', '-t', GetoptLong::OPTIONAL_ARGUMENT],
|
60
|
+
['--inst-counts', '-c', GetoptLong::NO_ARGUMENT],
|
61
|
+
['--broken-refs', '-b', GetoptLong::OPTIONAL_ARGUMENT],
|
62
|
+
['--delimiter', '-d', GetoptLong::OPTIONAL_ARGUMENT],
|
63
|
+
['--help', '-h', GetoptLong::NO_ARGUMENT]
|
64
|
+
)
|
65
|
+
|
66
|
+
opts.each do |option, argument|
|
67
|
+
case option
|
68
|
+
when '--top-structs' : top_structs = argument.split(/\s+/)
|
69
|
+
when '--inst-counts' : show_inst_counts = argument
|
70
|
+
when '--broken-refs' : broken_refs = argument
|
71
|
+
when '--delimiter' : delimiter = argument
|
72
|
+
when '--help' : abort usage
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Get GDSII file directory from command line
|
77
|
+
unless (gds_file = ARGV[0])
|
78
|
+
abort usage
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
#
|
83
|
+
# Class to define a structure within the hierarchy
|
84
|
+
#
|
85
|
+
class HierStruct
|
86
|
+
# Make the attributes accessible
|
87
|
+
attr_accessor :name, :children
|
88
|
+
|
89
|
+
# Create a new HierStruct
|
90
|
+
def initialize(name, delimiter, inst_counts, broken_refs)
|
91
|
+
@name = name
|
92
|
+
@delimiter = delimiter
|
93
|
+
@inst_counts = inst_counts
|
94
|
+
@broken_refs = broken_refs.to_sym unless broken_refs.nil?
|
95
|
+
@children = Hash.new {|hash, key| hash[key] = 0}
|
96
|
+
end
|
97
|
+
|
98
|
+
# Display the hierarchy of this HierStruct
|
99
|
+
def puts(structs, prefix='', suffix='')
|
100
|
+
# build the hierarchy string then display it
|
101
|
+
string = prefix + @delimiter + @name + suffix
|
102
|
+
$stdout.puts string
|
103
|
+
|
104
|
+
# display the hierarchy for all children of this struct
|
105
|
+
@children.each_pair do |struct_name, num_placed|
|
106
|
+
|
107
|
+
cnt_suffix = (@inst_counts) ? "(#{num_placed})" : ''
|
108
|
+
|
109
|
+
if (struct = structs[struct_name])
|
110
|
+
# display the child's hierarchy
|
111
|
+
struct.puts(structs, string, cnt_suffix)
|
112
|
+
else
|
113
|
+
# broken reference; deal with appropriately
|
114
|
+
case @broken_refs
|
115
|
+
when :annotate : $stdout.puts string + '(MISSING)'
|
116
|
+
when :prune : nil
|
117
|
+
else
|
118
|
+
$stdout.puts string + @delimiter + struct_name + cnt_suffix
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
#
|
128
|
+
# Main code
|
129
|
+
#
|
130
|
+
|
131
|
+
# get the structure and instance placement from the gdsii file
|
132
|
+
structs = {}
|
133
|
+
has_parent = {}
|
134
|
+
File.open(gds_file, 'rb') do |file|
|
135
|
+
while (rec=Record.read(file)) do
|
136
|
+
if rec.is_strname?
|
137
|
+
# inside a structure definition
|
138
|
+
str = HierStruct.new(rec.data_value, delimiter, show_inst_counts, broken_refs)
|
139
|
+
structs[str.name] = str
|
140
|
+
has_parent[str.name] = false unless has_parent.has_key?(str.name)
|
141
|
+
elsif rec.is_sname?
|
142
|
+
# instance in this structure
|
143
|
+
ref_str = rec.data_value
|
144
|
+
str.children[ref_str] += 1
|
145
|
+
has_parent[ref_str] = true
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
|
151
|
+
# if the user provides a list of top structure names, then use that list;
|
152
|
+
# otherwise build our own.
|
153
|
+
if top_structs.empty?
|
154
|
+
top_structs = has_parent.delete_if {|key, value| value}.keys.sort
|
155
|
+
end
|
156
|
+
|
157
|
+
# Output hierarch(y/ies)...
|
158
|
+
unless top_structs.empty?
|
159
|
+
top_structs.each do |struct|
|
160
|
+
if structs.has_key?(struct)
|
161
|
+
structs[struct].puts(structs)
|
162
|
+
else
|
163
|
+
warn "WARNING: structure #{struct} not found"
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|