corelogic: reorder buffer (untested)
This commit is contained in:
parent
eed8fa374d
commit
43653dbe1a
|
@ -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)
|
Loading…
Reference in New Issue