| #!/usr/bin/env python3 |
| # |
| # Script to read a GDS file, and find the given cellname if it has the |
| # standard random two-character prefix generated by magic when writing |
| # out a vendor GDS, and report the prefix. No changes are made to any |
| # file. |
| |
| import os |
| import sys |
| |
| def usage(): |
| print('find_gds_prefix.py <cell_name> <path_to_cell_gds>') |
| |
| if __name__ == '__main__': |
| debug = False |
| |
| if len(sys.argv) == 1: |
| print("No options given to find_gds_prefix.py.") |
| usage() |
| sys.exit(0) |
| |
| optionlist = [] |
| arguments = [] |
| |
| for option in sys.argv[1:]: |
| if option.find('-', 0) == 0: |
| optionlist.append(option) |
| else: |
| arguments.append(option) |
| |
| if len(arguments) != 2: |
| print("Wrong number of arguments given to find_gds_prefix.py.") |
| usage() |
| sys.exit(0) |
| |
| for option in optionlist: |
| if option == '-debug': |
| debug = True |
| |
| cellname = arguments[0] |
| cellsource = arguments[1] |
| |
| cellsrcdir = os.path.split(cellsource)[0] |
| cellinfile = os.path.split(cellsource)[1] |
| |
| print('Reading GDS file looking for prefixed cell ' + cellname) |
| with open(cellsource, 'rb') as ifile: |
| celldata = ifile.read() |
| |
| #---------------------------------------------------------------------- |
| # Assume that celldata contains the cell in question. |
| # Find the extend of the data from 'beginstr' to 'endstr' |
| #---------------------------------------------------------------------- |
| |
| datalen = len(celldata) |
| dataptr = 0 |
| found = False |
| while dataptr < datalen: |
| # Read stream records up to 'beginstr' |
| bheader = celldata[dataptr:dataptr + 2] |
| reclen = int.from_bytes(bheader, 'big') |
| if reclen == 0: |
| print('Error: found zero-length record at position ' + str(dataptr)) |
| break |
| |
| rectype = celldata[dataptr + 2] |
| datatype = celldata[dataptr + 3] |
| |
| brectype = rectype.to_bytes(1, byteorder='big') |
| bdatatype = datatype.to_bytes(1, byteorder='big') |
| |
| if rectype == 5: # beginstr |
| saveptr = dataptr |
| |
| elif rectype == 6: # strname |
| if datatype != 6: |
| print('Error: Structure name record is not a string!') |
| sys.exit(1) |
| |
| bstring = celldata[dataptr + 4: dataptr + reclen] |
| # Odd length strings end in null byte which needs to be removed |
| if bstring[-1] == 0: |
| bstring = bstring[:-1] |
| strname = bstring.decode('ascii') |
| if strname[3:] == cellname: |
| print('Cell ' + strname + ' found at position ' + str(saveptr)) |
| print('Prefix: ' + strname[0:3]) |
| found = True |
| break |
| elif strname == cellname: |
| print('Unprefixed cell ' + strname + ' found at position ' + str(saveptr)) |
| elif debug: |
| print('Cell ' + strname + ' position ' + str(dataptr) + ' (ignored)') |
| |
| # Advance the pointer past the data |
| dataptr += reclen |
| |
| if not found: |
| print('Failed to find a prefixed cell ' + cellname) |
| sys.exit(1) |
| |
| exit(0) |