Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 2 commits
  • 3 files changed
  • 0 comments
  • 1 contributor
46  milkymist/asmicon/bankmachine.py
@@ -13,16 +13,25 @@ def __init__(self, geom_settings, address_align):
13 13
 		self.address_align = address_align
14 14
 		
15 15
 		self._b1 = self.geom_settings.col_a - self.address_align
16  
-		self._b2 = self._b1 + self.geom_settings.row_a
17  
-	
18  
-	def bank(self, address):
19  
-		return address[self._b2:]
  16
+		self._b2 = self._b1 + self.geom_settings.bank_a
20 17
 	
21 18
 	def row(self, address):
22  
-		return address[self._b1:self._b2]
  19
+		if isinstance(address, int):
  20
+			return address >> self._b2
  21
+		else:
  22
+			return address[self._b2:]
  23
+	
  24
+	def bank(self, address):
  25
+		if isinstance(address, int):
  26
+			return (address & (2**self._b2 - 1)) >> self._b1
  27
+		else:
  28
+			return address[self._b1:self._b2]
23 29
 	
24 30
 	def col(self, address):
25  
-		return Cat(Constant(0, BV(self.address_align)), address[:self._b1])
  31
+		if isinstance(address, int):
  32
+			return (address & (2**self._b1 - 1)) << self.address_align
  33
+		else:
  34
+			return Cat(Constant(0, BV(self.address_align)), address[:self._b1])
26 35
 
27 36
 class _Selector:
28 37
 	def __init__(self, slicer, bankn, slots):
@@ -46,8 +55,8 @@ def get_fragment(self):
46 55
 		for slot in self.slots:
47 56
 			outstanding = Signal()
48 57
 			comb.append(outstanding.eq(
49  
-				self.slicer.bank(slot.adr) == self.bankn & \
50  
-				slot.state == SLOT_PENDING
  58
+				(self.slicer.bank(slot.adr) == self.bankn) & \
  59
+				(slot.state == SLOT_PENDING)
51 60
 			))
52 61
 			outstandings.append(outstanding)
53 62
 		
@@ -69,9 +78,9 @@ def get_fragment(self):
69 78
 			)
70 79
 		]
71 80
 		hits = []
72  
-		for slot in self.slots:
  81
+		for slot, os in zip(self.slots, outstandings):
73 82
 			hit = Signal()
74  
-			comb.append(hit.eq(self.slicer.row(slot.adr) == openrow))
  83
+			comb.append(hit.eq((self.slicer.row(slot.adr) == openrow) & os))
75 84
 			hits.append(hit)
76 85
 		
77 86
 		# Determine best request
@@ -79,8 +88,8 @@ def get_fragment(self):
79 88
 		has_hit = Signal()
80 89
 		comb.append(has_hit.eq(optree("|", hits)))
81 90
 		
82  
-		best_hit = [rr.request[i].eq(hit & os)
83  
-			for i, (hit, os) in enumerate(zip(hits, outstandings))]
  91
+		best_hit = [rr.request[i].eq(hit)
  92
+			for i, hit in enumerate(hits)]
84 93
 		best_fallback = [rr.request[i].eq(os)
85 94
 			for i, os in enumerate(outstandings)]
86 95
 		select_stmt = If(has_hit,
@@ -91,10 +100,15 @@ def get_fragment(self):
91 100
 		
92 101
 		if self.slots[0].time:
93 102
 			# Implement anti-starvation timer
  103
+			matures = []
  104
+			for slot, os in zip(self.slots, outstandings):
  105
+				mature = Signal()
  106
+				comb.append(mature.eq(slot.mature & os))
  107
+				matures.append(mature)
94 108
 			has_mature = Signal()
95  
-			comb.append(has_mature.eq(optree("|", [slot.mature for slot in self.slots])))
96  
-			best_mature = [rr.request[i].eq(slot.mature & os)
97  
-				for i, (slot, os) in enumerate(zip(self.slots, outstandings))]
  109
+			comb.append(has_mature.eq(optree("|", matures)))
  110
+			best_mature = [rr.request[i].eq(mature)
  111
+				for i, mature in enumerate(matures)]
98 112
 			select_stmt = If(has_mature, *best_mature).Else(select_stmt)
99 113
 		comb.append(select_stmt)
100 114
 		
@@ -109,7 +123,7 @@ def get_fragment(self):
109 123
 			rr.ce.eq(self.ack),
110 124
 			self.tag.eq(rr.grant)
111 125
 		]
112  
-		comb += [slot.process.eq(rr.grant == i & self.ack)
  126
+		comb += [slot.process.eq((rr.grant == i) & self.stb & self.ack)
113 127
 			for i, slot in enumerate(self.slots)]
114 128
 		
115 129
 		return Fragment(comb, sync) + rr.get_fragment()
25  tb/asmicon/common.py
@@ -39,3 +39,28 @@ def do_simulation(self, s):
39 39
 	
40 40
 	def get_fragment(self):
41 41
 		return Fragment(sim=[self.do_simulation])
  42
+
  43
+class SlotsLogger:
  44
+	def __init__(self, slicer, slots):
  45
+		self.slicer = slicer
  46
+		self.slots = slots
  47
+		
  48
+	def do_simulation(self, sim):
  49
+		state_strs = ["EMPTY", "PEND", "PRCESS"]
  50
+		rw_strs = ["RD", "WR"]
  51
+		print("\t" + "\t".join([str(x) for x in range(len(self.slots))]))
  52
+		print("State:\t" + "\t".join([state_strs[sim.rd(s.state)] for s in self.slots]))
  53
+		print("RW:\t" + "\t".join([rw_strs[sim.rd(s.we)] for s in self.slots]))
  54
+		print("Row:\t" + "\t".join([str(self.slicer.row(sim.rd(s.adr))) for s in self.slots]))
  55
+		print("Bank:\t" + "\t".join([str(self.slicer.bank(sim.rd(s.adr))) for s in self.slots]))
  56
+		print("Col:\t" + "\t".join([str(self.slicer.col(sim.rd(s.adr))) for s in self.slots]))
  57
+		times = []
  58
+		for s in self.slots:
  59
+			if s.time:
  60
+				times.append(str(sim.rd(s._counter)) + "/" + str(s.time))
  61
+			else:
  62
+				times.append("N/A")
  63
+		print("Time:\t" + "\t".join(times))
  64
+
  65
+	def get_fragment(self):
  66
+		return Fragment(sim=[self.do_simulation])
77  tb/asmicon/selector.py
... ...
@@ -0,0 +1,77 @@
  1
+from migen.fhdl.structure import *
  2
+from migen.bus.asmibus import *
  3
+from migen.sim.generic import Simulator, TopLevel
  4
+from migen.sim.icarus import Runner
  5
+
  6
+from milkymist import asmicon
  7
+from milkymist.asmicon.bankmachine import _AddressSlicer, _Selector, _Buffer
  8
+
  9
+from common import SlotsLogger
  10
+
  11
+sdram_geom = asmicon.GeomSettings(
  12
+	bank_a=2,
  13
+	row_a=13,
  14
+	col_a=10
  15
+)
  16
+
  17
+def my_generator(dt, offset):
  18
+	for t in range(dt):
  19
+		yield None
  20
+	for x in range(10):
  21
+		t = TRead(x + offset)
  22
+		yield t
  23
+
  24
+class Selector:
  25
+	def __init__(self, slicer, bankn, slots):
  26
+		self.selector = _Selector(slicer, bankn, slots)
  27
+		self.queue = []
  28
+	
  29
+	def do_simulation(self, s):
  30
+		if s.rd(self.selector.stb):
  31
+			tag = s.rd(self.selector.tag)
  32
+			self.queue.append(tag)
  33
+			print("==> SELECTED: " + str(tag))
  34
+		print("")
  35
+	
  36
+	def get_fragment(self):
  37
+		comb = [self.selector.ack.eq(1)]
  38
+		return self.selector.get_fragment() + Fragment(comb, sim=[self.do_simulation])
  39
+
  40
+class Completer:
  41
+	def __init__(self, hub, queue):
  42
+		self.hub = hub
  43
+		self.queue = queue
  44
+	
  45
+	def do_simulation(self, s):
  46
+		if self.queue:
  47
+			tag = self.queue.pop()
  48
+			s.wr(self.hub.call, 1)
  49
+			s.wr(self.hub.tag_call, tag)
  50
+		else:
  51
+			s.wr(self.hub.call, 0)
  52
+		
  53
+	def get_fragment(self):
  54
+		return Fragment(sim=[self.do_simulation])
  55
+
  56
+def main():
  57
+	hub = Hub(12, 128, 8)
  58
+	initiators = [Initiator(hub.get_port(), my_generator(0, 2200*(i//6)+i*10))
  59
+		for i in range(8)]
  60
+	hub.finalize()
  61
+	
  62
+	slots = hub.get_slots()
  63
+	slicer = _AddressSlicer(sdram_geom, 2)
  64
+	logger = SlotsLogger(slicer, slots)
  65
+	selector = Selector(slicer, 0, slots)
  66
+	completer = Completer(hub, selector.queue)
  67
+	
  68
+	def end_simulation(s):
  69
+		s.interrupt = all([i.done for i in initiators])
  70
+	
  71
+	fragment = hub.get_fragment() + sum([i.get_fragment() for i in initiators], Fragment()) + \
  72
+		logger.get_fragment() + selector.get_fragment() + completer.get_fragment() + \
  73
+		Fragment(sim=[end_simulation])
  74
+	sim = Simulator(fragment, Runner(), TopLevel("my.vcd"))
  75
+	sim.run()
  76
+
  77
+main()

No commit comments for this range

Something went wrong with that request. Please try again.