signal <= 0 yield Timer(5000) # ps signal <= 1 yield Timer(5000) # ps # ============================================================================== @cocotb.coroutine def run_test(dut): """Setup testbench and run a test.""" cocotb.fork(clock_gen(dut.c)) tb = DFF_TB(dut, BinaryValue(0,1)) clkedge = RisingEdge(dut.c) # Apply random input data by input_gen via BitDriver for 100 clock cycle. tb.start() for i in range(100): yield clkedge # Stop generation of input data. One more clock cycle is needed to capture # the resulting output of the DUT. tb.stop() yield clkedge # Print result of scoreboard. raise tb.scoreboard.result # ============================================================================== # Register test. factory = TestFactory(run_test) factory.generate_tests()
for index, values in enumerate(data_generator(bits=len(dut.in1))): expected.append(sorted(values)) yield RisingEdge(dut.clk) dut.in1 = values[0] dut.in2 = values[1] dut.in3 = values[2] dut.in4 = values[3] dut.in5 = values[4] yield ReadOnly() expect = expected.pop(0) if expect is None: continue got = [int(dut.out5), int(dut.out4), int(dut.out3), int(dut.out2), int(dut.out1)] if got != expect: dut.log.error('Expected %s' % expect) dut.log.error('Got %s' % got) raise TestFailure("Output didn't match") dut.log.info('Sucessfully sent %d cycles of data' % (index + 1)) # Generate permutations of the test tests = TestFactory(run_test) tests.add_option('data_generator', [random_data, corner_cases]) tests.generate_tests()
cocotb.fork(Clock(dut.clk, 100).start()) #Overwriting debug (original) with the one from env debug = os.getenv('COCOTB_DEBUG') # None/1 driver = ImageDriver(dut) monitor = JpegMonitor(dut) if debug: # pragma: no cover driver.log.setLevel(logging.DEBUG) monitor.log.setLevel(logging.DEBUG) stimulus = Image.open(filename) yield driver.send(stimulus) output = yield monitor.wait_for_recv() if debug: # pragma: no cover output.save(filename + "_process.jpg") difference = compare(stimulus, output) dut.log.info("Compressed image differs to original by %f%%" % (difference)) if difference > threshold: # pragma: no cover raise TestFailure("Resulting image file was too different (%f > %f)" % (difference, threshold)) tf = TestFactory(process_image) tf.add_option("filename", [os.path.join('test_images', f) for f in os.listdir('test_images')]) tf.generate_tests()
data_packets = int(ceil(len(dut.input_data) / len(dut.s_axi__RDATA))) n = 0 sniffed_data = [] while data_avail: tmp_value = 0 for i in range(data_packets): rd = yield axi_lite.read_reg(0xc + i * 0x4) tmp_value |= ((rd & (2**32 - 1)) << (32 * i)) sniffed_data.append(tmp_value) rd = yield axi_lite.read_reg(0x8) data_avail = (rd >> 31) & 0x1 assert n < FIFO_DEPTH, f'Read {n+1} values when fifo depth is {FIFO_DEPTH}' n += 1 assert count >= len(sniffed_data), f'{count} < {len(sniffed_data)}' assert subfinder(buff, sniffed_data), f'{sniffed_data} not in {buff}' tf_check_data = TF(check_data) tf_check_data.add_option('', [0] * 3) # dummy variable to force repetition of test (pytest could be used but it would regenerate the core each time) tf_check_data.generate_tests() @pytest.mark.parametrize("width", [8, 32, 40, 64]) def test_datapath_sniffer(width): core = DatapathSniffer(width=width, depth=FIFO_DEPTH, domain_data='data', domain_axi='axi') ports = core.get_ports() run(core, 'nmigen_datapath_sniffer.tests.test_datapath_sniffer', ports=ports, vcd_file=f'./output.vcd')
return itertools.cycle([1, 1, 1, 0]) if cocotb.SIM_NAME: data_width = len(cocotb.top.axi_wdata) byte_width = data_width // 8 max_burst_size = (byte_width - 1).bit_length() for test in [run_test_write, run_test_read]: factory = TestFactory(test) factory.add_option("idle_inserter", [None, cycle_pause]) factory.add_option("backpressure_inserter", [None, cycle_pause]) factory.add_option("size", [None] + list(range(max_burst_size))) factory.generate_tests() for test in [run_test_write_words, run_test_read_words]: factory = TestFactory(test) factory.generate_tests() factory = TestFactory(run_stress_test) factory.generate_tests() # cocotb-test tests_dir = os.path.dirname(__file__) @pytest.mark.parametrize("data_width", [8, 16, 32])
debug = os.getenv('COCOTB_DEBUG') # None/1 driver = ImageDriver(dut) monitor = JpegMonitor(dut) if debug: # pragma: no cover driver.log.setLevel(logging.DEBUG) monitor.log.setLevel(logging.DEBUG) stimulus = Image.open(filename) yield driver.send(stimulus) output = yield monitor.wait_for_recv() if debug: # pragma: no cover output.save(filename + "_process.jpg") difference = compare(stimulus, output) dut.log.info("Compressed image differs to original by %f%%" % (difference)) if difference > threshold: # pragma: no cover raise TestFailure("Resulting image file was too different (%f > %f)" % (difference, threshold)) tf = TestFactory(process_image) tf.add_option( "filename", [os.path.join('test_images', f) for f in os.listdir('test_images')]) tf.generate_tests()
yield init_test(dut) buff_in = [] buff_out = [] cocotb.fork(input_monitor(dut, buff_in)) cocotb.fork(output_monitor(dut, buff_out)) dut.clken <= 1 for _ in range(100): dut.input_a <= random.getrandbits(width_in) dut.input_b <= random.getrandbits(width_in) yield RisingEdge(dut.clk) yield RisingEdge(dut.clk) check_output(buff_in, buff_out) tf_test_data = TF(check_data) tf_test_data.generate_tests() @pytest.mark.parametrize("input_w, output_w", [ (8, 24), ]) def test_mac(input_w, output_w): core = MAC(input_w=input_w, output_w=output_w) ports = core.get_ports() vcd_file = vcd_only_if_env(f'./test_mac_i{input_w}_o{output_w}.vcd') run(core, 'cnn.tests.test_mac', ports=ports, vcd_file=vcd_file)
#fact.add_option("write_setup", [0, clk_t / 2]) #fact.add_option("write_hold", [clk_t / 2, clk_t]) #fact.add_option("read_setup", [clk_t, 3 * clk_t / 2]) #fact.add_option("read_hold", [clk_t / 2, clk_t]) #fact.generate_tests() # #fact = TestFactory(tmr_test_count) #fact.add_option("setup", [0, clk_t / 4]) #fact.add_option("hold", [clk_t / 4, 3 * clk_t / 4]) #fact.generate_tests(prefix="partial_") # #fact = TestFactory(tmr_test_count) #fact.add_option("setup", [0]) #fact.add_option("hold", [clk_t]) #fact.generate_tests(prefix="continuous_") #fact = TestFactory(tmr_test_lapse) #fact.add_option("write_setup", [0, clk_t / 2]) #fact.add_option("write_hold", [clk_t / 2, clk_t]) #fact.add_option("read_setup", [clk_t, 3 * clk_t / 2]) #fact.add_option("read_hold", [clk_t / 2, clk_t]) #fact.generate_tests() fact = TestFactory(tmr_test_alarm) #fact.add_option("setup", [0, clk_t / 2]) #fact.add_option("hold", [clk_t / 2, clk_t]) fact.add_option("lapse", [4]) fact.add_option("setup", [0]) fact.add_option("hold", [clk_t]) fact.generate_tests()
yield init_test(dut) for (r_name, r_dir, r_addr, r_fields), r_value in zip(regs_ro, data): for f_name, f_size, f_offset in r_fields: setattr(dut, f_name, unmask(r_value, f_size, f_offset)) yield RisingEdge(dut.clk) for (r_name, r_dir, r_addr, r_fields), r_value in zip(regs_ro, data): rd = yield axi_lite.read_reg(r_addr) assert rd == r_value, f'{hex(rd)} == {hex(r_value)}' tf_test_rw = TF(check_rw_regs) tf_test_rw.generate_tests() tf_test_ro = TF(check_ro_regs) tf_test_ro.generate_tests() def test_axi_lite_device(): core = AxiLiteDevice(addr_w=5, data_w=32, registers=regs) ports = [core.axi_lite[f] for f in core.axi_lite.fields] ports += [core.registers[f] for f in core.registers.fields] run(core, 'cores_nmigen.test.test_axi_lite', ports=ports, vcd_file='./test_axi_lite_device.vcd')
def check_data(dut, period_ns_w, period_ns_r, burps_in, burps_out, dummy=0): length = 200 yield init_test(dut, period_ns_w, period_ns_r) input_stream = DataStreamDriver(dut, 'input_', dut.write_clk) output_stream = DataStreamDriver(dut, 'output_', dut.read_clk) data = [random.getrandbits(len(input_stream.bus.data)) for _ in range(length)] cocotb.fork(input_stream.send(data, burps=burps_in)) rcv = yield output_stream.recv(burps=burps_out) assert data == rcv, f'\n{data}\n!=\n{rcv}' tf_check = TF(check_data) tf_check.add_option('period_ns_w', [10]) tf_check.add_option('period_ns_r', [10, 22, 3]) tf_check.add_option('burps_in', [False, True]) tf_check.add_option('burps_out', [False, True]) tf_check.add_option('dummy', [0] * 3) tf_check.generate_tests(postfix='_cdc') @pytest.mark.parametrize("width, depth", [(random.randint(2, 20), random.randint(2, 10))]) def test_main(width, depth): fifo = StreamFifoCDC(input_stream=DataStream(width, 'sink', name='input'), output_stream=DataStream(width, 'source', name='output'), depth=depth, r_domain='read', w_domain='write') ports = [fifo.input[f] for f in fifo.input.fields] ports += [fifo.output[f] for f in fifo.output.fields] run(fifo, 'cores_nmigen.test.test_fifo_cdc', ports=ports, vcd_file='test_stream_fifo_cdc.vcd')
getattr(dut, AXI_PREFIX + '_ARLEN').value = arlen await axim.read(address, burst_length) raise TestFailure("Mismatch between ARLEN value ({}) and number " "of read words ({}), but the driver did not " "raise an exception".format(arlen, burst_length)) except AXIReadBurstLengthMismatch: pass single_beat = TestFactory(test_single_beat) single_beat.add_option('driver', (AXI4Master, AXI4LiteMaster)) single_beat.add_option('address_latency', (0, )) single_beat.add_option('data_latency', (0, )) single_beat.generate_tests() single_beat_with_latency = TestFactory(test_single_beat) single_beat_with_latency.add_option('driver', (AXI4Master, )) single_beat_with_latency.add_option('address_latency', (0, 5)) single_beat_with_latency.add_option('data_latency', (1, 10)) single_beat_with_latency.generate_tests(postfix="_latency") incr_burst = TestFactory(test_incr_burst) incr_burst.add_option('return_rresp', (True, False)) incr_burst.add_option('size', (None, )) incr_burst.generate_tests() incr_burst_size = TestFactory(test_incr_burst) incr_burst_size.add_option('return_rresp', (False, )) incr_burst_size.add_option('size', (1, 2))
def data_check(dut, driver): yield init_test(dut) a_stream = driver(dut, 'a_', dut.clk) b_stream = driver(dut, 'b_', dut.clk) r_stream = driver(dut, 'r_', dut.clk) a_width = len(a_stream.bus.TDATA) b_width = len(a_stream.bus.TDATA) a_data = [random.getrandbits(a_width) for _ in range(20)] b_data = [random.getrandbits(b_width) for _ in range(20)] cocotb.fork(a_stream.send(a_data)) cocotb.fork(b_stream.send(b_data)) r_data = yield r_stream.recv() for a, b, r in zip(a_data, b_data, r_data): assert a + b == r tf_random_len = TF(data_check) tf_random_len.add_option('driver', [AxiStreamDriver, AxiStreamDriverBurps]) tf_random_len.generate_tests() def test_axis(): m = Adder(10, 'sync', AxiStream) ports = [] for i in [m.a, m.b, m.r]: ports += [i[f] for f in i.fields] run(m, 'adder.tests.test_axis', ports=ports, vcd_file='axis.vcd')
for t in range(0, xact_nr - 1): yield tb.rdxact(14, 0, random.getrandbits(32), 3, 0) for e in range(0, post_cycles): yield RisingEdge(dut.aclk) random.seed(time.time()) clk_t = 2000 xact_nr = 3 exit_on_fail = True fact = TestFactory(axi4ls_test_reset) fact.add_option("clk_delay", [clk_t / 2, clk_t, 3 * clk_t / 2]) fact.add_option("reset_hold", [clk_t / 4, clk_t / 2, clk_t / 3, clk_t]) fact.add_option("post_delay", [clk_t / 4, clk_t / 2, clk_t / 3, clk_t]) fact.generate_tests() fact = TestFactory(axi4ls_test_wrxact) fact.add_option("addr", [0, 1, 4, 6, 8, 11]) fact.add_option("addr_delay", [0, clk_t / 2, 3 * clk_t / 4, 5 * clk_t / 4]) fact.add_option("data_delay", [0, clk_t / 2, 3 * clk_t / 4, 5 * clk_t / 4]) fact.add_option("resp_delay", [0, clk_t / 2, 3 * clk_t / 4, 5 * clk_t / 4]) fact.add_option("resp", [0]) fact.add_option("post_cycles", [0, 1, 4]) fact.generate_tests("valid_") fact = TestFactory(axi4ls_test_wrxact) fact.add_option("addr", [12]) fact.add_option("addr_delay", [0, clk_t / 2, 3 * clk_t / 4, 5 * clk_t / 4]) fact.add_option("data_delay", [0, clk_t / 2, 3 * clk_t / 4, 5 * clk_t / 4]) fact.add_option("resp_delay", [0, clk_t / 2, 3 * clk_t / 4, 5 * clk_t / 4])
width_in = len(dut.INPUT__data) width_out = len(dut.OUTPUT__data) ratio = convertion_ratio(dut) input_len = 100 * ratio + int(not(multiple)) output_len = ceil(input_len / ratio) data = [random.randint(0, 2**width_in-1) for _ in range(input_len)] cocotb.fork(input_stream.send(data, burps=burps_in)) rcv = yield output_stream.recv(burps=burps_out) yield RisingEdge(dut.clk) expected = calculate_expected_result(data, width_in, width_out) assert len(rcv) >= output_len, f'Read {len(rcv)} instead of {output_len} values in burst' assert rcv == expected, f'rcv=\n{rcv}\n\nexpected=\n{expected}\n' tf_test = TF(check_data) tf_test.add_option('multiple', [True, False]) tf_test.add_option('burps_in', [False, True]) tf_test.add_option('burps_out', [False, True]) tf_test.generate_tests() @pytest.mark.parametrize("width_in, width_out", [(8, 24), (24, 24), (24, 8)]) def test_width_converter(width_in, width_out): core = WidthConverter(width_in=width_in, width_out=width_out) ports = [core.input[f] for f in core.input.fields] ports += [core.output[f] for f in core.output.fields] run(core, 'cores_nmigen.test.test_width_converter', ports=ports, vcd_file=f'./output_i{width_in}_o{width_out}.vcd')