Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 2 commits
  • 2 files changed
  • 0 comments
  • 1 contributor
19  examples/sim/abstract_transactions_lasmi.py
@@ -4,27 +4,32 @@
4 4
 from migen.sim.generic import Simulator
5 5
 
6 6
 def my_generator(n):
  7
+	bank = n % 4
7 8
 	for x in range(4):
8  
-		t = TWrite(4*n+x, 0x100+x)
  9
+		t = TWrite(4*bank+x, 0x1000*bank + 0x100*x)
9 10
 		yield t
10  
-		print("Wrote in {0} cycle(s)".format(t.latency))
  11
+		print("{0}: Wrote in {1} cycle(s)".format(n, t.latency))
11 12
 		
12 13
 	for x in range(4):
13  
-		t = TRead(4*n+x)
  14
+		t = TRead(4*bank+x)
14 15
 		yield t
15  
-		print("Read {0:x} in {1:x} cycle(s)".format(t.data, t.latency))
  16
+		print("{0}: Read {1:x} in {2} cycle(s)".format(n, t.data, t.latency))
  17
+		assert(t.data == 0x1000*bank + 0x100*x)
16 18
 
17 19
 class MyModel(lasmibus.TargetModel):
18 20
 	def read(self, bank, address):
19  
-		#print("read from bank {0} address {1}".format(bank, address))
20  
-		return 0x1000*bank + 0x200+address
  21
+		r = 0x1000*bank + 0x100*address
  22
+		#print("read from bank {0} address {1} -> {2:x}".format(bank, address, r))
  23
+		return r
21 24
 	
22 25
 	def write(self, bank, address, data, we):
23 26
 		print("write to bank {0} address {1:x} data {2:x}".format(bank, address, data))
  27
+		assert(data == 0x1000*bank + 0x100*address)
24 28
 
25 29
 class TB(Module):
26 30
 	def __init__(self):
27  
-		self.submodules.controller = lasmibus.Target(MyModel(), aw=4, dw=32, nbanks=4, read_latency=4, write_latency=1)
  31
+		self.submodules.controller = lasmibus.Target(MyModel(), aw=4, dw=32, nbanks=4, req_queue_size=4,
  32
+			read_latency=4, write_latency=1)
28 33
 		self.submodules.xbar = lasmibus.Crossbar([self.controller.bus], 4, 2)
29 34
 		self.initiators = [lasmibus.Initiator(my_generator(n), bus) for n, bus in enumerate(self.xbar.masters)]
30 35
 		self.submodules += self.initiators
52  migen/bus/lasmibus.py
@@ -174,12 +174,14 @@ def do_simulation(self, s):
174 174
 		s.wr(self.bus.dat_w, 0)
175 175
 		s.wr(self.bus.dat_we, 0)
176 176
 		if not self.done:
177  
-			if self.transaction is not None and s.rd(self.bus.ack):
178  
-				s.wr(self.bus.stb, 0)
179  
-				if isinstance(self.transaction, TRead):
180  
-					self.transaction_end = s.cycle_counter + self.bus.read_latency
181  
-				else:
182  
-					self.transaction_end = s.cycle_counter + self.bus.write_latency - 1
  177
+			if self.transaction is not None:
  178
+				if s.rd(self.bus.req_ack):
  179
+					s.wr(self.bus.stb, 0)
  180
+				if s.rd(self.bus.dat_ack):
  181
+					if isinstance(self.transaction, TRead):
  182
+						self.transaction_end = s.cycle_counter + self.bus.read_latency
  183
+					else:
  184
+						self.transaction_end = s.cycle_counter + self.bus.write_latency - 1
183 185
 
184 186
 			if self.transaction is None or s.cycle_counter == self.transaction_end:
185 187
 				if self.transaction is not None:
@@ -224,38 +226,54 @@ def select_bank(self, pending_banks):
224 226
 			self.last_bank += 1
225 227
 		return self.last_bank
226 228
 
  229
+class _ReqFIFO(Module):
  230
+	def __init__(self, req_queue_size, bank):
  231
+		self.req_queue_size = req_queue_size
  232
+		self.bank = bank
  233
+		self.contents = []
  234
+
  235
+	def do_simulation(self, s):
  236
+		if len(self.contents) < self.req_queue_size:
  237
+			if s.rd(self.bank.stb):
  238
+				self.contents.append((s.rd(self.bank.we), s.rd(self.bank.adr)))
  239
+			s.wr(self.bank.req_ack, 1)
  240
+		else:
  241
+			s.wr(self.bank.req_ack, 0)
  242
+		s.wr(self.bank.lock, bool(self.contents))
  243
+
227 244
 class Target(Module):
228 245
 	def __init__(self, model, *ifargs, **ifkwargs):
229 246
 		self.model = model
230 247
 		self.bus = Interface(*ifargs, **ifkwargs)
  248
+		self.req_fifos = [_ReqFIFO(self.bus.req_queue_size, getattr(self.bus, "bank"+str(nb)))
  249
+			for nb in range(self.bus.nbanks)]
  250
+		self.submodules += self.req_fifos
231 251
 		self.rd_pipeline = [None]*self.bus.read_latency
232 252
 		self.wr_pipeline = [None]*(self.bus.write_latency + 1)
233 253
 
234 254
 	def do_simulation(self, s):
235 255
 		# determine banks with pending requests
236  
-		pending_banks = set()
237  
-		for nb in range(self.bus.nbanks):
238  
-			bank = getattr(self.bus, "bank"+str(nb))
239  
-			if s.rd(bank.stb) and not s.rd(bank.ack):
240  
-				pending_banks.add(nb)
  256
+		pending_banks = set(nb for nb, rf in enumerate(self.req_fifos) if rf.contents)
241 257
 
242 258
 		# issue new transactions
243 259
 		selected_bank_n = self.model.select_bank(pending_banks)
  260
+		selected_transaction = None
244 261
 		for nb in range(self.bus.nbanks):
245 262
 			bank = getattr(self.bus, "bank"+str(nb))
246 263
 			if nb == selected_bank_n:
247  
-				s.wr(bank.ack, 1)
  264
+				s.wr(bank.dat_ack, 1)
  265
+				selected_transaction = self.req_fifos[nb].contents.pop(0)
248 266
 			else:
249  
-				s.wr(bank.ack, 0)
  267
+				s.wr(bank.dat_ack, 0)
250 268
 		
251 269
 		rd_transaction = None
252 270
 		wr_transaction = None
253 271
 		if selected_bank_n >= 0:
254  
-			selected_bank = getattr(self.bus, "bank"+str(selected_bank_n))
255  
-			if s.rd(selected_bank.we):
256  
-				wr_transaction = selected_bank_n, s.rd(selected_bank.adr)
  272
+			we, adr = selected_transaction
  273
+			if we:
  274
+				wr_transaction = selected_bank_n, adr
257 275
 			else:
258  
-				rd_transaction = selected_bank_n, s.rd(selected_bank.adr)
  276
+				rd_transaction = selected_bank_n, adr
259 277
 
260 278
 		# data pipeline
261 279
 		self.rd_pipeline.append(rd_transaction)

No commit comments for this range

Something went wrong with that request. Please try again.