def sim(): from myhdl import Simulation, traceSignals, ResetSignal from rhea.system import Clock import sys clk = Clock(0, 50E6) rst = ResetSignal(0, active = 1, async = 0) spi_bus = SpiInterface() clk_inst = clk.gen() @instance def rst_inst(): rst.next = 1 yield(delay(100)) rst.next = 0 test_inst = traceSignals(top, clk, rst, spi_bus) sim = Simulation(clk_inst, rst_inst, test_inst) sim.run(10000) print sys.stdout.flush()
def convert(color_depth=(10, 10, 10,)): """ convert the vgasys to verilog """ clock = Clock(0, frequency=50e6) reset = Reset(0, active=0, async=False) vselect = Signal(bool(0)) hsync = Signal(bool(0)) vsync = Signal(bool(0)) cd = color_depth red = Signal(intbv(0)[cd[0]:]) green = Signal(intbv(0)[cd[1]:]) blue = Signal(intbv(0)[cd[2]:]) pxlen = Signal(bool(0)) active = Signal(bool(0)) inst = xula_vga( clock, reset, vselect, hsync, vsync, red, green, blue, pxlen, active ) tb_convert(inst)
def __init__(self, sck=None, mosi=None, miso=None, ss=None): """ """ self.htck = 234 if any([port is None for port in (sck, mosi, miso, ss)]): self.sck = Clock(0, frequency=100e3) self.mosi = Signal(True) self.miso = Signal(True) self.ss = Signal(intbv(0xFF)[8:]) else: self.sck = sck self.mosi = mosi self.miso = miso self.ss = ss # @todo: where/how is the following used? # make into an array self.csn = Signal(True) # for simulation and modeling only self.outval = intbv(0)[8:] self.inval = intbv(0)[8:]
def test_parallella_serdes(args=None): args = tb_default_args(args) clock = Clock(0, frequency=50e6) reset = Reset(0, active=1, async=True) txp = Signal(intbv(0)[6:]) txn = Signal(intbv(0)[6:]) rxp = Signal(intbv(0)[6:]) rxn = Signal(intbv(0)[6:]) leds = Signal(intbv(0)[8:]) def _bench_serdes(): tbdut = parallella_serdes(clock, txp, txn, rxp, rxn, leds) tbclk = clock.gen(hticks=10000) @always_comb def tblpk(): rxp.next = txp rxn.next = txn @instance def tbstim(): yield reset.pulse(32) yield clock.posedge for ii in range(100): for jj in range(1000): yield clock.posedge yield delay(1000) raise StopSimulation return tbdut, tbclk, tblpk, tbstim run_testbench(_bench_serdes, timescale='1ps', args=args) myhdl.toVerilog.directory = "output" myhdl.toVerilog.no_testbench = True myhdl.toVerilog(parallella_serdes, clock, txp, txn, rxp, rxn, leds)
def test_known_prbs5(args=None): args = tb_default_args(args) clock = Clock(0, frequency=125e6) reset = Reset(0, active=1, async=False) glbl = Global(clock, reset) prbs = Signal(intbv(0)[8:]) expected_pattern = ( 0xC7, 0xAE, 0x90, 0xE6, ) @myhdl.block def bench_prbs5(): tbdut = prbs_generate(glbl, prbs, order=5, initval=0x1F) tbclk = clock.gen(hticks=8000) @instance def tbstim(): yield reset.pulse(32) yield clock.posedge # for debugging, test prints occur after the module prints yield delay(1) for ii, ep in enumerate(expected_pattern): assert prbs == ep yield clock.posedge # for debugging, test prints occur after the module prints yield delay(1) yield delay(100) raise StopSimulation return tbdut, tbclk, tbstim run_testbench(bench_prbs5, timescale='1ps', args=args)
def test_devprim(args=None): args = tb_default_args(args) clock = Clock(0, frequency=50e6) reset = Reset(0, active=0, async=True) led = Signal(intbv(0)) def _bench_devprim(): tbdut = de0nano_soc_device_prims(clock, reset, led) tbclk = clock.gen(hticks=10000) @instance def tbstim(): print("start simulation") yield reset.pulse(36) yield clock.posedge for ii in range(40): yield delay(11111) print("end simulation") raise StopSimulation return tbdut, tbclk, tbstim run_testbench(_bench_devprim, args=args)
def testbench(): # First we instanciate the external world for this module # with something close enough to reality. clk = Clock(0, frequency=10) rst = ResetSignal(0, active=0, async=False) # This is simulating the reset sig. led = Signal(intbv(0)[8:]) # the leds button = Signal(True) # the button def _bench(): clkgen = clk.gen(5) # simulate the clock inst = snow(led, clk, rst, button) # We hook it up to our implementation. @instance def stimulus(): """ This simulates a button press after a while clocks. """ # the mojo board auto-reset at the beginning yield clk.posedge rst.next = True yield clk.posedge rst.next = False for j in range(4): for i in range(randint(0, 50)): yield clk.posedge button.next = False yield clk.posedge button.next = True for i in range(100): yield clk.posedge raise StopSimulation return clkgen, stimulus, inst return _bench
def test_devprim(args=None): args = tb_default_args(args) clock = Clock(0, frequency=125e6) reset = Reset(0, active=0, isasync=True) leds = Signal(intbv(0)[4:]) @myhdl.block def bench_devprim(): tbdut = zybo_device_prim(clock, leds, reset) tbclk = clock.gen(hticks=10000) @instance def tbstim(): print("start simulation") yield reset.pulse(36) yield clock.posedge for ii in range(40): yield delay(11111) print("end simulation") raise StopSimulation return tbdut, tbclk, tbstim run_testbench(bench_devprim, args=args)
def testbench_memmap(args=None): """ """ args = tb_default_args(args) clock = Clock(0, frequency=50e6) reset = Reset(0, active=1, async=False) glbl = Global(clock, reset) csbus = Barebone(glbl, data_width=8, address_width=16) def bench_memmap(): tbdut = peripheral(csbus) tbclk = clock.gen() print(csbus.regfiles) @instance def tbstim(): yield reset.pulse(111) raise StopSimulation return tbdut, tbclk, tbstim run_testbench(bench_memmap)
def create_test(): from rhea.system import Clock from myhdl import instance, delay top = create_top() bus = top.create_bus() bus.CLK_I = Clock(0, frequency=50e6) @instance def rst_inst(): bus.RST_I.next = 1 yield (delay(100)) bus.RST_I.next = 0 clock_inst = bus.CLK_I.gen() # bus.SEL_I = Signal(intbv(2)[2:0]) master_inst = master(bus) top_inst = top.gen(bus) return rst_inst, clock_inst, master_inst, top_inst
import myhdl from myhdl import (Signal, intbv, instance, always_comb, delay, StopSimulation) from rhea.cores.spi import spi_controller from rhea.cores.spi import SPIBus from rhea.models.spi import SPIEEPROM from rhea.system import Global, Clock, Reset, Signals from rhea.system import Wishbone from rhea.system import FIFOBus from rhea.utils.test import run_testbench, tb_convert, tb_args, tb_default_args # global signals used by many clock = Clock(0, frequency=100e6) reset = Reset(0, active=1, isasync=True) glbl = Global(clock, reset) portmap = dict(glbl=glbl, spibus=SPIBus(), fifobus=FIFOBus(), cso=spi_controller.cso()) @myhdl.block def spi_controller_top(clock, reset, sck, mosi, miso, ss): """SPI top-level for conversion testing""" glbl = Global(clock, reset) spibus = SPIBus(sck, mosi, miso, ss) fifobus = FIFOBus()
def test_async_fifo(args=None): """ verify the asynchronous FIFO """ if args is None: args = Namespace(width=8, size=16, name='test') reset = ResetSignal(0, active=1, async=True) wclk = Clock(0, frequency=22e6) rclk = Clock(0, frequency=50e6) fbus = FIFOBus(width=args.width) start = Signal(bool(0)) @myhdl.block def bench_async_fifo(): tbclkw = wclk.gen() tbclkr = rclk.gen() tbdut = fifo_async(wclk, rclk, fbus, reset) tbpr = procuder_consumer(wclk, rclk, fbus, start) @instance def tbstim(): print("start test 1") fbus.write_data.next = 0xFE reset.next = reset.active yield delay(3 * 33) reset.next = not reset.active # reset is delayed by at least two for ii in range(5): yield wclk.posedge # test normal cases for num_bytes in range(1, args.size + 1): # Write some byte for ii in range(num_bytes): yield wclk.posedge fbus.write_data.next = ii fbus.write.next = True yield wclk.posedge fbus.write.next = False # If 16 bytes written make sure FIFO is full yield wclk.posedge if num_bytes == args.size: assert fbus.full, "FIFO should be full!" while fbus.empty: yield rclk.posedge fbus.read.next = True yield rclk.posedge for ii in range(num_bytes): yield rclk.posedge fbus.read.next = True assert fbus.read_valid assert fbus.read_data == ii, "rdata %x ii %x " % ( fbus.read_data, ii) yield rclk.posedge fbus.read.next = False yield rclk.posedge assert fbus.empty raise StopSimulation return myhdl.instances()
def tb_sdram(args): """ SDRAM controller testbench """ # @todo: get the number of address to test from argparse num_addr = 100 # number of address to test # internal clock clock = Clock(0, frequency=50e6) reset = Reset(0, active=0, async=False) # sdram clock clock_sdram = Clock(0, frequency=100e6) # interfaces to the modules glbl = Global(clock=clock, reset=reset) ixbus = Wishbone(glbl=glbl, data_width=32, address_width=32) exbus = SDRAMInterface() exbus.clk = clock_sdram # Models sdram = SDRAMModel(exbus) # model driven by model :) max_addr = 2048 # @todo: add actual SDRAM memory size limit max_data = 2**16 # @todo: add actual databus width def _bench_sdram(): """ This test exercises a SDRAM controller ... """ tbmdl_sdm = sdram.process() tbmdl_ctl = sdram_controller_model(exbus, ixbus) # this test currently only exercises the models, # insert a second SDRAMInterface to test an actual # controller # tbdut = sdram_sdr_controller(ibus, exbus) tbclk = clock.gen(hticks=10 * 1000) tbclk_sdram = clock_sdram.gen(hticks=5 * 1000) @instance def tbstim(): reset.next = reset.active yield delay(18000) reset.next = not reset.active # test a bunch of random addresses try: saved_addr_data = {} for ii in range(num_addr): # get a random address and random data, save the address and data addr = randint(0, max_addr - 1) data = randint(0, max_data - 1) saved_addr_data[addr] = data yield ixbus.writetrans(addr, data) yield ixbus.readtrans(addr) read_data = ixbus.get_read_data() assert read_data == data, "{:08X} != {:08X}".format( read_data, data) yield delay(20 * 1000) # verify all the addresses have the last written data for addr, data in saved_addr_data.items(): yield ixbus.readtrans(addr) read_data = ixbus.get_read_data() assert read_data == data yield clock.posedge for ii in range(10): yield delay(1000) except AssertionError as err: # if test check fails about let the simulation run more cycles, # useful for debug yield delay(20000) raise err raise StopSimulation return tbclk, tbclk_sdram, tbstim, tbmdl_sdm, tbmdl_ctl run_testbench(_bench_sdram, timescale='1ps')
resolution=resolution, color_depth=color_depth) # LCD video driver glcd = lt24lcd(glbl, vmem, lcd) gens = gtick, gconv, rtl_read, rtl_leds, gbar, glcd return gens # the default port map # @todo: should be able to extact this from the board # @todo: definition: # @todo: portmap = brd.map_ports(de0nano_converters) de0nano_converters.portmap = { 'clock': Clock(0, frequency=50e6), 'reset': Reset(0, active=0, async=True), 'led': Signal(intbv(0)[8:]), 'adc_cs_n': Signal(bool(1)), 'adc_saddr': Signal(bool(1)), 'adc_sdat': Signal(bool(1)), 'adc_sclk': Signal(bool(1)), 'i2c_sclk': Signal(bool(1)), 'i2c_sdat': TristateSignal(bool(0)), 'g_sensor_cs_n': Signal(bool(1)), 'g_sensor_int': Signal(bool(1)), 'lcd_on': Signal(bool(1)), 'lcd_resetn': Signal(bool(1)), 'lcd_csn': Signal(bool(1)), 'lcd_rs': Signal(bool(1)), 'lcd_wrn': Signal(bool(1)),
def tb_fifo_ramp(args): clock = Clock(0, frequency=50e6) reset = Reset(0, active=1, async=False) glbl = Global(clock, reset) regbus = Wishbone(glbl) fifobus = FIFOBus() def _bench_fifo_ramp(): tbdut = fifo_ramp(clock, reset, regbus, fifobus, base_address=0x0000) tbrbor = regbus.interconnect() tbclk = clock.gen() asserr = Signal(bool(0)) @instance def tbstim(): print("start fifo ramp test") try: yield delay(100) yield reset.pulse(111) # verify an incrementing pattern over the fifobus yield regbus.writetrans(0x07, 2) # div of two yield regbus.readtrans(0x07) assert 2 == regbus.get_read_data() yield regbus.writetrans(0x00, 1) # enable yield regbus.readtrans(0x00) assert 1 == regbus.get_read_data(), "cfg reg write failed" # monitor the bus until ?? ramps Nramps, rr, timeout = 128, 0, 0 while rr < Nramps and timeout < (20 * Nramps): cnt = 0 for ii, sh in enumerate(( 24, 16, 8, 0, )): yield delay(1000) yield regbus.readtrans(0x08 + ii) cntpart = regbus.get_read_data() cnt = cnt | (cntpart << sh) print( "{:<8d}: ramp count[{:<4d}, {:d}]: {:08X}, {:02X} - timeout {:d}" .format(now(), rr, ii, cnt, cntpart, timeout)) timeout += 1 # @todo: add ramp check if cnt != rr or (timeout % 1000) == 0: print(" ramp {} {}".format( int(cnt), int(rr), )) rr = int(cnt) print("{}, {}, {}".format(Nramps, rr, timeout)) except AssertionError as err: asserr.next = True for _ in range(10): yield clock.posedge raise err raise StopSimulation # monitor the values from the fifo bus, it should # be a simple "ramp" increasing values _mask = 0xFF _cval = Signal(modbv(0, min=0, max=256)) @always(clock.posedge) def tbmon(): if fifobus.write: assert _cval == fifobus.write_data _cval.next = _cval + 1 return tbclk, tbdut, tbstim, tbmon, tbrbor run_testbench(_bench_fifo_ramp, args=args)
def test_fifo_fast(args=None): """ verify the synchronous FIFO """ clock = Clock(0, frequency=50e6) reset = Reset(0, active=0, async=True) if args is None: args = Namespace(width=8, size=16, name='test') else: # @todo: verify args has the attributes needed for the FIFOBus pass fbus = FIFOBus(width=args.width) glbl = Global(clock, reset) @myhdl.block def bench_fifo_fast(): # @todo: use args.fast, args.use_srl_prim tbdut = cores.fifo.fifo_fast(glbl, fbus, size=args.size, use_srl_prim=False) @instance def tbstim(): fbus.write_data.next = 0xFE reset.next = reset.active yield delay(33) reset.next = not reset.active for ii in range(5): yield clock.posedge # test the normal cases for num_bytes in range(1, args.size + 1): # write some bytes for ii in range(num_bytes): # print('nbyte %x wdata %x' % (num_bytes, ii)) fbus.write_data.next = ii fbus.write.next = True # wait for 1 clock cyle to # allow the fifo ops to occur yield clock.posedge fbus.write.next = False fbus.write_data.next = 0xFE # if 16 bytes written make sure FIFO is full yield clock.posedge if num_bytes == args.size: assert fbus.count == args.size assert fbus.full, "FIFO should be full!" assert not fbus.empty, "FIFO should not be empty" for cc in range(5): yield clock.posedge for ii in range(num_bytes): fbus.read.next = True yield clock.posedge # print("rdata %x ii %x " % (fbus.read_data, ii)) assert fbus.read_valid assert fbus.read_data == ii, "rdata %x ii %x " % ( fbus.read_data, ii) fbus.read.next = False yield clock.posedge assert fbus.empty fbus.clear.next = True yield clock.posedge fbus.clear.next = not fbus.clear for ii in range(5): yield clock.posedge raise StopSimulation return myhdl.instances() # normal fifo r/w run_testbench(bench_fifo_fast)
def test_fifo_sync(args=None): """ verify the synchronous FIFO """ if args is None: args = Namespace(width=8, size=16, name='test') else: assert hasattr(args, 'width') assert hasattr(args, 'size') args = tb_default_args(args) reset = ResetSignal(0, active=1, async=True) clock = Clock(0, frequency=50e6) glbl = Global(clock, reset) fbus = FIFOBus(width=args.width) @myhdl.block def bench_fifo_sync(): tbdut = fifo_sync(glbl, fbus, size=args.size) tbclk = clock.gen() @instance def tbstim(): fbus.write_data.next = 0xFE reset.next = reset.active yield delay(33) reset.next = not reset.active for ii in range(5): yield clock.posedge # test the normal cases for num_bytes in range(1, args.size + 1): # write some bytes for ii in range(num_bytes): yield clock.posedge fbus.write_data.next = ii + 0xCE fbus.write.next = True yield clock.posedge fbus.write.next = False fbus.write_data.next = 0xFE # if 16 bytes written make sure FIFO is full yield clock.posedge if num_bytes == args.size: assert fbus.full, "FIFO should be full!" assert not fbus.empty, "FIFO should not be empty" # fbus.read.next = True # yield clock.posedge for ii in range(5): yield clock.posedge if not fbus.empty: break for ii in range(num_bytes): fbus.read.next = True yield clock.posedge assert fbus.read_valid assert fbus.read_data == ii + 0xCE, \ "rdata %x ii %x " % (fbus.read_data, ii + 0xCE) fbus.read.next = False yield clock.posedge assert fbus.empty raise StopSimulation w = args.width write_data, read_data = Signals(intbv(0)[w:], 2) @always_comb def tbmon(): write_data.next = fbus.write_data read_data.next = fbus.read_data return tbdut, tbclk, tbstim, tbmon run_testbench(bench_fifo_sync, args=args)
def test(args=None): if args is None: args = Namespace(trace=False) clock = Clock(0, frequency=50e6) reset = Reset(0, active=0, async=False) sdi, sdo = [Signal(bool(0)) for _ in range(2)] pin = [Signal(intbv(0)[16:]) for _ in range(1)] pout = [Signal(intbv(0)[16:]) for _ in range(3)] valid = Signal(bool(0)) def bench_serio(): tbclk = clock.gen() tbdut = io_stub(clock, reset, sdi, sdo, pin, pout, valid) @instance def tbstim(): yield reset.pulse(13) yield clock.posedge for pp in pout: pp.next = 0 sdi.next = False yield delay(200) yield clock.posedge for ii in range(1000): yield clock.posedge assert sdo == False assert pin[0] == 0 for pp in pout: pp.next = 0xFFFF sdi.next = True yield valid.posedge yield delay(200) yield clock.posedge for ii in range(1000): yield clock.posedge assert sdo == True assert pin[0] == 0xFFFF raise StopSimulation return tbdut, tbclk, tbstim run_testbench(bench_serio, args=args) # a top-level conversion stub def top_stub(clock, reset, sdi, sdo): pin = [Signal(intbv(0)[16:0]) for _ in range(1)] pout = [Signal(intbv(0)[16:0]) for _ in range(3)] valid = Signal(bool(0)) stub_inst = io_stub(clock, reset, sdi, sdo, pin, pout, valid) return stub_inst # convert the design stub tb_convert(top_stub, clock, reset, sdi, sdo)
def convert(): """convert the faux-top-level""" clock = Clock(0, frequency=50e6) reset = Reset(0, active=1, async=False) sck, mosi, miso, ss = Signals(bool(0), 4) tb_convert(spi_controller_top, clock, reset, sck, mosi, miso, ss)
def test_rw_ffifo(args=None): """ verify the synchronous FIFO Read and write at the same time, the FIFO should remain unchanged. """ clock = Clock(0, frequency=50e6) reset = Reset(0, active=0, async=True) if args is None: args = Namespace(width=8, size=16, name='test') else: # @todo: verify args has the attributes needed for the FIFOBus pass fbus = FIFOBus(width=args.width) glbl = Global(clock, reset) @myhdl.block def bench_rw_fifo_fast(): # @todo: use args.fast, args.use_srl_prim tbdut = cores.fifo.fifo_fast(glbl, fbus, size=args.size, use_srl_prim=False) @instance def tbstim(): fbus.write_data.next = 0xFE reset.next = reset.active yield delay(33) reset.next = not reset.active for ii in range(5): yield clock.posedge for num_bytes in range(1, args.size): # write some bytes for ii in range(num_bytes): # print('nbyte %x wdata %x' % (num_bytes, ii)) fbus.write_data.next = ii fbus.write.next = True yield clock.posedge fbus.write.next = False fbus.write_data.next = 0xFE a = fbus.count for cc in range(5): yield clock.posedge # if 16 bytes written make sure FIFO is full yield clock.posedge if num_bytes == args.size: assert fbus.count == args.size assert fbus.full, "FIFO should be full!" assert not fbus.empty, "FIFO should not be empty" # r/w at the same time, should not # change the size of the fifo for ii in range(num_bytes, args.size): fbus.write_data.next = ii fbus.write.next = True fbus.read.next = True yield clock.posedge assert fbus.read_data == (ii - num_bytes) assert fbus.read_valid if ii == 0: assert fbus.empty else: assert not fbus.empty fbus.write.next = False fbus.write_data.next = 0xFE fbus.read.next = False assert a == fbus.count for cc in range(5): yield clock.posedge # read remaining bytes for ii in range(num_bytes): fbus.read.next = True yield clock.posedge # print("rdata %x ii %x " % (fbus.read_data, ii)) assert fbus.read_valid assert fbus.read_data == ((args.size - num_bytes) + ii), \ "rdata %x ii %x " % (fbus.read_data, \ ((args.size - num_bytes) + ii)) fbus.read.next = False yield clock.posedge assert fbus.empty fbus.clear.next = True yield clock.posedge fbus.clear.next = not fbus.clear for ii in range(5): yield clock.posedge raise StopSimulation return myhdl.instances() # r/w at the same time for trial in range(100): run_testbench(bench_rw_fifo_fast)
def testbench_to_generic(args=None): """ Test memory-mapped bus and the mapping to a generic bus :param args: :return: """ depth = 16 # number of memory address width = 32 # memory-mapped bus data width maxval = 2**width run = False if args is None else True args = tb_default_args(args) if not hasattr(args, 'num_loops'): args.num_loops = 10 clock = Clock(0, frequency=100e6) reset = Reset(0, active=1, async=False) glbl = Global(clock, reset) if hasattr(args, 'bustype'): address_width = 18 membus = busmap[args.bustype](glbl, data_width=width, address_width=address_width) else: address_width = int(ceil(log(depth, 2))) + 4 membus = Barebone(glbl, data_width=width, address_width=address_width) @myhdl.block def bench_to_generic(): tbdut = peripheral_memory(membus, depth=depth) tbitx = membus.interconnect() tbclk = clock.gen() testvals = {} @instance def tbstim(): yield reset.pulse(42) yield clock.posedge # only testing one peripheral, set the peripheral/slave # address to the first ... if isinstance(membus, Barebone): membus.per_addr.next = 1 peraddr = 0 else: peraddr = 0x10000 yield clock.posedge for ii in range(args.num_loops): randaddr = randint(0, depth - 1) | peraddr randdata = randint(0, maxval - 1) testvals[randaddr] = randdata yield membus.writetrans(randaddr, randdata) yield clock.posedge for addr, data in testvals.items(): yield membus.readtrans(addr) read_data = membus.get_read_data() assert read_data == data, "{:08X} != {:08X}".format( read_data, data) yield clock.posedge yield delay(100) raise StopSimulation return tbdut, tbitx, tbclk, tbstim if run: run_testbench(bench_to_generic, args=args)
def test_spi_memory_mapped(args=None): args = tb_default_args(args) base_address = ba = 0x400 clock = Clock(0, frequency=50e6) reset = Reset(0, active=1, isasync=False) glbl = Global(clock, reset) regbus = Wishbone(glbl) fifobus = FIFOBus(size=16) spiee = SPIEEPROM() spibus = SPIBus() asserr = Signal(bool(0)) @myhdl.block def bench_spi(): tbdut = spi_controller(glbl, spibus, fifobus=fifobus, mmbus=regbus) tbeep = spiee.gen(clock, reset, spibus) tbclk = clock.gen(hticks=5) # grab all the register file outputs tbmap = regbus.interconnect() # get a reference to the SPI register file rf = regbus.regfiles['SPI_000'] # dumpy the registers for the SPI peripheral print("SPI register file") for name, reg in rf.registers.items(): print(" {0} {1:04X} {2:04X}".format(name, reg.addr, int(reg))) print("") @instance def tbstim(): yield reset.pulse(33) yield delay(100) yield clock.posedge try: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # loop through the registers and check the default # values, these are the offset values. for addr, sig in rf.roregs: yield regbus.readtrans(addr + ba) assert regbus.get_read_data() == int(sig), \ "Invalid read-only value" for addr, sig in rf.rwregs: # need to skip the FIFO read / write if addr in ( rf.sptx.addr, rf.sprx.addr, ): pass else: yield regbus.readtrans(addr + ba) assert regbus.get_read_data() == int(sig), \ "Invalid default value" # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # enable the system print("enable the SPI core") yield regbus.writetrans(rf.spst.addr, 0x02) # register data drives fifo yield regbus.writetrans(rf.spcr.addr, 0x9A) # default plus enable (98 + 02) print("write to the transmit register") for data in (0x02, 0x00, 0x00, 0x00, 0x55): print("\nwriting to sptx {:02x}".format(data)) yield regbus.writetrans(rf.sptx.addr, data) print("") yield regbus.readtrans(rf.sptc.addr) print("TX FIFO count {}".format(regbus.get_read_data())) yield regbus.readtrans(rf.sprc.addr) print("RX FIFO count {}".format(regbus.get_read_data())) yield delay(1000) print("wait for return bytes") for ii in range(1000): yield regbus.readtrans(rf.sprc.addr) if regbus.get_read_data() == 5: break yield delay(10) # verify bytes received and not timeout print("RX FIFO count {}".format(regbus.get_read_data())) assert regbus.get_read_data() == 5 print("read the returned bytes") for ii in range(5): yield regbus.readtrans(rf.sprx.addr) print("spi readback {0}".format(regbus.get_read_data())) except Exception as err: print("@W: exception {0}".format(err)) yield delay(100) traceback.print_exc() raise err yield delay(100) raise StopSimulation return tbstim, tbdut, tbeep, tbclk, tbmap run_testbench(bench_spi, args=args)
def test_register_file(args=None): global regfile args = tb_default_args(args) # top-level signals and interfaces clock = Clock(0, frequency=50e6) reset = Reset(0, active=1, async=False) glbl = Global(clock, reset) regbus = Wishbone(glbl) def _bench_regfile(): tbdut = memmap_peripheral(glbl, regbus, 0xAA) tbor = regbus.interconnect() tbmclk = clock.gen(hticks=5) asserr = Signal(bool(0)) mon_ack = Signal(bool(0)) @always_comb def tbmon(): mon_ack.next = regbus.ack_o regdef = regfile.get_regdef() @instance def tbstim(): try: yield delay(100) yield reset.pulse(110) yield clock.posedge for k, reg in regdef.items(): if reg.access == 'ro': yield regbus.readtrans(reg.addr) rval = regbus.get_read_data() assert rval == reg.default, \ "ro: {:02x} != {:02x}".format(rval, reg.default) else: wval = randint(0, (2**reg.width) - 1) yield regbus.writetrans(reg.addr, wval) for _ in range(4): yield clock.posedge yield regbus.readtrans(reg.addr) rval = regbus.get_read_data() assert rval == wval, \ "rw: {:02x} != {:02x} @ {:04X}".format( rval, wval, reg.addr) yield delay(100) except AssertionError as err: print("@E: %s".format(err)) traceback.print_exc() asserr.next = True for _ in range(10): yield clock.posedge raise err raise StopSimulation return tbmclk, tbstim, tbdut, tbmon, tbor run_testbench(_bench_regfile, args=args)
def tb_vgasys(args=None): if args is None: args = Namespace() resolution = (80, 60) line_rate = 4000 refresh_rate = 60 color_depth = (10, 10, 10) else: # @todo: retrieve these from ... resolution = args.resolution refresh_rate = args.refresh_rate line_rate = args.line_rate color_depth = args.color_depth clock = Clock(0, frequency=1e6) reset = Reset(0, active=0, async=False) vselect = Signal(bool(0)) # intergace to the VGA driver and emulated display vga = VGA(color_depth=color_depth) def _bench_vgasys(): # top-level VGA system tbdut = mm_vgasys(clock, reset, vselect, vga.hsync, vga.vsync, vga.red, vga.green, vga.blue, vga.pxlen, vga.active, resolution=resolution, color_depth=color_depth, refresh_rate=refresh_rate, line_rate=line_rate) # group global signals glbl = Global(clock=clock, reset=reset) # a display for each dut mvd = VGADisplay(frequency=clock.frequency, resolution=resolution, refresh_rate=refresh_rate, line_rate=line_rate, color_depth=color_depth) # connect VideoDisplay model to the VGA signals tbvd = mvd.process(glbl, vga) # clock generator tbclk = clock.gen() @instance def tbstim(): reset.next = reset.active yield delay(18) reset.next = not reset.active # Wait till a full screen has been updated while mvd.update_cnt < 3: yield delay(1000) print("display updates complete") time.sleep(1) # @todo: verify video system memory is correct! # @todo: (self checking!). Read one of the frame # @todo: png's and verify a couple bars are expected raise StopSimulation return tbclk, tbvd, tbstim, tbdut # run the verification simulation run_testbench(_bench_vgasys)
def testbench_streamer(args=None): args = tb_default_args(args) if not hasattr(args, 'keep'): args.keep = False if not hasattr(args, 'bustype'): args.bustype = 'barebone' clock = Clock(0, frequency=100e6) reset = Reset(0, active=1, async=False) glbl = Global(clock, reset) # @todo: support all stream types ... upstream = AXI4StreamLitePort(data_width=32) downstream = AXI4StreamLitePort(data_width=32) def _bench_streamer(): tbdut = streamer_top(clock, reset, upstream, downstream, keep=args.keep) tbclk = clock.gen() dataout = [] @instance def tbstim(): yield reset.pulse(42) downstream.awaccept.next = True downstream.waccept.next = True data = [randint(0, (2**32) - 1) for _ in range(10)] for dd in data: upstream.awvalid.next = True upstream.awdata.next = 0xA upstream.wvalid.next = True upstream.wdata.next = dd yield clock.posedge upstream.awvalid.next = False upstream.wvalid.next = False # @todo: wait the appropriate delay given the number of # @todo: streaming registers yield delay(100) print(data) print(dataout) assert False not in [di == do for di, do in zip(data, dataout)] raise StopSimulation @always(clock.posedge) def tbcap(): if downstream.wvalid: dataout.append(int(downstream.wdata)) return tbdut, tbclk, tbstim, tbcap run_testbench(_bench_streamer, args=args) myhdl.toVerilog.name = "{}".format(streamer_top.__name__) if args.keep: myhdl.toVerilog.name += '_keep' myhdl.toVerilog.directory = 'output' myhdl.toVerilog(streamer_top, clock, reset, upstream, downstream)
def test_spi_controller_cso(args=None): args = tb_default_args(args) clock = Clock(0, frequency=50e6) reset = Reset(0, active=1, isasync=False) glbl = Global(clock, reset) spibus = SPIBus() # a FIFOBus to push-pull data from the SPI controller fifobus = FIFOBus(width=8) # control-status object for the SPI controller cso = spi_controller.cso() spiee = SPIEEPROM() asserr = Signal(bool(0)) @myhdl.block def bench_spi_cso(): spi_controller.debug = True # enable debug monitors tbdut = spi_controller(glbl, spibus, fifobus, cso=cso) tbeep = spiee.process(clock, reset, spibus) tbclk = clock.gen(hticks=5) @instance def tbstim(): yield reset.pulse(33) yield delay(100) yield clock.posedge try: # enable the SPI core cso.enable.next = True cso.bypass_fifo.next = True cso.loopback.next = True # write to the transmit FIFO values = (0x02, 0x00, 0x00, 0x00, 0x55) for data in values: cso.tx_byte.next = data cso.tx_write.next = True yield clock.posedge cso.tx_write.next = False while cso.tx_fifo_count > 0: yield delay(100) while cso.rx_fifo_count < 5: yield delay(100) ii, nticks = 0, 0 while ii < len(values): if cso.rx_empty: cso.rx_read.next = False else: cso.rx_read.next = True if cso.rx_byte_valid: assert values[ii] == cso.rx_byte, \ "{:<4d}: data mismatch, {:02X} != {:02X}".format( ii, int(values[ii]), int(cso.rx_byte)) ii += 1 nticks = 0 yield clock.posedge, cso.rx_empty.posedge cso.rx_read.next = False if nticks > 30: raise TimeoutError nticks += 1 cso.rx_read.next = False yield clock.posedge except AssertionError as err: asserr.next = True print("@E: assertion {}".format(err)) yield delay(100) traceback.print_exc() raise err raise StopSimulation # monitor signals for debugging tx_write, rx_read = Signals(bool(0), 2) @always_comb def tbmon(): rx_read.next = cso.rx_read tx_write.next = cso.tx_write return tbdut, tbeep, tbclk, tbstim, tbmon run_testbench(bench_spi_cso, args=args)
def test_memmap_command_bridge(args=None): nloops = 37 args = tb_default_args(args) clock = Clock(0, frequency=50e6) reset = Reset(0, active=1, async=False) glbl = Global(clock, reset) fifobus = FIFOBus() memmap = Barebone(glbl, data_width=32, address_width=28) fifobus.clock = clock def bench_command_bridge(): tbclk = clock.gen() tbdut = command_bridge(glbl, fifobus, memmap) readpath, writepath = FIFOBus(), FIFOBus() readpath.clock = writepath.clock = clock tbmap = fifobus.assign_read_write_paths(readpath, writepath) tbftx = fifo_fast(reset, clock, writepath) # user write path tbfrx = fifo_fast(reset, clock, readpath) # user read path # @todo: add other bus types tbmem = memmap_peripheral_bb(clock, reset, memmap) # save the data read ... read_value = [] @instance def tbstim(): yield reset.pulse(32) fifobus.read.next = False fifobus.write.next = False assert not fifobus.full assert fifobus.empty assert fifobus.read_data == 0 fifobus.write_data.next = 0 try: # test a single address pkt = CommandPacket(True, 0x0000) yield pkt.put(readpath) yield pkt.get(writepath, read_value, [0]) pkt = CommandPacket(False, 0x0000, [0x5555AAAA]) yield pkt.put(readpath) yield pkt.get(writepath, read_value, [0x5555AAAA]) # test a bunch of random addresses for ii in range(nloops): randaddr = randint(0, (2**20) - 1) randdata = randint(0, (2**32) - 1) pkt = CommandPacket(False, randaddr, [randdata]) yield pkt.put(readpath) yield pkt.get(writepath, read_value, [randdata]) except Exception as err: print("Error: {}".format(str(err))) traceback.print_exc() yield delay(2000) raise StopSimulation wp_read, wp_valid = Signals(bool(0), 2) wp_read_data = Signal(intbv(0)[8:]) wp_empty, wp_full = Signals(bool(0), 2) @always_comb def tbmon(): wp_read.next = writepath.read wp_read_data.next = writepath.read_data wp_valid.next = writepath.read_valid wp_full.next = writepath.full wp_empty.next = writepath.empty return tbclk, tbdut, tbmap, tbftx, tbfrx, tbmem, tbstim, tbmon run_testbench(bench_command_bridge, args=args)
def tb_lt24lcd_driver(args=None): clock = Clock(0, frequency=50e6) reset = Reset(0, active=1, async=False) glbl = Global(clock, reset) lcd = LT24Interface() display = LT24LCDDisplay() cmd = Signal(intbv(0)[8:]) datalen = Signal(intbv(0, min=0, max=lcd.number_of_pixels+1)) data = Signal(intbv(0)[16:]) datasent = Signal(bool(0)) datalast = Signal(bool(0)) cmd_in_progress = Signal(bool(0)) def _bench_lt24lcd_driver(): tbdut = lt24lcd_driver(glbl, lcd, cmd, datalen, data, datasent, datalast, cmd_in_progress, maxlen=lcd.number_of_pixels) gtck = glbl_timer_ticks(glbl, tick_div=100) tbmdl = display.process(glbl, lcd) tbclk = clock.gen() @instance def tbstim(): yield reset.pulse(111) yield clock.posedge # -------------------------------------------- # send a column write command print("column write command") cmd.next = 0x2A bytes = [0, 0, 0, 239] data.next = bytes[0] datalen.next = 4 for ii in range(4): yield datasent.posedge data.next = bytes[ii+1] if ii < 3 else 0 cmd.next = 0 yield cmd_in_progress.negedge yield clock.posedge # -------------------------------------------- # send a page address write command print("page address write command") cmd.next = 0x2B bytes = [0, 0, 1, 0x3F] data.next = bytes[0] datalen.next = 4 for ii in range(4): yield datasent.posedge data.next = bytes[ii+1] if ii < 3 else 0 cmd.next = 0 yield cmd_in_progress.negedge yield clock.posedge # -------------------------------------------- # write display memory, full update print("display update") cmd.next = 0x2C data.next = randint(0, data.max-1) datalen.next = lcd.number_of_pixels for ii in range(lcd.number_of_pixels): yield datasent.posedge data.next = randint(0, data.max-1) if (ii % 5000) == 0: print("{} pixels xfer'd".format(ii)) cmd.next = 0 yield cmd_in_progress.negedge yield clock.posedge print("display update complete") # -------------------------------------------- # @todo: verify the display received an image yield delay(100) raise StopSimulation return tbdut, tbmdl, tbclk, tbstim, gtck run_testbench(_bench_lt24lcd_driver)
def test_prbs_check(args=None): # @todo: select different parameters: order ... args = tb_default_args(args) order = 9 clock = Clock(0, frequency=125e6) reset = Reset(0, active=1, async=False) glbl = Global(clock, reset) prbs = Signal(intbv(0)[8:]) locked = Signal(bool(0)) inject_error = Signal(bool(0)) word_count = Signal(intbv(0)[64:]) error_count = Signal(intbv(0)[64:]) def _bench_prbs_checker(): tbgen = prbs_generate(glbl, prbs, inject_error=inject_error, order=order) tbdut = prbs_check(glbl, prbs, locked, word_count, error_count, order=order) tbclk = clock.gen() maxcycles = 2 * ((2**order) - 1) @instance def tbstim(): yield reset.pulse(32) yield clock.posedge assert not locked for ii in range(maxcycles): yield clock.posedge assert locked assert error_count == 0 for ii in range(randint(0, 1000)): yield clock.posedge assert locked assert error_count == 0 assert word_count > 0 lwc = int(word_count) inject_error.next = True yield clock.posedge inject_error.next = False yield clock.posedge assert locked for ii in range(randint(0, 1000)): yield clock.posedge assert locked assert error_count == 1 assert word_count > lwc lec = int(error_count) inject_error.next = True yield clock.posedge yield clock.posedge for ii in range(2000): yield clock.posedge if not locked: break assert error_count > lec lec = int(error_count) assert not locked inject_error.next = False for ii in range(maxcycles): yield clock.posedge assert locked yield delay(100) raise StopSimulation return tbgen, tbdut, tbclk, tbstim run_testbench(_bench_prbs_checker, timescale='1ps', args=args)
def test_ibh(args=None): args = tb_default_args(args) numbytes = 13 clock = Clock(0, frequency=50e6) reset = Reset(0, active=0, async=True) glbl = Global(clock, reset) led = Signal(intbv(0)[8:]) sw = Signal(intbv(1)[8:]) pmod = Signal(intbv(0)[8:]) uart_tx = Signal(bool(0)) uart_rx = Signal(bool(0)) uartmdl = UARTModel() baudrate = uartmdl.baudrate baudticks = int((1 / baudrate) / 1e-9) def _bench_ibh(): tbclk = clock.gen() tbmdl = uartmdl.process(glbl, uart_tx, uart_rx) tbdut = atlys_blinky_host(clock, reset, led, sw, pmod, uart_tx, uart_rx) @instance def tbstim(): yield reset.pulse(33) yield delay(1000) # test loopback for ii in range(5): wb = randint(0, 255) uartmdl.write(wb) # wait for the send (return) yield delay(baudticks * (8 + 2) + 2 * baudticks) rb = uartmdl.read() assert rb == wb sw.next = 0 yield delay(100) # send a write that should enable all five LEDs pkt = CommandPacket(False, address=0x20, vals=[0xFF]) for bb in pkt.rawbytes: uartmdl.write(bb) waitticks = baudticks * 10 * 28 yield delay(waitticks) timeout = 100 yield delay(waitticks) # get the response packet for ii in range(PACKET_LENGTH): rb = uartmdl.read() while rb is None and timeout > 0: yield clock.posedge rb = uartmdl.read() timeout -= 1 if rb is None: raise Exception("TimeoutError") # the last byte should be the byte written assert rb == 0xFF yield delay(1000) raise StopSimulation return tbclk, tbmdl, tbdut, tbstim run_testbench(_bench_ibh, args=args) myhdl.toVerilog.directory = 'output' myhdl.toVerilog(atlys_blinky_host, clock, reset, led, sw, pmod, uart_tx, uart_rx)
def test_zybo_vga(args=None): args = tb_default_args(args) resolution = ( 80, 60, ) refresh_rate = 60 line_rate = 31250 color_depth = ( 6, 6, 6, ) clock = Clock(0, frequency=125e6) glbl = Global(clock) vga = VGA(color_depth=color_depth) vga_hsync, vga_vsync = Signals(bool(0), 2) vga_red, vga_green, vga_blue = Signals(intbv(0)[6:], 3) led, btn = Signals(intbv(0)[4:], 2) @myhdl.block def bench(): tbdut = zybo_vga(led, btn, vga_red, vga_green, vga_blue, vga_hsync, vga_vsync, clock, resolution=resolution, color_depth=color_depth, refresh_rate=refresh_rate, line_rate=line_rate) tbclk = clock.gen() mdl = VGADisplay(frequency=clock.frequency, resolution=resolution, refresh_rate=refresh_rate, line_rate=line_rate, color_depth=color_depth) tbmdl = mdl.process(glbl, vga) @instance def tbstim(): yield delay(100000) raise StopSimulation return tbdut, tbclk, tbmdl, tbstim # run the above testbench, the above testbench doesn't functionally # verify anything only verifies basics. run_testbench(bench, args=args) # test conversion portmap = dict(led=led, btn=btn, vga_red=vga_red, vga_grn=vga_green, vga_blu=vga_blue, vga_hsync=vga_hsync, vga_vsync=vga_vsync, clock=clock) inst = zybo_vga(**portmap) tb_convert(inst)