| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- import time
- import re
- import pexpect
- class QuartusTCL:
- def __init__(self):
- self.tcl = pexpect.spawn('quartus_stp --shell')
- self.tcl.expect('tcl> ')
- out = self.tcl.before
- self.version = 'Version unknown'
- for line in out.split(b'\n'):
- line = line.replace(b'\x1b[0m', b'').replace(b'\x1b[0;32m', b'')
- line = line.decode().strip()
- if line.startswith('Info: Version'):
- self.version = line[6:]
- break
- def send_cmd(self, cmd, timeout=45):
- self.tcl.sendline(cmd)
- try:
- self.tcl.expect('tcl> ', timeout=timeout)
- lines = self.tcl.before.decode().split('\r\n')[1:-1]
- return list(filter(None, lines))
- except pexpect.exceptions.TIMEOUT:
- raise QUATUS_TCL_TIMEOUT()
- def get_hardware_names(self):
- out = self.send_cmd('get_hardware_names')
- return re.findall(r'{([^\{]*)}', out[0])
- def get_device_names(self, hardware):
- out = self.send_cmd(f'get_device_names -hardware_name {{{hardware}}}')
- return re.findall(r'{([^\{]*)}', out[0])
- def start_insystem_source_probe(self, device, hardware):
- out = self.send_cmd(f'start_insystem_source_probe -device_name {{{device}}} -hardware_name {{{hardware}}}')
- if len(out) > 0 and out[0].startswith('ERROR'):
- raise INSYS_SPI_ERROR(out[0][7:])
- def read_probe_data(self, index, value_in_hex=False):
- cmd = f'read_probe_data -instance_index {index}'
- if value_in_hex:
- cmd += ' -value_in_hex'
- out = self.send_cmd(cmd)
- if len(out) > 0 and out[0].startswith('ERROR'):
- raise INSYS_SPI_ERROR(out[0][7:])
- if len(out) == 0:
- return ''
- return out[0]
- def write_source_data(self, index, value, value_in_hex=False):
- cmd = f'write_source_data -instance_index {index} -value "{value}"'
- if value_in_hex:
- cmd += ' -value_in_hex'
- out = self.send_cmd(cmd)
- if len(out) > 0 and out[0].startswith('ERROR'):
- raise INSYS_SPI_ERROR(out[0][7:])
- def read_source_data(self, index, value_in_hex=False):
- cmd = f'read_source_data -instance_index {index}'
- if value_in_hex:
- cmd += ' -value_in_hex'
- out = self.send_cmd(cmd)
- if len(out) > 0 and out[0].startswith('ERROR'):
- raise INSYS_SPI_ERROR(out[0][7:])
- if len(out) == 0:
- return ''
- return out[0]
- def end_insystem_source_probe(self):
- out = self.send_cmd(f'end_insystem_source_probe')
- if len(out) > 0 and out[0].startswith('ERROR'):
- raise INSYS_SPI_ERROR(out[0][7:])
- def begin_memory_edit(self, device, hardware):
- out = self.send_cmd(f'begin_memory_edit -device_name {{{device}}} -hardware_name {{{hardware}}}')
- if len(out) > 0 and out[0].startswith('ERROR'):
- raise INSYS_MEM_ERROR(out[0][7:])
- def end_memory_edit(self):
- out = self.send_cmd(f'end_memory_edit')
- if len(out) > 0 and out[0].startswith('ERROR'):
- raise INSYS_MEM_ERROR(out[0][7:])
- def get_editable_mem_instances(self, device, hardware):
- """
- :param device:
- :param hardware:
- :return: list of tuple [<index> <depth> <width> <read/write mode> <instance type> <instance name>]
- """
- out = self.send_cmd(f'get_editable_mem_instances -device_name {{{device}}} -hardware_name {{{hardware}}}')
- res = []
- if len(out) == 0:
- return res
- if out[0].startswith('ERROR'):
- raise INSYS_MEM_ERROR(out[0][7:])
- for i in re.findall(r'{([^\{]*)}', out[0]):
- try:
- c = i.split(' ')
- res.append((int(c[0]), int(c[1]), int(c[2]), c[3], c[4], c[5]))
- except (IndexError, ValueError):
- continue
- return res
- def read_content_from_memory(self, index, start_address, word_count, content_in_hex=False):
- cmd = f'read_content_from_memory -instance_index {index} -start_address {start_address} ' \
- f'-word_count {word_count}'
- if content_in_hex:
- cmd += ' -content_in_hex'
- out = self.send_cmd(cmd)
- if len(out) == 0:
- return ''
- if out[0].startswith('ERROR'):
- raise INSYS_MEM_ERROR(out[0][7:])
- return out[0]
- def write_content_to_memory(self, index, start_address, word_count, content, content_in_hex=False):
- cmd = f'read_content_from_memory -content "{content}" -instance_index {index} ' \
- f'-start_address {start_address} -word_count {word_count}'
- if content_in_hex:
- cmd += ' -content_in_hex'
- out = self.send_cmd(cmd)
- if len(out) > 0 and out[0].startswith('ERROR'):
- raise INSYS_MEM_ERROR(out[0][7:])
- def get_insystem_source_probe_instance_info(self, device, hardware):
- """
- :param device:
- :param hardware:
- :return: list of tuple [<index> <source width> <probe width> <instance name>]
- """
- out = self.send_cmd(
- f'get_insystem_source_probe_instance_info -device_name {{{device}}} -hardware_name {{{hardware}}}')
- res = []
- if len(out) == 0:
- return res
- if out[0].startswith('ERROR'):
- raise INSYS_SPI_ERROR(out[0][7:])
- for i in re.findall(r'{([^\{]*)}', out[0]):
- try:
- c = i.split(' ')
- res.append((int(c[0]), int(c[1]), int(c[2]), c[3]))
- except (IndexError, ValueError):
- continue
- return res
- def disconnect(self):
- self.tcl.sendline('exit')
- time.sleep(0.1)
- if self.tcl.isalive():
- self.tcl.kill(1)
- class QUARTUS_TCL_EXCEPTION(Exception):
- pass
- class QUATUS_TCL_TIMEOUT(QUARTUS_TCL_EXCEPTION):
- pass
- class INSYS_SPI_ERROR(QUARTUS_TCL_EXCEPTION):
- def __init__(self, message):
- self.message = message
- class INSYS_MEM_ERROR(QUARTUS_TCL_EXCEPTION):
- def __init__(self, message):
- self.message = message
|