)
)
-
-class Buffer(Module):
- def __init__(self, description, data_depth, cmd_depth=4, almost_full=None):
- self.sink = sink = stream.Endpoint(description)
- self.source = source = stream.Endpoint(description)
-
- # # #
-
- sink_status = Status(self.sink)
- source_status = Status(self.source)
- self.submodules += sink_status, source_status
-
- # store incoming packets
- # cmds
- def cmd_description():
- layout = [("error", 1)]
- return EndpointDescription(layout)
- cmd_fifo = SyncFIFO(cmd_description(), cmd_depth)
- self.submodules += cmd_fifo
- self.comb += cmd_fifo.sink.stb.eq(sink_status.eop)
- if hasattr(sink, "error"):
- self.comb += cmd_fifo.sink.error.eq(sink.error)
-
- # data
- data_fifo = SyncFIFO(description, data_depth, buffered=True)
- self.submodules += data_fifo
- self.comb += [
- self.sink.connect(data_fifo.sink, leave_out=set(["stb", "ack"])),
- data_fifo.sink.stb.eq(self.sink.stb & cmd_fifo.sink.ack),
- self.sink.ack.eq(data_fifo.sink.ack & cmd_fifo.sink.ack),
- ]
-
- # output packets
- self.fsm = fsm = FSM(reset_state="IDLE")
- self.submodules += fsm
- fsm.act("IDLE",
- If(cmd_fifo.source.stb,
- NextState("OUTPUT")
- )
- )
- if hasattr(source, "error"):
- source_error = self.source.error
- else:
- source_error = Signal()
-
- fsm.act("OUTPUT",
- data_fifo.source.connect(self.source, leave_out=set("error")),
- source_error.eq(cmd_fifo.source.error),
- If(source_status.eop,
- cmd_fifo.source.ack.eq(1),
- NextState("IDLE")
- )
- )
-
- # compute almost full
- if almost_full is not None:
- self.almost_full = Signal()
- self.comb += self.almost_full.eq(data_fifo.level > almost_full)
-
# XXX