Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

bus/lasmi: interface definition and crossbar (untested)

  • Loading branch information...
commit 35f9f2e9d7c7dd374a0decea8a5ee28cfaa87f4c 1 parent 85813b3
Sébastien Bourdeauducq authored June 08, 2013

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

  1. 147  migen/bus/lasmibus.py
147  migen/bus/lasmibus.py
... ...
@@ -0,0 +1,147 @@
  1
+from migen.fhdl.std import *
  2
+from migen.genlib import roundrobin
  3
+from migen.genlib.record import *
  4
+from migen.genlib.misc import optree
  5
+
  6
+class Interface(Record):
  7
+	def __init__(self, aw, dw, nbanks, read_latency, write_latency):
  8
+		self.aw = aw
  9
+		self.dw = dw
  10
+		self.nbanks = nbanks
  11
+		self.read_latency = read_latency
  12
+		self.write_latency = write_latency
  13
+
  14
+		bank_layout = [
  15
+			("adr",		aw,		DIR_M_TO_S),
  16
+			("we",		1,		DIR_M_TO_S),
  17
+			("stb",		1,		DIR_M_TO_S),
  18
+			("ack",		1,		DIR_S_TO_M)
  19
+		]
  20
+		if nbanks > 1:
  21
+			layout = [("bank"+str(i), bank_layout) for i in range(nbanks)]
  22
+		else:
  23
+			layout = bank_layout
  24
+		layout += [
  25
+			("dat_w",	dw, 	DIR_M_TO_S),
  26
+			("dat_we",	dw//8, 	DIR_M_TO_S),
  27
+			("dat_r",	dw, 	DIR_S_TO_M)
  28
+		]
  29
+		Record.__init__(self, layout)
  30
+
  31
+def _getattr_all(l, attr):
  32
+	it = iter(l)
  33
+	r = getattr(next(it), attr)
  34
+	for e in it:
  35
+		if getattr(e, attr) != r:
  36
+			raise ValueError
  37
+	return r
  38
+
  39
+class Crossbar(Module):
  40
+	def __init__(self, controllers, nmasters, cba_shift):
  41
+		ncontrollers = len(controllers)
  42
+		rca_bits = _getattr_all(controllers, "aw")
  43
+		dw = _getattr_all(controllers, "dw")
  44
+		nbanks = _getattr_all(controllers, "nbanks")
  45
+		read_latency = _getattr_all(controllers, "read_latency")
  46
+		write_latency = _getattr_all(controllers, "write_latency")
  47
+
  48
+		bank_bits = log2_int(nbanks, False)
  49
+		controller_bits = log2_int(ncontrollers, False)
  50
+		self.masters = [Interface(rca_bits + bank_bits + controller_bits, dw, 1, read_latency, write_latency)
  51
+			for i in range(nmasters)]
  52
+		masters_a = Array(self.masters)
  53
+
  54
+		###
  55
+
  56
+		m_ca, m_ba, m_rca = self._split_master_addresses(controller_bits, bank_bits, rca_bits, cba_shift)
  57
+		
  58
+		for nc, controller in enumerate(controllers):
  59
+			if controller_bits:
  60
+				controller_selected = [ca == nc for ca in m_ca]
  61
+			else:
  62
+				controller_selected = [1]*nmasters
  63
+			for nb in range(nbanks):
  64
+				bank = getattr(controller, "bank"+str(nb))
  65
+
  66
+				# arbitrate
  67
+				rr = roundrobin.RoundRobin(nmasters, roundrobin.SP_CE)
  68
+				self.submodules += rr
  69
+				bank_selected = [cs & (ba == nb) for cs, ba in zip(controller_selected, m_ba)]
  70
+				bank_requested = [bs & master.stb for bs, master in zip(bank_selected, self.masters)]
  71
+				self.comb += [
  72
+					rr.request.eq(Cat(*bank_requested)),
  73
+					rr.ce.eq(~bank.stb | bank.ack)
  74
+				]
  75
+
  76
+				# route requests
  77
+				self.comb += [
  78
+					bank.adr.eq(Array(m_rca)[rr.grant]),
  79
+					bank.we.eq(masters_a[rr.grant].we),
  80
+					bank.stb.eq(masters_a[rr.grant].stb),
  81
+					masters_a[rr.grant].ack.eq(bank.ack)
  82
+				]
  83
+
  84
+			# route data writes
  85
+			controller_selected_wl = controller_selected
  86
+			for i in range(write_latency):
  87
+				n_controller_selected_wl = [Signal() for i in range(nmasters)]
  88
+				self.sync += [n.eq(o) for n, o in zip(n_controller_selected_wl, controller_selected_wl)]
  89
+				controller_selected_wl = n_controller_selected_wl
  90
+			dat_w_maskselect = []
  91
+			dat_we_maskselect = []
  92
+			for master, selected in zip(self.masters, controller_selected_wl):
  93
+				o_dat_w = Signal(dw)
  94
+				o_dat_we = Signal(dw//8)
  95
+				self.comb += If(selected,
  96
+						o_dat_w.eq(master.dat_w),
  97
+						o_dat_we.eq(master.dat_we)
  98
+					)
  99
+				dat_w_maskselect.append(o_dat_w)
  100
+				dat_we_maskselect.append(o_dat_we)
  101
+			self.comb += [
  102
+				controller.dat_w.eq(optree("|", dat_w_maskselect)),
  103
+				controller.dat_we.eq(optree("|", dat_we_maskselect))
  104
+			]
  105
+
  106
+		# route data reads
  107
+		if controller_bits:
  108
+			for master in self.masters:
  109
+				controller_sel = Signal(controller_bits)
  110
+				for nc, controller in enumerate(controllers):
  111
+					for nb in range(nbanks):
  112
+						bank = getattr(controller, "bank"+str(nb))
  113
+						self.comb += If(bank.stb & bank.ack, controller_sel.eq(nc))
  114
+				for i in range(read_latency):
  115
+					n_controller_sel = Signal(controller_bits)
  116
+					self.sync += n_controller_sel.eq(controller_sel)
  117
+					controller_sel = n_controller_sel
  118
+				self.comb += master.dat_r.eq(Array(controllers)[controller_sel].dat_r)
  119
+		else:
  120
+			self.comb += [master.dat_r.eq(controllers[0].dat_r) for master in self.masters]
  121
+
  122
+	def _split_master_addresses(self, controller_bits, bank_bits, rca_bits, cba_shift):
  123
+		m_ca = []	# controller address
  124
+		m_ba = []	# bank address
  125
+		m_rca = []	# row and column address
  126
+		for master in self.masters:
  127
+			cba = Signal(controller_bits + bank_bits)
  128
+			rca = Signal(rca_bits)
  129
+			cba_upper = cba_shift + controller_bits + bank_bits
  130
+			self.comb += cba.eq(master.adr[cba_shift:cba_upper])
  131
+			if cba_shift < rca_bits:
  132
+				self.comb += rca.eq(Cat(master.adr[:cba_shift], master.adr[cba_upper:]))
  133
+			else:
  134
+				self.comb += rca.eq(master.adr[:cba_shift])
  135
+
  136
+			if controller_bits:
  137
+				ca = Signal(controller_bits)
  138
+				ba = Signal(bank_bits)
  139
+				self.comb += Cat(ba, ca).eq(cba)
  140
+			else:
  141
+				ca = None
  142
+				ba = cba
  143
+
  144
+			m_ca.append(ca)
  145
+			m_ba.append(ba)
  146
+			m_rca.append(rca)
  147
+		return m_ca, m_ba, m_rca

0 notes on commit 35f9f2e

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