def __init__(self, fc_init=[[0]*6]*8, *args, **kwargs): self.log = logging.getLogger(f"cocotb.pcie.{type(self).__name__}.{id(self)}") self.log.name = f"cocotb.pcie.{type(self).__name__}" self.parent = None self.rx_handler = None self.max_link_speed = None self.max_link_width = None self.tx_queue = Queue(1) self.tx_queue_sync = Event() self.rx_queue = Queue() self.cur_link_speed = None self.cur_link_width = None self.time_scale = get_sim_steps(1, 'sec') # ACK/NAK protocol # TX self.next_transmit_seq = 0x000 self.ackd_seq = 0xfff self.retry_buffer = Queue() # RX self.next_recv_seq = 0x000 self.nak_scheduled = False self.ack_nak_latency_timer = 0 self.max_payload_size = 128 self.max_latency_timer = 0 self.send_ack = Event() self._ack_latency_timer_cr = None # Flow control self.send_fc = Event() self.fc_state = [FcChannelState(fc_init[k], self.start_fc_update_timer) for k in range(8)] self.fc_initialized = False self.fc_init_vc = 0 self.fc_init_type = FcType.P self.fc_idle_timer_steps = get_sim_steps(10, 'us') self.fc_update_steps = get_sim_steps(30, 'us') self._fc_update_timer_cr = None super().__init__(*args, **kwargs) # VC0 is always active self.fc_state[0].active = True cocotb.fork(self._run_transmit()) cocotb.fork(self._run_receive()) cocotb.fork(self._run_fc_update_idle_timer())
async def test_time_units_eq_None(dut): """Test deprecation warning when time units are None""" with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") Timer(1, units=None) assert issubclass(w[-1].category, DeprecationWarning) assert 'Using units=None is deprecated, use units="step" instead.' in str( w[-1].message) with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") Clock(dut.clk, 2, units=None) assert issubclass(w[-1].category, DeprecationWarning) assert 'Using units=None is deprecated, use units="step" instead.' in str( w[-1].message) with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") get_sim_steps(222, units=None) assert issubclass(w[-1].category, DeprecationWarning) assert 'Using units=None is deprecated, use units="step" instead.' in str( w[-1].message) with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") await cocotb.triggers.with_timeout(example(), timeout_time=12_000_000, timeout_unit=None) assert issubclass(w[-1].category, DeprecationWarning) assert 'Using timeout_unit=None is deprecated, use timeout_unit="step" instead.' in str( w[-1].message)
def __init__(self, signal, period, units=None): BaseClock.__init__(self, signal) self.period = get_sim_steps(period, units) self.half_period = get_sim_steps(period / 2.0, units) self.frequency = 1.0 / get_time_from_sim_steps(self.period, units='us') self.hdl = None self.signal = signal self.coro = None self.mcoro = None
def __init__(self, signal, period, units=None): BaseClock.__init__(self, signal) self.period = get_sim_steps(period, units) self.half_period = get_sim_steps(period / 2.0, units) self.frequency = 1.0 / get_time_from_sim_steps(self.period,units='us') self.hdl = None self.signal = signal self.coro = None self.mcoro = None
def __init__(self, signal, period, units="step"): BaseClock.__init__(self, signal) if units is None: warnings.warn( 'Using units=None is deprecated, use units="step" instead.', DeprecationWarning, stacklevel=2) units="step" # don't propagate deprecated value self.period = get_sim_steps(period, units) self.half_period = get_sim_steps(period / 2.0, units) self.frequency = 1.0 / get_time_from_sim_steps(self.period, units='us') self.hdl = None self.signal = signal self.coro = None self.mcoro = None
async def _run_clock(self, period): half_period = get_sim_steps(period / 2.0, 'ns') t = Timer(half_period) while True: await t self.dut.output_clk.value = 1 await t self.dut.output_clk.value = 0
async def test_get_sim_steps(_): # test invalid round_mode specifier with pytest.raises(ValueError, match="^Invalid round_mode specifier: notvalid"): utils.get_sim_steps(1, "step", round_mode="notvalid") # test default, update if default changes with pytest.raises(ValueError): utils.get_sim_steps(0.5, "step") # test valid with pytest.raises(ValueError): utils.get_sim_steps(0.5, "step", round_mode="error") assert utils.get_sim_steps(24.0, "step", round_mode="error") == 24 assert utils.get_sim_steps(1.2, "step", round_mode="floor") == 1 assert utils.get_sim_steps(1.2, "step", round_mode="ceil") == 2 assert utils.get_sim_steps(1.2, "step", round_mode="round") == 1
async def test_get_sim_steps(_): # test invalid round_mode specifier with pytest.raises(ValueError) as e: utils.get_sim_steps(1, "step", "notvalid") assert "invalid" in str(e).lower() # test default, update if default changes with pytest.raises(ValueError): utils.get_sim_steps(0.5, "step") # test valid with pytest.raises(ValueError): utils.get_sim_steps(0.5, "step", "error") assert utils.get_sim_steps(24.0, "step", "error") == 24 assert utils.get_sim_steps(1.2, "step", "floor") == 1 assert utils.get_sim_steps(1.2, "step", "ceil") == 2 assert utils.get_sim_steps(1.2, "step", "round") == 1
async def _run_clock(self, period): half_period = get_sim_steps(period / 2.0, 'ns') t = Timer(half_period) while True: await t self.rx_clk <= 1 await t self.rx_clk <= 0
def __init__(self, time_ps, units=None): """ Args: time_ps (numbers.Real or decimal.Decimal): The time value. Note that despite the name this is not actually in picoseconds but depends on the *units* argument. units (str or None, optional): One of ``None``, ``'fs'``, ``'ps'``, ``'ns'``, ``'us'``, ``'ms'``, ``'sec'``. When no *units* is given (``None``) the timestep is determined by the simulator. Examples: >>> await Timer(100, units='ps') The time can also be a ``float``: >>> await Timer(100e-9, units='sec') which is particularly convenient when working with frequencies: >>> freq = 10e6 # 10 MHz >>> await Timer(1 / freq, units='sec') Other builtin exact numeric types can be used too: >>> from fractions import Fraction >>> await Timer(Fraction(1, 10), units='ns') >>> from decimal import Decimal >>> await Timer(Decimal('100e-9'), units='sec') These are most useful when using computed durations while avoiding floating point inaccuracies. See Also: :func:`~cocotb.utils.get_sim_steps` Raises: TriggerException: If a negative value is passed for Timer setup. .. versionchanged:: 1.5 Raise an exception when Timer uses a negative value as it is undefined behavior. Warn for 0 as this will cause erratic behavior in some simulators as well. """ GPITrigger.__init__(self) if time_ps <= 0: if time_ps == 0: warnings.warn( "Timer setup with value 0, which might exhibit undefined behavior in some simulators", category=RuntimeWarning, stacklevel=2) else: raise TriggerException( "Timer value time_ps must not be negative") self.sim_steps = get_sim_steps(time_ps, units)
async def _run_clocks(self, period): half_period = get_sim_steps(period / 2.0, 'ns') t = Timer(half_period) while True: await t self.tx_clk.value = 1 self.rx_clk.value = 1 await t self.tx_clk.value = 0 self.rx_clk.value = 0
def __init__(self, time_ps, units=None): """ Args: time_ps (numbers.Real or decimal.Decimal): The time value. Note that despite the name this is not actually in picoseconds but depends on the *units* argument. units (str or None, optional): One of ``None``, ``'fs'``, ``'ps'``, ``'ns'``, ``'us'``, ``'ms'``, ``'sec'``. When no *units* is given (``None``) the timestep is determined by the simulator. Examples: >>> await Timer(100, units='ps') The time can also be a ``float``: >>> await Timer(100e-9, units='sec') which is particularly convenient when working with frequencies: >>> freq = 10e6 # 10 MHz >>> await Timer(1 / freq, units='sec') Other builtin exact numeric types can be used too: >>> from fractions import Fraction >>> await Timer(Fraction(1, 10), units='ns') >>> from decimal import Decimal >>> await Timer(Decimal('100e-9'), units='sec') These are most useful when using computed durations while avoiding floating point inaccuracies. See Also: :func:`~cocotb.utils.get_sim_steps` """ GPITrigger.__init__(self) self.sim_steps = get_sim_steps(time_ps, units)
def __init__(self, time_ps, units=None): GPITrigger.__init__(self) self.sim_steps = get_sim_steps(time_ps, units)
def __init__(self, time=None, units="step", *, time_ps=None): """ Args: time (numbers.Real or decimal.Decimal): The time value. .. versionchanged:: 1.5.0 Previously this argument was misleadingly called `time_ps`. units (str, optional): One of ``'step'``, ``'fs'``, ``'ps'``, ``'ns'``, ``'us'``, ``'ms'``, ``'sec'``. When *units* is ``'step'``, the timestep is determined by the simulator (see :make:var:`COCOTB_HDL_TIMEPRECISION`). Examples: >>> await Timer(100, units='ps') The time can also be a ``float``: >>> await Timer(100e-9, units='sec') which is particularly convenient when working with frequencies: >>> freq = 10e6 # 10 MHz >>> await Timer(1 / freq, units='sec') Other builtin exact numeric types can be used too: >>> from fractions import Fraction >>> await Timer(Fraction(1, 10), units='ns') >>> from decimal import Decimal >>> await Timer(Decimal('100e-9'), units='sec') These are most useful when using computed durations while avoiding floating point inaccuracies. See Also: :func:`~cocotb.utils.get_sim_steps` Raises: TriggerException: If a negative value is passed for Timer setup. .. versionchanged:: 1.5 Raise an exception when Timer uses a negative value as it is undefined behavior. Warn for 0 as this will cause erratic behavior in some simulators as well. .. versionchanged:: 1.5 Support ``'step'`` as the the *units* argument to mean "simulator time step". .. deprecated:: 1.5 Using None as the the *units* argument is deprecated, use ``'step'`` instead. """ GPITrigger.__init__(self) if time_ps is not None: if time is not None: raise TypeError("Gave argument to both the 'time' and deprecated 'time_ps' parameter") time = time_ps warnings.warn( "The parameter name 'time_ps' has been renamed to 'time'. Please update your invocation.", DeprecationWarning, stacklevel=2) else: if time is None: raise TypeError("Missing required argument 'time'") if time <= 0: if time == 0: warnings.warn("Timer setup with value 0, which might exhibit undefined behavior in some simulators", category=RuntimeWarning, stacklevel=2) else: raise TriggerException("Timer value time_ps must not be negative") if units is None: warnings.warn( 'Using units=None is deprecated, use units="step" instead.', DeprecationWarning, stacklevel=2) units = "step" # don't propagate deprecated value self.sim_steps = get_sim_steps(time, units)
def __init__(self, time_ps, delta_neg, delta_pos, units=None): GPITrigger.__init__(self) self.sim_steps = get_sim_steps(time_ps, units) self.delta_neg = delta_neg self.delta_pos = delta_pos
def sim_steps(self): # lazy so we don't call into the simulator until we need to return get_sim_steps(self._time_ps, self._units)