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)
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
def __init__(self, dut, debug=False): self.dut = dut self.stream_in = AvalonSTDriver(dut, "stream_in", dut.clk) self.backpressure = BitDriver(self.dut.stream_out_ready, self.dut.clk) self.stream_out = AvalonSTMonitor( dut, "stream_out", dut.clk, config={'firstSymbolInHighOrderBits': True}) self.csr = AvalonMaster(dut, "csr", dut.clk) cocotb.fork( stream_out_config_setter(dut, self.stream_out, self.stream_in)) # Create a scoreboard on the stream_out bus self.pkts_sent = 0 self.expected_output = [] with warnings.catch_warnings(): warnings.simplefilter("ignore") self.scoreboard = Scoreboard(dut) self.scoreboard.add_interface(self.stream_out, self.expected_output) # Reconstruct the input transactions from the pins # and send them to our 'model' self.stream_in_recovered = AvalonSTMonitor(dut, "stream_in", dut.clk, callback=self.model) # Set verbosity on our various interfaces level = logging.DEBUG if debug else logging.WARNING self.stream_in.log.setLevel(level) self.stream_in_recovered.log.setLevel(level)
def __init__(self, dut: cocotb.handle.HierarchyObject, num_samples): self.dut = dut self.dut._log.debug("Building/Connecting Testbench") # Sanity checks assert (self.CLOCK_FREQ_MHZ * 1e9 / fm_global.fs_rx_c).is_integer(), \ "Clock rate and fs_rx_c must have an integer relation!" self.fir_in_strobe = BitDriver(self.dut.iValDry, self.dut.iClk)
def __init__(self, dut): self.dut = dut self.clkedge = RisingEdge(dut.clk) self.stream_in = AvalonSTDriver(self.dut, "asi", dut.clk) self.stream_out = AvalonSTMonitor(self.dut, "aso", dut.clk) with warnings.catch_warnings(): warnings.simplefilter("ignore") self.scoreboard = Scoreboard(self.dut, fail_immediately=True) self.expected_output = [] self.scoreboard.add_interface(self.stream_out, self.expected_output) self.backpressure = BitDriver(self.dut.aso_ready, self.dut.clk)
def __init__(self, dut: cocotb.handle.HierarchyObject, n_sec): self.dut = dut # Sanity checks assert (self.CLOCK_FREQ_MHZ * 1e9 / fm_global.fs_rx_c).is_integer(), \ "Clock rate and fs_rx_c must have an integer relation!" # Instantiate model golden_data_directory = "../../../../../sim/matlab/verification_data/" self.model = FM_RECEIVER_MODEL(n_sec, golden_data_directory) # Connect AXI interface (IP input) self.axis_m = Axi4StreamMaster(dut, "s0_axis", dut.clk_i) # Backpressure from I2S output self.backpressure_i2s = BitDriver(dut.m0_axis_tready, dut.clk_i) # AXILite register interface self.axil_mm_m = AxiLiteMaster(AxiLiteBus.from_prefix(dut, "s_axi"), dut.clk_i, dut.rst_n_i, reset_active_level=False) # Variables self.tb_data_handler = TB_DATA_HANDLER() self.tb_analyzer_helper = TB_ANALYZER_HELPER(self.model, self.tb_data_handler, is_cocotb=True)