Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 2 commits
  • 4 files changed
  • 0 comments
  • 1 contributor
45  migen/actorlib/dma_lasmi.py
@@ -11,8 +11,7 @@ def __init__(self, lasmim, fifo_depth=None):
11 11
 		###
12 12
 
13 13
 		if fifo_depth is None:
14  
-			fifo_depth = lasmim.read_latency + 2
15  
-		assert(fifo_depth >= lasmim.read_latency)
  14
+			fifo_depth = lasmim.req_queue_size + lasmim.read_latency + 2
16 15
 	
17 16
 		# request issuance
18 17
 		request_enable = Signal()
@@ -22,8 +21,8 @@ def __init__(self, lasmim, fifo_depth=None):
22 21
 			lasmim.we.eq(0),
23 22
 			lasmim.stb.eq(self.address.stb & request_enable),
24 23
 			lasmim.adr.eq(self.address.payload.a),
25  
-			self.address.ack.eq(lasmim.ack),
26  
-			request_issued.eq(lasmim.stb & lasmim.ack)
  24
+			self.address.ack.eq(lasmim.req_ack),
  25
+			request_issued.eq(lasmim.stb & lasmim.req_ack)
27 26
 		]
28 27
 
29 28
 		# FIFO reservation level counter
@@ -44,7 +43,7 @@ def __init__(self, lasmim, fifo_depth=None):
44 43
 		]
45 44
 
46 45
 		# data available
47  
-		data_available = request_issued
  46
+		data_available = lasmim.dat_ack
48 47
 		for i in range(lasmim.read_latency):
49 48
 			new_data_available = Signal()
50 49
 			self.sync += new_data_available.eq(data_available)
@@ -66,42 +65,38 @@ def __init__(self, lasmim, fifo_depth=None):
66 65
 
67 66
 
68 67
 class Writer(Module):
69  
-	def __init__(self, lasmim):
  68
+	def __init__(self, lasmim, fifo_depth=None):
70 69
 		self.address_data = Sink([("a", lasmim.aw), ("d", lasmim.dw)])
71 70
 		self.busy = Signal()
72 71
 
73 72
 		###
74 73
 
  74
+		if fifo_depth is None:
  75
+			fifo_depth = lasmim.req_queue_size + lasmim.read_latency + 2
  76
+
  77
+		fifo = SyncFIFO(lasmim.dw, fifo_depth)
  78
+		self.submodules += fifo
  79
+
75 80
 		self.comb += [
76 81
 			lasmim.we.eq(1),
77  
-			lasmim.stb.eq(self.address_data.stb),
  82
+			lasmim.stb.eq(fifo.writable & self.address_data.stb),
78 83
 			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)
  84
+			self.address_data.ack.eq(fifo.writable & lasmim.req_ack),
  85
+			fifo.we.eq(self.address_data.stb & lasmim.req_ack),
  86
+			fifo.din.eq(self.address_data.payload.d)
88 87
 		]
89 88
 
  89
+		data_valid = lasmim.dat_ack
90 90
 		for i in range(lasmim.write_latency):
91 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
  92
+			self.sync += new_data_valid.eq(data_valid),
98 93
 			data_valid = new_data_valid
99  
-			data = new_data
100 94
 
101 95
 		self.comb += [
  96
+			fifo.re.eq(data_valid),
102 97
 			If(data_valid,
103 98
 				lasmim.dat_we.eq(2**(lasmim.dw//8)-1),
104  
-				lasmim.dat_w.eq(data)
  99
+				lasmim.dat_w.eq(fifo.dout)
105 100
 			),
106  
-			self.busy.eq(busy_expr)
  101
+			self.busy.eq(fifo.readable)
107 102
 		]
29  migen/bus/lasmibus.py
@@ -5,10 +5,11 @@
5 5
 from migen.genlib.misc import optree
6 6
 
7 7
 class Interface(Record):
8  
-	def __init__(self, aw, dw, nbanks, read_latency, write_latency):
  8
+	def __init__(self, aw, dw, nbanks, req_queue_size, read_latency, write_latency):
9 9
 		self.aw = aw
10 10
 		self.dw = dw
11 11
 		self.nbanks = nbanks
  12
+		self.req_queue_size = req_queue_size
12 13
 		self.read_latency = read_latency
13 14
 		self.write_latency = write_latency
14 15
 
@@ -16,7 +17,9 @@ def __init__(self, aw, dw, nbanks, read_latency, write_latency):
16 17
 			("adr",		aw,		DIR_M_TO_S),
17 18
 			("we",		1,		DIR_M_TO_S),
18 19
 			("stb",		1,		DIR_M_TO_S),
19  
-			("ack",		1,		DIR_S_TO_M)
  20
+			("req_ack",	1,		DIR_S_TO_M),
  21
+			("dat_ack",	1,		DIR_S_TO_M),
  22
+			("lock",	1,		DIR_S_TO_M)
20 23
 		]
21 24
 		if nbanks > 1:
22 25
 			layout = [("bank"+str(i), bank_layout) for i in range(nbanks)]
@@ -43,12 +46,13 @@ def __init__(self, controllers, nmasters, cba_shift):
43 46
 		rca_bits = _getattr_all(controllers, "aw")
44 47
 		dw = _getattr_all(controllers, "dw")
45 48
 		nbanks = _getattr_all(controllers, "nbanks")
  49
+		req_queue_size = _getattr_all(controllers, "req_queue_size")
46 50
 		read_latency = _getattr_all(controllers, "read_latency")
47 51
 		write_latency = _getattr_all(controllers, "write_latency")
48 52
 
49 53
 		bank_bits = log2_int(nbanks, False)
50 54
 		controller_bits = log2_int(ncontrollers, False)
51  
-		self.masters = [Interface(rca_bits + bank_bits + controller_bits, dw, 1, read_latency, write_latency)
  55
+		self.masters = [Interface(rca_bits + bank_bits + controller_bits, dw, 1, req_queue_size, read_latency, write_latency)
52 56
 			for i in range(nmasters)]
53 57
 
54 58
 		###
@@ -60,16 +64,20 @@ def __init__(self, controllers, nmasters, cba_shift):
60 64
 				controller_selected = [ca == nc for ca in m_ca]
61 65
 			else:
62 66
 				controller_selected = [1]*nmasters
63  
-			master_acks = [0]*nmasters
  67
+			master_req_acks = [0]*nmasters
  68
+			master_dat_acks = [0]*nmasters
64 69
 			for nb in range(nbanks):
65 70
 				bank = getattr(controller, "bank"+str(nb))
66 71
 
67 72
 				# arbitrate
68  
-				rr = roundrobin.RoundRobin(nmasters, roundrobin.SP_WITHDRAW)
  73
+				rr = roundrobin.RoundRobin(nmasters, roundrobin.SP_CE)
69 74
 				self.submodules += rr
70 75
 				bank_selected = [cs & (ba == nb) for cs, ba in zip(controller_selected, m_ba)]
71 76
 				bank_requested = [bs & master.stb for bs, master in zip(bank_selected, self.masters)]
72  
-				self.comb += rr.request.eq(Cat(*bank_requested)),
  77
+				self.comb += [
  78
+					rr.request.eq(Cat(*bank_requested)),
  79
+					rr.ce.eq(~bank.stb & ~bank.lock)
  80
+				]
73 81
 
74 82
 				# route requests
75 83
 				self.comb += [
@@ -77,10 +85,13 @@ def __init__(self, controllers, nmasters, cba_shift):
77 85
 					bank.we.eq(Array(self.masters)[rr.grant].we),
78 86
 					bank.stb.eq(Array(bank_requested)[rr.grant])
79 87
 				]
80  
-				master_acks = [master_ack | ((rr.grant == nm) & bank.ack)
81  
-					for nm, master_ack in enumerate(master_acks)]
  88
+				master_req_acks = [master_req_ack | ((rr.grant == nm) & Array(bank_selected)[rr.grant] & bank.req_ack)
  89
+					for nm, master_req_ack in enumerate(master_req_acks)]
  90
+				master_dat_acks = [master_dat_ack | ((rr.grant == nm) & bank.dat_ack)
  91
+					for nm, master_dat_ack in enumerate(master_dat_acks)]
82 92
 
83  
-			self.comb += [master.ack.eq(master_ack) for master, master_ack in zip(self.masters, master_acks)]
  93
+			self.comb += [master.req_ack.eq(master_req_ack) for master, master_req_ack in zip(self.masters, master_req_acks)]
  94
+			self.comb += [master.dat_ack.eq(master_dat_ack) for master, master_dat_ack in zip(self.masters, master_dat_acks)]
84 95
 
85 96
 			# route data writes
86 97
 			controller_selected_wl = controller_selected
14  migen/bus/wishbone2lasmi.py
@@ -72,8 +72,8 @@ def __init__(self, cachesize, lasmim):
72 72
 		# Control FSM
73 73
 		assert(lasmim.write_latency >= 1 and lasmim.read_latency >= 1)
74 74
 		fsm = FSM("IDLE", "TEST_HIT",
75  
-			"EVICT_REQUEST", "EVICT_DATA",
76  
-			"REFILL_WRTAG", "REFILL_REQUEST", "REFILL_DATA",
  75
+			"EVICT_REQUEST", "EVICT_WAIT_DATA_ACK", "EVICT_DATA",
  76
+			"REFILL_WRTAG", "REFILL_REQUEST", "REFILL_WAIT_DATA_ACK", "REFILL_DATA",
77 77
 			delayed_enters=[
78 78
 				("EVICT_DATAD", "EVICT_DATA", lasmim.write_latency-1),
79 79
 				("REFILL_DATAD", "REFILL_DATA", lasmim.read_latency-1)
@@ -103,7 +103,10 @@ def __init__(self, cachesize, lasmim):
103 103
 		fsm.act(fsm.EVICT_REQUEST,
104 104
 			lasmim.stb.eq(1),
105 105
 			lasmim.we.eq(1),
106  
-			If(lasmim.ack, fsm.next_state(fsm.EVICT_DATAD))
  106
+			If(lasmim.req_ack, fsm.next_state(fsm.EVICT_WAIT_DATA_ACK))
  107
+		)
  108
+		fsm.act(fsm.EVICT_WAIT_DATA_ACK,
  109
+			If(lasmim.dat_ack, fsm.next_state(fsm.EVICT_DATAD))
107 110
 		)
108 111
 		fsm.act(fsm.EVICT_DATA,
109 112
 			write_to_lasmi.eq(1),
@@ -117,7 +120,10 @@ def __init__(self, cachesize, lasmim):
117 120
 		)
118 121
 		fsm.act(fsm.REFILL_REQUEST,
119 122
 			lasmim.stb.eq(1),
120  
-			If(lasmim.ack, fsm.next_state(fsm.REFILL_DATAD))
  123
+			If(lasmim.req_ack, fsm.next_state(fsm.REFILL_WAIT_DATA_ACK))
  124
+		)
  125
+		fsm.act(fsm.REFILL_WAIT_DATA_ACK,
  126
+			If(lasmim.dat_ack, fsm.next_state(fsm.REFILL_DATAD))
121 127
 		)
122 128
 		fsm.act(fsm.REFILL_DATA,
123 129
 			write_from_lasmi.eq(1),
38  migen/genlib/fifo.py
... ...
@@ -1,5 +1,6 @@
1 1
 from migen.fhdl.std import *
2 2
 from migen.genlib.cdc import NoRetiming, MultiReg, GrayCounter
  3
+from migen.genlib.record import layout_len, Record
3 4
 
4 5
 def _inc(signal, modulo):
5 6
 	if modulo == 2**flen(signal):
@@ -12,17 +13,28 @@ def _inc(signal, modulo):
12 13
 		)
13 14
 
14 15
 class _FIFOInterface:
15  
-	def __init__(self, width, depth):
16  
-		self.din = Signal(width)
  16
+	def __init__(self, width_or_layout, depth):
17 17
 		self.we = Signal()
18 18
 		self.writable = Signal() # not full
19  
-		self.dout = Signal(width)
20 19
 		self.re = Signal()
21 20
 		self.readable = Signal() # not empty
22 21
 
  22
+		if isinstance(width_or_layout, list):
  23
+			self.din = Record(width_or_layout)
  24
+			self.dout = Record(width_or_layout)
  25
+			self.din_bits = self.din.raw_bits()
  26
+			self.dout_bits = self.dout.raw_bits()
  27
+			self.width = layout_len(width_or_layout)
  28
+		else:
  29
+			self.din = Signal(width_or_layout)
  30
+			self.dout = Signal(width_or_layout)
  31
+			self.din_bits = self.din
  32
+			self.dout_bits = self.dout
  33
+			self.width = width_or_layout
  34
+
23 35
 class SyncFIFO(Module, _FIFOInterface):
24  
-	def __init__(self, width, depth):
25  
-		_FIFOInterface.__init__(self, width, depth)
  36
+	def __init__(self, width_or_layout, depth):
  37
+		_FIFOInterface.__init__(self, width_or_layout, depth)
26 38
 
27 39
 		###
28 40
 
@@ -36,14 +48,14 @@ def __init__(self, width, depth):
36 48
 		level = Signal(max=depth+1)
37 49
 		produce = Signal(max=depth)
38 50
 		consume = Signal(max=depth)
39  
-		storage = Memory(width, depth)
  51
+		storage = Memory(self.width, depth)
40 52
 		self.specials += storage
41 53
 
42 54
 		wrport = storage.get_port(write_capable=True)
43 55
 		self.specials += wrport
44 56
 		self.comb += [
45 57
 			wrport.adr.eq(produce),
46  
-			wrport.dat_w.eq(self.din),
  58
+			wrport.dat_w.eq(self.din_bits),
47 59
 			wrport.we.eq(do_write)
48 60
 		]
49 61
 		self.sync += If(do_write, _inc(produce, depth))
@@ -52,7 +64,7 @@ def __init__(self, width, depth):
52 64
 		self.specials += rdport
53 65
 		self.comb += [
54 66
 			rdport.adr.eq(consume),
55  
-			self.dout.eq(rdport.dat_r)
  67
+			self.dout_bits.eq(rdport.dat_r)
56 68
 		]
57 69
 		self.sync += If(do_read, _inc(consume, depth))
58 70
 
@@ -69,8 +81,8 @@ def __init__(self, width, depth):
69 81
 		]
70 82
 
71 83
 class AsyncFIFO(Module, _FIFOInterface):
72  
-	def __init__(self, width, depth):
73  
-		_FIFOInterface.__init__(self, width, depth)
  84
+	def __init__(self, width_or_layout, depth):
  85
+		_FIFOInterface.__init__(self, width_or_layout, depth)
74 86
 
75 87
 		###
76 88
 
@@ -102,18 +114,18 @@ def __init__(self, width, depth):
102 114
 			self.readable.eq(consume.q != produce_rdomain)
103 115
 		]
104 116
 
105  
-		storage = Memory(width, depth)
  117
+		storage = Memory(self.width, depth)
106 118
 		self.specials += storage
107 119
 		wrport = storage.get_port(write_capable=True, clock_domain="write")
108 120
 		self.specials += wrport
109 121
 		self.comb += [
110 122
 			wrport.adr.eq(produce.q_binary[:-1]),
111  
-			wrport.dat_w.eq(self.din),
  123
+			wrport.dat_w.eq(self.din_bits),
112 124
 			wrport.we.eq(produce.ce)
113 125
 		]
114 126
 		rdport = storage.get_port(clock_domain="read")
115 127
 		self.specials += rdport
116 128
 		self.comb += [
117 129
 			rdport.adr.eq(consume.q_binary[:-1]),
118  
-			self.dout.eq(rdport.dat_r)
  130
+			self.dout_bits.eq(rdport.dat_r)
119 131
 		]

No commit comments for this range

Something went wrong with that request. Please try again.