本文整理汇总了Python中cocotb.log.SimLog.debug方法的典型用法代码示例。如果您正苦于以下问题:Python SimLog.debug方法的具体用法?Python SimLog.debug怎么用?Python SimLog.debug使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类cocotb.log.SimLog
的用法示例。
在下文中一共展示了SimLog.debug方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。
示例1: Feed
# 需要导入模块: from cocotb.log import SimLog [as 别名]
# 或者: from cocotb.log.SimLog import debug [as 别名]
class Feed(object):
def __init__(self, name, filepath=None):
self.name = name
self._packets = {}
self._filepath = filepath
self.fullname = '\'' + self.name + '\''
self.log = SimLog('cocotb.' + self.name)
if self._filepath:
self._source = open(self._filepath)
self.log.debug("loaded file %s" % self._filepath)
self.log.debug("Created feed!")
def addmsg(self, tag, data):
""" Add a defined message to the internal feed store """
self._packets[tag] = data
def getmsg(self):
""" Get a string representation of the current list head
This packet will be ready to send
"""
if self._packets:
tag, packet = self._packets.popitem()
return str(packet)
else:
self.log.warn("No packets in feed %s" % self.fullname)
return None
示例2: RunningTest
# 需要导入模块: from cocotb.log import SimLog [as 别名]
# 或者: from cocotb.log.SimLog import debug [as 别名]
class RunningTest(RunningCoroutine):
"""Add some useful Test functionality to a RunningCoroutine."""
class ErrorLogHandler(logging.Handler):
def __init__(self, fn):
self.fn = fn
logging.Handler.__init__(self, level=logging.DEBUG)
def handle(self, record):
self.fn(self.format(record))
def __init__(self, inst, parent):
self.error_messages = []
RunningCoroutine.__init__(self, inst, parent)
self.log = SimLog("cocotb.test.%s" % self.__name__, id(self))
self.started = False
self.start_time = 0
self.start_sim_time = 0
self.expect_fail = parent.expect_fail
self.expect_error = parent.expect_error
self.skip = parent.skip
self.stage = parent.stage
self.handler = RunningTest.ErrorLogHandler(self._handle_error_message)
cocotb.log.addHandler(self.handler)
def _advance(self, outcome):
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.start_sim_time = get_sim_time('ns')
self.started = True
try:
self.log.debug("Sending {}".format(outcome))
return outcome.send(self._coro)
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 raise_error(self, "Send raised exception:")
def _handle_error_message(self, msg):
self.error_messages.append(msg)
示例3: Trigger
# 需要导入模块: from cocotb.log import SimLog [as 别名]
# 或者: from cocotb.log.SimLog import debug [as 别名]
class Trigger(object):
"""Base class to derive from"""
def __init__(self):
self.log = SimLog("cocotb.%s" % (self.__class__.__name__), id(self))
self.signal = None
self.primed = False
def prime(self, *args):
self.primed = True
def unprime(self):
"""Remove any pending callbacks if necessary"""
self.primed = False
self.log.debug("Unprimed")
def __del__(self):
"""Ensure if a trigger drops out of scope we remove any pending callbacks"""
self.unprime()
def __str__(self):
return self.__class__.__name__
示例4: BusMonitor
# 需要导入模块: from cocotb.log import SimLog [as 别名]
# 或者: from cocotb.log.SimLog import debug [as 别名]
class BusMonitor(Monitor):
"""Wrapper providing common functionality for monitoring busses."""
_signals = []
_optional_signals = []
def __init__(self, entity, name, clock, reset=None, reset_n=None,
callback=None, event=None, bus_separator="_", config={}, array_idx=None):
self.log = SimLog("cocotb.%s.%s" % (entity._name, name))
self.entity = entity
self.name = name
self.clock = clock
self.config = self._default_config.copy()
for configoption, value in config.items():
self.config[configoption] = value
self.log.debug("Setting config option %s to %s" %
(configoption, str(value)))
self.bus = Bus(self.entity, self.name, self._signals,
optional_signals=self._optional_signals,
bus_separator=bus_separator,array_idx=array_idx)
self._reset = reset
self._reset_n = reset_n
Monitor.__init__(self, callback=callback, event=event)
@property
def in_reset(self):
"""Boolean flag showing whether the bus is in reset state or not."""
if self._reset_n is not None:
return not bool(self._reset_n.value.integer)
if self._reset is not None:
return bool(self._reset.value.integer)
return False
def __str__(self):
return "%s(%s)" % (self.__class__.__name__, self.name)
示例5: Driver
# 需要导入模块: from cocotb.log import SimLog [as 别名]
# 或者: from cocotb.log.SimLog import debug [as 别名]
#.........这里部分代码省略.........
"""
# self._busy = Lock()
self._pending = Event(name="Driver._pending")
self._sendQ = deque()
# Subclasses may already set up logging
if not hasattr(self, "log"):
self.log = SimLog("cocotb.driver.%s" % (self.__class__.__name__))
# Create an independent coroutine which can send stuff
self._thread = cocotb.scheduler.add(self._send_thread())
def kill(self):
if self._thread:
self._thread.kill()
self._thread = None
def append(self, transaction, callback=None, event=None):
"""
Queue up a transaction to be sent over the bus.
Mechanisms are provided to permit the caller to know when the
transaction is processed
callback: optional function to be called when the transaction has been
sent
event: event to be set when the tansaction has been sent
"""
self._sendQ.append((transaction, callback, event))
self._pending.set()
def clear(self):
"""
Clear any queued transactions without sending them onto the bus
"""
self._sendQ = deque()
@coroutine
def send(self, transaction, sync=True):
"""
Blocking send call (hence must be "yielded" rather than called)
Sends the transaction over the bus
Args:
transaction (any): the transaction to send
Kwargs:
sync (boolean): synchronise the transfer by waiting for risingedge
"""
yield self._send(transaction, None, None, sync=sync)
def _driver_send(self, transaction, sync=True):
"""
actual impementation of the send.
subclasses should override this method to implement the actual send
routine
"""
raise NotImplementedError("Subclasses of Driver should define a "
"_driver_send coroutine")
@coroutine
def _send(self, transaction, callback, event, sync=True):
"""
assumes the caller has already acquired the busy lock
releases busy lock once sending is complete
"""
yield self._driver_send(transaction, sync=sync)
# Notify the world that this transaction is complete
if event:
event.set()
if callback:
callback(transaction)
# No longer hogging the bus
# self.busy.release()
@coroutine
def _send_thread(self):
while True:
# Sleep until we have something to send
while not self._sendQ:
self._pending.clear()
yield self._pending.wait()
synchronised = False
# Send in all the queued packets,
# only synchronise on the first send
while self._sendQ:
transaction, callback, event = self._sendQ.popleft()
self.log.debug("Sending queued packet...")
yield self._send(transaction, callback, event,
sync=not synchronised)
synchronised = True
示例6: SimHandle
# 需要导入模块: from cocotb.log import SimLog [as 别名]
# 或者: from cocotb.log.SimLog import debug [as 别名]
class SimHandle(object):
def __init__(self, handle):
"""
Args:
_handle [integer] : vpi/vhpi handle to the simulator object
"""
self._handle = handle # handle used for future simulator transactions
self._sub_handles = {} # Dictionary of SimHandle objects created by getattr
self._len = None
self.name = simulator.get_name_string(self._handle)
self.fullname = self.name + '(%s)' % simulator.get_type_string(self._handle)
self.log = SimLog('cocotb.' + self.name)
self.log.debug("Created!")
self._r_edge = _RisingEdge(self)
self._f_edge = _FallingEdge(self)
def __hash__(self):
return self._handle
def __str__(self):
return "%s @0x%x" % (self.name, self._handle)
def __getattr__(self, name):
""" Query the simulator for a object with the specified name
and cache the result to build a tree
"""
if name in self._sub_handles:
return self._sub_handles[name]
new_handle = simulator.get_handle_by_name(self._handle, name)
if not new_handle:
self._raise_testerror("%s contains no object named %s" % (self.name, name))
self._sub_handles[name] = SimHandle(new_handle)
return self._sub_handles[name]
def _raise_testerror(self, msg):
lastframe = sys._getframe(2)
if sys.version_info[0] >= 3:
buff = StringIO()
traceback.print_stack(lastframe, file=buff)
else:
buff_bytes = BytesIO()
traceback.print_stack(lastframe, file=buff_bytes)
buff = StringIO(buff_bytes.getvalue().decode("UTF8"))
self.log.error("%s\n%s" % (msg, buff.getvalue()))
exception = TestError(msg)
exception.stderr.write(buff.getvalue())
buff.close()
raise exception
def __setattr__(self, name, value):
"""Provide transparent access to signals"""
if not name.startswith('_') and not name in ["name", "fullname", "log", "value"] \
and self.__hasattr__(name):
getattr(self, name).setcachedvalue(value)
return
object.__setattr__(self, name, value)
def __hasattr__(self, name):
"""
Since calling hasattr(handle, "something") will print out a
backtrace to the log since usually attempting to access a
non-existent member is an error we provide a 'peek function
We still add the found handle to our dictionary to prevent leaking
handles.
"""
if name in self._sub_handles:
return self._sub_handles[name]
new_handle = simulator.get_handle_by_name(self._handle, name)
if new_handle:
self._sub_handles[name] = SimHandle(new_handle)
return new_handle
def __getitem__(self, index):
if index in self._sub_handles:
return self._sub_handles[index]
new_handle = simulator.get_handle_by_index(self._handle, index)
if not new_handle:
self._raise_testerror("%s contains no object at index %d" % (self.name, index))
self._sub_handles[index] = SimHandle(new_handle)
return self._sub_handles[index]
def __setitem__(self, index, value):
"""Provide transparent assignment to bit index"""
self.__getitem__(index).setcachedvalue(value)
def getvalue(self):
result = BinaryValue()
result.binstr = self._get_value_str()
return result
def setimmediatevalue(self, value):
"""
Set the value of the underlying simulation object to value.
Args:
value (ctypes.Structure, cocotb.binary.BinaryValue, int)
The value to drive onto the simulator object
#.........这里部分代码省略.........
示例7: TestFactory
# 需要导入模块: from cocotb.log import SimLog [as 别名]
# 或者: from cocotb.log.SimLog import debug [as 别名]
#.........这里部分代码省略.........
* ``gen_b`` with ``random_backpressure`` and no idles
* ``gen_b`` with ``random_backpressure`` and ``random_idles``
The tests are appended to the calling module for auto-discovery.
Tests are simply named ``test_function_N``. The docstring for the test (hence
the test description) includes the name and description of each generator.
"""
def __init__(self, test_function, *args, **kwargs):
"""
Args:
test_function (function): the function that executes a test.
Must take 'dut' as the first argument.
*args: Remaining args are passed directly to the test function.
Note that these arguments are not varied. An argument that
varies with each test must be a keyword argument to the
test function.
*kwargs: Remaining kwargs are passed directly to the test function.
Note that these arguments are not varied. An argument that
varies with each test must be a keyword argument to the
test function.
"""
if not isinstance(test_function, cocotb.coroutine):
raise TypeError("TestFactory requires a cocotb coroutine")
self.test_function = test_function
self.name = self.test_function._func.__name__
self.args = args
self.kwargs_constant = kwargs
self.kwargs = {}
self.log = SimLog("cocotb.regression")
def add_option(self, name, optionlist):
"""Add a named option to the test.
Args:
name (str): Name of the option. Passed to test as a keyword
argument.
optionlist (list): A list of possible options for this test knob.
"""
self.kwargs[name] = optionlist
def generate_tests(self, prefix="", postfix=""):
"""
Generates exhaustive set of tests using the cartesian product of the
possible keyword arguments.
The generated tests are appended to the namespace of the calling
module.
Args:
prefix (str): Text string to append to start of ``test_function`` name
when naming generated test cases. This allows reuse of
a single ``test_function`` with multiple
:class:`TestFactories <.TestFactory>` without name clashes.
postfix (str): Text string to append to end of ``test_function`` name
when naming generated test cases. This allows reuse of
a single ``test_function`` with multiple
:class:`TestFactories <.TestFactory>` without name clashes.
"""
frm = inspect.stack()[1]
mod = inspect.getmodule(frm[0])
d = self.kwargs
for index, testoptions in enumerate((
dict(zip(d, v)) for v in
product(*d.values())
)):
name = "%s%s%s_%03d" % (prefix, self.name, postfix, index + 1)
doc = "Automatically generated test\n\n"
for optname, optvalue in testoptions.items():
if callable(optvalue):
if not optvalue.__doc__:
desc = "No docstring supplied"
else:
desc = optvalue.__doc__.split('\n')[0]
doc += "\t%s: %s (%s)\n" % (optname, optvalue.__name__,
desc)
else:
doc += "\t%s: %s\n" % (optname, repr(optvalue))
self.log.debug("Adding generated test \"%s\" to module \"%s\"" %
(name, mod.__name__))
kwargs = {}
kwargs.update(self.kwargs_constant)
kwargs.update(testoptions)
if hasattr(mod, name):
self.log.error("Overwriting %s in module %s. "
"This causes a previously defined testcase "
"not to be run. Consider setting/changing "
"name_postfix" % (name, mod))
setattr(mod, name, _create_test(self.test_function, name, doc, mod,
*self.args, **kwargs))
示例8: Scheduler
# 需要导入模块: from cocotb.log import SimLog [as 别名]
# 或者: from cocotb.log.SimLog import debug [as 别名]
class Scheduler(object):
"""The main scheduler.
Here we accept callbacks from the simulator and schedule the appropriate
coroutines.
A callback fires, causing the :any:`react` method to be called, with the
trigger that caused the callback as the first argument.
We look up a list of coroutines to schedule (indexed by the trigger) and
schedule them in turn. NB implementors should not depend on the scheduling
order!
Some additional management is required since coroutines can return a list
of triggers, to be scheduled when any one of the triggers fires. To
ensure we don't receive spurious callbacks, we have to un-prime all the
other triggers when any one fires.
Due to the simulator nuances and fun with delta delays we have the
following modes:
Normal mode
- Callbacks cause coroutines to be scheduled
- Any pending writes are cached and do not happen immediately
ReadOnly mode
- Corresponds to cbReadOnlySynch (VPI) or vhpiCbLastKnownDeltaCycle
(VHPI). In this state we are not allowed to perform writes.
Write mode
- Corresponds to cbReadWriteSynch (VPI) or vhpiCbEndOfProcesses (VHPI)
In this mode we play back all the cached write updates.
We can legally transition from normal->write by registering a ReadWrite
callback, however usually once a simulator has entered the ReadOnly phase
of a given timestep then we must move to a new timestep before performing
any writes. The mechanism for moving to a new timestep may not be
consistent across simulators and therefore we provide an abstraction to
assist with compatibility.
Unless a coroutine has explicitly requested to be scheduled in ReadOnly
mode (for example wanting to sample the finally settled value after all
delta delays) then it can reasonably be expected to be scheduled during
"normal mode" i.e. where writes are permitted.
"""
_MODE_NORMAL = 1 # noqa
_MODE_READONLY = 2 # noqa
_MODE_WRITE = 3 # noqa
_MODE_TERM = 4 # noqa
# Singleton events, recycled to avoid spurious object creation
_readonly = ReadOnly()
# TODO[gh-759]: For some reason, the scheduler requires that these triggers
# are _not_ the same instances used by the tests themselves. This is risky,
# because it can lead to them overwriting each other's callbacks. We should
# try to remove this `copy.copy` in future.
_next_timestep = copy.copy(NextTimeStep())
_readwrite = copy.copy(ReadWrite())
_timer1 = Timer(1)
_timer0 = Timer(0)
def __init__(self):
self.log = SimLog("cocotb.scheduler")
if _debug:
self.log.setLevel(logging.DEBUG)
# A dictionary of pending coroutines for each trigger,
# indexed by trigger
self._trigger2coros = collections.defaultdict(list)
# A dictionary of pending triggers for each coroutine, indexed by coro
self._coro2triggers = collections.defaultdict(list)
# Our main state
self._mode = Scheduler._MODE_NORMAL
# A dictionary of pending writes
self._writes = {}
self._pending_coros = []
self._pending_callbacks = []
self._pending_triggers = []
self._pending_threads = []
self._pending_events = [] # Events we need to call set on once we've unwound
self._terminate = False
self._test_result = None
self._entrypoint = None
self._main_thread = threading.current_thread()
# Select the appropriate scheduling algorithm for this simulator
self.advance = self.default_scheduling_algorithm
self._is_reacting = False
def default_scheduling_algorithm(self):
"""
Decide whether we need to schedule our own triggers (if at all) in
#.........这里部分代码省略.........
示例9: Scheduler
# 需要导入模块: from cocotb.log import SimLog [as 别名]
# 或者: from cocotb.log.SimLog import debug [as 别名]
class Scheduler(object):
"""
The main scheduler.
Here we accept callbacks from the simulator and schedule the appropriate
coroutines.
A callback fires, causing the `react`_ method to be called, with the
trigger that caused the callback as the first argument.
We look up a list of coroutines to schedule (indexed by the trigger) and
schedule them in turn. NB implementors should not depend on the scheduling
order!
Some additional management is required since coroutines can return a list
of triggers, to be scheduled when any one of the triggers fires. To
ensure we don't receive spurious callbacks, we have to un-prime all the
other triggers when any one fires.
Due to the simulator nuances and fun with delta delays we have the
following modes:
Normal mode
- Callbacks cause coroutines to be scheduled
- Any pending writes are cached and do not happen immediately
ReadOnly mode
- Corresponds to cbReadOnlySynch (VPI) or vhpiCbLastKnownDeltaCycle
(VHPI). In this state we are not allowed to perform writes.
Write mode
- Corresponds to cbReadWriteSynch (VPI) or vhpiCbEndOfProcesses (VHPI)
In this mode we play back all the cached write updates.
We can legally transition from normal->write by registering a ReadWrite
callback, however usually once a simulator has entered the ReadOnly phase
of a given timestep then we must move to a new timestep before performing
any writes. The mechanism for moving to a new timestep may not be
consistent across simulators and therefore we provide an abstraction to
assist with compatibility.
Unless a coroutine has explicitly requested to be scheduled in ReadOnly
mode (for example wanting to sample the finally settled value after all
delta delays) then it can reasonably be expected to be scheduled during
"normal mode" i.e. where writes are permitted.
"""
_MODE_NORMAL = 1 # noqa
_MODE_READONLY = 2 # noqa
_MODE_WRITE = 3 # noqa
_MODE_TERM = 4 # noqa
# Singleton events, recycled to avoid spurious object creation
_readonly = ReadOnly()
_next_timestep = _NextTimeStep()
_readwrite = _ReadWrite()
_timer1 = Timer(1)
_timer0 = Timer(0)
def __init__(self):
self.log = SimLog("cocotb.scheduler")
if _debug:
self.log.setLevel(logging.DEBUG)
# A dictionary of pending coroutines for each trigger,
# indexed by trigger
self._trigger2coros = collections.defaultdict(list)
# A dictionary of pending triggers for each coroutine, indexed by coro
self._coro2triggers = collections.defaultdict(list)
# Our main state
self._mode = Scheduler._MODE_NORMAL
# A dictionary of pending writes
self._writes = {}
self._pending_coros = []
self._pending_callbacks = []
self._pending_triggers = []
self._terminate = False
self._test_result = None
self._entrypoint = None
# Select the appropriate scheduling algorithm for this simulator
self.advance = self.default_scheduling_algorithm
def default_scheduling_algorithm(self):
"""
Decide whether we need to schedule our own triggers (if at all) in
order to progress to the next mode.
This algorithm has been tested against the following simulators:
Icarus Verilog
"""
if not self._terminate and self._writes:
#.........这里部分代码省略.........
示例10: Scoreboard
# 需要导入模块: from cocotb.log import SimLog [as 别名]
# 或者: from cocotb.log.SimLog import debug [as 别名]
class Scoreboard(object):
"""Generic scoreboarding class
We can add interfaces by providing a monitor and an expected output queue
The expected output can either be a function which provides a transaction
or a simple list containing the expected output.
TODO:
Statistics for end-of-test summary etc.
"""
def __init__(self, dut, reorder_depth=0, fail_immediately=True):
self.dut = dut
self.log = SimLog("cocotb.scoreboard.%s" % self.dut._name)
self.errors = 0
self.expected = {}
self._imm = fail_immediately
@property
def result(self):
"""Determine the test result, do we have any pending data remaining?"""
fail = False
for monitor, expected_output in self.expected.items():
if callable(expected_output):
self.log.debug("Can't check all data returned for %s since "
"expected output is callable function rather "
"than a list" % str(monitor))
continue
if len(expected_output):
self.log.warn("Still expecting %d transactions on %s" %
(len(expected_output), str(monitor)))
for index, transaction in enumerate(expected_output):
self.log.info("Expecting %d:\n%s" %
(index, hexdump(str(transaction))))
if index > 5:
self.log.info("... and %d more to come" %
(len(expected_output) - index - 1))
break
fail = True
if fail:
return TestFailure("Not all expected output was received")
if self.errors:
return TestFailure("Errors were recorded during the test")
return TestSuccess()
def compare(self, got, exp, log, strict_type=True):
"""
Common function for comparing two transactions.
Can be re-implemented by a subclass.
"""
# Compare the types
if strict_type and type(got) != type(exp):
self.errors += 1
log.error("Received transaction type is different than expected")
log.info("Received: %s but expected %s" %
(str(type(got)), str(type(exp))))
if self._imm:
raise TestFailure("Received transaction of wrong type. "
"Set strict_type=False to avoid this.")
return
# Or convert to a string before comparison
elif not strict_type:
got, exp = str(got), str(exp)
# Compare directly
if got != exp:
self.errors += 1
# Try our best to print out something useful
strgot, strexp = str(got), str(exp)
log.error("Received transaction differed from expected output")
if not strict_type:
log.info("Expected:\n" + hexdump(strexp))
else:
log.info("Expected:\n" + repr(exp))
if not isinstance(exp, str):
try:
for word in exp:
log.info(str(word))
except:
pass
if not strict_type:
log.info("Received:\n" + hexdump(strgot))
else:
log.info("Received:\n" + repr(got))
if not isinstance(got, str):
try:
for word in got:
log.info(str(word))
except:
pass
log.warning("Difference:\n%s" % hexdiffs(strexp, strgot))
if self._imm:
raise TestFailure("Received transaction differed from expected"
"transaction")
else:
#.........这里部分代码省略.........
示例11: SimHandleBase
# 需要导入模块: from cocotb.log import SimLog [as 别名]
# 或者: from cocotb.log.SimLog import debug [as 别名]
class SimHandleBase(object):
"""
Base class for all simulation objects.
We maintain a handle which we can use for GPI calls
"""
# For backwards compatibility we support a mapping of old member names
# which may alias with the simulator hierarchy. In these cases the
# simulator result takes priority, only falling back to the python member
# if there is no colliding object in the elaborated design.
_compat_mapping = {
"log" : "_log",
"fullname" : "_fullname",
"name" : "_name",
}
def __init__(self, handle):
"""
Args:
handle (integer) : the GPI handle to the simulator object
"""
self._handle = handle
self._len = None
self._sub_handles = {} # Dictionary of children
self._invalid_sub_handles = {} # Dictionary of invalid queries
self._discovered = False
self._name = simulator.get_name_string(self._handle)
self._type = simulator.get_type_string(self._handle)
self._fullname = self._name + "(%s)" % self._type
self._log = SimLog("cocotb.%s" % self._name)
self._log.debug("Created")
def __hash__(self):
return self._handle
def __len__(self):
"""Returns the 'length' of the underlying object.
For vectors this is the number of bits.
"""
if self._len is None:
self._len = simulator.get_num_elems(self._handle)
return self._len
def __eq__(self, other):
# Permits comparison of handles i.e. if clk == dut.clk
if isinstance(other, SimHandleBase):
if self._handle == other._handle: return 0
return 1
def __ne__(self, other):
return not self.__eq__(other)
def __repr__(self):
return self._fullname
def _raise_testerror(self, msg):
lastframe = sys._getframe(2)
if sys.version_info[0] >= 3:
buff = StringIO()
traceback.print_stack(lastframe, file=buff)
else:
buff_bytes = BytesIO()
traceback.print_stack(lastframe, file=buff_bytes)
buff = StringIO(buff_bytes.getvalue().decode("UTF8"))
self._log.error("%s\n%s" % (msg, buff.getvalue()))
exception = TestError(msg)
exception.stderr.write(buff.getvalue())
buff.close()
raise exception
示例12: Scheduler
# 需要导入模块: from cocotb.log import SimLog [as 别名]
# 或者: from cocotb.log.SimLog import debug [as 别名]
class Scheduler(object):
def __init__(self):
self.waiting = collections.defaultdict(list)
self.delay_waiting = collections.defaultdict(list)
self.log = SimLog("cocotb.scheduler")
self.writes = {}
self.writes_lock = threading.RLock()
self._remove = []
self._pending_adds = []
self._startpoint = None
self._terminate = False
self._test_result = None
self._do_cleanup = None
self._entry_lock = RLock()
self._external_trigger = threading.Semaphore(1)
self._external_trigger._value = False
self._external = False
self._readonly = False
self._react_timer = None
# Keep this last
self._readwrite = self.add(self.move_to_rw())
def react(self, trigger):
"""
React called when a trigger fires. We find any coroutines that are waiting on the particular
trigger and schedule them.
"""
trigger.log.debug("Fired!")
if isinstance(trigger, ReadOnly):
self.enable_react_delay()
self._readonly = True
if trigger not in self.waiting:
# This isn't actually an error - often might do event.set() without knowing
# whether any coroutines are actually waiting on this event
# NB should catch a GPI trigger cause that would be catestrophic
self.log.debug("Not waiting on triggger that fired! (%s)" % (str(trigger)))
return
# Scheduled coroutines may append to our waiting list
# so the first thing to do is pop all entries waiting
# on this trigger.
self._scheduling = self.waiting.pop(trigger)
to_run = len(self._scheduling)
self.log.debug("%d pending coroutines for event %s" % (to_run, trigger))
while self._scheduling:
coroutine = self._scheduling.pop(0)
del_list = trigger.clearpeers()
while del_list:
self.remove(del_list.pop(0))
self.schedule(coroutine, trigger=trigger)
self.log.debug("Scheduled coroutine %s" % (coroutine.__name__))
# Various interactions with the simulator cannot occur during
# ReadOnly event periods
if self._readonly is False:
# We may also have possible routines that need to be added since
# the exit from ReadOnly
for ptrigger, pwaiting in self.delay_waiting.items():
for pcoro in pwaiting:
self.delay_waiting[ptrigger].remove(pcoro)
self._add_trigger(ptrigger, pcoro)
del self.delay_waiting[ptrigger]
# If the python has caused any subsequent events to fire we might
# need to schedule more coroutines before we drop back into the
# simulator
self._entry_lock.acquire()
while self._pending_adds:
coroutine = self._pending_adds.pop(0)
self._entry_lock.release()
self.add(coroutine)
self._entry_lock.acquire()
self._entry_lock.release()
# If we've performed any writes that are cached then schedule
# another callback for the read-write part of the sim cycle, but
# if we are terminating then do not allow another callback to be
# scheduled, only do this if this trigger was not ReadOnly as
# Scheduling ReadWrite is a violation, it will be picked up
# on next react
if self._terminate is False and len(self.writes) and self._readwrite is None:
self._readwrite = self.add(self.move_to_rw())
return
def set_external(self):
""" Take the semaphore to indicate to the react later that there an external
is being added to the list
"""
# self._external_trigger.acquire()
self._external_trigger._value = True
def playout_writes(self):
if self.writes:
#.........这里部分代码省略.........
示例13: Scoreboard
# 需要导入模块: from cocotb.log import SimLog [as 别名]
# 或者: from cocotb.log.SimLog import debug [as 别名]
class Scoreboard(object):
"""Generic scoreboarding class
We can add interfaces by providing a monitor and an expected output queue
The expected output can either be a function which provides a transaction
or a simple list containing the expected output.
TODO:
Statistics for end-of-test summary etc.
"""
def __init__(self, dut, reorder_depth=0, fail_immediately=True):
self.dut = dut
self.log = SimLog("cocotb.scoreboard.%s" % self.dut.name)
self.errors = 0
self.expected = {}
self._imm = fail_immediately
@property
def result(self):
"""Determine the test result - do we have any pending data remaining?"""
fail = False
for monitor, expected_output in self.expected.iteritems():
if callable(expected_output):
self.log.debug("Can't check all data returned for %s since expected output is \
callable function rather than a list" % str(monitor))
continue
if len(expected_output):
self.log.warn("Still expecting %d transactions on %s" % (len(expected_output), str(monitor)))
for index, transaction in enumerate(expected_output):
self.log.info("Expecting %d:\n%s" % (index, hexdump(str(transaction))))
if index > 5:
self.log.info("... and %d more to come" % (len(expected_output) - index - 1))
break
fail = True
if fail:
return TestFailure("Not all expected output was received")
if self.errors:
return TestFailure("Errors were recorded during the test")
return TestSuccess()
def add_interface(self, monitor, expected_output, compare_fn=None):
"""Add an interface to be scoreboarded.
Provides a function which the monitor will callback with received transactions
Simply check against the expected output.
"""
# save a handle to the expected output so we can check if all expected data has
# been received at the end of a test.
self.expected[monitor] = expected_output
# Enforce some type checking as we only work with a real monitor
if not isinstance(monitor, Monitor):
raise TypeError("Expected monitor on the interface but got %s" % (monitor.__class__.__name__))
if compare_fn is not None:
if callable(compare_fn):
monitor.add_callback(compare_fn)
return
raise TypeError("Expected a callable compare function but got %s" % str(type(compare_fn)))
def check_received_transaction(transaction):
"""Called back by the monitor when a new transaction has been received"""
log = logging.getLogger(self.log.name + '.' + monitor.name)
if callable(expected_output):
exp = expected_output(transaction)
elif len(expected_output):
exp = expected_output.pop(0)
else:
self.errors += 1
log.error("Received a transaction but wasn't expecting anything")
log.info("Got: %s" % (hexdump(str(transaction))))
if self._imm: raise TestFailure("Received a transaction but wasn't expecting anything")
return
if type(transaction) != type(exp):
self.errors += 1
log.error("Received transaction is a different type to expected transaction")
log.info("Got: %s but expected %s" % (str(type(transaction)), str(type(exp))))
if self._imm: raise TestFailure("Received transaction of wrong type")
return
if transaction != exp:
self.errors += 1
log.error("Received transaction differed from expected output")
log.info("Expected:\n" + hexdump(exp))
if not isinstance(exp, str):
try:
for word in exp: self.log.info(str(word))
except: pass
log.info("Received:\n" + hexdump(transaction))
if not isinstance(transaction, str):
try:
for word in transaction: self.log.info(str(word))
except: pass
#.........这里部分代码省略.........
示例14: SimLog
# 需要导入模块: from cocotb.log import SimLog [as 别名]
# 或者: from cocotb.log.SimLog import debug [as 别名]
except AttributeError as e:
log.error("Unable to set loging level to %s" % level)
_default_log = logging.INFO
log.setLevel(_default_log)
loggpi = SimLog('cocotb.gpi')
# Notify GPI of log level
simulator.log_level(_default_log)
# If stdout/stderr are not TTYs, Python may not have opened them with line
# buffering. In that case, try to reopen them with line buffering
# explicitly enabled. This ensures that prints such as stack traces always
# appear. Continue silently if this fails.
try:
if not sys.stdout.isatty():
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 1)
log.debug("Reopened stdout with line buffering")
if not sys.stderr.isatty():
sys.stderr = os.fdopen(sys.stderr.fileno(), 'w', 1)
log.debug("Reopened stderr with line buffering")
except Exception as e:
log.warning("Failed to ensure that stdout/stderr are line buffered: %s", e)
log.warning("Some stack traces may not appear because of this.")
scheduler = Scheduler()
regression_manager = None
plusargs = {}
# To save typing provide an alias to scheduler.add
fork = scheduler.add
示例15: Monitor
# 需要导入模块: from cocotb.log import SimLog [as 别名]
# 或者: from cocotb.log.SimLog import debug [as 别名]
class Monitor(object):
def __init__(self, callback=None, event=None):
"""
Constructor for a monitor instance
callback will be called with each recovered transaction as the argument
If the callback isn't used, received transactions will be placed on a
queue and the event used to notify any consumers.
"""
self._event = event
self._wait_event = None
self._recvQ = []
self._callbacks = []
self.stats = MonitorStatistics()
self._wait_event = Event()
# Subclasses may already set up logging
if not hasattr(self, "log"):
self.log = SimLog("cocotb.monitor.%s" % (self.__class__.__name__))
if callback is not None:
self.add_callback(callback)
# Create an independent coroutine which can receive stuff
self._thread = cocotb.scheduler.add(self._monitor_recv())
def kill(self):
if self._thread:
self._thread.kill()
self._thread = None
def __len__(self):
return len(self._recvQ)
def __getitem__(self, idx):
return self._recvQ[idx]
def add_callback(self, callback):
self.log.debug("Adding callback of function %s to monitor" %
(callback.__name__))
self._callbacks.append(callback)
@coroutine
def wait_for_recv(self, timeout=None):
if timeout:
t = Timer(timeout)
fired = yield [self._wait_event.wait(), t]
if fired is t:
raise ReturnValue(None)
else:
yield self._wait_event.wait()
pkt = self._wait_event.data
raise ReturnValue(pkt)
@coroutine
def _monitor_recv(self):
"""
actual impementation of the receiver
subclasses should override this method to implement the actual receive
routine and call self._recv() with the recovered transaction
"""
raise NotImplementedError("Attempt to use base monitor class without "
"providing a _monitor_recv method")
def _recv(self, transaction):
"""Common handling of a received transaction."""
self.stats.received_transactions += 1
# either callback based consumer
for callback in self._callbacks:
callback(transaction)
# Or queued with a notification
if not self._callbacks:
self._recvQ.append(transaction)
if self._event is not None:
self._event.set()
# If anyone was waiting then let them know
if self._wait_event is not None:
self._wait_event.set(data=transaction)
self._wait_event.clear()