def read(self, path): try: uid = self.topology.getAssemblyUID(path) # try: # self.lock_request(uid) try: inst = self.topology.getAssembly(uid) try: value = inst.read() return value # try: # self.lock_release(uid) # return value # except SchedulerError as e: # raise SchedulerError( # "Scheduler.read: Error detected while releasing mutex lock.\n{:s}".format(str(e))) except SchedulerError as e: raise SchedulerError( "Scheduler.read: Error detected while reading from instance.\n{:s}" .format(str(e))) except SchedulerError as e: raise SchedulerError( "Scheduler.read: Error detected while obtaining instance.\n{:s}" .format(str(e))) # except SchedulerError as e: # raise SchedulerError("Scheduler.read: Error detected while obtaining mutex lock.\n{:s}".format(str(e))) except SchedulerError as e: raise SchedulerError( "Scheduler.read: Error detected while obtaining UID.\n{:s}". format(str(e)))
def apply(self): self.capture = False if not self.cached: self.__init_segments() self.cached = True seg = self.depth() while seg is not None: seg.apply() seg = seg.breadth() if self.pending: if self.data_mode is None: raise SchedulerError("Pending conflict with data_mode!") # Concatenate vectors together into a single vector to scan value = concat([v for v in self.segments]) wrvf = RVF() if self.capture and self.data_mode: wrvf.command = "SDR" elif self.capture and not self.data_mode: wrvf.command = "SIR" elif self.data_mode: wrvf.command = "SDRNC" elif not self.data_mode: wrvf.command = "SIRNC" else: raise SchedulerError("Invalid data_mode detected.") wrvf.uid = self.uid wrvf.payload = value self.client_interface.request(wrvf) self.request_count += 1 self.pending = False self.data_mode = None self.logger.debug( "JTAGNetwork.apply(uid={:d}, command={:s}, payload={:s})\n". format(wrvf.uid, wrvf.command, str(wrvf.payload)))
def write_read(self, path, value: intbv): try: uid = self.topology.getAssemblyUID(path) # try: # self.lock_request(uid) try: inst = self.topology.getAssembly(uid) try: inst.write_read(value) # try: # self.lock_release(uid) # except SchedulerError as e: # raise SchedulerError( # "Scheduler.write_read: Error detected while releasing mutex lock.\n{:s}".format(str(e))) except SchedulerError as e: raise SchedulerError( "Scheduler.write_read: Error detected while writing to instance.\n{:s}" .format(str(e))) except SchedulerError as e: raise SchedulerError( "Scheduler.write_read: Error detected while obtaining instance.\n{:s}" .format(str(e))) # except SchedulerError as e: # raise SchedulerError("Scheduler.write_read: Error detected while obtaining mutex lock.\n{:s}".format(str(e))) except SchedulerError as e: raise SchedulerError( "Scheduler.write_read: Error detected while obtaining UID.\n{:s}" .format(str(e)))
def lock_request(self, uid): from p2654model.assembly.LeafAssembly import LeafAssembly seg = self._lookup(uid, LeafAssembly) if seg is not None: leaf = seg try: self.logger.debug( "[{:d}] lock_request() calling self.cycle_mutex.acquire()\n" .format(threading.get_ident())) self.cycle_mutex.acquire() except RuntimeError as e: raise SchedulerError( "Scheduler.lock_request(): error while locking cycle_mutex on leaf {:d}.\n{:s}" .format(uid, str(e))) if self.tot_pending_leaves >= 0: in_cycle = 1 try: self.logger.debug( "[{:d}] lock_request() calling self.start_cycle_cv.notify()\n" .format(threading.get_ident())) self.start_cycle_cv.notify() except RuntimeError: raise SchedulerError( "Scheduler.lock_request(): error while signalling start_cycle_cv on leaf {:d}." .format(uid)) try: self.logger.debug( "[{:d}] lock_request() calling self.cycle_mutex.release()\n" .format(threading.get_ident())) self.cycle_mutex.release() except RuntimeError: raise SchedulerError( "error while unlocking cycle_mutex on leaf {:d}.".format( uid))
def _select(self, suid): if self.keyreg is None: raise SchedulerError("keyreg must be defined before use.") uid = suid try: selected_seg = self.description.get_addr_dr(self.keyreg.get_value()) except SchedulerError: self.logger.debug("=====================================================\n") self.keyreg.write(self.description.get_default_code()) return 1 if selected_seg is not None: if selected_seg.uid != uid: found = False # Find the first match in the table as the default value k = self.description.get_first_match(uid) if k is not None: self.logger.debug("++++++++++++++++++++++++++++++++++++++++++\n") self.keyreg.write(k) return 1 else: raise SchedulerError("Unable to locate selector for uid {:d}.".format(uid)) else: return 0 # Already selected_uid else: raise SchedulerError("Unable to locate a code for value in keyreg {:s}.".format(str(self.keyreg.read())))
def read(self): if self.direction == DataRegister.Direction.WRITE_ONLY: raise SchedulerError("Read attempted on a WRITE_ONLY register!") if self.__read_value is None: # apply() should have updated this value if was able to run. Otherwise, raise error. raise SchedulerError("Attempt to read a DataRegister before synchronized.") return self.__read_value
def apply(self): self.capture = False self.pending_count = 0 seg = self.depth() while seg is not None: seg.apply() seg = seg.breadth() if self.pending_count > 1: raise SchedulerError("Multiple competing paths detected.") if self.pending: self.local_access_mutex.acquire() uid = self.rvf.uid command = self.rvf.command payload = self.rvf.payload self.pending = False self.local_access_mutex.release() self.logger.debug("self.rvf.command = {:s}.\n".format(command)) if command == "SIR": self.logger.debug("Calling scan_ir().") tdo = self.jtag_controller.scan_ir(len(payload), str(payload)) # payload must be an intbv type resp = RVF() resp.command = "SIR" resp.uid = uid self.logger.debug("SIR tdo={:s}".format(tdo)) resp.payload = intbv(int(tdo, 16), _nrbits=len(payload)) self.host_interface.response(resp) elif command == "SIRNC": # fmt = "{:0" + "{:d}".format((len(self.rvf.payload) + 1) // 4) + "X}" # print("fmt = {:s}\n".format(fmt)) # tdi = fmt.format(int(self.rvf.payload)) # tdi = "{0:0{1}X}".format(int(payload), (len(payload) + 1) // 4) tdi = str(payload) self.logger.debug("tdi = {:s}\n".format(tdi)) self.jtag_controller.scan_ir(len(payload), tdi) # payload must be an intbv type resp = RVF() resp.command = "SIRNC" resp.uid = self.rvf.uid resp.payload = intbv(0) self.host_interface.response(resp) elif command == "SDR": tdo = self.jtag_controller.scan_dr(len(payload), str(payload)) # payload must be an intbv type resp = RVF() resp.command = "SDR" resp.uid = uid self.logger.debug("SDR tdo={:s}".format(tdo)) resp.payload = intbv(int(tdo, 16), _nrbits=len(payload)) self.host_interface.response(resp) elif command == "SDRNC": self.jtag_controller.scan_dr(len(payload), str(payload)) # payload must be an intbv type resp = RVF() resp.command = "SDRNC" resp.uid = uid resp.payload = intbv(0) self.host_interface.response(resp) else: raise SchedulerError("Invalid command detected. ({:s})".format(command))
def __init__(self, entity_name, reg_length, safe_value): self.logger = logging.getLogger( 'P2654Model.description.ScanRegisterDescription.ScanRegisterDescription' ) self.logger.info('Creating an instance of ScanRegisterDescription') if not isinstance(safe_value, intbv): raise SchedulerError("safe_value is not of type intbv.") if reg_length != len(safe_value): raise SchedulerError( "reg_length does not match the number of bits in the safe_value." ) self.__reg_length = reg_length # the length of the Test Data Register of the given leaf segment. self.__safe_value = safe_value # reference to the safe value or default value to use AssemblyDescription.__init__(self, entity_name)
def write_read(self, value): if not isinstance(value, intbv): raise SchedulerError("val is not of type intbv.") if len(value) != self.reg_length: raise SchedulerError("Size of value does not match register size.") self.local_access_mutex.acquire() self.__value = value self.__read_value = None self.pending = True self.capture = True self.local_access_mutex.release() self.logger.debug("ScanRegister.write_read({:s})\n".format(str(value))) from p2654model.scheduler.Scheduler import SchedulerFactory SchedulerFactory.get_scheduler().mark_pending()
def write(self, value): if self.direction == DataRegister.Direction.READ_ONLY: raise SchedulerError("Write attempted on a READ_ONLY register!") if not isinstance(value, intbv): raise SchedulerError("val is not of type intbv.") if len(value) != self.reg_length: raise SchedulerError("Size of value does not match register size.") self.logger.debug("DataRegister.write({:s})\n".format(str(value))) self.local_access_mutex.acquire() self.__value = value self.__read_value = None self.pending = True self.capture = False self.local_access_mutex.release() from p2654model.scheduler.Scheduler import SchedulerFactory SchedulerFactory.get_scheduler().mark_pending()
def resp_handler(self, rvf: RVF): self.logger.debug("TAP.resp_handler(uid={:d}, command={:s}, payload={:s})\n".format(rvf.uid, rvf.command, str(rvf.payload))) uid = rvf.uid resp = RVF() self.response_mutex.acquire() resp.payload = rvf.payload self.response_mutex.release() if rvf.command == "SIR": resp.uid = self.depth().uid resp.command = "CAPSCAN" self.host_interface.response(resp) elif rvf.command == "SIRNC": resp.uid = self.depth().uid resp.command = "SCAN" self.host_interface.response(resp) elif rvf.command == "SDR": resp.uid = self.depth().breadth().uid resp.command = "CAPSCAN" self.host_interface.response(resp) elif rvf.command == "SDRNC": resp.uid = self.depth().breadth().uid resp.command = "SCAN" self.host_interface.response(resp) else: raise SchedulerError("Invalid command received.") self.request_count -= 1 if self.request_count == 0: pass # Notify all requests have been satisfied SchedulerFactory.get_scheduler().clear_pending()
def resp_handler(self, rvf: RVF): self.logger.debug( "ScanMux.resp_handler(uid={:d}, command={:s}, payload={:s})\n". format(rvf.uid, rvf.command, str(rvf.payload))) uid = rvf.uid resp = RVF() self.response_mutex.acquire() resp.payload = rvf.payload resp.command = rvf.command self.response_mutex.release() found = False seg = self.depth() while seg is not None: if seg == self.selected_seg: resp.uid = seg.uid seg.client_interface.response(resp) found = True break seg = seg.breadth() if not found: raise SchedulerError("Unable to locate selected_uid assembly.") self.request_count -= 1 if self.request_count == 0: pass # Notify all requests have been satisfied SchedulerFactory.get_scheduler().clear_pending()
def _deselect(self, suid): if self.keyreg is None: raise SchedulerError("keyreg must be defined before use.") uid = suid self.logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n") self.keyreg.write(self.description.get_default_code() ) # Use first element as default disable pattern
def getAssemblyUID_r(self, abs_path, index, node): depth_seg = node while depth_seg is not None: old_index = index terminal, token, index = self._tokenize(abs_path, index) found = 0 s = depth_seg while s is not None: if not s.is_visible(): inv_depth_seg = s.depth() inv_uid = self.getAssemblyUID_r(abs_path, old_index, inv_depth_seg) if inv_uid is not None: return inv_uid elif token == s.name: found = 1 break s = s.breadth() if found == 0: raise SchedulerError( "Topology.getAssemblyUID_r(): Path does not exist (%s)." % abs_path) elif terminal == 0: depth_seg = depth_seg.depth() else: return s.uid return None
def __init__(self, entity_name): self.logger = logging.getLogger( 'P2654Model.description.AssemblyDescription.AssemblyDescription') self.logger.info('Creating an instance of AssemblyDescription') if entity_name is None: raise SchedulerError("entity_name has not bee defined.") self.__entity_name = entity_name
def apply(self): if self.pending: arvf = RVF() arvf.command = "ADDRESS" arvf.uid = self.uid arvf.payload = self.address self.client_interface.request(arvf) self.response_cv.wait() wrvf = RVF() if self.capture and not self.update: wrvf.command = "READ" elif self.capture and self.update: wrvf.command = "WRITE_READ" elif self.update and not self.capture: wrvf.command = "WRITE" else: raise SchedulerError("Invalid command state!") wrvf.uid = self.uid self.local_access_mutex.acquire() wrvf.payload = self.rvf.payload self.local_access_mutex.release() self.client_interface.request(wrvf) self.local_access_mutex.acquire() self.request_count += 1 self.pending = False self.local_access_mutex.release() self.logger.debug( "PortalRegister.apply(uid={:d}, command={:s}, payload={:s})\n". format(wrvf.uid, wrvf.command, str(wrvf.payload)))
def hcb_address(self, rvf: RVF): self.logger.debug("DataMux.hcb_address(uid={:d}, command={:s}, payload={:s})\n".format(rvf.uid, rvf.command, str(rvf.payload))) code = rvf.payload if len(code) != self.kreg.reg_len: raise SchedulerError("Address is invalid length!") self.keyreg.write(code) self.host_interface.response(rvf)
def hcb_handler(self, rvf: RVF): cb = self.host_callbacks[rvf.command] if cb is None: raise SchedulerError( "Unidentified callback command has been called {:s}.".format( rvf.command)) self.logger.debug("hcb_handler({:s})\t{:s}\n".format( rvf.command, str(cb))) cb(rvf)
def defineTAP(self, name, entity_name, tir, mux): from p2654model.assembly.TAP import TAP if name is None: raise SchedulerError("Topology.defineTAP(): name was None.") description = TAPDescription(entity_name, tir.reg_length) tap = TAP(name, description) tap.append_assembly(tir) tap.append_assembly(mux) tap.uid = self.__uid_counter self.__uid_counter += 1 return tap
def defineJTAGControllerAssembly(self, name, entity_name, jtag_controller, tap): from p2654model.assembly.JTAGControllerAssembly import JTAGControllerAssembly if name is None: raise SchedulerError( "Topology.defineJTAGControllerAssembly(): name was None.") description = JTAGControllerDescription(entity_name) jc = JTAGControllerAssembly(name, description, jtag_controller) jc.append_assembly(tap) jc.uid = self.__uid_counter self.__uid_counter += 1 return jc
def lock_release(self, uid): from p2654model.experiment7.Assembly import LeafAssembly # seg = self._lookup(uid, LeafAssembly) # if seg is not None: # leaf = seg # try: # print("[{:d}] lock_release() calling self.cycle_mutex.release()\n".format(threading.get_ident())) # self.cycle_mutex.release() # except RuntimeError as e: # raise SchedulerError( # "Scheduler.lock_release(): error while releasing cycle_mutex on leaf {:d}.\n{:s}".format(uid, str(e))) try: self.logger.debug( "[{:d}] lock_release() calling self.release_mutex.acquire()\n". format(threading.get_ident())) self.release_mutex.acquire() self.release_v = 1 try: self.logger.debug( "[{:d}] lock_release() calling self.release_cv.notify()\n". format(threading.get_ident())) self.release_cv.notify() try: self.logger.debug( "[{:d}] lock_release() calling self.release_mutex.release()\n" .format(threading.get_ident())) self.release_mutex.release() return 0 except RuntimeError as e: raise SchedulerError( "error while unlocking release_mutex on leaf {:d}.\n{:s}" .format(uid, e)) except RuntimeError as e: raise SchedulerError( "error while signalling release_cv on leaf {:s}.\n{:s}". format(uid, e)) except RuntimeError as e: raise SchedulerError( "error while locking release_mutex on leaf {:d}.\n{:s}".format( uid, e))
def apply(self): if self.keyreg is None: raise SchedulerError("keyreg must be defined before use.") # self.capture = False self.pending_count = 0 seg = self.depth() while seg is not None: seg.apply() seg = seg.breadth() if self.pending_count > 1: raise SchedulerError("Multiple competing paths detected.") try: self.selected_seg = self.description.get_ir_dr( self.keyreg.get_value()) except SchedulerError: self.logger.debug( "*******************************************************\n") self.keyreg.write(self.description.get_default_code()) self.selected_seg = self.description.get_ir_dr( self.description.get_default_code()) if self.selected_seg is None: raise SchedulerError("No path has been selected.") if self.pending: self.logger.debug("selected_seg.name = {:s}.".format( self.selected_seg.name)) if self.capture: wrvf = RVF() wrvf.command = "CAPSCAN" else: wrvf = RVF() wrvf.command = "SCAN" wrvf.uid = self.uid wrvf.payload = self.value self.client_interface.request(wrvf) self.request_count += 1 self.pending = False self.capture = False self.logger.debug( "ScanMux.apply(uid={:d}, command={:s}, payload={:s})\n".format( wrvf.uid, wrvf.command, str(wrvf.payload)))
def defineScanRegister(self, name, direction, entity_name, reg_length, safe_value): from p2654model.assembly.ScanRegister import ScanRegister if name is None: raise SchedulerError( "Topology.defineScanRegister(): name was None.") reg = ScanRegister( name, direction, ScanRegisterDescription(entity_name, reg_length, safe_value)) reg.uid = self.__uid_counter self.__uid_counter += 1 self.__totleaves += 1 return reg
def append_assembly(self, child): from p2654model.assembly.LeafAssembly import LeafAssembly if isinstance(self, LeafAssembly): raise SchedulerError("LeafAssembly is unable to append children.") if child is None: raise SchedulerError("child has not been defined.") if self.depth() is None: # the parent has no children self.set_depth_next(child) else: s = self.depth() last = None while s is not None: last = s if child.name == s.name: raise SchedulerError("Duplicate child name {:s}.".format( child.name)) s = last._breadth_next # last points to the last of the parent subsegments if last is not None: last._breadth_next = child return self
def __send_response(self, uid, command, payload): resp = RVF() resp.payload = payload resp.command = command resp.uid = uid found = False seg = self.depth() while seg is not None: if uid == seg.uid: seg.client_interface.reponse(resp) found = True break seg = seg.breadth() if not found: raise SchedulerError("Unable to locate uid assembly.")
def hcb_isactive(self, rvf: RVF): if self.keyreg is None: raise SchedulerError("keyreg must be defined before use.") uid = rvf.uid code = self.keyreg.read() seldr = self.description.get_addr_dr(code) scheduler = SchedulerFactory.get_scheduler() assembly = scheduler.topology.getAssembly(uid) if seldr is not None: if assembly.entity_name == seldr.entity_name: self.__send_response(uid, "ISACTIVE", "FALSE") else: self.__send_response(uid, "ISACTIVE", "TRUE") else: self.__send_response(uid, "ISACTIVE", "FALSE")
def resp_handler(self, rvf: RVF): self.logger.debug("DataRegister.resp_handler(uid={:d}, command={:s}, payload={:s})\n".format(rvf.uid, rvf.command, str(rvf.payload))) if rvf.command == "WRITE": self.__read_value = None elif rvf.command == "READ" or rvf.command == "WRITE_READ": self.response_mutex.acquire() self.__read_value = rvf.payload self.response_mutex.release() else: raise SchedulerError("Invalid command received.") self.request_count -= 1 if self.request_count == 0: pass # Notify all requests have been satisfied from p2654model.scheduler.Scheduler import SchedulerFactory SchedulerFactory.get_scheduler().clear_pending()
def defineScanMux(self, name, entity_name, keyreg, rmap): from p2654model.assembly.ScanMux import ScanMux if name is None: raise SchedulerError( "Topology.defineScanRegister(): name was None.") description = ScanMuxDescription(entity_name, keyreg.reg_length) for m in rmap: description.add_dr_register(m[1], m[0], m[2]) mux = ScanMux(name, description) mux.set_keyreg(keyreg) for m in mux.description.get_drs(): mux.append_assembly(m) mux.uid = self.__uid_counter self.__uid_counter += 1 self.__totleaves += 1 return mux
def getAssemblyPath(self, uid): period = 0 tokenized_path = [] abs_path = "" if self._findpath_lifo(self.top, uid, tokenized_path) == 0: raise SchedulerError( "Topology.getAssemblyPath(): uid does not exist (%d)" % uid) try: while True: token = self._lifo_pop(tokenized_path) if period == 0: period = 1 else: abs_path = abs_path + "." abs_path = abs_path + token except Exception: pass return abs_path
def __list_callbacks(self, rvf: RVF): if self.host_interface is None: raise SchedulerError("host_interface must be defined.") cbs = self.host_callbacks.keys() msg = "" first = True for c in cbs: if first: msg = c first = False else: msg = msg + ", " + c rvf.payload = msg seg = self.depth() while seg is not None: if seg.uid == rvf.uid: seg.client_interface.response(rvf) break seg = seg.breadth()