| #!/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) |