Shop OBEX P1 Docs P2 Docs Learn Events
DXF to GSDII — Parallax Forums

DXF to GSDII

potatoheadpotatohead Posts: 10,254
edited 2007-09-01 20:00 in General Discussion
I'm modeling a test structure layout, as a favor to someone. I'm not a semiconductor expert --just creating the geometry according to the rules!

The target fab has asked for GSDII format file. Anyone know of free / trial ware translators for this?

It's a one time project, with a few masks to generate from DXF data.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Propeller Wiki: Share the coolness!

Comments

  • kelvin jameskelvin james Posts: 531
    edited 2007-08-22 17:30
    "ACE" and "LINKCAD" have trial versions of their convertors. Here is a link for ACE.

    www.numericalinnovations.com/index.asp?PageAction=VIEWPROD&ProdID=9
  • Beau SchwabeBeau Schwabe Posts: 6,547
    edited 2007-08-22 19:19
    potatohead,
    You might get better results if you search for "GDSII" or "GDS2" or "GDSii" rather than "GSDII" <- Note "S" and "D" are transposed.


    Here is a section of Visual Basic code that I wrote that will Parse a GDSII file.... it shouldn't be too difficult to go the other way around.
    I'm not familiar with how the DXF data is setup, so I wouldn't know exactly what it looks like or how to parse it.

    There are also some free GDS2TXT and TXT2GDS converters out there that help make the GDSII file human readable that might work for you,
    but basically for GDS2TXT conversions, they do what the VB code below does.

    Sub ReadGDS(FileName$)
        DesignMenu.Slider1.Visible = "True"
        Open FileName$ For Binary As 1
             FileSize = LOF(1)
             Debug.Print "---------------------------------------"
             Debug.Print FileName$
             Debug.Print FileSize
             Debug.Print "---------------------------------------"
             DataSize = 0
             While Seek(1) < FileSize And Sw1 = 0
                   Pcnt = Int((Seek(1) / FileSize) * 100)
                   DesignMenu.Slider1.Value = Pcnt
                   DataSize = TBSI - 4
                   Record = HexWord
                   
                   'Debug.Print "Record Type -"; Record, "Record Size -"; DataSize
                   ExitButton = DesignMenu.Slider1.Tag
                   If ExitButton = "Slider Click" Then
                      GoTo ExitSub
                   End If
                   
                   Select Case Record
                   Case "0000"  'End of File
                        GoTo ExitSub
                   Case "0002"  'HEADER
                        Debug.Print Record, "GDS Version ="; Str$(TBSI)
                   Case "0102"  'BGNLIB
                        Debug.Print Record, BGNdata
                   Case "0206"  'LIBNAME
                        Debug.Print Record, "Library Name ="; Input(DataSize, #1)
                   Case "0305"  'UNITS
                        GridUnit = Str$(EBRN)
                        MeterUnit = Str$(EBRN)
                        Debug.Print Record, "Grid Unit ="; GridUnit
                        Debug.Print , "MeterUnit ="; MeterUnit
                   Case "0400"  'ENDLIB
                        Debug.Print Record, "Library End"
                   Case "0502"  'BGNSTR
                        Debug.Print Record, BGNdata
                   Case "0606"  'STRNAME
                        Debug.Print Record, "Structure Name ="; Input(DataSize, #1)
                   Case "0700"  'ENDSTR
                        Debug.Print Record, "Structure End"
                   Case "0800"  'BOUNDARY
                        Debug.Print Record, "Boundary Start"
                   Case "0900"  'PATH
                        Debug.Print Record, "Path Start"
                   Case "0A00"  'SREF
                        Debug.Print Record, "Reference Structure Start"
                   Case "0B00"  'AREF
                        Debug.Print Record, "Array Start"
                   Case "0C00"  'TEXT
                        Debug.Print Record, "Text Start"
                   Case "0D02"  'LAYER
                        Debug.Print Record, "Layer ="; TBSI
                   Case "0E02"  'DATATYPE
                        Debug.Print Record, "Data type ="; TBSI
                   Case "0F03"  'WIDTH
                        Debug.Print Record, "Width ="; FBSI
                   Case "1003"  'XY
                        Debug.Print Record, "XY coordinates ="; XY(DataSize)
                   Case "1100"  'ENDEL
                        Debug.Print Record, "Element End"
                   Case "1206"  'SNAME
                        Debug.Print Record, "Referenced Structure Name ="; Input(DataSize, #1)
                   Case "1302"  'COLROW
                        Debug.Print Record, "Columns ="; TBSI
                        Debug.Print , "   Rows ="; TBSI
                   Case "1400"  'TEXTNODE
                        Debug.Print Record, "Not Used"
                   Case "1500"  'NODE
                        Debug.Print Record, "Node Start"
                   Case "1602"  'TEXTTYPE
                        Debug.Print Record, "Text Type ="; TBSI
                   Case "1701"  'PRESENTATION
                        Debug.Print Record, "Text presentation ="; PRESENTATION
                   Case "1906"  'STRING
                        Debug.Print Record, Input(DataSize, #1)
                   Case "1A01"  'STRANS
                        Debug.Print Record, "Text Transformation ="; STRANS
                   Case "1B05"  'MAG
                        Debug.Print Record, "Magnification Factor ="; EBRN
                   Case "1C05"  'ANGLE
                        Debug.Print Record, "Angular Rotation ="; EBRN
                   Case "1F06"  'REFLIBS
                        Debug.Print Record, "Reference Libraries ="; Input(DataSize, #1)
                   Case "2006"  'FONTS
                        Debug.Print Record, "Text Font ="; Input(DataSize, #1)
                   Case "2102"  'PATHTYPE
                        Debug.Print Record, "Path type ="; TBSI
                   Case "2202"  'GENERATIONS
                        Debug.Print Record, "Backup Copies ="; TBSI
                   Case "2306"  'ATTRTABLE
                        Debug.Print Record, "Attribute definition file ="; Input(DataSize, #1)
                   Case "2406"  'STYPTABLE
                        Debug.Print Record, "Unreleased Feature ="; Input(DataSize, #1)
                   Case "2502"  'STRTYPE
                        Debug.Print Record, "Unreleased Feature ="; TBSI
                   Case "2601"  'ELFLAGS
                        Debug.Print Record, ELFLAGS
                   Case "2703"  'ELKEY
                        Debug.Print Record, "Unreleased Feature ="; FBSI
                   Case "2A02"  'NODETYPE
                        Debug.Print Record, "Node Type ="; TBSI
                   Case "2B02"  'PROPATTR
                        Debug.Print Record, "Attribute Number ="; TBSI
                   Case "2C06"  'PROPVALUE
                        Debug.Print Record, Input(DataSize, #1)
                   Case "2D00"  'BOX
                        Debug.Print Record, "Box Start"
                   Case "2E02"  'BOXTYPE
                        Debug.Print Record, "Box Type ="; TBSI
                   Case "2F03"  'PLEX
                        Debug.Print Record, FBSI
                   Case "3003"  'BGNEXTN
                        Debug.Print Record, FBSI
                   Case "3103"  'ENDEXTN
                        Debug.Print Record, FBSI
                   Case "3202"  'TAPENUM
                        Debug.Print Record, "Tape number ="; TBSI
                   Case "3302"  'TAPECODE
                        Debug.Print Record, "Tape code ="; TBSI
                   Case "3401"  'STRCLASS
                        Debug.Print Record, "Cadence Internal ="; STRCLASS
                   Case "3503"  'RESERVED
                        Debug.Print Record, "RESERVED ="; Input(DataSize, #1)
                   Case "3602"  'FORMAT
                        Debug.Print Record, TBSI
                   Case "3706"  'MASK
                        Debug.Print Record, Input(DataSize, #1)
                   Case "3800"  'ENDMASKS
                        Debug.Print Record, "Mask End"
                   Case "3902"  'LIBDIRSIZE
                        Debug.Print Record, "Library Directory Size ="; TBSI
                   Case "3A06"  'SRFNAME
                        Debug.Print Record, "Spacing Rules file ="; Input(DataSize, #1)
                   Case "3B02"  'LIBSECUR
                        Debug.Print Record, "Access Control List ="; LIBSECUR(DataSize)
                   Case "3C00"  'BORDER
                        Debug.Print Record, "Border Start"
                   Case "3D00"  'SOFTFENCE
                        Debug.Print Record, "Soft fence Start"
                   Case "3E00"  'HARDFENCE
                        Debug.Print Record, "Hard fence Start"
                   Case "3F00"  'SOFTWIRE
                        Debug.Print Record, "Soft wire Start"
                   Case "4000"  'HARDWIRE
                        Debug.Print Record, "Hard wire Start"
                   Case "4100"  'PATHPORT
                        Debug.Print Record, "Path port Start"
                   Case "4200"  'NODEPORT
                        Debug.Print Record, "Node port Start"
                   Case "4300"  'USERCONSTRAINT
                        Debug.Print Record, "User constraint Start"
                   Case "4400"  'SPACER ERROR
                        Debug.Print Record, "Spacer error Start"
                   Case "4500"  'CONTACT
                        Debug.Print Record, "Contact Start"
                   End Select
                   If Mid$(Record, 1, 2) = "28" Then    'LINKTYPE
                      Temp = Seek(1)
                      Seek #1, Temp - 1
                      Debug.Print "28", "Unreleased Feature"; TBSI
                   End If
                   If Mid$(Record, 1, 2) = "29" Then    'LINKKEYS
                      Temp = Seek(1)
                      Seek #1, Temp - 1
                      Debug.Print "29", "Unreleased Feature"; FBSI
                   End If
                   DoEvents
                 Wend
    ExitSub:
        Close #1
        DesignMenu.Slider1.Visible = "False"
        DesignMenu.Slider1.Tag = ""
    End Sub
    Function BGNdata()
             Dim TempData(12)
             apm = "a"
             apa = "a"
             For N = 1 To 12
                 Temp = TBSI
                 If N = 1 Or N = 7 Then Temp = Temp + 1900
                 If N = 4 Or N = 10 And Temp > 12 Then
                    Temp = Temp - 12
                    If N = 4 Then apm = "p"
                    If N = 10 Then apa = "p"
                 End If
                 TempData(N) = Trim$(Str$(Temp))
                 If Len(TempData(N)) < 2 Then
                    TempData(N) = "0" + TempData(N)
                 End If
             Next N
             Modify_Date = TempData(2) + "/" + TempData(3) + "/" + TempData(1)
             Modify_Time = TempData(4) + ":" + TempData(5) + ":" + TempData(6) + apm
             Access_Date = TempData(8) + "/" + TempData(9) + "/" + TempData(7)
             Access_Time = TempData(10) + ":" + TempData(11) + ":" + TempData(12) + apa
             Temp = Modify_Date + " " + Modify_Time + " -- " + Access_Date + " " + Access_Time
             BGNdata = Temp
    End Function
    Function EBRN()
             'Eight Byte Real Number
             Dim Mantissa As Double
             Dim TempN As Double
             Dim B(7)
             B(7) = Asc(Input(1, #1))
             B(6) = Asc(Input(1, #1))
             B(5) = Asc(Input(1, #1))
             B(4) = Asc(Input(1, #1))
             B(3) = Asc(Input(1, #1))
             B(2) = Asc(Input(1, #1))
             B(1) = Asc(Input(1, #1))
             B(0) = Asc(Input(1, #1))
             Sign = 1 - (Int((B(7) And &H80) / &H80) * 2)
             Exponent = (B(7) And &H7F) - 64
             Weight = 1
             For N = 6 To 0 Step -1
                 For Bit_ = 7 To 0 Step -1
                     BitPosition = 2 ^ Bit_
                     Weight = Weight * 2
                     BitValue = Int((B(N) And BitPosition) / BitPosition) * (1 / Weight)
                     Mantissa = Mantissa + BitValue
                 Next Bit_
             Next N
             TempN = (Sign * Mantissa) * (16 ^ Exponent)
             EBRN = TempN
    End Function
    Function ELFLAGS()
             D1 = Asc(Input(1, #1))
             D0 = Asc(Input(1, #1))
             DataSize = DataSize - 2
             TemplateData = Int((D1 And 128) / 128)
             ExternalData = Int((D1 And 64) / 64)
             If TemplateData = 0 Then
                TD = "Template data is off"
             Else
                TD = "Template data is on"
             End If
             If ExternalData = 0 Then
                ED = "ExternalData data is off"
             Else
                ED = "ExternalData data is on"
             End If
             Temp = TD + " " + ED
             ELFLAGS = Temp
    End Function
    Function FBRN()
             'Four Byte Real Number
             Dim Mantissa As Double
             Dim TempN As Double
             Dim B(3) As Byte
             B(3) = Asc(Input(1, #1))
             B(2) = Asc(Input(1, #1))
             B(1) = Asc(Input(1, #1))
             B(0) = Asc(Input(1, #1))
             Sign = 1 - (Int((B(3) And &H80) / &H80) * 2)
             Exponent = (B(3) And &H7F) - 64
             Weight = 1
             For N = 2 To 0 Step -1
                 For Bit_ = 7 To 0 Step -1
                     BitPosition = 2 ^ Bit_
                     Weight = Weight * 2
                     BitValue = Int((B(N) And BitPosition) / BitPosition) * (1 / Weight)
                     Mantissa = Mantissa + BitValue
                 Next Bit_
             Next N
             TempN = (Sign * Mantissa) * (16 ^ Exponent)
             FBRN = TempN
    End Function
    Function FBSI()
             'Four Byte Signed Integer
             D = Hex$(Asc(Input(1, #1)))
             C = Hex$(Asc(Input(1, #1)))
             B = Hex$(Asc(Input(1, #1)))
             A = Hex$(Asc(Input(1, #1)))
             FBSI = Val("&H" + D + C + B + A)
    End Function
    Function HexByte(D0)
             Temp = Hex$(D0)
             If Len(Temp) = 1 Then Temp = "0" + Temp
             HexByte = Temp
    End Function
    Function HexWord()
             D1 = Asc(Input(1, #1))
             D0 = Asc(Input(1, #1))
             HexWord = HexByte(D1) + HexByte(D0)
    End Function
    Function LIBSECUR(DataSize)
             JunkFiller = Input(DataSize, #1)
             LIBSECUR = "Access Control List"
    End Function
    Function PRESENTATION()
             D1 = Asc(Input(1, #1))
             D0 = Asc(Input(1, #1))
             Font_ = (D1 And 12) \ 4
             Vert = (D1 And 48) \ 16
             Horz = (D1 And 192) \ 64
             Select Case Vert
                    Case 0
                         VertJust = "Top"
                    Case 1
                         VertJust = "Middle"
                    Case 2
                         VertJust = "Bottom"
             End Select
             Select Case Horz
                    Case 0
                         HorzJust = "Left"
                    Case 1
                         HorzJust = "Center"
                    Case 2
                         HorzJust = "Right"
             End Select
             Temp = "Font = " + Str$(Font_) + " " + VertJust + " " + HorzJust
             PRESENTATION = Temp
    End Function
    Function STRANS()
             D1 = Asc(Input(1, #1))
             D0 = Asc(Input(1, #1))
             XaxisReflect = (D0 And 1)
             AbsoluteMagnification = Int((D1 And 32) / 32)
             AbsoluteAngle = Int((D1 And 64) / 64)
             If XaxisReflect = 0 Then
                 XR = "X-Axis is not reflected"
             Else
                 XR = "X-Axis is reflected"
             End If
             If AbsoluteMagnification = 0 Then
                 AM = "Absolute Magnification is off."
             Else
                 AM = "Absolute Magnification is on."
             End If
             If AbsoluteAngle = 0 Then
                 AA = "Absolute Angle is off."
             Else
                 AA = "Absolute Angle is on."
             End If
             Temp = XR + " " + AM + " " + AA
             STRANS = Temp
    End Function
    Function STRCLASS()
             D1 = Asc(Input(1, #1))
             D0 = Asc(Input(1, #1))
             STRCLASS = "Cadence internal use only"
    End Function
    Function TBSI()
             'Two Byte Signed Integer
             B = Hex$(Asc(Input(1, #1)))
             A = Hex$(Asc(Input(1, #1)))
             TBSI = Val("&H" + B + A)
    End Function
    Function XY(DataSize)
             Temp = ""
             While DataSize > 0
                   DataSize = DataSize - 8
                   tempX = Str$(FBSI)
                   tempY = Str$(FBSI)
                   Temp = Temp + "(" + tempX + "," + tempY + ")"
             Wend
             XY = Temp
    End Function
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.

    Post Edited (Beau Schwabe (Parallax)) : 8/22/2007 7:25:01 PM GMT
  • potatoheadpotatohead Posts: 10,254
    edited 2007-09-01 20:00
    Thanks for the search hint, and the code Beau.

    Learned a few things!

    1. The polyline construct in DXF is very important. The system I am on, does not have this. This means some pre-processing of the file is required. I ended up using the following:

    LinkCAD. They have a 5 day trial. If one needs to do some learning, I recommend putting this in a VM to allow for enough time to grok things.

    The core idea is that polygons can be derived from connected lines, whose endpoints are within some small distance. Works well, given the DXF file is clean and only contains those entities that form the edges of the intended structures. LinkCAD will examine the file, looking for shared line endpoints, then build polygons from that.

    This works nicely and gave me some before and after code. IMHO, this is a niche for somebody. That program is expensive for what it does. I'm kicking myself right now for not keeping some old CADKEY CADL code. It has a similar algorithm that could easily be modified to output the necessary polygons. To be fair, the LinkCAD program does a lot of different translations that are a lot more complex than what I'm doing. However, there is a lot of free / inexpensive software out there that will do DXF files nicely. Seems like a basic converter, that's stripped down, would open some doors for hobby people.

    That's the only real barrier for elementary DXF files, composed of only lines. One that contains polylines would probably map right into the code Beau posted. If I end up doing this kind of thing again, it's worth some time spent on that problem. (worth about 1K) actually!

    2. Verification of the final output is necessary to determine if the derived polygons are correct.

    A program called Visual Chip Inspector can be had for a trial. It works just fine for verification.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Propeller Wiki: Share the coolness!
Sign In or Register to comment.