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.

94 lines
2.6 KiB

  1. import logging
  2. from cocotb.triggers import FallingEdge, RisingEdge, Timer, ReadOnly
  3. class Vai:
  4. """VAI base class"""
  5. def __init__(self, clock, data, valid, accept, *args, **kwargs):
  6. self._version = "0.0.1"
  7. self.log = logging.getLogger(f"cocotb.{valid._path}")
  8. self._data = data
  9. self._valid = valid
  10. self._accept = accept
  11. self._clock = clock
  12. self._clkedge = RisingEdge(self._clock)
  13. class VaiDriver(Vai):
  14. """Valid-Accept Driver"""
  15. def __init__(self, clock, data, valid, accept, *args, **kwargs):
  16. super().__init__(clock, data, valid, accept, *args, **kwargs)
  17. self.log.info("Valid-accept driver")
  18. self.log.info(" cocotbext-vai version %s", self._version)
  19. self.log.info(" Copyright (c) 2022 Torsten Meissner")
  20. # Hack to drive lists of signals
  21. if isinstance(self._data, list):
  22. for entry in self._data:
  23. entry.setimmediatevalue(0)
  24. else:
  25. self._data.setimmediatevalue(0)
  26. self._valid.setimmediatevalue(0)
  27. async def send(self, data, sync=True):
  28. if sync:
  29. await self._clkedge
  30. self._valid.value = 1
  31. # Hack to drive lists of signals
  32. if isinstance(self._data, list):
  33. for i in range(len(self._data)):
  34. self._data[i].value = data[i]
  35. else:
  36. self.log.info("Sending data: %s", hex(data))
  37. self._data.value = data
  38. while True:
  39. await ReadOnly()
  40. if self._accept.value:
  41. break
  42. await self._clkedge
  43. await self._clkedge
  44. self._valid.value = 0
  45. class VaiReceiver(Vai):
  46. """Valid-Accept Receiver"""
  47. def __init__(self, clock, data, valid, accept, *args, **kwargs):
  48. super().__init__(clock, data, valid, accept, *args, **kwargs)
  49. self.log.info("Valid-accept receiver")
  50. self.log.info(" cocotbext-vai version %s", self._version)
  51. self.log.info(" Copyright (c) 2022 Torsten Meissner")
  52. # Drive input defaults (setimmediatevalue to avoid x asserts)
  53. self._accept.setimmediatevalue(0)
  54. async def receive(self, sync=True):
  55. if sync:
  56. await self._clkedge
  57. while True:
  58. await ReadOnly()
  59. if self._valid.value:
  60. break
  61. await self._clkedge
  62. await self._clkedge
  63. self._accept.value = 1
  64. _rec = self._data.value
  65. self.log.info("Received data: %s", hex(_rec))
  66. await self._clkedge
  67. self._accept.value = 0
  68. return _rec