Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

actorlib: LASMI DMA (untested)

  • Loading branch information...
commit 3a284b9c1ece996bad1e0d83c5d8edfed72ea16b 1 parent 932bfa7
Sébastien Bourdeauducq authored June 10, 2013

Showing 1 changed file with 107 additions and 0 deletions. Show diff stats Hide diff stats

  1. 107  migen/actorlib/dma_lasmi.py
107  migen/actorlib/dma_lasmi.py
... ...
@@ -0,0 +1,107 @@
  1
+from migen.fhdl.std import *
  2
+from migen.flow.actor import *
  3
+from migen.genlib.fifo import SyncFIFO
  4
+
  5
+class Reader(Module):
  6
+	def __init__(self, lasmim, fifo_depth=None):
  7
+		self.address = Sink([("a", lasmim.aw)])
  8
+		self.data = Source([("d", lasmim.dw)])
  9
+		self.busy = Signal()
  10
+	
  11
+		###
  12
+
  13
+		if fifo_depth is None:
  14
+			fifo_depth = lasmim.read_latency + 2
  15
+		assert(fifo_depth >= lasmim.read_latency)
  16
+	
  17
+		# request issuance
  18
+		request_enable = Signal()
  19
+		request_issued = Signal()
  20
+
  21
+		self.comb += [
  22
+			self.bus.we.eq(0),
  23
+			lasmim.stb.eq(self.address.stb & request_enable),
  24
+			lasmim.adr.eq(self.address.payload.a),
  25
+			self.address.ack.eq(lasmim.ack),
  26
+			request_issued.eq(lasmim.stb & lasmim.ack)
  27
+		]
  28
+
  29
+		# FIFO reservation level counter
  30
+		# incremented when data is planned to be queued
  31
+		# decremented when data is dequeued
  32
+		data_dequeued = Signal()
  33
+		rsv_level = Signal(max=fifo_depth+1)
  34
+		self.sync += [
  35
+			If(request_issued,
  36
+				If(~data_dequeued, rsv_level.eq(rsv_level + 1))
  37
+			).Elif(data_dequeued,
  38
+				rsv_level.eq(rsv_level - 1)
  39
+			)
  40
+		]
  41
+		self.comb += [
  42
+			self.busy.eq(rsv_level != 0),
  43
+			request_enable.eq(rsv_level != fifo_depth)
  44
+		]
  45
+
  46
+		# data available
  47
+		data_available = request_issued
  48
+		for i in range(lasmim.read_latency):
  49
+			new_data_available = Signal()
  50
+			self.sync += new_data_available.eq(data_available)
  51
+			data_available = new_data_available
  52
+
  53
+		# FIFO
  54
+		fifo = SyncFIFO(lasmim.dw, fifo_depth)
  55
+		self.submodules += fifo
  56
+
  57
+		self.comb += [
  58
+			fifo.din.eq(lasmim.dat_r),
  59
+			fifo.we.eq(data_available),
  60
+
  61
+			self.data.stb.eq(fifo.readable),
  62
+			fifo.re.eq(self.data.ack),
  63
+			self.data.payload.d.eq(fifo.dout),
  64
+			data_dequeued.eq(self.data.stb & self.data.ack)
  65
+		]
  66
+
  67
+
  68
+class Writer(Module):
  69
+	def __init__(self, lasmim):
  70
+		self.address_data = Sink([("a", lasmim.aw), ("d", lasmim.dw)])
  71
+		self.busy = Signal()
  72
+
  73
+		###
  74
+
  75
+		self.comb += [
  76
+			lasmim.we.eq(1),
  77
+			lasmim.stb.eq(self.address_data.stb),
  78
+			lasmim.adr.eq(self.address_data.payload.a),
  79
+			self.address_data.ack.eq(lasmim.ack)
  80
+		]
  81
+
  82
+		busy_expr = 0
  83
+		data_valid = Signal()
  84
+		data = Signal(lasmim.dw)
  85
+		self.comb += [
  86
+			data_valid.eq(lasmim.stb & lasmim.ack),
  87
+			data.eq(self.address_data.payload.d)
  88
+		]
  89
+
  90
+		for i in range(lasmim.write_latency):
  91
+			new_data_valid = Signal()
  92
+			new_data = Signal(lasmim.dw)
  93
+			self.sync += [
  94
+				new_data_valid.eq(data_valid),
  95
+				new_data.eq(data)
  96
+			]
  97
+			busy_expr = busy_expr | new_data_valid
  98
+			data_valid = new_data_valid
  99
+			data = new_data
  100
+
  101
+		self.comb += [
  102
+			If(data_valid,
  103
+				lasmim.dat_we.eq(2**(lasmim.dw//8)-1),
  104
+				lasmim.dat_w.eq(data)
  105
+			),
  106
+			self.busy.eq(busy_expr)
  107
+		]

0 notes on commit 3a284b9

Please sign in to comment.
Something went wrong with that request. Please try again.