Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

bus/asmi: port sharing support

  • Loading branch information...
commit 792b8fed1bfd78cc228cec85ec4c4acc59aee180 1 parent f202946
Sébastien Bourdeauducq authored May 12, 2013

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

  1. 81  migen/bus/asmibus.py
81  migen/bus/asmibus.py
... ...
@@ -1,6 +1,7 @@
1 1
 from migen.fhdl.structure import *
2 2
 from migen.fhdl.module import Module, FinalizeError
3 3
 from migen.genlib.misc import optree
  4
+from migen.genlib import roundrobin
4 5
 from migen.bus.transactions import *
5 6
 from migen.sim.generic import Proxy
6 7
 
@@ -300,3 +301,83 @@ def do_simulation(self, s):
300 301
 		else:
301 302
 			s.wr(self.hub.call, 0)
302 303
 			self._calling_tag = -1
  304
+
  305
+# Port sharing
  306
+
  307
+class SharedPort:
  308
+	def __init__(self, base_port):
  309
+		if not base_port.finalized:
  310
+			raise FinalizeError
  311
+		self.finalized = True
  312
+
  313
+		nslots = len(base_port.slots)
  314
+
  315
+		self.hub = base_port.hub
  316
+		self.base = base_port.base
  317
+		# 1 if that slot is assigned to us
  318
+		self.slots = [Signal() for i in range(nslots)]
  319
+		
  320
+		# request issuance
  321
+		self.adr = Signal(self.hub.aw)
  322
+		self.we = Signal()
  323
+		self.stb = Signal()
  324
+		if nslots > 1:
  325
+			self.tag_issue = Signal(max=nslots)
  326
+		self.ack = Signal()
  327
+		
  328
+		# request completion
  329
+		self.call = Signal()
  330
+		self.tag_call = Signal(self.hub.tagbits)
  331
+		self.dat_r = Signal(self.hub.dw)
  332
+		self.dat_w = Signal(self.hub.dw)
  333
+		self.dat_wm = Signal(self.hub.dw//8)
  334
+
  335
+	def get_call_expression(self, slotn=0):
  336
+		if not self.finalized:
  337
+			raise FinalizeError
  338
+		return self.call \
  339
+			& (self.tag_call == (self.base + slotn))
  340
+
  341
+class PortSharer(Module):
  342
+	def __init__(self, base_port, nshares):
  343
+		self.shared_ports = [SharedPort(base_port) for i in range(nshares)]
  344
+
  345
+		###
  346
+
  347
+		# request issuance
  348
+		self.submodules.rr = roundrobin.RoundRobin(nshares, roundrobin.SP_CE)
  349
+		self.comb += [
  350
+			self.rr.request.eq(Cat(*[sp.stb for sp in self.shared_ports])),
  351
+			self.rr.ce.eq(base_port.ack)
  352
+		]
  353
+		self.comb += [
  354
+			base_port.adr.eq(Array(sp.adr for sp in self.shared_ports)[self.rr.grant]),
  355
+			base_port.we.eq(Array(sp.we for sp in self.shared_ports)[self.rr.grant]),
  356
+			base_port.stb.eq(Array(sp.stb for sp in self.shared_ports)[self.rr.grant]),
  357
+		]
  358
+		if hasattr(base_port, "tag_issue"):
  359
+			self.comb += [sp.tag_issue.eq(base_port.tag_issue) for sp in self.shared_ports]
  360
+		self.comb += [sp.ack.eq(base_port.ack & (self.rr.grant == n)) for n, sp in enumerate(self.shared_ports)]
  361
+
  362
+		# request completion
  363
+		self.comb += [sp.call.eq(base_port.call & Array(sp.slots)[base_port.tag_call-base_port.base])
  364
+			for sp in self.shared_ports]
  365
+		self.comb += [sp.tag_call.eq(base_port.tag_call) for sp in self.shared_ports]
  366
+		self.comb += [sp.dat_r.eq(base_port.dat_r) for sp in self.shared_ports]
  367
+		self.comb += [
  368
+			base_port.dat_w.eq(optree("|", [sp.dat_w for sp in self.shared_ports])),
  369
+			base_port.dat_wm.eq(optree("|", [sp.dat_wm for sp in self.shared_ports])),
  370
+		]
  371
+		
  372
+		# request ownership tracking
  373
+		if hasattr(base_port, "tag_issue"):
  374
+			for sp in self.shared_ports:
  375
+				self.sync += If(sp.stb & sp.ack, Array(sp.slots)[sp.tag_issue].eq(1))
  376
+				for n, slot in enumerate(sp.slots):
  377
+					self.sync += If(base_port.call & (base_port.tag_call == (base_port.base + n)), slot.eq(0))
  378
+		else:
  379
+			for sp in self.shared_ports:
  380
+				self.sync += [
  381
+					If(sp.stb & sp.ack, sp.slots[0].eq(1)),
  382
+					If(base_port.call & (base_port.tag_call == base_port.base), sp.slots[0].eq(0))
  383
+				]

0 notes on commit 792b8fe

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