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.

hp_dma.py 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. from migen import *
  2. from migen_axi.interconnect import axi
  3. from misoc.interconnect.csr import *
  4. from operator import attrgetter
  5. class HP_DMA_READ(Module, AutoCSR):
  6. def __init__(self, bus=None):
  7. self.bus = bus or axi.Interface(data_width=64)
  8. self.addr_base = CSRStorage(32)
  9. self.n_bursts = CSRStorage(32) # Number of bursts to do -1
  10. self.trigger = CSR(1)
  11. self.n_cycles = CSRStatus(32)
  12. self.status = CSRStatus(1)
  13. self.n_read = CSRStatus(32)
  14. self.dout = Signal(32)
  15. self.dout_stb = Signal()
  16. ###
  17. ar, aw, w, r, b = attrgetter("ar", "aw", "w", "r", "b")(self.bus)
  18. BURST_LEN = 16
  19. trigger_stb = self.trigger.re
  20. addr = Signal(32)
  21. read_request_accepted = Signal() # Asserted when the read request has been accepted
  22. read_request = Signal()
  23. n_done = Signal(32)
  24. self.submodules.fsm = fsm = FSM(reset_state="IDLE")
  25. fsm.act("IDLE",
  26. If(trigger_stb,
  27. NextValue(addr, self.addr_base.storage),
  28. NextValue(read_request, 1),
  29. NextState("RUNNING")
  30. )
  31. )
  32. fsm.act("RUNNING",
  33. If(read_request_accepted,
  34. NextValue(addr, addr+BURST_LEN),
  35. NextValue(n_done, n_done+1),
  36. If(n_done == self.n_bursts.storage,
  37. NextState("IDLE"),
  38. NextValue(read_request, 0)
  39. )
  40. )
  41. )
  42. ### Read
  43. self.comb += [
  44. ar.addr.eq(self.addr_base.storage),
  45. self.dout.eq(r.data),
  46. r.ready.eq(1),
  47. ar.burst.eq(axi.Burst.incr.value),
  48. ar.len.eq(BURST_LEN-1), # Number of transfers in burst (0->1 transfer, 1->2 transfers...)
  49. ar.size.eq(3), # Width of burst: 3 = 8 bytes = 64 bits
  50. ar.cache.eq(0xf),
  51. ]
  52. # read control
  53. self.comb += read_request_accepted.eq(ar.ready & ar.valid)
  54. self.submodules.read_fsm = read_fsm = FSM(reset_state="IDLE")
  55. read_fsm.act("IDLE",
  56. If(read_request,
  57. ar.valid.eq(1),
  58. If(ar.ready,
  59. NextState("WAIT")
  60. ).Else(
  61. NextState("READ_START")
  62. )
  63. )
  64. )
  65. read_fsm.act("READ_START",
  66. ar.valid.eq(1),
  67. If(ar.ready,
  68. NextState("WAIT"),
  69. )
  70. )
  71. read_fsm.act("WAIT",
  72. NextState("IDLE")
  73. )
  74. self.comb += self.dout_stb.eq(r.valid & r.ready)
  75. n_bursts_received = Signal(32)
  76. self.sync += [
  77. If(trigger_stb, n_bursts_received.eq(0)),
  78. If(self.dout_stb & r.last, n_bursts_received.eq(n_bursts_received+1))
  79. ]
  80. self.sync += [
  81. If(trigger_stb, self.status.status.eq(1)),
  82. If(n_bursts_received==self.n_bursts.storage+1, self.status.status.eq(0))
  83. ]
  84. self.sync += [
  85. If(self.status.status, self.n_cycles.status.eq(self.n_cycles.status+1)),
  86. If(trigger_stb, self.n_cycles.status.eq(0))
  87. ]
  88. self.sync += [
  89. If(self.dout_stb, self.n_read.status.eq(self.n_read.status+1)),
  90. If(trigger_stb, self.n_read.status.eq(0))
  91. ]