From 43653dbe1aafc9a9036735d9c2eb31f291c4bd68 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Thu, 12 Jul 2012 18:33:28 +0200 Subject: [PATCH] corelogic: reorder buffer (untested) --- migen/corelogic/buffers.py | 80 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 migen/corelogic/buffers.py diff --git a/migen/corelogic/buffers.py b/migen/corelogic/buffers.py new file mode 100644 index 000000000..b788a34fb --- /dev/null +++ b/migen/corelogic/buffers.py @@ -0,0 +1,80 @@ +from migen.fhdl.structure import * + +class ReorderSlot: + def __init__(self, tag_width, data_width): + self.wait_data = Signal() + self.has_data = Signal() + self.tag = Signal(BV(tag_width)) + self.data = Signal(BV(data_width)) + +class ReorderBuffer: + def __init__(self, tag_width, data_width, depth): + self.depth = depth + + # issue + self.can_issue = Signal() + self.issue = Signal() + self.tag_issue = Signal(BV(tag_width)) + + # call + self.call = Signal() + self.tag_call = Signal(BV(tag_width)) + self.data_call = Signal(BV(data_width)) + + # readback + self.can_read = Signal() + self.read = Signal() + self.data_read = Signal(BV(data_width)) + + self._empty_count = Signal(BV(bits_for(self.depth)), reset=self.depth) + self._produce = Signal(BV(bits_for(self.depth-1))) + self._consume = Signal(BV(bits_for(self.depth-1))) + self._slots = Array(ReorderSlot(tag_width, data_width) + for n in range(self.depth)) + + def get_fragment(self): + # issue + comb = [ + self.can_issue.eq(self._empty_count != 0) + ] + sync = [ + If(self.issue & self.can_issue, + self._empty_count.eq(self._empty_count - 1), + If(self._produce == self.depth - 1, + self._produce.eq(0) + ).Else( + self._produce.eq(self._produce + 1) + ), + self._slots[self._produce].wait_data.eq(1), + self._slots[self._produce].tag.eq(self.tag_issue) + ) + ] + + # call + for n, slot in enumerate(self._slots): + sync.append( + If(self.call & slot.wait_data & (self.tag_call == slot.tag), + slot.wait_data.eq(0), + slot.has_data.eq(1), + slot.data.eq(self.data_call) + ) + ) + + # readback + comb += [ + self.can_read.eq(self._slots[self._consume].has_data), + self.data_read.eq(self._slots[self._consume].data) + ] + sync += [ + If(self.read & self.can_read, + self._empty_count.eq(self._empty_count + 1), + If(self._consume == self.depth - 1, + self._consume.eq(0) + ).Else( + self._consume.eq(self._consume + 1) + ), + self._slots[self._consume].has_data.eq(0) + ) + ] + + return Fragment(comb, sync) \ No newline at end of file