Examples of using cocotb for functional verification of VHDL designs with GHDL.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

81 lines
2.6 KiB

  1. # test_uart.py
  2. import logging
  3. import random
  4. import cocotb
  5. import pprint
  6. from collections import defaultdict
  7. from Sram import SramRead, SramWrite, SramMonitor
  8. from cocotb.clock import Clock
  9. from cocotb.triggers import FallingEdge, RisingEdge, Timer, ReadOnly
  10. from cocotbext.wishbone.driver import WishboneMaster, WBOp
  11. # Reset coroutine
  12. async def reset_dut(reset_n, duration_ns):
  13. reset_n.value = 1
  14. await Timer(duration_ns, units="ns")
  15. reset_n.value = 0
  16. def bv_to_hexstr(data):
  17. return str(hex(data.integer))
  18. @cocotb.test()
  19. async def test_wishbone(dut):
  20. """ First simple test """
  21. clkedge = RisingEdge(dut.wbclk_i)
  22. # Connect reset
  23. reset = dut.wbrst_i
  24. # Create empty SRAM memory
  25. memory = defaultdict()
  26. mem_read = SramRead(dut.wbclk_i, dut.localren_o,
  27. dut.localadress_o, dut.localdata_i, memory);
  28. mem_write = SramWrite(dut.wbclk_i, dut.localwen_o,
  29. dut.localadress_o, dut.localdata_o, memory);
  30. sram_monitor = SramMonitor(dut.wbclk_i, dut.localwen_o, dut.localren_o,
  31. dut.localadress_o, dut.localdata_i, dut.localdata_o);
  32. wbmaster = WishboneMaster(dut, "", dut.wbclk_i,
  33. width=16, # size of data bus
  34. timeout=10, # in clock cycle number
  35. signals_dict={"cyc": "wbcyc_i",
  36. "stb": "wbstb_i",
  37. "we": "wbwe_i",
  38. "adr": "wbadr_i",
  39. "datwr":"wbdat_i",
  40. "datrd":"wbdat_o",
  41. "ack": "wback_o" })
  42. # Drive input defaults (setimmediatevalue to avoid x asserts)
  43. dut.wbcyc_i.setimmediatevalue(0)
  44. dut.wbstb_i.setimmediatevalue(0)
  45. dut.wbwe_i.setimmediatevalue(0)
  46. dut.wbadr_i.setimmediatevalue(0)
  47. dut.wbdat_i.setimmediatevalue(0)
  48. clock = Clock(dut.wbclk_i, 10, units="ns") # Create a 10 ns period clock
  49. cocotb.start_soon(clock.start()) # Start the clock
  50. # Execution will block until reset_dut has completed
  51. dut._log.info("Hold reset")
  52. await reset_dut(reset, 100)
  53. dut._log.info("Released reset")
  54. # Test 10 Wishbone transmissions
  55. for i in range(10):
  56. await clkedge
  57. adr = random.randint(0, 255)
  58. data = random.randint(0, 2**16-1)
  59. await wbmaster.send_cycle([WBOp(adr=adr, dat=data)])
  60. rec = await wbmaster.send_cycle([WBOp(adr=adr)])
  61. # Example to print transactions collected by SRAM monitor
  62. with open('results/sram_transactions.log', 'w', encoding='utf-8') as f:
  63. f.write((f"{'Time':7}{'Type':7}{'Adr':6}{'Data'}\n"))
  64. for k, v in sram_monitor.transactions.items():
  65. f.write((f"{k:7}{v['type']:7}{bv_to_hexstr(v['adr']):6}{bv_to_hexstr(v['data'])} \n"))