Example #1
0
 def prime(self, callback):
     """FIXME: document"""
     if self.cbhdl == 0:
         self.cbhdl = simulator.register_readonly_callback(callback, self)
         if self.cbhdl == 0:
             raise_error(self, "Unable set up %s Trigger" % (str(self)))
     Trigger.prime(self)
Example #2
0
 def prime(self, callback):
     if self.cbhdl is None:
         self.cbhdl = simulator.register_value_change_callback(
             self.signal._handle, callback, self._rising, self)
         if self.cbhdl is None:
             raise_error(self, "Unable set up %s Trigger" % (str(self)))
     Trigger.prime(self)
Example #3
0
    def _add_trigger(self, trigger, coroutine):
        """Adds a new trigger which will cause the coroutine to continue when fired"""
        try:
            # If we are in readonly for the currently firing trigger then new coroutines
            # are not added to the waiting list and primed, they are instead
            # added to a secondary list of events that will then be handled on the next
            # entry to react when we exit ReadOnly into NextTimeStep
            if self._readonly is True:
                self._entry_lock.acquire()
                self.delay_waiting[trigger].append(coroutine)
                self._entry_lock.release()
            else:
                self._entry_lock.acquire()
                self.waiting[trigger].append(coroutine)
                self._entry_lock.release()
                # We drop the lock before calling out to the simulator (most likely consequence of prime)
                trigger.prime(self.react)

        except TestError as e:
            self.waiting[trigger].remove(coroutine)
            # Do not re-call raise_error since the error will already be logged at point of interest
            raise e

        except Exception as e:
            self.waiting[trigger].remove(coroutine)
            raise_error(self, "Unable to prime a trigger: %s" % str(e))
Example #4
0
 def prime(self, callback):
     """Register notification of a value change via a callback"""
     if self.cbhdl is None:
         self.cbhdl = simulator.register_value_change_callback(self.signal._handle, callback, 3, self)
         if self.cbhdl is None:
             raise_error(self, "Unable set up %s Trigger" % (str(self)))
     Trigger.prime(self)
Example #5
0
 def prime(self, callback):
     """Register for a timed callback"""
     if self.cbhdl is None:
         self.cbhdl = simulator.register_timed_callback(self.time_ps, callback, self)
         if self.cbhdl is None:
             raise_error(self, "Unable set up %s Trigger" % (str(self)))
     Trigger.prime(self)
Example #6
0
    def prime(self, callback):
        self._callback = callback

        def _check(obj):
            if self.signal.value:
                self.num_cycles -= 1

                if self.num_cycles <= 0:
                    self._callback(self)
                    return

            self.cbhdl = simulator.register_value_change_callback(self.signal.
                                                                  _handle,
                                                                  _check,
                                                                  self)
            if self.cbhdl is None:
                raise_error(self, "Unable set up %s Trigger" % (str(self)))

        self.cbhdl = simulator.register_value_change_callback(self.signal.
                                                              _handle,
                                                              _check,
                                                              self)
        if self.cbhdl is None:
            raise_error(self, "Unable set up %s Trigger" % (str(self)))
        Trigger.prime(self)
Example #7
0
    def send(self, value):
        if not self.started:
            self.error_messages = []
            self.log.info("Starting test: \"%s\"\nDescription: %s" %
                          (self.funcname, self.__doc__))
            self.start_time = time.time()
            self.started = True
        try:
            self.log.debug("Sending trigger %s" % (str(value)))
            return self._coro.send(value)
        except TestComplete as e:
            if isinstance(e, TestFailure):
                self.log.warning(str(e))
            else:
                self.log.info(str(e))

            buff = StringIO()
            for message in self.error_messages:
                print(message, file=buff)
            e.stderr.write(buff.getvalue())
            raise
        except StopIteration:
            raise TestSuccess()
        except Exception as e:
            raise_error(self, "Send raised exception: %s" % (str(e)))
Example #8
0
 def prime(self, callback):
     """FIXME: document"""
     if self.cbhdl == 0:
         self.cbhdl = simulator.register_readonly_callback(callback, self)
         if self.cbhdl == 0:
             raise_error(self, "Unable set up %s Trigger" % (str(self)))
     Trigger.prime(self)
Example #9
0
    def send(self, value):
        if not self.started:
            self.error_messages = []
            self.log.info("Starting test: \"%s\"\nDescription: %s" %
                          (self.funcname, self.__doc__))
            self.start_time = time.time()
            self.started = True
        try:
            self.log.debug("Sending trigger %s" % (str(value)))
            return self._coro.send(value)
        except TestComplete as e:
            if isinstance(e, TestFailure):
                self.log.warning(str(e))
            else:
                self.log.info(str(e))

            buff = StringIO()
            for message in self.error_messages:
                print(message, file=buff)
            e.stderr.write(buff.getvalue())
            raise
        except StopIteration:
            raise TestSuccess()
        except Exception as e:
            raise_error(self, "Send raised exception: %s" % (str(e)))
Example #10
0
    def prime(self, callback):
        """FIXME: document"""
        self._callback = callback

        def _check(obj):
            self.unprime()

            if self.signal.value:
                self.num_cycles -= 1

                if self.num_cycles <= 0:
                    self._callback(self)
                    return

            self.cbhdl = simulator.register_value_change_callback(self.signal.
                                                                  _handle,
                                                                  _check,
                                                                  self._rising,
                                                                  self)
            if self.cbhdl == 0:
                raise_error(self, "Unable set up %s Trigger" % (str(self)))

        self.cbhdl = simulator.register_value_change_callback(self.signal.
                                                              _handle,
                                                              _check,
                                                              self._rising,
                                                              self)
        if self.cbhdl == 0:
            raise_error(self, "Unable set up %s Trigger" % (str(self)))
        Trigger.prime(self)
Example #11
0
 def prime(self, callback):
     if self.cbhdl == 0:
         # import pdb
         # pdb.set_trace()
         self.cbhdl = simulator.register_rwsynch_callback(callback, self)
         if self.cbhdl == 0:
             raise_error(self, "Unable set up %s Trigger" % (str(self)))
     Trigger.prime(self)
Example #12
0
 def prime(self, callback):
     """Register notification of a value change via a callback"""
     if self.cbhdl is None:
         self.cbhdl = simulator.register_value_change_callback(
             self.signal._handle, callback, 3, self)
         if self.cbhdl is None:
             raise_error(self, "Unable set up %s Trigger" % (str(self)))
     Trigger.prime(self)
Example #13
0
 def prime(self, callback):
     """Register for a timed callback"""
     if self.cbhdl == 0:
         self.cbhdl = simulator.register_timed_callback(
             self.sim_steps, callback, self)
         if self.cbhdl == 0:
             raise_error(self, "Unable set up %s Trigger" % (str(self)))
     Trigger.prime(self)
Example #14
0
 def _check(obj):
     if self.signal.value:
         self._callback(self)
     else:
         simulator.deregister_callback(self.cbhdl)
         self.cbhdl = simulator.create_callback(self)
         if simulator.register_value_change_callback(self.cbhdl, self.signal._handle, _check, self):
             raise_error(self, "Unable set up %s Trigger" % (str(self)))
Example #15
0
 def prime(self, callback):
     if self.cbhdl is None:
         #import pdb
         #pdb.set_trace()
         self.cbhdl = simulator.register_rwsynch_callback(callback, self)
         if self.cbhdl is None:
             raise_error(self, "Unable set up %s Trigger" % (str(self)))
     Trigger.prime(self)
Example #16
0
 def prime(self, callback):
     """FIXME: document"""
     if self.cbhdl == 0:
         # import pdb
         # pdb.set_trace()
         self.cbhdl = simulator.register_rwsynch_callback(callback, self)
         if self.cbhdl == 0:
             raise_error(self, "Unable set up %s Trigger" % (str(self)))
     Trigger.prime(self)
Example #17
0
 def prime(self, callback):
     """Register notification of a value change via a callback"""
     if self.cbhdl == 0:
         self.cbhdl = simulator.register_value_change_callback(
             self.signal._handle, callback,
             type(self)._edge_type, self)
         if self.cbhdl == 0:
             raise_error(self, "Unable set up %s Trigger" % (str(self)))
     super(_EdgeBase, self).prime()
Example #18
0
 def prime(self, callback):
     """Register notification of a value change via a callback"""
     if self.cbhdl == 0:
         self.cbhdl = simulator.register_value_change_callback(
             self.signal._handle, callback, type(self)._edge_type, self
         )
         if self.cbhdl == 0:
             raise_error(self, "Unable set up %s Trigger" % (str(self)))
     super(_EdgeBase, self).prime()
Example #19
0
 def prime(self, callback):
     if self.cbhdl is None:
         self.cbhdl = simulator.register_value_change_callback(self.signal.
                                                               _handle,
                                                               callback,
                                                               self._rising,
                                                               self)
         if self.cbhdl is None:
             raise_error(self, "Unable set up %s Trigger" % (str(self)))
     Trigger.prime(self)
Example #20
0
        def _check(obj):
            if self.signal.value:
                self.num_cycles -= 1

                if self.num_cycles <= 0:
                    self._callback(self)
                    return

            if simulator.register_value_change_callback(self.cbhdl, self.signal._handle, _check, self):
                raise_error(self, "Unable set up %s Trigger" % (str(self)))
Example #21
0
    def prime(self, callback):
        Trigger.prime(self)
        self._callback = callback

        def _check(obj):
            if self.signal.value:
                self._callback(self)
            else:
                simulator.reenable_callback(self.cbhdl)

        if simulator.register_value_change_callback(self.cbhdl, self.signal._handle, _check, self):
            raise_error(self, "Unable set up %s Trigger" % (str(self)))
Example #22
0
        def _check(obj):
            self.unprime()

            if self.signal.value:
                self.num_cycles -= 1

                if self.num_cycles <= 0:
                    self._callback(self)
                    return

            self.cbhdl = simulator.register_value_change_callback(
                self.signal._handle, _check, self._rising, self)
            if self.cbhdl == 0:
                raise_error(self, "Unable set up %s Trigger" % (str(self)))
Example #23
0
    def release(self):
        if not self.locked:
            raise_error(
                self, "Attempt to release an unacquired Lock %s" % (str(self)))

        self.locked = False

        # nobody waiting for this lock
        if not self._pending_primed:
            return

        trigger = self._pending_primed.pop(0)
        self.locked = True
        trigger()
Example #24
0
    def prime(self, callback):
        Trigger.prime(self)
        self._callback = callback

        def _check(obj):
            condition = self.signal.value == self._rising
            if condition:
                self._callback(self)
            else:
                #Riviera doesn't seem to like re-using a callback handle?
                simulator.reenable_callback(self.cbhdl)

        if simulator.register_value_change_callback(self.cbhdl, self.signal._handle, _check, self):
            raise_error(self, "Unable set up %s Trigger" % (str(self)))
Example #25
0
    def release(self):

        if not self.locked:
            raise_error(self, "Attempt to release an unacquired Lock %s" % (str(self)))

        self.locked = False

        # nobody waiting for this lock
        if not self._pending_primed:
            return

        trigger = self._pending_primed.pop(0)
        self.locked = True
        trigger()
Example #26
0
 def send(self, value):
     try:
         if isinstance(value, ExternalException):
             self.log.debug("Injecting ExternalException(%s)" % (repr(value)))
             return self._coro.throw(value.exception)
         self._started = True
         return self._coro.send(value)
     except TestComplete as e:
         if isinstance(e, TestFailure):
             self.log.warning(str(e))
         raise
     except ExternalException as e:
         self.retval = e
         self._finished = True
         raise CoroutineComplete(callback=self._finished_cb)
     except ReturnValue as e:
         self.retval = e.retval
         self._finished = True
         raise CoroutineComplete(callback=self._finished_cb)
     except StopIteration as e:
         self._finished = True
         self.retval = getattr(e, 'value', None)  # for python >=3.3
         raise CoroutineComplete(callback=self._finished_cb)
     except Exception as e:
         self._finished = True
         raise raise_error(self, "Send raised exception: %s" % (str(e)))
Example #27
0
 def send(self, value):
     try:
         return self._coro.send(value)
     except TestComplete as e:
         if isinstance(e, TestFailure):
             self.log.warning(str(e))
         else:
             self.log.info(str(e))
         raise
     except ReturnValue as e:
         self.retval = e.retval
         raise CoroutineComplete(callback=self._finished_cb)
     except StopIteration:
         raise CoroutineComplete(callback=self._finished_cb)
     except Exception as e:
         raise_error(self, "Send raised exception: %s" % (str(e)))
Example #28
0
 def send(self, value):
     try:
         if isinstance(value, ExternalException):
             self.log.debug("Injecting ExternalException(%s)" %
                            (repr(value)))
             return self._coro.throw(value.exception)
         self._started = True
         return self._coro.send(value)
     except TestComplete as e:
         if isinstance(e, TestFailure):
             self.log.warning(str(e))
         raise
     except ExternalException as e:
         self.retval = e
         self._finished = True
         raise CoroutineComplete(callback=self._finished_cb)
     except ReturnValue as e:
         self.retval = e.retval
         self._finished = True
         raise CoroutineComplete(callback=self._finished_cb)
     except StopIteration:
         self._finished = True
         raise CoroutineComplete(callback=self._finished_cb)
     except Exception as e:
         self._finished = True
         raise raise_error(self, "Send raised exception: %s" % (str(e)))
Example #29
0
 def send(self, value):
     try:
         return self._coro.send(value)
     except TestComplete as e:
         if isinstance(e, TestFailure):
             self.log.warning(str(e))
         raise
     except ReturnValue as e:
         self.retval = e.retval
         self._finished = True
         raise CoroutineComplete(callback=self._finished_cb)
     except StopIteration:
         self._finished = True
         raise CoroutineComplete(callback=self._finished_cb)
     except Exception as e:
         self._finished = True
         raise_error(self, "Send raised exception: %s" % (str(e)))
Example #30
0
def test_raise_error_deprecated(dut):
    yield Timer(1)
    with assert_deprecated():
        with assert_raises(TestError):
            raise_error(Timer(1), "A test exception")
Example #31
0
    def schedule(self, coroutine, trigger=None):
        """
        Schedule a coroutine by calling the send method

        Args:
            coroutine (cocotb.decorators.coroutine): The coroutine to schedule

            trigger (cocotb.triggers.Trigger): The trigger that caused this
                                                coroutine to be scheduled
        """
        if hasattr(trigger, "pass_retval"):
            sendval = trigger.retval
            if _debug:
                coroutine.log.debug("Scheduling with ReturnValue(%s)" %
                                    (repr(sendval)))
        else:
            sendval = trigger
            if _debug:
                coroutine.log.debug("Scheduling with %s" % str(trigger))

        try:
            result = coroutine.send(sendval)
            if _debug:
                self.log.debug("Coroutine %s yielded %s (mode %d)" %
                               (coroutine.__name__, str(result), self._mode))

        # TestComplete indication is game over, tidy up
        except TestComplete as test_result:
            # Tag that close down is needed, save the test_result
            # for later use in cleanup handler
            self.finish_test(test_result)
            return

        # Normal co-routine completion
        except cocotb.decorators.CoroutineComplete as exc:
            if _debug:
                self.log.debug("Coroutine completed: %s" % str(coroutine))
            self.unschedule(coroutine)
            return

        # Don't handle the result if we're shutting down
        if self._terminate:
            return

        # Queue current routine to schedule when the nested routine exits
        if isinstance(result, cocotb.decorators.RunningCoroutine):
            if _debug:
                self.log.debug("Scheduling nested co-routine: %s" %
                               result.__name__)

            self.queue(result)
            new_trigger = result.join()
            self._coroutine_yielded(coroutine, [new_trigger])

        elif isinstance(result, Trigger):
            self._coroutine_yielded(coroutine, [result])

        elif (isinstance(result, list) and
                not [t for t in result if not isinstance(t, Trigger)]):
            self._coroutine_yielded(coroutine, result)

        else:
            msg = ("Coroutine %s yielded something the scheduler can't handle"
                   % str(coroutine))
            msg += ("\nGot type: %s repr: %s str: %s" %
                    (type(result), repr(result), str(result)))
            msg += "\nDid you forget to decorate with @cocotb.cocorutine?"
            try:
                raise_error(self, msg)
            except Exception as e:
                self.finish_test(e)

        # Handle any newly queued coroutines that need to be scheduled
        while self._pending_coros:
            self.add(self._pending_coros.pop(0))

        while self._pending_callbacks:
            self._pending_callbacks.pop(0)()
Example #32
0
 def __call__(self, *args, **kwargs):
     try:
         return RunningCoroutine(self._func(*args, **kwargs), self)
     except Exception as e:
         raise raise_error(self, "Hook raised exception:")
Example #33
0
 def __call__(self, *args, **kwargs):
     try:
         return RunningTest(self._func(*args, **kwargs), self)
     except Exception as e:
         raise raise_error(self, "Test raised exception:")
Example #34
0
 def _wrapped_hook(*args, **kwargs):
     try:
         return RunningCoroutine(self._func(*args, **kwargs), self)
     except Exception as e:
         raise raise_error(self, str(e))
Example #35
0
    def schedule(self, coroutine, trigger=None):
        """
        Schedule a coroutine by calling the send method

        Args:
            coroutine (cocotb.decorators.coroutine): The coroutine to schedule

            trigger (cocotb.triggers.Trigger): The trigger that caused this
                                                coroutine to be scheduled
        """
        if hasattr(trigger, "pass_retval"):
            self.log.debug("Coroutine returned a retval")
            sendval = trigger.retval
        else:
            coroutine.log.debug("Scheduling (%s)" % str(trigger))
            sendval = trigger
        try:

            try:
                result = coroutine.send(sendval)

            # Normal co-routine completion
            except cocotb.decorators.CoroutineComplete as exc:
                self.log.debug("Coroutine completed execution with CoroutineComplete: %s" % str(coroutine))

                # Call any pending callbacks that were waiting for this coroutine to exit
                exc()
                return

            # Entries may have been added to the remove list while the
            # coroutine was running, clear these down and deschedule
            # before resuming
            if self._terminate is False:
                self.prune_routines()

            if isinstance(result, Trigger):
                self._add_trigger(result, coroutine)
            elif isinstance(result, cocotb.decorators.RunningCoroutine):
                if self._terminate is False:
                    self.log.debug("Scheduling nested co-routine: %s" % result.__name__)

                    # Queue current routine to schedule when the nested routine exits
                    self.queue(result)
                    new_trigger = result.join()
                    new_trigger.pass_retval = True
                    self._add_trigger(new_trigger, coroutine)

            elif isinstance(result, list):
                for trigger in result:
                    trigger.addpeers(result)
                    self._add_trigger(trigger, coroutine)
            else:
                msg = "Coroutine %s yielded something that was not a trigger or a coroutine!" % str(coroutine)
                msg += "\nGot type: %s repr: %s str: %s" % (type(result), repr(result), str(result))
                msg += "\nDid you forget to decorate with @cocotb.cocorutine?"
                raise_error(self, msg)

        # TestComplete indication is game over, tidy up
        except TestComplete as test_result:
            # Tag that close down is needed, save the test_result
            # for later use in cleanup handler
            # If we're already tearing down we ignore any further test results
            # that may be raised. Required because currently Python triggers don't unprime
            if not self._terminate:
                self.finish_test(test_result)
                return

        coroutine.log.debug("Finished sheduling coroutine (%s)" % str(trigger))
Example #36
0
    def schedule(self, coroutine, trigger=None):
        """Schedule a coroutine by calling the send method.

        Args:
            coroutine (cocotb.decorators.coroutine): The coroutine to schedule.
            trigger (cocotb.triggers.Trigger): The trigger that caused this
                coroutine to be scheduled.
        """
        if trigger is None:
            send_outcome = outcomes.Value(None)
        else:
            send_outcome = trigger._outcome
        if _debug:
            self.log.debug("Scheduling with {}".format(send_outcome))

        try:
            result = coroutine._advance(send_outcome)
            if _debug:
                self.log.debug("Coroutine %s yielded %s (mode %d)" %
                               (coroutine.__name__, str(result), self._mode))

        # TestComplete indication is game over, tidy up
        except TestComplete as test_result:
            # Tag that close down is needed, save the test_result
            # for later use in cleanup handler
            self.log.debug("TestComplete received: %s" %
                           test_result.__class__.__name__)
            self.finish_test(test_result)
            return

        # Normal coroutine completion
        except cocotb.decorators.CoroutineComplete as exc:
            if _debug:
                self.log.debug("Coroutine completed: %s" % str(coroutine))
            self.unschedule(coroutine)
            return

        # Don't handle the result if we're shutting down
        if self._terminate:
            return

        # Queue current routine to schedule when the nested routine exits
        yield_successful = False
        if isinstance(result, cocotb.decorators.RunningCoroutine):

            if not result.has_started():
                self.queue(result)
                if _debug:
                    self.log.debug("Scheduling nested coroutine: %s" %
                                   result.__name__)
            else:
                if _debug:
                    self.log.debug("Joining to already running coroutine: %s" %
                                   result.__name__)

            new_trigger = result.join()
            self._coroutine_yielded(coroutine, [new_trigger])
            yield_successful = True

        elif isinstance(result, Trigger):
            if _debug:
                self.log.debug("%s: is instance of Trigger" % result)
            self._coroutine_yielded(coroutine, [result])
            yield_successful = True

        # If we get a list, make sure it's a list of triggers or coroutines.
        # For every coroutine, replace it with coroutine.join().
        # This could probably be done more elegantly via list comprehension.
        elif isinstance(result, list):
            new_triggers = []
            for listobj in result:
                if isinstance(listobj, Trigger):
                    new_triggers.append(listobj)
                elif isinstance(listobj, cocotb.decorators.RunningCoroutine):
                    if _debug:
                        self.log.debug("Scheduling coroutine in list: %s" %
                                       listobj.__name__)
                    if not listobj.has_started():
                        self.queue(listobj)
                    new_trigger = listobj.join()
                    new_triggers.append(new_trigger)
                else:
                    # If we encounter something not a coroutine or trigger,
                    # set the success flag to False and break out of the loop.
                    yield_successful = False
                    break

            # Make sure the lists are the same size. If they are not, it means
            # it contained something not a trigger/coroutine, so do nothing.
            if len(new_triggers) == len(result):
                self._coroutine_yielded(coroutine, new_triggers)
                yield_successful = True

        # If we didn't successfully yield anything, thrown an error.
        # Do it this way to make the logic in the list case simpler.
        if not yield_successful:
            msg = (
                "Coroutine %s yielded something the scheduler can't handle" %
                str(coroutine))
            msg += ("\nGot type: %s repr: %s str: %s" %
                    (type(result), repr(result), str(result)))
            msg += "\nDid you forget to decorate with @cocotb.coroutine?"
            try:
                raise_error(self, msg)
            except Exception as e:
                self.finish_test(e)

        # We do not return from here until pending threads have completed, but only
        # from the main thread, this seems like it could be problematic in cases
        # where a sim might change what this thread is.
        def unblock_event(ext):
            @cocotb.coroutine
            def wrapper():
                ext.event.set()
                yield PythonTrigger()

        if self._main_thread is threading.current_thread():

            for ext in self._pending_threads:
                ext.thread_start()
                if _debug:
                    self.log.debug("Blocking from %s on %s" %
                                   (threading.current_thread(), ext.thread))
                state = ext.thread_wait()
                if _debug:
                    self.log.debug(
                        "Back from wait on self %s with newstate %d" %
                        (threading.current_thread(), state))
                if state == external_state.EXITED:
                    self._pending_threads.remove(ext)
                    self._pending_events.append(ext.event)

        # Handle any newly queued coroutines that need to be scheduled
        while self._pending_coros:
            self.add(self._pending_coros.pop(0))

        while self._pending_callbacks:
            self._pending_callbacks.pop(0)()
Example #37
0
 def _wrapped_test(*args, **kwargs):
     try:
         return RunningTest(self._func(*args, **kwargs), self)
     except Exception as e:
         raise raise_error(self, str(e))
Example #38
0
 def _wrapped_hook(*args, **kwargs):
     try:
         return RunningCoroutine(self._func(*args, **kwargs), self)
     except Exception as e:
         raise raise_error(self, str(e))
Example #39
0
 def __call__(self, *args, **kwargs):
     try:
         return RunningCoroutine(self._func(*args, **kwargs), self)
     except Exception as e:
         raise raise_error(self, "Hook raised exception:")
Example #40
0
 def prime(self, callback):
     self.cbhdl = simulator.create_callback(self)
     if simulator.register_readonly_callback(self.cbhdl, callback, self):
         raise_error(self, "Unable set up %s Trigger" % (str(self)))
Example #41
0
 def prime(self, callback):
     if self.cbhdl is None:
         self.cbhdl = simulator.register_readonly_callback(callback, self)
         if self.cbhdl is None:
             raise_error(self, "Unable set up %s Trigger" % (str(self)))
     Trigger.prime(self)
Example #42
0
    def schedule(self, coroutine, trigger=None):
        """
        Schedule a coroutine by calling the send method

        Args:
            coroutine (cocotb.decorators.coroutine): The coroutine to schedule

            trigger (cocotb.triggers.Trigger): The trigger that caused this
                                                coroutine to be scheduled
        """
        if hasattr(trigger, "pass_retval"):
            sendval = trigger.retval
            if _debug:
                coroutine.log.debug("Scheduling with ReturnValue(%s)" %
                                    (repr(sendval)))
        else:
            sendval = trigger
            if _debug:
                coroutine.log.debug("Scheduling with %s" % str(trigger))

        try:
            result = coroutine.send(sendval)
            if _debug:
                self.log.debug("Coroutine %s yielded %s (mode %d)" %
                               (coroutine.__name__, str(result), self._mode))

        # TestComplete indication is game over, tidy up
        except TestComplete as test_result:
            # Tag that close down is needed, save the test_result
            # for later use in cleanup handler
            self.log.debug("TestComplete received: %s" % test_result.__class__.__name__)
            self.finish_test(test_result)
            return

        # Normal co-routine completion
        except cocotb.decorators.CoroutineComplete as exc:
            if _debug:
                self.log.debug("Coroutine completed: %s" % str(coroutine))
            self.unschedule(coroutine)
            return

        # Don't handle the result if we're shutting down
        if self._terminate:
            return

        # Queue current routine to schedule when the nested routine exits
        if isinstance(result, cocotb.decorators.RunningCoroutine):
            if _debug:
                self.log.debug("Scheduling nested co-routine: %s" %
                               result.__name__)

            self.queue(result)
            new_trigger = result.join()
            self._coroutine_yielded(coroutine, [new_trigger])

        elif isinstance(result, Trigger):
            self._coroutine_yielded(coroutine, [result])

        elif (isinstance(result, list) and
                not [t for t in result if not isinstance(t, Trigger)]):
            self._coroutine_yielded(coroutine, result)

        else:
            msg = ("Coroutine %s yielded something the scheduler can't handle"
                   % str(coroutine))
            msg += ("\nGot type: %s repr: %s str: %s" %
                    (type(result), repr(result), str(result)))
            msg += "\nDid you forget to decorate with @cocotb.coroutine?"
            try:
                raise_error(self, msg)
            except Exception as e:
                self.finish_test(e)

        # Handle any newly queued coroutines that need to be scheduled
        while self._pending_coros:
            self.add(self._pending_coros.pop(0))

        while self._pending_callbacks:
            self._pending_callbacks.pop(0)()
Example #43
0
 def prime(self, callback):
     if self.cbhdl is None:
         self.cbhdl = simulator.register_nextstep_callback(callback, self)
         if self.cbhdl is None:
             raise_error(self, "Unable set up %s Trigger" % (str(self)))
     Trigger.prime(self)
Example #44
0
    def schedule(self, coroutine, trigger=None):
        """Schedule a coroutine by calling the send method.

        Args:
            coroutine (cocotb.decorators.coroutine): The coroutine to schedule.
            trigger (cocotb.triggers.Trigger): The trigger that caused this
                coroutine to be scheduled.
        """
        if trigger is None:
            send_outcome = outcomes.Value(None)
        else:
            send_outcome = trigger._outcome
        if _debug:
            self.log.debug("Scheduling with {}".format(send_outcome))

        try:
            result = coroutine._advance(send_outcome)
            if _debug:
                self.log.debug("Coroutine %s yielded %s (mode %d)" %
                               (coroutine.__name__, str(result), self._mode))

        # TestComplete indication is game over, tidy up
        except TestComplete as test_result:
            # Tag that close down is needed, save the test_result
            # for later use in cleanup handler
            self.log.debug("TestComplete received: %s" % test_result.__class__.__name__)
            self.finish_test(test_result)
            return

        # Normal coroutine completion
        except cocotb.decorators.CoroutineComplete as exc:
            if _debug:
                self.log.debug("Coroutine completed: %s" % str(coroutine))
            self.unschedule(coroutine)
            return

        # Don't handle the result if we're shutting down
        if self._terminate:
            return

        # convert lists into `First` Waitables.
        if isinstance(result, list):
            result = cocotb.triggers.First(*result)

        # convert waitables into coroutines
        if isinstance(result, cocotb.triggers.Waitable):
            result = result._wait()

        # convert coroutinues into triggers
        if isinstance(result, cocotb.decorators.RunningCoroutine):
            if not result.has_started():
                self.queue(result)
                if _debug:
                    self.log.debug("Scheduling nested coroutine: %s" %
                                   result.__name__)
            else:
                if _debug:
                    self.log.debug("Joining to already running coroutine: %s" %
                                   result.__name__)

            result = result.join()

        if isinstance(result, Trigger):
            if _debug:
                self.log.debug("%s: is instance of Trigger" % result)
            self._coroutine_yielded(coroutine, result)

        else:
            msg = ("Coroutine %s yielded something the scheduler can't handle"
                   % str(coroutine))
            msg += ("\nGot type: %s repr: %s str: %s" %
                    (type(result), repr(result), str(result)))
            msg += "\nDid you forget to decorate with @cocotb.coroutine?"
            try:
                raise_error(self, msg)
            except Exception as e:
                self.finish_test(e)

        # We do not return from here until pending threads have completed, but only
        # from the main thread, this seems like it could be problematic in cases
        # where a sim might change what this thread is.
        def unblock_event(ext):
            @cocotb.coroutine
            def wrapper():
                ext.event.set()
                yield PythonTrigger()

        if self._main_thread is threading.current_thread():

            for ext in self._pending_threads:
                ext.thread_start()
                if _debug:
                    self.log.debug("Blocking from %s on %s" % (threading.current_thread(), ext.thread))
                state = ext.thread_wait()
                if _debug:
                    self.log.debug("Back from wait on self %s with newstate %d" % (threading.current_thread(), state))
                if state == external_state.EXITED:
                    self._pending_threads.remove(ext)
                    self._pending_events.append(ext.event)

        # Handle any newly queued coroutines that need to be scheduled
        while self._pending_coros:
            self.add(self._pending_coros.pop(0))

        while self._pending_callbacks:
            self._pending_callbacks.pop(0)()
Example #45
0
 def prime(self, callback):
     Trigger.prime(self)
     if simulator.register_rwsynch_callback(self.cbhdl, callback, self):
         raise_error(self, "Unable set up %s Trigger" % (str(self)))
Example #46
0
 def prime(self, callback):
     if self.cbhdl == 0:
         self.cbhdl = simulator.register_nextstep_callback(callback, self)
         if self.cbhdl == 0:
             raise_error(self, "Unable set up %s Trigger" % (str(self)))
     Trigger.prime(self)
Example #47
0
    def schedule(self, coroutine, trigger=None):
        """
        Schedule a coroutine by calling the send method

        Args:
            coroutine (cocotb.decorators.coroutine): The coroutine to schedule

            trigger (cocotb.triggers.Trigger): The trigger that caused this
                                                coroutine to be scheduled
        """
        if hasattr(trigger, "pass_retval"):
            sendval = trigger.retval
            if _debug:
                if isinstance(sendval, ReturnValue):
                    coroutine.log.debug("Scheduling with ReturnValue(%s)" %
                                        (repr(sendval)))
                elif isinstance(sendval, ExternalException):
                    coroutine.log.debug("Scheduling with ExternalException(%s)" %
                                        (repr(sendval.exception)))

        else:
            sendval = trigger
            if _debug:
                coroutine.log.debug("Scheduling with %s" % str(trigger))

        try:
            result = coroutine.send(sendval)
            if _debug:
                self.log.debug("Coroutine %s yielded %s (mode %d)" %
                               (coroutine.__name__, str(result), self._mode))

        # TestComplete indication is game over, tidy up
        except TestComplete as test_result:
            # Tag that close down is needed, save the test_result
            # for later use in cleanup handler
            self.log.debug("TestComplete received: %s" % test_result.__class__.__name__)
            self.finish_test(test_result)
            return

        # Normal co-routine completion
        except cocotb.decorators.CoroutineComplete as exc:
            if _debug:
                self.log.debug("Coroutine completed: %s" % str(coroutine))
            self.unschedule(coroutine)
            return

        # Don't handle the result if we're shutting down
        if self._terminate:
            return

        # Queue current routine to schedule when the nested routine exits
        if isinstance(result, cocotb.decorators.RunningCoroutine):

            if not result.has_started():
                self.queue(result)
                if _debug:
                    self.log.debug("Scheduling nested co-routine: %s" %
                                   result.__name__)
            else:
                if _debug:
                    self.log.debug("Joining to already running co-routine: %s" %
                                   result.__name__)

            new_trigger = result.join()
            self._coroutine_yielded(coroutine, [new_trigger])

        elif isinstance(result, Trigger):
            if _debug:
                self.log.debug("%s: is instance of Trigger" % result)
            self._coroutine_yielded(coroutine, [result])

        elif (isinstance(result, list) and
                not [t for t in result if not isinstance(t, Trigger)]):
            self._coroutine_yielded(coroutine, result)

        else:
            msg = ("Coroutine %s yielded something the scheduler can't handle"
                   % str(coroutine))
            msg += ("\nGot type: %s repr: %s str: %s" %
                    (type(result), repr(result), str(result)))
            msg += "\nDid you forget to decorate with @cocotb.coroutine?"
            try:
                raise_error(self, msg)
            except Exception as e:
                self.finish_test(e)

        # We do not return from here until pending threads have completed, but only
        # from the main thread, this seems like it could be problematic in cases
        # where a sim might change what this thread is.
        def unblock_event(ext):
            @cocotb.coroutine
            def wrapper():
                ext.event.set()
                yield PythonTrigger()

        if self._main_thread is threading.current_thread():

            for ext in self._pending_threads:
                ext.thread_start()
                if _debug:
                    self.log.debug("Blocking from %s on %s" % (threading.current_thread(), ext.thread))
                state = ext.thread_wait()
                if _debug:
                    self.log.debug("Back from wait on self %s with newstate %d" % (threading.current_thread(), state))
                if state == external_state.EXITED:
                    self._pending_threads.remove(ext)
                    self._pending_events.append(ext.event)

        # Handle any newly queued coroutines that need to be scheduled
        while self._pending_coros:
            self.add(self._pending_coros.pop(0))

        while self._pending_callbacks:
            self._pending_callbacks.pop(0)()
Example #48
0
 def __call__(self, *args, **kwargs):
     try:
         return RunningTest(self._func(*args, **kwargs), self)
     except Exception as e:
         raise raise_error(self, "Test raised exception:")
Example #49
0
 def _wrapped_test(*args, **kwargs):
     try:
         return RunningTest(self._func(*args, **kwargs), self)
     except Exception as e:
         raise raise_error(self, str(e))
Example #50
0
    def schedule(self, coroutine, trigger=None):
        """Schedule a coroutine by calling the send method.

        Args:
            coroutine (cocotb.decorators.coroutine): The coroutine to schedule.
            trigger (cocotb.triggers.Trigger): The trigger that caused this
                coroutine to be scheduled.
        """
        if trigger is None:
            send_outcome = outcomes.Value(None)
        else:
            send_outcome = trigger._outcome
        if _debug:
            self.log.debug("Scheduling with {}".format(send_outcome))

        try:
            result = coroutine._advance(send_outcome)
            if _debug:
                self.log.debug("Coroutine %s yielded %s (mode %d)" %
                               (coroutine.__name__, str(result), self._mode))

        # TestComplete indication is game over, tidy up
        except TestComplete as test_result:
            # Tag that close down is needed, save the test_result
            # for later use in cleanup handler
            self.log.debug("TestComplete received: %s" % test_result.__class__.__name__)
            self.finish_test(test_result)
            return

        # Normal coroutine completion
        except cocotb.decorators.CoroutineComplete as exc:
            if _debug:
                self.log.debug("Coroutine completed: %s" % str(coroutine))
            self.unschedule(coroutine)
            return

        # Don't handle the result if we're shutting down
        if self._terminate:
            return

        # Queue current routine to schedule when the nested routine exits
        yield_successful = False
        if isinstance(result, cocotb.decorators.RunningCoroutine):

            if not result.has_started():
                self.queue(result)
                if _debug:
                    self.log.debug("Scheduling nested coroutine: %s" %
                                   result.__name__)
            else:
                if _debug:
                    self.log.debug("Joining to already running coroutine: %s" %
                                   result.__name__)

            new_trigger = result.join()
            self._coroutine_yielded(coroutine, [new_trigger])
            yield_successful = True

        elif isinstance(result, Trigger):
            if _debug:
                self.log.debug("%s: is instance of Trigger" % result)
            self._coroutine_yielded(coroutine, [result])
            yield_successful = True

        # If we get a list, make sure it's a list of triggers or coroutines.
        # For every coroutine, replace it with coroutine.join().
        # This could probably be done more elegantly via list comprehension.
        elif isinstance(result, list):
            new_triggers = []
            for listobj in result:
                if isinstance(listobj, Trigger):
                    new_triggers.append(listobj)
                elif isinstance(listobj, cocotb.decorators.RunningCoroutine):
                    if _debug:
                        self.log.debug("Scheduling coroutine in list: %s" %
                                       listobj.__name__)
                    if not listobj.has_started():
                        self.queue(listobj)
                    new_trigger = listobj.join()
                    new_triggers.append(new_trigger)
                else:
                    # If we encounter something not a coroutine or trigger,
                    # set the success flag to False and break out of the loop.
                    yield_successful = False
                    break

            # Make sure the lists are the same size. If they are not, it means
            # it contained something not a trigger/coroutine, so do nothing.
            if len(new_triggers) == len(result):
                self._coroutine_yielded(coroutine, new_triggers)
                yield_successful = True

        # If we didn't successfully yield anything, thrown an error.
        # Do it this way to make the logic in the list case simpler.
        if not yield_successful:
            msg = ("Coroutine %s yielded something the scheduler can't handle"
                   % str(coroutine))
            msg += ("\nGot type: %s repr: %s str: %s" %
                    (type(result), repr(result), str(result)))
            msg += "\nDid you forget to decorate with @cocotb.coroutine?"
            try:
                raise_error(self, msg)
            except Exception as e:
                self.finish_test(e)

        # We do not return from here until pending threads have completed, but only
        # from the main thread, this seems like it could be problematic in cases
        # where a sim might change what this thread is.
        def unblock_event(ext):
            @cocotb.coroutine
            def wrapper():
                ext.event.set()
                yield PythonTrigger()

        if self._main_thread is threading.current_thread():

            for ext in self._pending_threads:
                ext.thread_start()
                if _debug:
                    self.log.debug("Blocking from %s on %s" % (threading.current_thread(), ext.thread))
                state = ext.thread_wait()
                if _debug:
                    self.log.debug("Back from wait on self %s with newstate %d" % (threading.current_thread(), state))
                if state == external_state.EXITED:
                    self._pending_threads.remove(ext)
                    self._pending_events.append(ext.event)

        # Handle any newly queued coroutines that need to be scheduled
        while self._pending_coros:
            self.add(self._pending_coros.pop(0))

        while self._pending_callbacks:
            self._pending_callbacks.pop(0)()
Example #51
0
 def prime(self, callback):
     """Register for a timed callback"""
     self.cbhdl = simulator.create_callback(self)
     if simulator.register_timed_callback(self.cbhdl, self.time_ps, callback, self):
         raise_error(self, "Unable set up %s Trigger" % (str(self)))