Use this method to find bsdl descriptions for devices.
    The caching on this method drastically lower the execution
    time when there are a lot of bsdl files and more than one
    device. May move it into a metaclass to make it more
    transparent.

def get_descriptor_for_idcode(idcode):
    """Use this method to find bsdl descriptions for devices.
    The caching on this method drastically lower the execution
    time when there are a lot of bsdl files and more than one
    device. May move it into a metaclass to make it more
    transparent."""
    idcode = idcode&0x0fffffff
    id_str = "XXXX"+bin(idcode)[2:].zfill(28)

    descr_file_path = _check_cache_for_idcode(id_str)
    if descr_file_path:
        with open(descr_file_path, 'r') as f:
            dat = json.load(f)
        if dat.get("_file_version",-1) == JTAGDeviceDescription.version:
            return JTAGDeviceDescription(dat.get('idcode'),
                                         dat.get('name'),
                                         dat.get('ir_length'),
                                         dat.get('instruction_opcodes'),
                                         dat.get('registers'),
                                         dat.get('instruction_register_map'))

    print("    Device detected ("+id_str+"). Fetching missing descriptor...")
    sid = get_sid(id_str)
    details = get_details(sid)
    attribs = decode_bsdl(sid)

    #VERIFYING PARSED DATA FROM 2 SOURCES. MESSY BUT USEFUL.
    instruction_length = 0
    if attribs.get('INSTRUCTION_LENGTH') ==\
       details.get('INSTRUCTION_LENGTH'):
        instruction_length = attribs.get('INSTRUCTION_LENGTH')
    elif attribs.get('INSTRUCTION_LENGTH') and\
       details.get('INSTRUCTION_LENGTH'):
        raise Exception("INSTRUCTION_LENGTH can not be determined")
    elif attribs.get('INSTRUCTION_LENGTH'):
        instruction_length = attribs.get('INSTRUCTION_LENGTH')
    else:
        instruction_length = details.get('INSTRUCTION_LENGTH')

    for instruction_name in details.get('instructions'):
        if instruction_name not in\
           attribs.get('INSTRUCTION_OPCODE',[]):
            raise Exception("INSTRUCTION_OPCODE sources do not match")

    #print(attribs['IDCODE_REGISTER'])
    descr = JTAGDeviceDescription(attribs['IDCODE_REGISTER'].upper(),
                                  details['name'], instruction_length,
                                  attribs['INSTRUCTION_OPCODE'],
                                  attribs['REGISTERS'],
                                  attribs['INSTRUCTION_TO_REGISTER'])

    #CACHE DESCR AS FILE!
    if not os.path.isdir(base_descr_dir):
        os.makedirs(base_descr_dir)
    descr_file_path = os.path.join(base_descr_dir,
                                   attribs['IDCODE_REGISTER']\
                                   .upper()+'.json')
    with open(descr_file_path, 'w') as f:
        json.dump(descr._dump(), f)

    return descr