def test_btn_led(): clock = Clock(0, frequency=500e3) reset = Reset(0, active=0, async=False) leds = Signal(intbv(0)[8:]) btns = Signal(intbv(0)[4:]) def _test(): # bus_type = ('A', 'B', 'W', 'X') # avalon, barebone, wishbon, AXI tbdut = m_btn_led_mm(clock, reset, leds, btns, bus_type='A') def dumpg(glist): for gg in glist: if isinstance(gg, (list,tuple)): dumpg(gg) elif gg is not None: print("{:16}: {}".format(gg.func.__name__, gg.func.__module__)) dumpg(tbdut) tbclk = clock.gen() @instance def tbstim(): reset.next = reset.active yield delay(10) reset.next = not reset.active yield clock.posedge #assert leds == 0 for ii in range(3): # simulate a button press btns.next = 1 << ii yield delay(12) btns.next = 0 for cc in range(8): yield clock.posedge # @todo: a more interesting check #assert leds != 0 yield delay(100) raise StopSimulation return tbdut, tbclk, tbstim tb_clean_vcd(_test.__name__) Simulation(traceSignals(_test)).run() #Simulation(_test()).run() # currently an error when converting to both at once, # only convert to one at a time. toVerilog(m_btn_led_mm, clock, reset, leds, btns)
def test(): clock = Clock(0) reset = Reset(0, active=0, async=False) sdi, sdo = [Signal(bool(0)) for _ in range(2)] pin = [Signal(intbv(0)[16:]) for _ in range(7)] pout = [Signal(intbv(0)[16:]) for _ in range(3)] def _test(): tbclk = clock.gen() tbdut = io_stub(clock, reset, sdi, sdo, pin, pout) @instance def tbstim(): yield reset.pulse(13) yield clock.posedge # @todo: actually test something for ii in range(1000): yield clock.posedge raise StopSimulation return tbdut, tbclk, tbstim vcd = tb_clean_vcd('serio') traceSignals.name = vcd Simulation(traceSignals(_test)).run()
def test_hdmi(): """ simple test to demonstrate test framework """ clock = Signal(bool(0)) reset = ResetSignal(0, active=0, async=True) # this currently tests a Verilog version #tbdut = prep_cosim(clock, reset, args=args) tbdut = hdmi() def _test(): #tbdut = mm_hdmisys(glbl, vselect, hdmi, # resolution=res, # line_rate=line_rate) # clock for the design @always(delay(5)) def tbclk(): clock.next = not clock @instance def tbstim(): yield delay(13) reset.next = reset.active yield delay(33) reset.next = not reset.active yield clock.posedge try: for ii in range(100): yield delay(100) except AssertionError as err: print("@E: assertion error @ %d ns" % (now(),)) print(" %s" % (str(err),)) # additional simulation cycles after the error yield delay(111) raise err except Exception as err: print("@E: error occurred") print(" %s" % (str(err),)) raise err raise StopSimulation return tbclk, tbstim # run the above test vcd = tb_clean_vcd('_test') traceSignals.timescale = '1ns' traceSignals.name = vcd
def test_de0nano_lt24lcd(): portmap = de0nano_lt24lcd.portmap clock = portmap['clock'] reset = portmap['reset'] def _bench(): tbdut = de0nano_lt24lcd(**portmap) tbclk = clock.gen() @instance def tbstim(): yield reset.pulse(40) # relying on the design assertions for ii in range(1000): yield clock.posedge raise StopSimulation return tbdut, tbclk, tbstim vcd = tb_clean_vcd(_bench.__name__) traceSignals.name = vcd traceSignals.timescale = '1ns' Simulation(traceSignals(_bench)).run()
def test_fpgalink(): args = argparse.Namespace(cosim=False) args.vcd = tb_clean_vcd('fpgalink_fx2') tb_fpgalink(args)
assert fx2bus1.data_i is fx2ext.FDO fl.write_channel(1, [9]) fl.write_channel(2, [8]) fl.write_channel(3, [7]) fl.write_channel(4, [6]) bb = [ii for ii in (0xFE, 0xED, 0xFA, 0xCE)] bb[0] = fl.read_channel(1, 1) bb[1] = fl.read_channel(2, 1) bb[2] = fl.read_channel(3, 1) bb[3] = fl.read_channel(4, 1) print(bb) # ~~~~~~~~~~~~~~~ # Stop simulation fl.stop() time.sleep(1) if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument( '--cosim', action='store_true', default=False, help='Run cosimulation with verilog version of fpgalink requires icarus' ) args = parser.parse_args() args.vcd = tb_clean_vcd('fpgalink_fx2') tb_fpgalink(args)
def test_fifo_ramp(): clock = Clock(0, frequency=50e6) reset = Reset(0, active=1, async=False) glbl = Global(clock, reset) regbus = Wishbone(glbl) fifobus = FIFOBus() def _test_fifo_ramp(): tb_dut = fifo_ramp(clock, reset, regbus, fifobus, base_address=0x0000) tb_rbor = regbus.m_per_outputs() tb_clk = clock.gen() asserr = Signal(bool(0)) @instance def tb_stim(): try: yield delay(100) yield reset.pulse(111) # simply enable, enable the module and then # verify an incrementing pattern over the # fifobus yield regbus.write(0x00, 1) yield regbus.read(0x00) assert 1 == regbus.get_read_data(), "cfg reg write failed" # monitor the bus until ?? ramps Nramps, rr = 128, 0 while rr < Nramps: cnt = 0 for ii, sh in enumerate((24, 16, 8, 0)): yield regbus.read(0x08 + ii) cnt = cnt | (regbus.get_read_data() << sh) rr = cnt 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 tb_mon(): if fifobus.wr: assert _cval == fifobus.wdata _cval.next = _cval + 1 return tb_clk, tb_dut, tb_stim, tb_mon, tb_rbor vcd = tb_clean_vcd("_test_fifo_ramp") traceSignals.name = vcd g = traceSignals(_test_fifo_ramp) Simulation(g).run()
def test_afifo(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, rclk = [Signal(bool(0)), Signal(bool(0))] fbus = FIFOBus(width=args.width, size=args.size) start = Signal(bool(0)) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # clocks @always(delay(10)) def tbwclk(): wclk.next = not wclk @always(delay(12)) def tbrclk(): rclk.next = not rclk # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # FIFO writer and reader _wr = Signal(bool(0)) @instance def tb_always_wr(): was_full = False wrd = modbv(0)[args.width:] while True: if start: break yield wclk.posedge while True: yield wclk.posedge if not fbus.full and was_full: was_full = False for _ in range(17): yield wclk.posedge elif not fbus.full: fbus.wdata.next = wrd _wr.next = True yield delay(1) if not fbus.full: wrd[:] += 1 else: _wr.next = False was_full = True @always_comb def tb_always_wr_gate(): fbus.wr.next = _wr and not fbus.full @instance def tb_always_rd(): rdd = modbv(0)[args.width:] while True: if start: break yield wclk.posedge while True: try: yield rclk.posedge if not fbus.empty: fbus.rd.next = True else: fbus.rd.next = False if fbus.rvld: tmp = fbus.rdata assert tmp == rdd, " %d != %d " % (tmp, rdd) rdd[:] += 1 except AssertionError as err: for _ in range(10): yield rclk.posedge raise err # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def _test1(): tbdut = cores.fifo.fifo_async(reset, wclk, rclk, fbus) @instance def tbstim(): print("start test 1") fbus.wdata.next = 0xFE reset.next = reset.active yield delay(3*33) reset.next = not reset.active # reset is delayd 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): #print('%d wr %d' % (num_bytes, ii)) yield wclk.posedge fbus.wdata.next = ii fbus.wr.next = True yield wclk.posedge fbus.wr.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.rd.next = True yield rclk.posedge for ii in range(num_bytes): yield rclk.posedge fbus.rd.next = True #print("rdata %x ii %x " % (fbus.rdata, ii)) assert fbus.rvld assert fbus.rdata == ii, "rdata %x ii %x " % (fbus.rdata, ii) yield rclk.posedge fbus.rd.next = False yield rclk.posedge assert fbus.empty # Test overflows # Test underflows # Test write / read same time raise StopSimulation return tbdut, tbwclk, tbrclk, tbstim # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def _test2(): tbdut = cores.fifo.fifo_async(reset, wclk, rclk, fbus) @instance def tbstim(): print("start test 2") fbus.wdata.next = 0xFE reset.next = reset.active yield delay(3*33) reset.next = not reset.active yield delay(44) start.next = True for ii in range(2048): yield delay(100) raise StopSimulation return (tbdut, tbwclk, tbrclk, tb_always_wr, tb_always_wr_gate, tb_always_rd, tbstim) for tt in (_test1, _test2,): vcd = tb_clean_vcd('test_afifo_%s' % (tt.__name__)) traceSignals.name = vcd g = traceSignals(tt) Simulation(g).run()
# ~~~~~~~~~~~~~~~ # Test stimulus fl.reset() assert fx2bus1.data_i is fx2ext.FDO fl.write_channel(1, [9]) fl.write_channel(2, [8]) fl.write_channel(3, [7]) fl.write_channel(4, [6]) bb = [ii for ii in (0xFE, 0xED, 0xFA, 0xCE)] bb[0] = fl.read_channel(1, 1) bb[1] = fl.read_channel(2, 1) bb[2] = fl.read_channel(3, 1) bb[3] = fl.read_channel(4, 1) print(bb) # ~~~~~~~~~~~~~~~ # Stop simulation fl.stop() time.sleep(1) if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--cosim', action='store_true', default=False, help='Run cosimulation with verilog version of fpgalink requires icarus') args = parser.parse_args() args.vcd = tb_clean_vcd('fpgalink_fx2') tb_fpgalink(args)
def test_sfifo(args=None): """ verify the synchronous FIFO """ if args is None: args = Namespace(width=8, size=16, name="test") else: # @todo: verify args has the attributes needed for the FIFOBus pass reset = ResetSignal(0, active=1, async=True) clock = Signal(bool(0)) fbus = FIFOBus(width=args.width, size=args.size) def _test(): # @todo: use args.fast, args.use_srl_prim tbdut = fifo_sync(clock, reset, fbus) @always(delay(10)) def tbclk(): clock.next = not clock @instance def tbstim(): fbus.wdata.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)) yield clock.posedge fbus.wdata.next = ii fbus.wr.next = True yield clock.posedge fbus.wr.next = False fbus.wdata.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.rd.next = True yield clock.posedge for ii in range(num_bytes): yield clock.posedge fbus.rd.next = True # print("rdata %x ii %x " % (fbus.rdata, ii)) assert fbus.rvld assert fbus.rdata == ii, "rdata %x ii %x " % (fbus.rdata, ii) fbus.rd.next = False yield clock.posedge assert fbus.empty # Test overflows # Test underflows # Test write / read same time raise StopSimulation return tbdut, tbclk, tbstim vcd = tb_clean_vcd("test_fifo_sync_%d" % (args.size)) traceSignals.name = vcd g = traceSignals(_test) Simulation(g).run()
def test_spi(): base_address = ba = 0x400 clock = Clock(0, frequency=50e6) reset = Reset(0, active=1, async=False) glbl = Global(clock, reset) regbus = Wishbone(glbl) fiforx, fifotx = FIFOBus(size=16), FIFOBus(size=16) spiee = SPIEEPROM() spibus = SPIBus() asserr = Signal(bool(0)) def _test_spi(): tbdut = spi_controller(glbl, regbus, fiforx, fifotx, spibus, base_address=base_address) tbeep = spiee.gen(clock, reset, spibus) tbclk = clock.gen(hticks=5) # grab all the register file outputs tbmap = regbus.m_per_outputs() # 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.read(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.read(addr + ba) assert regbus.get_read_data() == int(sig), "Invalid default value" # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # enable the system print("enable the SPI core") yield regbus.write(rf.spst.addr, 0x02) # register data drives fifo yield regbus.write(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.write(rf.sptx.addr, data) print("") yield regbus.read(rf.sptc.addr) print("TX FIFO count {}".format(regbus.get_read_data())) yield regbus.read(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.read(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.read(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 vcd = tb_clean_vcd("_test_spi") traceSignals.name = vcd Simulation(traceSignals(_test_spi)).run()