From c129c98e10fde53fd5f180c04249584cb3188bb7 Mon Sep 17 00:00:00 2001
From: Sebastien Bourdeauducq <sebastien@milkymist.org>
Date: Sat, 31 Mar 2012 09:56:22 +0200
Subject: [PATCH] tb/asmicon/bankmachine: selector test bench

---
 tb/asmicon/common.py   | 25 ++++++++++++++
 tb/asmicon/selector.py | 77 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 102 insertions(+)
 create mode 100644 tb/asmicon/selector.py

diff --git a/tb/asmicon/common.py b/tb/asmicon/common.py
index f5ff89643..01d761b50 100644
--- a/tb/asmicon/common.py
+++ b/tb/asmicon/common.py
@@ -39,3 +39,28 @@ class CommandLogger:
 	
 	def get_fragment(self):
 		return Fragment(sim=[self.do_simulation])
+
+class SlotsLogger:
+	def __init__(self, slicer, slots):
+		self.slicer = slicer
+		self.slots = slots
+		
+	def do_simulation(self, sim):
+		state_strs = ["EMPTY", "PEND", "PRCESS"]
+		rw_strs = ["RD", "WR"]
+		print("\t" + "\t".join([str(x) for x in range(len(self.slots))]))
+		print("State:\t" + "\t".join([state_strs[sim.rd(s.state)] for s in self.slots]))
+		print("RW:\t" + "\t".join([rw_strs[sim.rd(s.we)] for s in self.slots]))
+		print("Row:\t" + "\t".join([str(self.slicer.row(sim.rd(s.adr))) for s in self.slots]))
+		print("Bank:\t" + "\t".join([str(self.slicer.bank(sim.rd(s.adr))) for s in self.slots]))
+		print("Col:\t" + "\t".join([str(self.slicer.col(sim.rd(s.adr))) for s in self.slots]))
+		times = []
+		for s in self.slots:
+			if s.time:
+				times.append(str(sim.rd(s._counter)) + "/" + str(s.time))
+			else:
+				times.append("N/A")
+		print("Time:\t" + "\t".join(times))
+
+	def get_fragment(self):
+		return Fragment(sim=[self.do_simulation])
diff --git a/tb/asmicon/selector.py b/tb/asmicon/selector.py
new file mode 100644
index 000000000..b817c71d8
--- /dev/null
+++ b/tb/asmicon/selector.py
@@ -0,0 +1,77 @@
+from migen.fhdl.structure import *
+from migen.bus.asmibus import *
+from migen.sim.generic import Simulator, TopLevel
+from migen.sim.icarus import Runner
+
+from milkymist import asmicon
+from milkymist.asmicon.bankmachine import _AddressSlicer, _Selector, _Buffer
+
+from common import SlotsLogger
+
+sdram_geom = asmicon.GeomSettings(
+	bank_a=2,
+	row_a=13,
+	col_a=10
+)
+
+def my_generator(dt, offset):
+	for t in range(dt):
+		yield None
+	for x in range(10):
+		t = TRead(x + offset)
+		yield t
+
+class Selector:
+	def __init__(self, slicer, bankn, slots):
+		self.selector = _Selector(slicer, bankn, slots)
+		self.queue = []
+	
+	def do_simulation(self, s):
+		if s.rd(self.selector.stb):
+			tag = s.rd(self.selector.tag)
+			self.queue.append(tag)
+			print("==> SELECTED: " + str(tag))
+		print("")
+	
+	def get_fragment(self):
+		comb = [self.selector.ack.eq(1)]
+		return self.selector.get_fragment() + Fragment(comb, sim=[self.do_simulation])
+
+class Completer:
+	def __init__(self, hub, queue):
+		self.hub = hub
+		self.queue = queue
+	
+	def do_simulation(self, s):
+		if self.queue:
+			tag = self.queue.pop()
+			s.wr(self.hub.call, 1)
+			s.wr(self.hub.tag_call, tag)
+		else:
+			s.wr(self.hub.call, 0)
+		
+	def get_fragment(self):
+		return Fragment(sim=[self.do_simulation])
+
+def main():
+	hub = Hub(12, 128, 8)
+	initiators = [Initiator(hub.get_port(), my_generator(0, 2200*(i//6)+i*10))
+		for i in range(8)]
+	hub.finalize()
+	
+	slots = hub.get_slots()
+	slicer = _AddressSlicer(sdram_geom, 2)
+	logger = SlotsLogger(slicer, slots)
+	selector = Selector(slicer, 0, slots)
+	completer = Completer(hub, selector.queue)
+	
+	def end_simulation(s):
+		s.interrupt = all([i.done for i in initiators])
+	
+	fragment = hub.get_fragment() + sum([i.get_fragment() for i in initiators], Fragment()) + \
+		logger.get_fragment() + selector.get_fragment() + completer.get_fragment() + \
+		Fragment(sim=[end_simulation])
+	sim = Simulator(fragment, Runner(), TopLevel("my.vcd"))
+	sim.run()
+
+main()