Example #1
0
class DFF_TB(object):
    def __init__(self, dut, init_val):
        """
        Setup the testbench.

        *init_val* signifies the ``BinaryValue`` which must be captured by the
        output monitor with the first rising clock edge.
        This must match the initial state of the D flip-flop in RTL.
        """
        # Some internal state
        self.dut = dut
        self.stopped = False

        # Create input driver and output monitor
        self.input_drv = BitDriver(signal=dut.d,
                                   clk=dut.c,
                                   generator=input_gen())
        self.output_mon = BitMonitor(name="output", signal=dut.q, clk=dut.c)

        # Create a scoreboard on the outputs
        self.expected_output = [init_val
                                ]  # a list with init_val as the first element
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            self.scoreboard = Scoreboard(dut)
        self.scoreboard.add_interface(self.output_mon, self.expected_output)

        # Use the input monitor to reconstruct the transactions from the pins
        # and send them to our 'model' of the design.
        self.input_mon = BitMonitor(name="input",
                                    signal=dut.d,
                                    clk=dut.c,
                                    callback=self.model)

    def model(self, transaction):
        """Model the DUT based on the input *transaction*.

        For a D flip-flop, what goes in at ``d`` comes out on ``q``,
        so the value on ``d`` (put into *transaction* by our ``input_mon``)
        can be used as expected output without change.
        Thus we can directly append *transaction* to the ``expected_output`` list,
        except for the very last clock cycle of the simulation
        (that is, after ``stop()`` has been called).
        """
        if not self.stopped:
            self.expected_output.append(transaction)

    def start(self):
        """Start generating input data."""
        self.input_drv.start()

    def stop(self):
        """Stop generating input data.

        Also stop generation of expected output transactions.
        One more clock cycle must be executed afterwards so that the output of
        the D flip-flop can be checked.
        """
        self.input_drv.stop()
        self.stopped = True
Example #2
0
class TB(object):
    def __init__(self, dut):
        # Some internal state
        self.dut = dut
        self.stopped = False

        # Use the input monitor to reconstruct the transactions from the pins
        # and send them to our 'model' of the design.
        self.input_mon = BitMonitor(name="input", signal=dut.Zybo_Example_sw_in, clk=dut.clk,
                                    callback=self.model)

        # Create input driver and output monitor
        self.input_drv = BitDriver(signal=dut.Zybo_Example_sw_in, clk=dut.clk, generator=input_gen())
        self.output_mon = BitMonitor(name="output", signal=dut.Zybo_Example_leds_out, clk=dut.clk)

        # Create a scoreboard on the outputs
        self.expected_output = []
        self.scoreboard = Scoreboard(dut)
        self.scoreboard.add_interface(self.output_mon, self.expected_output)

    def model(self, transaction):
        if not self.stopped:
            self.expected_output.append(transaction)

    def start(self):
        self.input_drv.start()

    def stop(self):
        self.input_drv.stop()
        self.stopped = True
Example #3
0
class DFF_TB(object):
    def __init__(self, dut, init_val):
        """
        Setup testbench.

        init_val signifies the BinaryValue which must be captured by the
        output monitor with the first risign edge. This is actually the initial 
        state of the flip-flop.
        """
        # Some internal state
        self.dut = dut
        self.stopped = False

        # Create input driver and output monitor
        self.input_drv = BitDriver(dut.d, dut.c, input_gen())
        self.output_mon = BitMonitor("output", dut.q, dut.c)
        
        # Create a scoreboard on the outputs
        self.expected_output = [ init_val ]
        self.scoreboard = Scoreboard(dut)
        self.scoreboard.add_interface(self.output_mon, self.expected_output)

        # Reconstruct the input transactions from the pins
        # and send them to our 'model'
        self.input_mon = BitMonitor("input", dut.d, dut.c,
                                    callback=self.model)

    def model(self, transaction):
        """Model the DUT based on the input transaction."""
        # Do not append an output transaction for the last clock cycle of the
        # simulation, that is, after stop() has been called.
        if not self.stopped:
            self.expected_output.append(transaction)

    def start(self):
        """Start generation of input data."""
        self.input_drv.start()

    def stop(self):
        """
        Stop generation of input data. 
        Also stop generation of expected output transactions.
        One more clock cycle must be executed afterwards, so that, output of
        D-FF can be checked.
        """
        self.input_drv.stop()
        self.stopped = True
Example #4
0
class ImpulseGeneratorTB(object):
    def __init__(self, dut):
        """
		Setup testbench.
		"""

        # Some internal state
        self.dut = dut
        self.stopped = False

        # Create input driver and output monitor
        self.input_drv = BitDriver(dut.enable, dut.clk, input_gen())
        dut.enable <= 0
        self.output_mon = BitMonitor("output", dut.impulse, dut.clk)

        # Create a scoreboard on the outputs
        self.expected_output = [BinaryValue(0, 1)]
        self.scoreboard = Scoreboard(dut)
        self.scoreboard.add_interface(self.output_mon, self.expected_output)

        # Reconstruct the input transactions from the pins
        # and send them to our 'model'
        self.input_mon = BitMonitor("input",
                                    dut.enable,
                                    dut.clk,
                                    callback=self.model)

        # Model variables
        self.triggered = False
        self.counter = 0

    @cocotb.coroutine
    def reset(self, duration=100000):
        self.dut._log.debug("Resetting DUT")
        self.dut.rst <= 1
        yield Timer(duration)
        yield RisingEdge(self.dut.clk)
        self.dut.rst <= 0
        self.dut._log.debug("Out of reset")

    def model(self, transaction):
        """ Model the DUT based on the input transaction. """
        # Do not append an output transaction for the last clock cycle of the
        # simulation, that is, after stop() has been called.
        if not self.stopped:

            print "--- PING"
            print(type(transaction))
            print(transaction.integer)

            if self.triggered:
                print "Appending 1"
                self.expected_output.append(BinaryValue(1, 1))
                self.counter = self.counter + 1
                if self.counter == 21 - 1:
                    self.triggered = False
            else:
                print "Appending 0"
                if transaction.integer == 0:
                    self.expected_output.append(BinaryValue(0, 1))
                if transaction.integer == 1:
                    self.expected_output.append(BinaryValue(1, 1))
                    self.counter = self.counter = 0
                    self.triggered = True

        # self.expected_output.append(transaction)

    def start(self):
        """Start generation of input data."""
        self.input_drv.start()

    def stop(self):
        """
		Stop generation of input data. 
		Also stop generation of expected output transactions.
		"""
        self.input_drv.stop()
        self.stopped = True