From cabae0c32b0caac9ed8104c5119b9839eb822f06 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Wed, 24 Jul 2013 19:25:14 +0200 Subject: [PATCH] genlib: remove direct uses of Fragment --- migen/genlib/buffers.py | 87 ----------------------------------------- migen/genlib/cdc.py | 27 ++++++------- migen/genlib/rob.py | 76 +++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 103 deletions(-) delete mode 100644 migen/genlib/buffers.py create mode 100644 migen/genlib/rob.py diff --git a/migen/genlib/buffers.py b/migen/genlib/buffers.py deleted file mode 100644 index 34a9a913..00000000 --- a/migen/genlib/buffers.py +++ /dev/null @@ -1,87 +0,0 @@ -from migen.fhdl.std import * - -class ReorderSlot: - def __init__(self, tag_width, data_width): - self.wait_data = Signal() - self.has_data = Signal() - self.tag = Signal(tag_width) - self.data = Signal(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(tag_width) - - # call - self.call = Signal() - self.tag_call = Signal(tag_width) - self.data_call = Signal(data_width) - - # readback - self.can_read = Signal() - self.read = Signal() - self.data_read = Signal(data_width) - - self._empty_count = Signal(max=self.depth+1, reset=self.depth) - self._produce = Signal(max=self.depth) - self._consume = Signal(max=self.depth) - 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) - ) - ] - - # do not touch empty count when issuing and reading at the same time - sync += [ - If(self.issue & self.can_issue & self.read & self.can_read, - self._empty_count.eq(self._empty_count) - ) - ] - - return Fragment(comb, sync) diff --git a/migen/genlib/cdc.py b/migen/genlib/cdc.py index 5759c929..773c7b2c 100644 --- a/migen/genlib/cdc.py +++ b/migen/genlib/cdc.py @@ -58,29 +58,24 @@ class MultiReg(Special): def lower(dr): return MultiRegImpl(dr.i, dr.o, dr.odomain, dr.n) -class PulseSynchronizer: +class PulseSynchronizer(Module): def __init__(self, idomain, odomain): - self.idomain = idomain - self.odomain = odomain self.i = Signal() self.o = Signal() - def get_fragment(self): + ### + toggle_i = Signal() toggle_o = Signal() toggle_o_r = Signal() - sync_i = [ - If(self.i, toggle_i.eq(~toggle_i)) - ] - sync_o = [ - toggle_o_r.eq(toggle_o) - ] - comb = [ - self.o.eq(toggle_o ^ toggle_o_r) - ] - return Fragment(comb, - {self.idomain: sync_i, self.odomain: sync_o}, - specials={MultiReg(toggle_i, toggle_o, self.odomain)}) + + sync_i = getattr(self.sync, idomain) + sync_o = getattr(self.sync, odomain) + + sync_i += If(self.i, toggle_i.eq(~toggle_i)) + self.specials += MultiReg(toggle_i, toggle_o, odomain) + sync_o += toggle_o_r.eq(toggle_o) + self.comb += self.o.eq(toggle_o ^ toggle_o_r) class GrayCounter(Module): def __init__(self, width): diff --git a/migen/genlib/rob.py b/migen/genlib/rob.py new file mode 100644 index 00000000..4da7ad2c --- /dev/null +++ b/migen/genlib/rob.py @@ -0,0 +1,76 @@ +from migen.fhdl.std import * + +class ReorderSlot: + def __init__(self, tag_width, data_width): + self.wait_data = Signal() + self.has_data = Signal() + self.tag = Signal(tag_width) + self.data = Signal(data_width) + +class ReorderBuffer(Module): + def __init__(self, tag_width, data_width, depth): + # issue + self.can_issue = Signal() + self.issue = Signal() + self.tag_issue = Signal(tag_width) + + # call + self.call = Signal() + self.tag_call = Signal(tag_width) + self.data_call = Signal(data_width) + + # readback + self.can_read = Signal() + self.read = Signal() + self.data_read = Signal(data_width) + + ### + + empty_count = Signal(max=depth+1, reset=depth) + produce = Signal(max=depth) + consume = Signal(max=depth) + slots = Array(ReorderSlot(tag_width, data_width) + for n in range(depth)) + + # issue + self.comb += self.can_issue.eq(empty_count != 0) + self.sync += If(self.issue & self.can_issue, + empty_count.eq(empty_count - 1), + If(produce == depth - 1, + produce.eq(0) + ).Else( + produce.eq(produce + 1) + ), + slots[produce].wait_data.eq(1), + slots[produce].tag.eq(self.tag_issue) + ) + + # call + for n, slot in enumerate(slots): + self.sync += 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 + self.comb += [ + self.can_read.eq(slots[consume].has_data), + self.data_read.eq(slots[consume].data) + ] + self.sync += [ + If(self.read & self.can_read, + empty_count.eq(empty_count + 1), + If(consume == depth - 1, + consume.eq(0) + ).Else( + consume.eq(consume + 1) + ), + slots[consume].has_data.eq(0) + ) + ] + + # do not touch empty count when issuing and reading at the same time + self.sync += If(self.issue & self.can_issue & self.read & self.can_read, + empty_count.eq(empty_count) + ) -- 2.30.2