def add_clock(self, period, *, phase=None, domain="sync", if_exists=False):
        """Add a clock to the simulation.

        Adds a stimulus that toggles the clock signal of :py:`domain` at a 50% duty cycle.

        The driven clock signal will toggle every half-:py:`period` seconds starting at :py:`phase`
        seconds after the beginning of the simulation; if not specified, :py:`phase` defaults to
        half-:py:`period` to avoid coinciding the first active edge with the beginning of
        the simulation.

        The clock domain to drive is selected by the :py:`domain` argument, which may be
        a :class:`~amaranth.hdl.ClockDomain` object or a :class:`str`. If it is a string,
        the clock domain with that name is retrieved from the :py:`toplevel` elaboratable.

        Raises
        ------
        :exc:`NameError`
            If :py:`domain` is a :class:`str`, the :py:`toplevel` elaboratable does not have
            a clock domain with that name, and :py:`if_exists` is :py:`False`.
        :exc:`~amaranth.hdl.DriverConflict`
            If :py:`domain` already has a clock driving it.
        :exc:`RuntimeError`
            If the simulation has been advanced since its creation or last reset.
        """
        if self._running:
            raise RuntimeError(r"Cannot add a clock to a running simulation")
        if isinstance(domain, ClockDomain):
            if (domain.name in self._design.fragment.domains and
                    domain is not self._design.fragment.domains[domain.name]):
                warnings.warn(
                    f"Adding a clock that drives a clock domain object named {domain.name!r}, "
                    f"which is distinct from an identically named domain in the simulated design",
                    UserWarning, stacklevel=2)
        elif domain in self._design.fragment.domains:
            domain = self._design.fragment.domains[domain]
        elif if_exists:
            return
        else:
            raise NameError(f"Domain {domain!r} is not present in simulation")
        if domain in self._clocked:
            raise DriverConflict(f"Domain {domain.name!r} already has a clock driving it")

        if not isinstance(period, Period):
            # TODO(amaranth-0.7): remove
            warnings.warn(
                f"Per RFC 66, the `period` argument of `add_clock()` will only accept a `Period`"
                f" in the future.",
                DeprecationWarning, stacklevel=1)
            period = Period(s=period)

        if phase is None:
            phase = period / 2
        elif not isinstance(phase, Period):
            # TODO(amaranth-0.7): remove
            warnings.warn(
                f"Per RFC 66, the `phase` argument of `add_clock()` will only accept a `Period`"
                f" (or `None`) in the future.",
                DeprecationWarning, stacklevel=1)
            phase = Period(s=phase)

        self._engine.add_clock_process(domain.clk, phase=phase.femtoseconds, period=period.femtoseconds)
        self._clocked.add(domain)
Add a clock to the simulation.

        Adds a stimulus that toggles the clock signal of :py:`domain` at a 50% duty cycle.

        The driven clock signal will toggle every half-:py:`period` seconds starting at :py:`phase`
        seconds after the beginning of the simulation; if not specified, :py:`phase` defaults to
        half-:py:`period` to avoid coinciding the first active edge with the beginning of
        the simulation.

        The clock domain to drive is selected by the :py:`domain` argument, which may be
        a :class:`~amaranth.hdl.ClockDomain` object or a :class:`str`. If it is a string,
        the clock domain with that name is retrieved from the :py:`toplevel` elaboratable.

        Raises
        ------
        :exc:`NameError`
            If :py:`domain` is a :class:`str`, the :py:`toplevel` elaboratable does not have
            a clock domain with that name, and :py:`if_exists` is :py:`False`.
        :exc:`~amaranth.hdl.DriverConflict`
            If :py:`domain` already has a clock driving it.
        :exc:`RuntimeError`
            If the simulation has been advanced since its creation or last reset.
        
amaranth/sim/core.py