DXF to GSDII
potatohead
Posts: 10,261
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!
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
www.numericalinnovations.com/index.asp?PageAction=VIEWPROD&ProdID=9
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
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!