Tim Edwards | 865f36f | 2021-06-05 10:28:45 -0400 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
| 2 | # |
| 3 | # Script to read a GDS file, and find the given cellname if it has the |
| 4 | # standard random two-character prefix generated by magic when writing |
| 5 | # out a vendor GDS, and report the prefix. No changes are made to any |
| 6 | # file. |
| 7 | |
| 8 | import os |
| 9 | import sys |
| 10 | |
| 11 | def usage(): |
| 12 | print('find_gds_prefix.py <cell_name> <path_to_cell_gds>') |
| 13 | |
| 14 | if __name__ == '__main__': |
| 15 | debug = False |
| 16 | |
| 17 | if len(sys.argv) == 1: |
| 18 | print("No options given to find_gds_prefix.py.") |
| 19 | usage() |
| 20 | sys.exit(0) |
| 21 | |
| 22 | optionlist = [] |
| 23 | arguments = [] |
| 24 | |
| 25 | for option in sys.argv[1:]: |
| 26 | if option.find('-', 0) == 0: |
| 27 | optionlist.append(option) |
| 28 | else: |
| 29 | arguments.append(option) |
| 30 | |
| 31 | if len(arguments) != 2: |
| 32 | print("Wrong number of arguments given to find_gds_prefix.py.") |
| 33 | usage() |
| 34 | sys.exit(0) |
| 35 | |
| 36 | for option in optionlist: |
| 37 | if option == '-debug': |
| 38 | debug = True |
| 39 | |
| 40 | cellname = arguments[0] |
| 41 | cellsource = arguments[1] |
| 42 | |
| 43 | cellsrcdir = os.path.split(cellsource)[0] |
| 44 | cellinfile = os.path.split(cellsource)[1] |
| 45 | |
| 46 | print('Reading GDS file looking for prefixed cell ' + cellname) |
| 47 | with open(cellsource, 'rb') as ifile: |
| 48 | celldata = ifile.read() |
| 49 | |
| 50 | #---------------------------------------------------------------------- |
| 51 | # Assume that celldata contains the cell in question. |
| 52 | # Find the extend of the data from 'beginstr' to 'endstr' |
| 53 | #---------------------------------------------------------------------- |
| 54 | |
| 55 | datalen = len(celldata) |
| 56 | dataptr = 0 |
| 57 | found = False |
| 58 | while dataptr < datalen: |
| 59 | # Read stream records up to 'beginstr' |
| 60 | bheader = celldata[dataptr:dataptr + 2] |
| 61 | reclen = int.from_bytes(bheader, 'big') |
| 62 | if reclen == 0: |
| 63 | print('Error: found zero-length record at position ' + str(dataptr)) |
| 64 | break |
| 65 | |
| 66 | rectype = celldata[dataptr + 2] |
| 67 | datatype = celldata[dataptr + 3] |
| 68 | |
| 69 | brectype = rectype.to_bytes(1, byteorder='big') |
| 70 | bdatatype = datatype.to_bytes(1, byteorder='big') |
| 71 | |
| 72 | if rectype == 5: # beginstr |
| 73 | saveptr = dataptr |
| 74 | |
| 75 | elif rectype == 6: # strname |
| 76 | if datatype != 6: |
| 77 | print('Error: Structure name record is not a string!') |
| 78 | sys.exit(1) |
| 79 | |
| 80 | bstring = celldata[dataptr + 4: dataptr + reclen] |
| 81 | # Odd length strings end in null byte which needs to be removed |
| 82 | if bstring[-1] == 0: |
| 83 | bstring = bstring[:-1] |
| 84 | strname = bstring.decode('ascii') |
| 85 | if strname[3:] == cellname: |
| 86 | print('Cell ' + strname + ' found at position ' + str(saveptr)) |
Tim Edwards | cc82b60 | 2021-06-06 16:35:34 -0400 | [diff] [blame] | 87 | print('Prefix: ' + strname[0:3]) |
Tim Edwards | 865f36f | 2021-06-05 10:28:45 -0400 | [diff] [blame] | 88 | found = True |
| 89 | break |
| 90 | elif strname == cellname: |
| 91 | print('Unprefixed cell ' + strname + ' found at position ' + str(saveptr)) |
| 92 | elif debug: |
| 93 | print('Cell ' + strname + ' position ' + str(dataptr) + ' (ignored)') |
| 94 | |
| 95 | # Advance the pointer past the data |
| 96 | dataptr += reclen |
| 97 | |
| 98 | if not found: |
| 99 | print('Failed to find a prefixed cell ' + cellname) |
| 100 | sys.exit(1) |
| 101 | |
| 102 | exit(0) |