Exemplo n.º 1
0
    def __init__(self, width, packet_size=512):
        super().__init__(width, 0)

        self.submodules.inner = _FIFOInterface(width, 0)

        self.flush    = Signal()
        self.flush_s  = Signal()

        self.queued   = Signal(max=1 + packet_size)
        self.complete = Signal()
        self.pending  = Signal()
        self.flushed  = Signal()
Exemplo n.º 2
0
    def __init__(self, width):
        super().__init__(width, 0)

        self.submodules.fifo = _FIFOInterface(width, 0)
Exemplo n.º 3
0
    def do_finalize(self):
        assert len(self.event_sources) < 2**6
        assert max(s.width for s in self.event_sources) <= 32

        # Fill the event, event data, and delay FIFOs.
        throttle_on = Signal()
        throttle_off = Signal()
        throttle_edge = Signal()
        throttle_fifos = []
        self.sync += [
            If(~self.throttle & throttle_on, self.throttle.eq(1),
               throttle_edge.eq(1)).Elif(self.throttle & throttle_off,
                                         self.throttle.eq(0),
                                         throttle_edge.eq(1)).Else(
                                             throttle_edge.eq(0))
        ]

        event_width = 1 + len(self.event_sources)
        if self.event_depth is None:
            event_depth = min(self._depth_for_width(event_width),
                              self._depth_for_width(self.delay_width))
        else:
            event_depth = self.event_depth

        self.submodules.event_fifo = event_fifo = \
            SyncFIFOBuffered(width=event_width, depth=event_depth)
        throttle_fifos.append(self.event_fifo)
        self.comb += [
            event_fifo.din.eq(
                Cat(self.throttle, [s.trigger for s in self.event_sources])),
            event_fifo.we.eq(
                reduce(lambda a, b: a | b, (s.trigger
                                            for s in self.event_sources))
                | throttle_edge)
        ]

        self.submodules.delay_fifo = delay_fifo = \
            SyncFIFOBuffered(width=self.delay_width, depth=event_depth)
        delay_timer = self._delay_timer = Signal(self.delay_width)
        self.sync += [
            If(delay_fifo.we,
               delay_timer.eq(0)).Else(delay_timer.eq(delay_timer + 1))
        ]
        self.comb += [
            delay_fifo.din.eq(delay_timer),
            delay_fifo.we.eq(event_fifo.we
                             | (delay_timer == ((1 << self.delay_width) - 1))
                             | self.done),
        ]

        for event_source in self.event_sources:
            if event_source.width > 0:
                event_source.submodules.data_fifo = event_data_fifo = \
                    SyncFIFOBuffered(event_source.width, event_source.depth)
                self.submodules += event_source
                throttle_fifos.append(event_data_fifo)
                self.comb += [
                    event_data_fifo.din.eq(event_source.data),
                    event_data_fifo.we.eq(event_source.trigger),
                ]
            else:
                event_source.submodules.data_fifo = _FIFOInterface(1, 0)

        # Throttle applets based on FIFO levels with hysteresis.
        self.comb += [
            throttle_on.eq(
                reduce(lambda a, b: a | b,
                       (f.fifo.level >= f.depth - f.depth //
                        (4 if f.depth > 4 else 2) for f in throttle_fifos))),
            throttle_off.eq(
                reduce(lambda a, b: a & b,
                       (f.fifo.level < f.depth // (4 if f.depth > 4 else 2)
                        for f in throttle_fifos))),
        ]

        # Dequeue events, and serialize events and event data.
        self.submodules.event_encoder = event_encoder = \
            PriorityEncoder(width=len(self.event_sources))
        self.submodules.event_decoder = event_decoder = \
            PriorityDecoder(width=len(self.event_sources))
        self.comb += event_decoder.i.eq(event_encoder.o)

        self.submodules.serializer = serializer = FSM(reset_state="WAIT-EVENT")
        rep_throttle_new = Signal()
        rep_throttle_cur = Signal()
        delay_septets = 5
        delay_counter = Signal(7 * delay_septets)
        serializer.act(
            "WAIT-EVENT",
            If(
                delay_fifo.readable,
                delay_fifo.re.eq(1),
                NextValue(delay_counter, delay_counter + delay_fifo.dout + 1),
            ),
            If(
                event_fifo.readable, event_fifo.re.eq(1),
                NextValue(event_encoder.i, event_fifo.dout[1:]),
                NextValue(rep_throttle_new, event_fifo.dout[0]),
                If((event_fifo.dout != 0) |
                   (rep_throttle_cur != event_fifo.dout[0]),
                   NextState("REPORT-DELAY"))).Elif(self.done,
                                                    NextState("REPORT-DELAY")))
        serializer.act(
            "REPORT-DELAY",
            If(delay_counter >= 128**4, NextState("REPORT-DELAY-5")).Elif(
                delay_counter >= 128**3, NextState("REPORT-DELAY-4")).Elif(
                    delay_counter >= 128**2, NextState("REPORT-DELAY-3")).Elif(
                        delay_counter >= 128**1,
                        NextState("REPORT-DELAY-2")).Else(
                            NextState("REPORT-DELAY-1")))
        for septet_no in range(delay_septets, 0, -1):
            if septet_no == 1:
                next_state = [
                    NextValue(delay_counter, 0),
                    If(rep_throttle_cur != rep_throttle_new,
                       NextState("REPORT-THROTTLE")).Elif(
                           event_encoder.i, NextState("REPORT-EVENT")).Elif(
                               self.done, NextState("REPORT-DONE")).Else(
                                   NextState("WAIT-EVENT"))
                ]
            else:
                next_state = [NextState("REPORT-DELAY-%d" % (septet_no - 1))]
            serializer.act(
                "REPORT-DELAY-%d" % septet_no,
                If(
                    self.output_fifo.writable,
                    self.output_fifo.din.eq(REPORT_DELAY | delay_counter.part(
                        (septet_no - 1) * 7, 7)), self.output_fifo.we.eq(1),
                    *next_state))
        serializer.act(
            "REPORT-THROTTLE",
            If(
                self.output_fifo.writable,
                NextValue(rep_throttle_cur, rep_throttle_new),
                If(
                    rep_throttle_new,
                    self.output_fifo.din.eq(REPORT_SPECIAL | SPECIAL_THROTTLE),
                ).Else(
                    self.output_fifo.din.eq(REPORT_SPECIAL
                                            | SPECIAL_DETHROTTLE), ),
                self.output_fifo.we.eq(1),
                If(event_encoder.n,
                   NextState("WAIT-EVENT")).Else(NextState("REPORT-EVENT"))))
        event_source = self.event_sources[event_encoder.o]
        event_data = Signal(32)
        serializer.act(
            "REPORT-EVENT",
            If(
                self.output_fifo.writable,
                NextValue(event_encoder.i, event_encoder.i & ~event_decoder.o),
                self.output_fifo.din.eq(REPORT_EVENT | event_encoder.o),
                self.output_fifo.we.eq(1),
                NextValue(event_data, event_source.data_fifo.dout),
                event_source.data_fifo.re.eq(1),
                If(event_source.width > 24,
                   NextState("REPORT-EVENT-DATA-4")).Elif(
                       event_source.width > 16,
                       NextState("REPORT-EVENT-DATA-3")).Elif(
                           event_source.width > 8,
                           NextState("REPORT-EVENT-DATA-2")).Elif(
                               event_source.width > 0,
                               NextState("REPORT-EVENT-DATA-1")).Else(
                                   If(event_encoder.i & ~event_decoder.o,
                                      NextState("REPORT-EVENT")).Else(
                                          NextState("WAIT-EVENT")))))
        for octet_no in range(4, 0, -1):
            if octet_no == 1:
                next_state = [
                    If(event_encoder.n,
                       NextState("WAIT-EVENT")).Else(NextState("REPORT-EVENT"))
                ]
            else:
                next_state = [
                    NextState("REPORT-EVENT-DATA-%d" % (octet_no - 1))
                ]
            serializer.act(
                "REPORT-EVENT-DATA-%d" % octet_no,
                If(
                    self.output_fifo.writable,
                    self.output_fifo.din.eq(
                        event_data.part((octet_no - 1) * 8, 8)),
                    self.output_fifo.we.eq(1), *next_state))
            serializer.act(
                "REPORT-DONE",
                If(self.output_fifo.writable,
                   self.output_fifo.din.eq(REPORT_SPECIAL | SPECIAL_DONE),
                   self.output_fifo.we.eq(1), NextState("DONE")))
            serializer.act("DONE", If(~self.done, NextState("WAIT-EVENT")))