def test_failure_from_system_task(dut): """Allow the dut to call $fail_test() from verilog""" clock = Clock(dut.clk, 100) clock.start() coro = cocotb.fork(clock_mon(dut)) extern = cocotb.fork(run_external(dut)) yield Timer(10000000)
def Wavedrom_test(dut): # Setting up clocks clk_100MHz = Clock(dut.clk, c_CLK_PERIOD, units='ns') cocotb.fork(clk_100MHz.start(start_high=False)) axi_aclk_100MHz = Clock(dut.axi_aclk, c_CLK_PERIOD, units='ns') cocotb.fork(axi_aclk_100MHz.start(start_high=False)) # AXI-Lite Master object axil_m = AXI4LiteMaster(dut, "s_axi", dut.axi_aclk) # Setting init values dut.reset <= 1 dut.Zybo_Example_sw_in <= 4 dut.Zybo_Example_bt_in <= 0 dut.axi_aresetn <= 0 # Wait one cycle and deactivate resets yield Timer(c_CLK_PERIOD, units='ns') dut.reset <= 0 dut.axi_aresetn <= 1 yield Timer(c_CLK_PERIOD, units='ns') # AXI-Lite write yield axil_m.write(c_BASEADDRESS+c_COUNT_OFFSET, 0x00000001) yield Timer(c_CLK_PERIOD, units='ns') # Wavedrom args = [dut.Zybo_Example_sw_in, dut.Zybo_Example_leds_out, dut.Zybo_Example_leds_rgb_out] with trace(*args, clk=dut.clk) as waves: yield ClockCycles(dut.clk, 12) dut._log.info(waves.dumpj(header = {'text':'WaveDrom example', 'tick':0})) waves.write('wavedrom.json', header = {'tick':0}, config = {'hscale':3})
async def test_all(dut): clock_w = Clock(dut.i_wclk, 10, units="us") clock_r = Clock(dut.i_rclk, 20, units="us") cocotb.fork(clock_w.start()) cocotb.fork(clock_r.start()) await reset(dut) dut.i_winc <= 1 data = 0 for i in range(20): data = data + 1 dut.i_wdata <= data await ClockCycles(dut.i_wclk, 1) dut.i_winc <= 0 await ClockCycles(dut.i_wclk, 5) dut.i_rinc <= 1 for i in range(20): await ClockCycles(dut.i_rclk, 1) dut.i_rinc <= 0 await ClockCycles(dut.i_rclk, 5)
async def new(dut): rx_clock = Clock(dut.rx_clk, 10, units='us') tx_clock = Clock(dut.tx_clk, 10, units='us') cocotb.fork(rx_clock.start()) cocotb.fork(tx_clock.start()) # Ensure the bus is in a known and quiet state before starting the monitors await Thing.reset(dut) return Thing(dut)
def test_clock_with_units(dut): clk_1mhz = Clock(dut.clk, 1.0, units='us') clk_250mhz = Clock(dut.clk, 4.0, units='ns') if str(clk_1mhz) != "Clock(1.0 MHz)": raise TestFailure("{} != 'Clock(1.0 MHz)'".format(str(clk_1mhz))) else: dut._log.info('Created clock >{}<'.format(str(clk_1mhz))) if str(clk_250mhz) != "Clock(250.0 MHz)": raise TestFailure("{} != 'Clock(250.0 MHz)'".format(str(clk_250mhz))) else: dut._log.info('Created clock >{}<'.format(str(clk_250mhz))) clk_gen = cocotb.fork(clk_1mhz.start()) start_time_ns = get_sim_time(units='ns') yield Timer(1) yield RisingEdge(dut.clk) edge_time_ns = get_sim_time(units='ns') if not isclose(edge_time_ns, start_time_ns + 1000.0): raise TestFailure("Expected a period of 1 us") start_time_ns = edge_time_ns yield RisingEdge(dut.clk) edge_time_ns = get_sim_time(units='ns') if not isclose(edge_time_ns, start_time_ns + 1000.0): raise TestFailure("Expected a period of 1 us") clk_gen.kill() clk_gen = cocotb.fork(clk_250mhz.start()) start_time_ns = get_sim_time(units='ns') yield Timer(1) yield RisingEdge(dut.clk) edge_time_ns = get_sim_time(units='ns') if not isclose(edge_time_ns, start_time_ns + 4.0): raise TestFailure("Expected a period of 4 ns") start_time_ns = edge_time_ns yield RisingEdge(dut.clk) edge_time_ns = get_sim_time(units='ns') if not isclose(edge_time_ns, start_time_ns + 4.0): raise TestFailure("Expected a period of 4 ns") clk_gen.kill()
async def test_project_7(dut): # wb clock clock = Clock(dut.wb_clk_i, 10, units="us") cocotb.fork(clock.start()) # drive a 5 MHz clock on gpio35 dut_clk = Clock(dut.io_in[35], 200, units="ns") cocotb.fork(dut_clk.start()) await reset(dut) project_number = 7 await wishbone_write(dut, ADDR_PROJECT, project_number) assert dut.active_project == project_number await ClockCycles(dut.proj_7.clock, 150) for i in range(8, 24): dut.io_in[i] <= 1 dut.io_in[36] <= 0 dut.io_in[24] <= 0 await ClockCycles(dut.proj_7.clock, 20) dut.io_in[36] <= 1 await ClockCycles(dut.proj_7.clock, 20) dut.io_in[36] <= 0 for i in range(100): dut.io_in[24] <= 1 await ClockCycles(dut.proj_7.clock, 1) #1 / 19 dut.io_in[24] <= 0 await ClockCycles(dut.proj_7.clock, 1) #2 / 20 assert dut.io_out[33] == True #hSync if i == 31 or i == 63 or i == 95: assert dut.io_out[34] == True #vSync for i in range(15): await ClockCycles(dut.proj_7.clock, 1) #3-18 / 21-36 assert dut.io_out[33] == False #hSync #await ClockCycles(dut.proj_7.clock, 1) #for i in range(32): #dut.io_in[24] <= 1 #await ClockCycles(dut.proj_7.clock, 1) #dut.io_in[24] <= 0 #await ClockCycles(dut.proj_7.clock, 15) #assert dut.io_out[33] == True #hSync #assert dut.io_out[34] == True #vSync await ClockCycles(dut.proj_7.clock, 100)
async def test_edge_detect_sync(dut): clock_slow = Clock(dut.clk_slow, 10, units="ns") clock_fast = Clock(dut.clk_fast, 6, units="ns") cocotb.fork(clock_fast.start()) cocotb.fork(clock_slow.start()) await RisingEdge(dut.clk_slow) for i in range(20): val = random.randint(0, 1) dut.data <= val await RisingEdge(dut.clk_slow)
async def test_clock_with_units(dut): clk_1mhz = Clock(dut.clk, 1.0, units='us') clk_250mhz = Clock(dut.clk, 4.0, units='ns') assert str(clk_1mhz) == "Clock(1.0 MHz)" dut._log.info('Created clock >{}<'.format(str(clk_1mhz))) assert str(clk_250mhz) == "Clock(250.0 MHz)" dut._log.info('Created clock >{}<'.format(str(clk_250mhz))) clk_gen = cocotb.fork(clk_1mhz.start()) start_time_ns = get_sim_time(units='ns') await Timer(1, "ns") await RisingEdge(dut.clk) edge_time_ns = get_sim_time(units='ns') assert isclose(edge_time_ns, start_time_ns + 1000.0), "Expected a period of 1 us" start_time_ns = edge_time_ns await RisingEdge(dut.clk) edge_time_ns = get_sim_time(units='ns') assert isclose(edge_time_ns, start_time_ns + 1000.0), "Expected a period of 1 us" clk_gen.kill() clk_gen = cocotb.fork(clk_250mhz.start()) start_time_ns = get_sim_time(units='ns') await Timer(1, "ns") await RisingEdge(dut.clk) edge_time_ns = get_sim_time(units='ns') assert isclose(edge_time_ns, start_time_ns + 4.0), "Expected a period of 4 ns" start_time_ns = edge_time_ns await RisingEdge(dut.clk) edge_time_ns = get_sim_time(units='ns') assert isclose(edge_time_ns, start_time_ns + 4.0), "Expected a period of 4 ns" clk_gen.kill()
def Zybo_Example_test(dut): # Setting up clocks clk_100MHz = Clock(dut.clk, c_CLK_PERIOD, units='ns') cocotb.fork(clk_100MHz.start(start_high=False)) axi_aclk_100MHz = Clock(dut.axi_aclk, c_CLK_PERIOD, units='ns') cocotb.fork(axi_aclk_100MHz.start(start_high=False)) # Setting init values dut.reset = 1 dut.Zybo_Example_sw_in = 0 dut.Zybo_Example_bt_in = 0 dut.axi_aresetn = 0 # AXI-Lite Master object axil_m = AXI4LiteMaster(dut, "s_axi", dut.axi_aclk) # tb tb=TB(dut) tb.start() # Wait one cycle and deactivate resets yield Timer(c_CLK_PERIOD, units='ns') dut.reset <= 0 dut.axi_aresetn <= 1 yield Timer(c_CLK_PERIOD, units='ns') # AXI-Lite read VERSION dut._log.info("AXI-Lite: Reading address 0x%02X" % (c_BASEADDRESS+c_VERSION_OFFSET)) s_value_read = yield axil_m.read(c_BASEADDRESS+c_VERSION_OFFSET) # Check check(dut, s_value_read, c_VERSION_VALUE) # AXI-Lite read CONFIG_ID dut._log.info("AXI-Lite: Reading address 0x%02X" % (c_BASEADDRESS+c_CONFIG_ID_OFFSET)) s_value_read = yield axil_m.read(c_BASEADDRESS+c_CONFIG_ID_OFFSET) # Check check(dut, s_value_read, c_CONFIG_ID_VALUE) # AXI-Lite read COUNT dut._log.info("AXI-Lite: Reading address 0x%02X" % (c_BASEADDRESS+c_COUNT_OFFSET)) s_value_read = yield axil_m.read(c_BASEADDRESS+c_COUNT_OFFSET) # Check check(dut, s_value_read, c_COUNT_VALUE) # AXI-Lite write yield axil_m.write(c_BASEADDRESS+c_COUNT_OFFSET, 0x00000001) yield Timer(c_CLK_PERIOD, units='ns') # end tb tb.stop()
def fsm_test(dut): # Setting up clocks clk_100MHz = Clock(dut.clk, c_CLK_PERIOD, units='ns') cocotb.fork(clk_100MHz.start(start_high=False)) # Setting init values dut.reset = 1 dut.fsm_in_0 = 0 dut.fsm_in_1 = 0 # Wait one cycle and deactivate reset yield Timer(c_CLK_PERIOD, units='ns') dut.reset <= 0 yield Timer(2*c_CLK_PERIOD, units='ns') assert dut.fsm_out_0 == 1 and dut.fsm_out_1 == 0, "FREE_MODE wrong" dut.fsm_in_0 <= 1 yield Timer(2*c_CLK_PERIOD, units='ns') assert dut.fsm_out_0 == 0 and dut.fsm_out_1 == 1, "FIXED_MODE wrong" dut.fsm_in_1 <= 1 yield Timer(c_CLK_PERIOD, units='ns') dut.fsm_in_0 <= 0 yield Timer(c_CLK_PERIOD, units='ns') assert dut.fsm_out_0 == 1 and dut.fsm_out_1 == 0, "FREE_MODE wrong" yield Timer(4*c_CLK_PERIOD, units='ns') dut.reset <= 1 dut.fsm_in_1 <= 0 yield Timer(2*c_CLK_PERIOD, units='ns') assert dut.fsm_out_0 == 0 and dut.fsm_out_1 == 0, "IDLE wrong" yield Timer(3*c_CLK_PERIOD, units='ns')
async def test_project_1(dut): clock = Clock(dut.wb_clk_i, 10, units="us") cocotb.fork(clock.start()) await reset(dut) # activate design 1 project_number = 1 await wishbone_write(dut, ADDR_PROJECT, project_number) assert dut.active_project == project_number # use external gpio as reset dut.la_data_in[0] <= 1 await ClockCycles(dut.wb_clk_i, 5) dut.la_data_in[0] <= 0 # setup a colour for some leds led_num = 7 r = 255 g = 10 b = 100 await wishbone_write(dut, ADDR_WS2812, (led_num << 24) + (r << 16) + (g << 8) + b) # wait some cycles await ClockCycles(dut.wb_clk_i, 500)
async def test_all(dut): clock_mhz = 12 clk_period_ns = round(1/clock_mhz * 1000, 2) dut.log.info("input clock = %d MHz, period = %.2f ns" % (clock_mhz, clk_period_ns)) clock = Clock(dut.clk, clk_period_ns, units="ns") cocotb.fork(clock.start()) await reset(dut) # adjust the update period to match clock freq period = clock_mhz * 100 - 1 await update_period(dut, period) for input_freq in [10, 69, 90]: # create an input signal period_us = round((1/input_freq) * 100, 2) dut.log.info("input freq = %d kHz, period = %.2f us" % (input_freq, period_us)) input_signal = cocotb.fork(Clock(dut.signal, period_us, units="us").start()) # give it 3 update periods to allow counters to adjust await ClockCycles(dut.clk, period * 3) assert await read_segments(dut) == input_freq # kill signal input_signal.kill()
class ChisNesPadTest(object): """ """ LOGLEVEL = logging.INFO PERIOD = (20, "ns") SUPER_NES_LEN = 16 NES_LEN = 8 def __init__(self, dut, reg_init_value=0xcafe, reg_len=16): if sys.version_info[0] < 3: raise Exception("Must be using Python 3") self._dut = dut self._dut._log.setLevel(self.LOGLEVEL) self.log = SimLog("ChisNesPad.{}".format(self.__class__.__name__)) self.log.setLevel(self.LOGLEVEL) self.reg_init_value = reg_init_value self._reg = reg_init_value self._reg_count = reg_len self._reg_len = reg_len self.clock = Clock(self._dut.clock, self.PERIOD[0], self.PERIOD[1]) self._clock_thread = cocotb.fork(self.clock.start()) self._register_thread = cocotb.fork(self._register()) @cocotb.coroutine def reset(self): short_per = Timer(100, units="ns") self._dut.reset <= 1 self._dut.io_sdata <= 0 self._dut.io_data_ready <= 0 yield short_per self._dut.reset <= 1 yield short_per self._dut.reset <= 0 yield short_per @cocotb.coroutine def _register(self): while True: try: dlatch = int(self._dut.io_dlatch) except ValueError: dlatch = 1 if dlatch != 0: yield FallingEdge(self._dut.io_dlatch) self._reg = self.reg_init_value self._reg_count = self._reg_len sdata_bit = (self.reg_init_value & (0x1 << (self._reg_len - 1))) >> (self._reg_len - 1) self._dut.io_sdata <= sdata_bit else: sdata_bit = self._reg & (0x1 << (self._reg_len - 1)) self._dut.io_sdata <= (sdata_bit != 0) if self._reg_count != 0: self._reg = (self._reg << 1) yield [ RisingEdge(self._dut.io_dclock), RisingEdge(self._dut.io_dlatch) ]
async def test_array_buses(dut): clock = Clock(dut.clk, 10, units="ns") cocotb.fork(clock.start()) clkedge = RisingEdge(dut.clk) in_data_0 = TestDriver(dut, "in", dut.clk, array_idx=0) in_data_1 = TestDriver(dut, "in", dut.clk, array_idx=1) out_data_0 = TestMonitor(dut, "in", dut.clk, array_idx=0, bank=0) out_data_1 = TestMonitor(dut, "in", dut.clk, array_idx=1, bank=1) out_data_0.add_expected(10) out_data_0.add_expected(30) out_data_1.add_expected(20) out_data_1.add_expected(40) await in_data_0.send(10) await clkedge await in_data_1.send(20) await clkedge await in_data_0.send(30) await clkedge await in_data_1.send(40) await clkedge await clkedge assert not out_data_0.expected assert not out_data_1.expected
async def oneloop(dut): """perf oneloop test""" t = TicToc() tb = settings() await reset(dut) clkobj = Clock(dut.clk, tb.period, 'us') cocotb.fork(clkobj.start()) t.tic() k = 0 for cycle in range(tb.dinArate * tb.npoints): await (RisingEdge(dut.clk)) if (cycle % tb.dinArate) == 0: k = k + 1 dut.dinA <= 1 if (k % 100 == 0): dut._log.info("Sim progress...{} %".format( int(100 * float(k) / tb.npoints))) else: dut.dinA <= 0 if (cycle % tb.dinBrate) == 0: dut.dinB <= 1 else: dut.dinB <= 0 t.toc() print(t.elapsed)
def filterTest(dut): # Set up the clock fs = 2e6 # Hz # Generate the test waveforms Stimulus = FilterAnaylserFunctions.WhiteNoiseGen(fs, 18) # START Test n_Reset = dut.n_Reset dut.data_i.value = 0 # Create a clock from which we start everything c = Clock(dut.clk, fs, "ns") cocotb.fork(c.start()) clkedge = RisingEdge(dut.clk) # This will call reset_dut sequentially # Execution will block until reset_dut has completed yield reset_dut(n_Reset, 1000) dut._log.debug("Post reset") inputSignal = [] Output = [] # Wait for the clock edge for i in range(len(Stimulus)): yield clkedge inputSignal.append(Stimulus[i]) dut.data_i.value = int(Stimulus[i]) Output.append(dut.data_o.value.signed_integer) print("Applied signal now plotting.") FilterAnaylserFunctions.fft(Output, fs, 1028)
async def main(dut): """ Test Rectified Linear Unit """ # Create a 10us period clock on port clk clock = Clock(dut.clk_i, 10, units="us") cocotb.fork(clock.start()) # Reset system await FallingEdge(dut.clk_i) dut.rst_n_i <= 0 dut.en_i <= 0 dut.data_i <= 0 dut.valid_i <= 0 dut.last_i <= 0 # reset await FallingEdge(dut.clk_i) dut.rst_n_i <= 1 # test 1 dut.en_i <= 1 await check_output(dut) # test 2 dut.en_i <= 0 await check_output_no_en(dut) # test 3 dut.en_i <= 1 for i in range(20): await check_output(dut)
async def test_pid(dut): """ Test dividing two fixed point numbers """ simsteps = 200 clock = Clock(dut.i_clk, 10, units="ns") # Create a 10us period clock on port clk cocotb.fork(clock.start()) # Start the clock mass_spring = get_wheel() pts = [mass_spring.x[0]] print(f"Terms: {dut.kP} {dut.kI} {dut.kD}") curpoint = pts[0] for i in range(simsteps): dut.i_curpoint <= cvt_fixed(curpoint, QBITS) dut.i_setpoint <= cvt_fixed(0, QBITS) await Timer(1) await RisingEdge(dut.i_clk) print(f"error {cvt_float(dut.error.value.signed_integer, QBITS)}, deriv: {cvt_float(dut.deriv.value.signed_integer, QBITS)}") print(f"error {dut.error.value}, deriv: {dut.deriv.value}") print(f"output {dut.o_out.value} curpoint: {curpoint}") output = cvt_float(dut.o_out.value.signed_integer, QBITS) print(f"converted output: {output}") print("") curpoint = mass_spring.step(0.1, output)[0] pts.append(curpoint) forceless = get_forceless_sim(simsteps) plt.plot(forceless, label="forceless") plt.plot(pts, label="controlled") plt.legend() plt.show()
async def test_c2h_dma_pressure(dut): """Test C2H DMA pressure.""" clock = Clock(dut.clk, 10, units='ns') cocotb.fork(clock.start()) tb = TestC2H(dut) channel = 2 await tb.reset() # my_id_valid is not high yet so the first packet will be missed, which # is an accident in this testbench, but a behavior we want to test so # it has been incorporated for now. See if i > 1 down below. for i in range(30): payload = bytearray() for j in range(10 * 4): payload.append(j % 256) payload = bytes(payload) header = int.to_bytes(0x4 + ((len(payload) // 4) << 4) + (channel << 14), length=4, byteorder='big') header = header + bytes(12) if i > 0: # See comment above for explaination tb.expect_memwrite(DMA_WND_START + 4096 * ((i-1) % DMA_WND_SIZE), header + endian_swap(payload)) await with_timeout(tb.data_tx.send(payload, channel=channel), 1000, 'ns') await RisingEdge(dut.clk) cntr = await tb.csr.read(0x6) # csr_c2h_staging_counter assert cntr == i + 1, 'expected csr_c2h_staging_counter to be incremented to %s' % (i + 1, ) await Timer(1000, 'ns') raise tb.scoreboard.result
async def test_relu(dut): """ Test Rectified Linear Unit """ # Create a 10us period clock on port clk clock = Clock(dut.clk_i, 10, units="us") cocotb.fork(clock.start()) # Reset system await FallingEdge(dut.clk_i) dut.rst_n_i <= 0 dut.data_i <= 0 dut.last_i <= 0 dut.valid_i <= 0 dut.ready_i <= 0 await FallingEdge(dut.clk_i) dut.rst_n_i <= 1 dut.ready_i <= 1 # Generate random values and compare results await FallingEdge(dut.clk_i) for _ in range(10): val = random.randint(-2 ** 31, 2 ** 31 - 1) dut.data_i <= val dut.valid_i <= 1 expected = max(0, val) await FallingEdge(dut.clk_i) observed = dut.data_o.value assert observed == expected,\ "expected = %d, observed = %d" % (expected, observed)
async def main(dut): """ Test Rectified Linear Unit """ # Create a 10us period clock on port clk clock = Clock(dut.clk_i, 10, units="us") cocotb.fork(clock.start()) # Reset system await FallingEdge(dut.clk_i) dut.rst_n_i <= 0 dut.en_i <= 0 dut.data_i <= 0 dut.valid_i <= 0 # reset await FallingEdge(dut.clk_i) dut.rst_n_i <= 1 # test 1 dut.en_i <= 1 x, y = get_test_vector() cocotb.fork(write_input(dut, x)) await check_output(dut, y) # test 2 dut.en_i <= 0 await check_output_no_en(dut) # test 3 dut.en_i <= 1 x, y = get_test_vector() cocotb.fork(write_input(dut, x)) await check_output(dut, y)
async def test_debouncer(dut): clock = Clock(dut.clk, 10, units="us") clocks_per_phase = 10 switch = BouncingSwitch(dut) cocotb.fork(clock.start()) await reset(dut) assert dut.debounced.value == 0 # toggle button 10 times for i in range(10): # set the switch, which will bounce await switch.set(1) # assert still low assert dut.debounced.value == 0 # wait 8 clock cycles (default history length in debounce.v) + 1 for register await ClockCycles(dut.clk, 9) # assert button is as set assert dut.debounced.value == 1 # same for off await switch.set(0) # assert still high assert dut.debounced.value == 1 # wait 8 clock cycles (default history length in debounce.v) + 1 for register await ClockCycles(dut.clk, 9) assert dut.debounced.value == 0
async def test_load(dut): clock = Clock(dut.clk, 10, units="us") cocotb.fork(clock.start()) await reset(dut) for period in range(0, 2000, 100): await update_period(dut, period) assert dut.update_period == period
async def run_test(dut, codec=0x12, data_in=None, backpressure_inserter=None): dut._log.info(f"Init testbench with codec={codec}") dut.m_axis_tready <= 0 #dut._log.setLevel(logging.DEBUG) """ Setup testbench and run a test. """ clock = Clock(dut.axis_aclk, 10, units="ns") # Create a 10ns period clock on port clk cocotb.fork(clock.start()) # Start the clock tb = HcuTb(dut, codec) await tb.reset() dut.m_axis_tready <= 1 if backpressure_inserter is not None: tb.backpressure.start(backpressure_inserter()) dut._log.info('Send Wt parsed from message') # Send in the packets for transaction in format_wt(codec): tb.s_axis.bus.tuser <= BinaryValue(80*'0'+little_endian_codec(codec)+32*'0') #transaction = format_wt_message(transaction, sha_type=sha_type) await tb.s_axis.send(transaction) dut._log.info('Wait for last outgoing transaction to be monitored') # Wait for last transmission while not (dut.m_axis_tlast.value and dut.m_axis_tvalid.value and dut.m_axis_tready.value): await RisingEdge(dut.axis_aclk) for _ in range(3): await RisingEdge(dut.axis_aclk) dut._log.info("DUT testbench finished!") raise tb.scoreboard.result
async def run_test(dut, codec=0x12, data_in=None, backpressure_inserter=None): dut.m_axis_tready <= 0 #dut.log.setLevel(logging.DEBUG) """ Setup testbench and run a test. """ clock = Clock(dut.axis_aclk, 10, units="ns") # Create a 10ns period clock on port clk cocotb.fork(clock.start()) # Start the clock tb = HashEngineTB(dut, codec, False) # Debug=False await tb.reset() dut.m_axis_tready <= 1 if backpressure_inserter is not None: tb.backpressure.start(backpressure_inserter()) # Send in the packets for transaction in data_in(): tb.s_axis.bus.tuser <= BinaryValue(80 * '0' + little_endian_codec(codec) + 32 * '0') await tb.s_axis.send(transaction) # Wait for all transactions to be received wait_transac = True while (wait_transac): await RisingEdge(dut.axis_aclk) wait_transac = False for monitor, expected_output in tb.scoreboard.expected.items(): if (len(expected_output)): wait_transac = True dut._log.info("DUT testbench finished!") raise tb.scoreboard.result
async def run_test(dut, data_in=None, codec=None, backpressure_inserter=None): dut.m_axis_tready <= 0 #dut.log.setLevel(logging.DEBUG) """ Setup testbench and run a test. """ clock = Clock(dut.axis_aclk, 10, units="ns") # Create a 10ns period clock on port clk cocotb.fork(clock.start()) # Start the clock tb = PadderTB(dut, codec, False) # Debug=False await tb.reset() dut.m_axis_tready <= 1 if backpressure_inserter is not None: tb.backpressure.start(backpressure_inserter()) # Send in the packets for transaction in data_in(): tb.s_axis.bus.tuser <= BinaryValue(80 * '0' + little_endian_codec(codec) + 32 * '0') await tb.s_axis.send(transaction, tuser=get_bytes(16, random_data())) # Wait for last transmission await RisingEdge(dut.axis_aclk) while not (dut.m_axis_tlast.value and dut.m_axis_tvalid.value and dut.m_axis_tready.value): await RisingEdge(dut.axis_aclk) for _ in range(3): await RisingEdge(dut.axis_aclk) dut._log.info("DUT testbench finished!") raise tb.scoreboard.result
async def ScanChainTestFull(dut): # = = = = = = = Get Design Variable = = = = = = = = = = = = = = = = = PConf = getConfig() clk = getFromPinAlias(dut, "clk") prog_clk = getFromPinAlias(dut, "prog_clk") pReset = getFromPinAlias(dut, "pReset") Reset = getFromPinAlias(dut, "Reset") test_en = getFromPinAlias(dut, "test_en") sc_head = getFromPinAlias(dut, "sc_head") sc_tail = getFromPinAlias(dut, "sc_tail") CLK_PERIOD = 10 # in nanoseconds # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = prog_clk <= 0 # Disable prog clock pReset <= 0 # Disable programming reset Reset <= 0 # Disable reset clock = Clock(clk, CLK_PERIOD*0.5, units="ns") cocotb.fork(clock.start()) # Start the clock # Clock Preamble Ticks 2 await ClockCycles(clk, 2) # Setup control signals await FallingEdge(clk) test_en <= 1 Reset <= 1 # Pass 1 bit logic to SCFF chain sc_head <= 1 await FallingEdge(clk) sc_head <= 0 try: start_scff_time = get_sim_time(units='ns') for X in range(1, 1+PConf["FPGA_SIZE_X"]): Yrange = range(1, 1+PConf["FPGA_SIZE_X"]) Yrange = reversed(Yrange) if (X % 2) else Yrange for Y in Yrange: ModuleName = f"grid_clb_{X}__{Y}_" PinName = "SC_OUT_BOT" if (X % 2) else "SC_OUT_TOP" InstPtr = eval(f"dut.fpga_core_uut.{ModuleName}.{PinName}") # Wait for tick start_time_ns = get_sim_time(units='ns') await with_timeout(FallingEdge(InstPtr), 50*CLK_PERIOD, 'ns') edge_time_ns = get_sim_time(units='ns') # Verify CLKTick = math.ceil((edge_time_ns-start_time_ns)/CLK_PERIOD) dut._log.info( f"Signal received at {ModuleName} at {CLKTick}") if (CLKTick != 8): TestFailure( f"Expected 8 ticks on module {ModuleName} received {CLKTick}") end_scff_time = get_sim_time(units='ns') TotalClock = math.ceil((end_scff_time-start_scff_time)/CLK_PERIOD) await ClockCycles(clk, 10) dut._log.info(f"Simulation Finished in clocks {TotalClock}") dut._log.info(f"Per Grid {TotalClock/(PConf['FPGA_SIZE_X']**2)}") except SimTimeoutError: raise TestFailure(f"Failed to receive signal on {ModuleName}")
async def test_analog_model(digital) -> None: """Exercise an Analog Front-end and its digital controller.""" clock = Clock(digital.clk, 1, units="us") # create a 1us period clock on port clk cocotb.start_soon(clock.start()) # start the clock afe_in_queue = Queue() afe_out_queue = Queue() afe = AFE(in_queue=afe_in_queue, out_queue=afe_out_queue) # instantiate the analog front-end cocotb.start_soon(gain_select(digital, afe)) for in_V in [0.1, 0.1, 0.0, 0.25, 0.25]: # set the input voltage await afe_in_queue.put(in_V) # get the converted digital value afe_out = await afe_out_queue.get() digital._log.info( f"AFE converted input value {in_V}V to {int(afe_out)}") # hand digital value over as "meas_val" to digital part (HDL) # "meas_val_valid" pulses for one clock cycle await RisingEdge(digital.clk) digital.meas_val.value = afe_out digital.meas_val_valid.value = 1 await RisingEdge(digital.clk) digital.meas_val_valid.value = 0 await Timer(3.3, "us")
async def run_c2h_dma_test(dut, dwords, channel): """Test C2H DMA.""" clock = Clock(dut.clk, 10, units='ns') cocotb.fork(clock.start()) tb = TestC2H(dut) await tb.reset() # Wait for my_id_valid await Timer(100, 'ns') payload = bytearray() for i in range(dwords * 4): payload.append(i % 256) payload = bytes(payload) header = int.to_bytes(0x4 + ((len(payload) // 4) << 4) + (channel << 14), length=4, byteorder='big') header = header + bytes(12) # TODO: Fragmentation is not implemented, so expect truncated packets tb.expect_memwrite(DMA_WND_START, header + endian_swap(payload[:224])) await with_timeout(tb.data_tx.send(payload, channel=channel), 1000, 'ns') await RisingEdge(dut.clk) cntr = await tb.csr.read(0x6) # csr_c2h_staging_counter assert cntr == 1, 'expected csr_c2h_staging_counter to be incremented to 1' await Timer(1000, 'ns') assert tb.dut.irq_c2h_avail == 1, 'expected irq_c2h_avail to be high' wptr = await tb.csr.read(0x2b) # c2h_dma_card_write_ptr await tb.csr.write(0x2a, wptr) # c2h_dma_host_read_ptr await Timer(100, 'ns') assert tb.dut.irq_c2h_avail == 0, 'expected irq_c2h_avail to be reset' raise tb.scoreboard.result
async def test_reg_simple(dut): """ Test basic functionality of register""" clock = Clock(dut.clk, 10, units="ns") # Create a 100MHz clock cocotb.fork(clock.start()) # Start the clock en = 0 clr = 0 d = 0 q = 0 dut.rst <= 1 dut.en = en dut.clr = clr dut.d = 0 await ClockCycles(dut.clk, 10) assert dut.q.value == q, "FAIL on q: Not 0 after reset" dut.rst <= 0 for i in range(100): clr = random.randint(0, 1) en = random.randint(0, 1) d = random.randint(0, 128) dut.en = en dut.clr = clr dut.d = d await RisingEdge(dut.clk) await FallingEdge(dut.clk) if clr: q = 0 elif en: q = d assert dut.q.value == q, f"FAIL on q: actual = {dut.q.value}, expect = {q}"