module Gdsii
There are two approaches to interacting with a GDSII file using this module:
-
At the record level (low-level)
-
At the record group level (high-level)
Approach #1¶ ↑
(See Record class for details)
Interaction at the record level is intended for streamlined file processing where the author has a good knowledge of the GDSII structure. A typical usage might be to streamline changes to a GDSII file such as changing bus bit characters on a node name from <> to [] format (see the samples directory of this library installation for an example). Here is a simple way to dump the all strings in a GDSII file using the Record class:
require 'gdsii' # Note: 'rb' is required for DOS/Windows compatibility File.open('mydesign.gds', 'rb') do |file| Gds::Record.read_each(file) do |record| puts record.data[0] if record.is_string? end end
Approach #2¶ ↑
(See Group, Library, Structure, Element, Boundary, Path, Text, SRef, ARef, Node, and Box classes for details)
The second approach offers a high-level interface to the GDSII format which might be ideal in cases where the author may not be familiar with the details of the GDSII format. This example will write a small transistor cell:
require 'gdsii' Gdsii::Library.new('MYLIB.DB') do |lib| Gdsii::Structure.new('trans') do |struct| # Diffusion layer struct.add Gdsii::Boundary.new(1, 0, [-2000,0, -2000,4000, 2000,4000, 2000,0, -2000,0]) # Gate layer... add a property labling as "gate" Gdsii::Path.new(2, 0, 0, 800, [0,-600, 0,4600]) do |path| path.add Gdsii::Property.new(1, 'gate') struct.add path end # Add this structure to the library lib.add struct end # Write the library to a file lib.write('trans.gds') end
Important notes¶ ↑
Look at inherited and mixed-in methods¶ ↑
The high-level classes in this GDSII library rely heavily upon inheritance and mixed-in modules to reduce code. When reviewing documentation, be sure to be aware of methods defined implicitly through class inheritance and through Module#include and Module#extend.
Use 'b' during R/W of files¶ ↑
Be sure to always use the 'b' read/write attribute when reading and writing GDSII files to ensure that read/write happens properly on DOS/Windows systems. For example (see IO#open for more details):
inf = File.open('mydesign.gds', 'rb') outf = File.open('mydesign.gds', 'wb')
Improving performance¶ ↑
The low-level GDSII methods will offer significantly better GDSII read/write performance as compared to the high-level methods. For most streamlined manipulations of GDSII files, the low-level methods are probably the best option. For smaller GDSII files or when code re-use/readability is important, then the performance hit with the high-level methods may not be a concern.
Here are some benchmarks using both low and high level methods to read and immediately write a GDSII file:
-
GDSII file size: 7 MB
-
WinXP machine: Intel(R) Pentium(R) M (Centrino) 1.6 Ghz @ 1 GB RAM
-
Linux machine (SuSE): 2x Intel(R) Pentium(R) 4 3.4 Ghz @ 1 GB RAM
Linux WinXP ------- -------
High-level methods: 8m 45s 11m 23s Low-level methods: 0m 45s 1m 29s
Constants
- DATATYPE_INFO
Gdsii::DATATYPE_INFO is an array of Gdsii::RecDataTypeInfo objects. The array order is significant in that the index of the array is the value of the record data type constant. This allows easy validation lookup based upon the record data type constants. Example:
Gdsii::DATATYPE_INFO[Gdsii::GRT_REAL8].name # => "REAL8" Gdsii::DATATYPE_INFO[Gdsii::GRT_REAL8].valid # => true Gdsii::DATATYPE_INFO[Gdsii::GRT_REAL8].size # => 8
- DEF_LIB_UNITS
- DEF_LIB_VERSION
- FORMAT_EDSIII_ARCHIVE
- FORMAT_EDSIII_FILTERED
- FORMAT_GDSII_ARCHIVE
These numbers correspond to GDSII format
- FORMAT_GDSII_FILTERED
- GDT_ASCII
- GDT_BITARRAY
- GDT_INT2
- GDT_INT4
- GDT_NO_DATA
GDSII record data types
- GDT_REAL4
- GDT_REAL8
- GRT_ANGLE
- GRT_AREF
- GRT_ATTRTABLE
- GRT_BGNEXTN
- GRT_BGNLIB
- GRT_BGNSTR
- GRT_BORDER
- GRT_BOUNDARY
- GRT_BOX
- GRT_BOXTYPE
- GRT_COLROW
- GRT_CONTACT
- GRT_DATATYPE
- GRT_ELFLAGS
- GRT_ELKEY
- GRT_ENDEL
- GRT_ENDEXTN
- GRT_ENDLIB
- GRT_ENDMASKS
- GRT_ENDSTR
- GRT_FONTS
- GRT_FORMAT
- GRT_GENERATIONS
- GRT_HARDFENCE
- GRT_HARDWIRE
- GRT_HEADER
These are GDSII record numbers and correspond to the GDSII number in the GDSII file specification
- GRT_LAYER
- GRT_LIBDIRSIZE
- GRT_LIBNAME
- GRT_LIBSECUR
- GRT_LINKKEYS
- GRT_LINKTYPE
- GRT_MAG
- GRT_MASK
- GRT_NODE
- GRT_NODEPORT
- GRT_NODETYPE
- GRT_PATH
- GRT_PATHPORT
- GRT_PATHTYPE
- GRT_PLEX
- GRT_PRESENTATION
- GRT_PROPATTR
- GRT_PROPVALUE
- GRT_REFLIBS
- GRT_RESERVED
- GRT_SNAME
- GRT_SOFTFENCE
- GRT_SOFTWIRE
- GRT_SPACER_ERROR
- GRT_SPACING
- GRT_SREF
- GRT_SRFNAME
- GRT_STRANS
- GRT_STRCLASS
- GRT_STRING
- GRT_STRNAME
- GRT_STRTYPE
- GRT_STYPTABLE
- GRT_TAPECODE
- GRT_TAPENUM
- GRT_TEXT
- GRT_TEXTNODE
- GRT_TEXTTYPE
- GRT_UINTEGER
- GRT_UNITS
- GRT_USERCONSTRAINT
- GRT_USTRING
- GRT_WIDTH
- GRT_XY
- PATHTYPE_CUSTOM
- PATHTYPE_EXTEND
- PATHTYPE_FLUSH
- PATHTYPE_ROUND
- RECORD_INFO
Gdsii::RECORD_INFO is an array of Gdsii::RecInfo objects. The array order is significant in that the index of the array is the value of the record and corresponds to the Gdsii::GRT_* constant values. This allows easy validation lookup based upon the record type constants. Example:
Gdsii::RECORD_INFO[Gdsii::GRT_HEADER].name # => "HEADER" Gdsii::RECORD_INFO[Gdsii::GRT_HEADER].valid # => true Gdsii::RECORD_INFO[Gdsii::GRT_HEADER].data_type # => 2
Public Class Methods
Returns the name for given record data type if it is found; if not, then the record data type number formatted as a String is returned
# File lib/gdsii/record/consts.rb, line 369 def gdt_name(gdt_number) if gdt_number.class == Fixnum if (0..DATATYPE_INFO.length-1).member?(gdt_number) DATATYPE_INFO[gdt_number].name else gdt_number.to_s end else gdt_number.inspect end end
Returns the name for given record type if it is found; if not, then the record number formatted as a String is returned
# File lib/gdsii/record/consts.rb, line 355 def grt_name(grt_number) if grt_number.class == Fixnum if (0..RECORD_INFO.length-1).member?(grt_number) RECORD_INFO[grt_number].name else grt_number.to_s end else grt_number.inspect end end
Private Instance Methods
Returns the name for given record data type if it is found; if not, then the record data type number formatted as a String is returned
# File lib/gdsii/record/consts.rb, line 369 def gdt_name(gdt_number) if gdt_number.class == Fixnum if (0..DATATYPE_INFO.length-1).member?(gdt_number) DATATYPE_INFO[gdt_number].name else gdt_number.to_s end else gdt_number.inspect end end
Returns the name for given record type if it is found; if not, then the record number formatted as a String is returned
# File lib/gdsii/record/consts.rb, line 355 def grt_name(grt_number) if grt_number.class == Fixnum if (0..RECORD_INFO.length-1).member?(grt_number) RECORD_INFO[grt_number].name else grt_number.to_s end else grt_number.inspect end end