Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
  • 2 commits
  • 3 files changed
  • 0 commit comments
  • 1 contributor
View
46 milkymist/asmicon/bankmachine.py
@@ -13,16 +13,25 @@ def __init__(self, geom_settings, address_align):
self.address_align = address_align
self._b1 = self.geom_settings.col_a - self.address_align
- self._b2 = self._b1 + self.geom_settings.row_a
-
- def bank(self, address):
- return address[self._b2:]
+ self._b2 = self._b1 + self.geom_settings.bank_a
def row(self, address):
- return address[self._b1:self._b2]
+ if isinstance(address, int):
+ return address >> self._b2
+ else:
+ return address[self._b2:]
+
+ def bank(self, address):
+ if isinstance(address, int):
+ return (address & (2**self._b2 - 1)) >> self._b1
+ else:
+ return address[self._b1:self._b2]
def col(self, address):
- return Cat(Constant(0, BV(self.address_align)), address[:self._b1])
+ if isinstance(address, int):
+ return (address & (2**self._b1 - 1)) << self.address_align
+ else:
+ return Cat(Constant(0, BV(self.address_align)), address[:self._b1])
class _Selector:
def __init__(self, slicer, bankn, slots):
@@ -46,8 +55,8 @@ def get_fragment(self):
for slot in self.slots:
outstanding = Signal()
comb.append(outstanding.eq(
- self.slicer.bank(slot.adr) == self.bankn & \
- slot.state == SLOT_PENDING
+ (self.slicer.bank(slot.adr) == self.bankn) & \
+ (slot.state == SLOT_PENDING)
))
outstandings.append(outstanding)
@@ -69,9 +78,9 @@ def get_fragment(self):
)
]
hits = []
- for slot in self.slots:
+ for slot, os in zip(self.slots, outstandings):
hit = Signal()
- comb.append(hit.eq(self.slicer.row(slot.adr) == openrow))
+ comb.append(hit.eq((self.slicer.row(slot.adr) == openrow) & os))
hits.append(hit)
# Determine best request
@@ -79,8 +88,8 @@ def get_fragment(self):
has_hit = Signal()
comb.append(has_hit.eq(optree("|", hits)))
- best_hit = [rr.request[i].eq(hit & os)
- for i, (hit, os) in enumerate(zip(hits, outstandings))]
+ best_hit = [rr.request[i].eq(hit)
+ for i, hit in enumerate(hits)]
best_fallback = [rr.request[i].eq(os)
for i, os in enumerate(outstandings)]
select_stmt = If(has_hit,
@@ -91,10 +100,15 @@ def get_fragment(self):
if self.slots[0].time:
# Implement anti-starvation timer
+ matures = []
+ for slot, os in zip(self.slots, outstandings):
+ mature = Signal()
+ comb.append(mature.eq(slot.mature & os))
+ matures.append(mature)
has_mature = Signal()
- comb.append(has_mature.eq(optree("|", [slot.mature for slot in self.slots])))
- best_mature = [rr.request[i].eq(slot.mature & os)
- for i, (slot, os) in enumerate(zip(self.slots, outstandings))]
+ comb.append(has_mature.eq(optree("|", matures)))
+ best_mature = [rr.request[i].eq(mature)
+ for i, mature in enumerate(matures)]
select_stmt = If(has_mature, *best_mature).Else(select_stmt)
comb.append(select_stmt)
@@ -109,7 +123,7 @@ def get_fragment(self):
rr.ce.eq(self.ack),
self.tag.eq(rr.grant)
]
- comb += [slot.process.eq(rr.grant == i & self.ack)
+ comb += [slot.process.eq((rr.grant == i) & self.stb & self.ack)
for i, slot in enumerate(self.slots)]
return Fragment(comb, sync) + rr.get_fragment()
View
25 tb/asmicon/common.py
@@ -39,3 +39,28 @@ def do_simulation(self, s):
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])
View
77 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()

No commit comments for this range

Something went wrong with that request. Please try again.