def add_testbench(self, constructor, *, background=False):
        """Add a testbench to the simulation.

        Adds a testbench that runs concurrently with the :py:`toplevel` elaboratable and is able to
        manipulate its inputs, outputs, and state.

        The behavior of the testbench is defined by its *constructor function*, which is
        an :py:`async` function that takes a single argument, the :class:`SimulatorContext`: ::

            async def testbench(ctx):
                ...
                await ctx.tick()
                ...

            sim.add_testbench(testbench)

        This method does not accept coroutines. Rather, the provided :py:`constructor` coroutine
        function is called immediately when the testbench is added to create a coroutine, as well as
        by the :meth:`reset` method.

        The testbench can be *critical* (the default) or *background* (if the :py:`background=True`
        argument is specified). The :meth:`run` method will continue advancing the simulation while
        any critical testbenches or processes are running, and will exit when only background
        testbenches or processes remain. A background testbench can temporarily become critical
        using the :meth:`~SimulatorContext.critical` context manager.

        At each point in time, all of the non-waiting testbenches are executed in the order in
        which they were added. If two testbenches share state, or must manipulate the design in
        a coordinated way, they may rely on this execution order for correctness.

        Raises
        ------
        :exc:`RuntimeError`
            If the simulation has been advanced since its creation or last reset.
        """
        if self._running:
            raise RuntimeError(r"Cannot add a testbench to a running simulation")
        constructor = self._check_function(constructor, kind="testbench")
        if inspect.iscoroutinefunction(constructor):
            self._engine.add_async_testbench(self, constructor, background=background)
        else:
            # TODO(amaranth-0.6): remove
            warnings.warn(
                f"Generator-based testbenches are deprecated per RFC 36. Use async "
                f"testbenches instead.",
                DeprecationWarning, stacklevel=1)
            constructor = coro_wrapper(constructor, testbench=True)
            self._engine.add_async_testbench(self, constructor, background=background)
Add a testbench to the simulation.

        Adds a testbench that runs concurrently with the :py:`toplevel` elaboratable and is able to
        manipulate its inputs, outputs, and state.

        The behavior of the testbench is defined by its *constructor function*, which is
        an :py:`async` function that takes a single argument, the :class:`SimulatorContext`: ::

            async def testbench(ctx):
                ...
                await ctx.tick()
                ...

            sim.add_testbench(testbench)

        This method does not accept coroutines. Rather, the provided :py:`constructor` coroutine
        function is called immediately when the testbench is added to create a coroutine, as well as
        by the :meth:`reset` method.

        The testbench can be *critical* (the default) or *background* (if the :py:`background=True`
        argument is specified). The :meth:`run` method will continue advancing the simulation while
        any critical testbenches or processes are running, and will exit when only background
        testbenches or processes remain. A background testbench can temporarily become critical
        using the :meth:`~SimulatorContext.critical` context manager.

        At each point in time, all of the non-waiting testbenches are executed in the order in
        which they were added. If two testbenches share state, or must manipulate the design in
        a coordinated way, they may rely on this execution order for correctness.

        Raises
        ------
        :exc:`RuntimeError`
            If the simulation has been advanced since its creation or last reset.
        
amaranth/sim/core.py