Example #1
0
    def __init__(self):
        self.sink = sink = stream.Endpoint(eth_phy_layout(8))
        self.source = source = stream.Endpoint(eth_phy_layout(8))

        self.error = Signal()

        # # #

        fsm = FSM(reset_state="IDLE")
        self.submodules += fsm

        fsm.act("IDLE",
            sink.ack.eq(1),
            If(sink.stb & ~sink.eop & (sink.data == eth_preamble >> 56),
                NextState("COPY")
            ),
            If(sink.stb & sink.eop, self.error.eq(1))
        )
        self.comb += [
            source.data.eq(sink.data),
            source.last_be.eq(sink.last_be)
        ]
        fsm.act("COPY",
            sink.connect(source, omit={"data", "last_be"}),
            If(source.stb & source.eop & source.ack,
                NextState("IDLE"),
            )
        )
Example #2
0
File: gap.py Project: m-labs/misoc
    def __init__(self):
        self.sink = sink = stream.Endpoint(eth_phy_layout(8))
        self.source = source = stream.Endpoint(eth_phy_layout(8))

        # # #

        counter = Signal(max=eth_interpacket_gap)
        counter_reset = Signal()
        counter_ce = Signal()
        self.sync += \
            If(counter_reset,
               counter.eq(0)
            ).Elif(counter_ce,
                counter.eq(counter + 1)
            )

        self.submodules.fsm = fsm = FSM(reset_state="COPY")
        fsm.act("COPY",
            counter_reset.eq(1),
            sink.connect(source),
            If(sink.stb & sink.eop & sink.ack,
                NextState("GAP")
            )
        )
        fsm.act("GAP",
            counter_ce.eq(1),
            If(counter == eth_interpacket_gap - 1,
                NextState("COPY")
            )
        )
Example #3
0
    def __init__(self, dw):
        assert dw == 8
        self.sink = sink = stream.Endpoint(eth_phy_layout(dw))
        self.source = source = stream.Endpoint(eth_phy_layout(dw))

        self.error = Signal()

        # # #

        fsm = FSM(reset_state="IDLE")
        self.submodules += fsm

        fsm.act(
            "IDLE", sink.ack.eq(1),
            If(sink.stb & ~sink.eop & (sink.data == eth_preamble >> 56),
               NextState("COPY")), If(sink.stb & sink.eop, self.error.eq(1)))
        self.comb += [
            source.data.eq(sink.data),
            source.last_be.eq(sink.last_be)
        ]
        fsm.act("COPY", sink.connect(source, omit={"data", "last_be"}),
                If(
                    source.stb & source.eop & source.ack,
                    NextState("IDLE"),
                ))
Example #4
0
    def __init__(self, dw, nrxslots=2, ntxslots=2):
        self.sink = stream.Endpoint(eth_phy_layout(dw))
        self.source = stream.Endpoint(eth_phy_layout(dw))
        self.bus = wishbone.Interface()

        # # #

        # storage in SRAM
        sram_depth = eth_mtu//(dw//8)
        self.submodules.sram = sram.LiteEthMACSRAM(dw, sram_depth, nrxslots, ntxslots)
        self.comb += [
            self.sink.connect(self.sram.sink),
            self.sram.source.connect(self.source)
        ]

        # Wishbone interface
        wb_rx_sram_ifs = [wishbone.SRAM(self.sram.writer.mems[n], read_only=True)
            for n in range(nrxslots)]
        # TODO: FullMemoryWE should move to Mibuild
        wb_tx_sram_ifs = [FullMemoryWE()(wishbone.SRAM(self.sram.reader.mems[n], read_only=False))
            for n in range(ntxslots)]
        wb_sram_ifs = wb_rx_sram_ifs + wb_tx_sram_ifs

        wb_slaves = []
        decoderoffset = log2_int(sram_depth, need_pow2=False)
        decoderbits = log2_int(len(wb_sram_ifs))
        for n, wb_sram_if in enumerate(wb_sram_ifs):
            def slave_filter(a, v=n):
                return a[decoderoffset:decoderoffset+decoderbits] == v
            wb_slaves.append((slave_filter, wb_sram_if.bus))
            self.submodules += wb_sram_if
        wb_con = wishbone.Decoder(self.bus, wb_slaves, register=True)
        self.submodules += wb_con
Example #5
0
    def __init__(self, dw, padding):
        self.sink = sink = stream.Endpoint(eth_phy_layout(dw))
        self.source = source = stream.Endpoint(eth_phy_layout(dw))

        # # #

        padding_limit = math.ceil(padding / (dw / 8)) - 1

        counter = Signal(16, reset=1)
        counter_done = Signal()
        counter_reset = Signal()
        counter_ce = Signal()
        self.sync += \
            If(counter_reset,
                counter.eq(0)
            ).Elif(counter_ce,
                counter.eq(counter + 1)
            )
        self.comb += counter_done.eq(counter >= padding_limit)

        self.submodules.fsm = fsm = FSM(reset_state="IDLE")
        fsm.act(
            "IDLE", sink.connect(source),
            If(
                source.stb & source.ack, counter_ce.eq(1),
                If(
                    sink.eop,
                    If(~counter_done, source.eop.eq(0),
                       NextState("PADDING")).Else(counter_reset.eq(1)))))
        fsm.act(
            "PADDING", source.stb.eq(1), source.eop.eq(counter_done),
            source.data.eq(0),
            If(source.stb & source.ack, counter_ce.eq(1),
               If(counter_done, counter_reset.eq(1), NextState("IDLE"))))
Example #6
0
    def __init__(self):
        self.sink = sink = stream.Endpoint(eth_phy_layout(8))
        self.source = source = stream.Endpoint(eth_phy_layout(8))

        # # #

        self.comb += [sink.connect(source), source.last_be.eq(sink.eop)]
Example #7
0
    def __init__(self, dw, ack_on_gap=False):
        self.sink = sink = stream.Endpoint(eth_phy_layout(dw))
        self.source = source = stream.Endpoint(eth_phy_layout(dw))

        # # #

        gap = math.ceil(eth_interpacket_gap/(dw//8))
        counter = Signal(max=gap)
        counter_reset = Signal()
        counter_ce = Signal()
        self.sync += \
            If(counter_reset,
               counter.eq(0)
            ).Elif(counter_ce,
                counter.eq(counter + 1)
            )

        self.submodules.fsm = fsm = FSM(reset_state="COPY")
        fsm.act("COPY",
            counter_reset.eq(1),
            sink.connect(source),
            If(sink.stb & sink.eop & sink.ack,
                NextState("GAP")
            )
        )
        fsm.act("GAP",
            counter_ce.eq(1),
            sink.ack.eq(int(ack_on_gap)),
            If(counter == (gap-1),
                NextState("COPY")
            )
        )
Example #8
0
    def __init__(self, dw, nrxslots=2, ntxslots=2, endianness="big"):
        self.sink = stream.Endpoint(eth_phy_layout(dw))
        self.source = stream.Endpoint(eth_phy_layout(dw))
        self.bus = wishbone.Interface(data_width=dw, adr_width=32-log2_int(dw//8))

        # # #

        # storage in SRAM
        sram_depth = eth_mtu//(dw//8)
        self.submodules.sram = sram.LiteEthMACSRAM(dw, sram_depth, nrxslots, ntxslots, endianness)
        self.comb += [
            self.sink.connect(self.sram.sink),
            self.sram.source.connect(self.source)
        ]

        # Wishbone interface
        wb_rx_sram_ifs = [wishbone.SRAM(self.sram.writer.mems[n], read_only=True, data_width=dw)
            for n in range(nrxslots)]
        # TODO: FullMemoryWE should move to Mibuild
        wb_tx_sram_ifs = [FullMemoryWE()(wishbone.SRAM(self.sram.reader.mems[n], read_only=False, data_width=dw))
            for n in range(ntxslots)]
        wb_sram_ifs = wb_rx_sram_ifs + wb_tx_sram_ifs

        wb_slaves = []
        decoderoffset = log2_int(sram_depth, need_pow2=False)
        decoderbits = log2_int(len(wb_sram_ifs))
        for n, wb_sram_if in enumerate(wb_sram_ifs):
            def slave_filter(a, v=n):
                return a[decoderoffset:decoderoffset+decoderbits] == v
            wb_slaves.append((slave_filter, wb_sram_if.bus))
            self.submodules += wb_sram_if
        wb_con = wishbone.Decoder(self.bus, wb_slaves, register=True)
        self.submodules += wb_con
Example #9
0
    def __init__(self, packet_min_length):
        self.sink = sink = stream.Endpoint(eth_phy_layout(8))
        self.source = source = stream.Endpoint(eth_phy_layout(8))

        # # #

        # TODO: see if we should drop the packet when
        # payload size < minimum ethernet payload size
        self.comb += sink.connect(source)
Example #10
0
    def __init__(self, dw, packet_min_length):
        self.sink = sink = stream.Endpoint(eth_phy_layout(dw))
        self.source = source = stream.Endpoint(eth_phy_layout(dw))

        # # #

        # TODO: see if we should drop the packet when
        # payload size < minimum ethernet payload size
        self.comb += sink.connect(source)
Example #11
0
    def __init__(self):
        self.sink = sink = stream.Endpoint(eth_phy_layout(8))
        self.source = source = stream.Endpoint(eth_phy_layout(8))

        # # #

        self.comb += [
            sink.connect(source),
            source.last_be.eq(sink.eop)
        ]
Example #12
0
    def __init__(self, dw):
        self.sink = stream.Endpoint(eth_phy_layout(dw))
        self.source = stream.Endpoint(eth_phy_layout(dw))

        # # #

        preamble = Signal(64, reset=eth_preamble)
        cnt_max = (64//dw)-1
        cnt = Signal(max=cnt_max+1)
        clr_cnt = Signal()
        inc_cnt = Signal()

        self.sync += \
            If(clr_cnt,
                cnt.eq(0)
            ).Elif(inc_cnt,
                cnt.eq(cnt+1)
            )

        fsm = FSM(reset_state="IDLE")
        self.submodules += fsm
        fsm.act("IDLE",
            self.sink.ack.eq(1),
            clr_cnt.eq(1),
            If(self.sink.stb,
                self.sink.ack.eq(0),
                NextState("INSERT"),
            )
        )
        fsm.act("INSERT",
            self.source.stb.eq(1),
            chooser(preamble, cnt, self.source.data),
            If(cnt == cnt_max,
                If(self.source.ack, NextState("COPY"))
            ).Else(
                inc_cnt.eq(self.source.ack)
            )
        )

        self.comb += [
            self.source.data.eq(self.sink.data),
            self.source.last_be.eq(self.sink.last_be)
        ]
        fsm.act("COPY",
            self.sink.connect(self.source, leave_out=set(["data", "last_be"])),

            If(self.sink.stb & self.sink.eop & self.source.ack,
                NextState("IDLE"),
            )
        )
Example #13
0
    def __init__(self, dw):
        self.sink = stream.Endpoint(eth_phy_layout(dw))
        self.source = stream.Endpoint(eth_phy_layout(dw))

        # # #

        preamble = Signal(64, reset=eth_preamble)
        cnt_max = (64//dw)-1
        cnt = Signal(max=cnt_max+1)
        clr_cnt = Signal()
        inc_cnt = Signal()

        self.sync += \
            If(clr_cnt,
                cnt.eq(0)
            ).Elif(inc_cnt,
                cnt.eq(cnt+1)
            )

        fsm = FSM(reset_state="IDLE")
        self.submodules += fsm
        fsm.act("IDLE",
            self.sink.ack.eq(1),
            clr_cnt.eq(1),
            If(self.sink.stb,
                self.sink.ack.eq(0),
                NextState("INSERT"),
            )
        )
        fsm.act("INSERT",
            self.source.stb.eq(1),
            chooser(preamble, cnt, self.source.data),
            If(cnt == cnt_max,
                If(self.source.ack, NextState("COPY"))
            ).Else(
                inc_cnt.eq(self.source.ack)
            )
        )

        self.comb += [
            self.source.data.eq(self.sink.data),
            self.source.last_be.eq(self.sink.last_be)
        ]
        fsm.act("COPY",
            self.sink.connect(self.source, omit=set(["data", "last_be"])),

            If(self.sink.stb & self.sink.eop & self.source.ack,
                NextState("IDLE"),
            )
        )
Example #14
0
    def __init__(self, dw, padding):
        self.sink = sink = stream.Endpoint(eth_phy_layout(dw))
        self.source = source = stream.Endpoint(eth_phy_layout(dw))

        # # #

        padding_limit = math.ceil(padding/(dw/8))-1

        counter = Signal(16, reset=1)
        counter_done = Signal()
        counter_reset = Signal()
        counter_ce = Signal()
        self.sync += \
            If(counter_reset,
                counter.eq(0)
            ).Elif(counter_ce,
                counter.eq(counter + 1)
            )
        self.comb += counter_done.eq(counter >= padding_limit)

        self.submodules.fsm = fsm = FSM(reset_state="IDLE")
        fsm.act("IDLE",
            sink.connect(source),
            If(source.stb & source.ack,
                counter_ce.eq(1),
                If(sink.eop,
                    If(~counter_done,
                        source.eop.eq(0),
                        NextState("PADDING")
                    ).Else(
                        counter_reset.eq(1)
                    )
                )
            )
        )
        fsm.act("PADDING",
            source.stb.eq(1),
            source.eop.eq(counter_done),
            source.data.eq(0),
            If(source.stb & source.ack,
                counter_ce.eq(1),
                If(counter_done,
                    counter_reset.eq(1),
                    NextState("IDLE")
                )
            )
        )
Example #15
0
    def __init__(self):
        self.sink = sink = stream.Endpoint(eth_phy_layout(8))
        self.source = source = stream.Endpoint(eth_phy_layout(8))

        # # #

        counter = Signal(max=eth_interpacket_gap)
        counter_reset = Signal()
        counter_ce = Signal()
        self.sync += \
            If(counter_reset,
               counter.eq(0)
            ).Elif(counter_ce,
                counter.eq(counter + 1)
            )

        self.submodules.fsm = fsm = FSM(reset_state="COPY")
        fsm.act("COPY", counter_reset.eq(1), sink.connect(source),
                If(sink.stb & sink.eop & sink.ack, NextState("GAP")))
        fsm.act("GAP", counter_ce.eq(1),
                If(counter == eth_interpacket_gap - 1, NextState("COPY")))
Example #16
0
    def __init__(self):
        self.sink = sink = stream.Endpoint(eth_phy_layout(8))
        self.source = source = stream.Endpoint(eth_phy_layout(8))

        # # #

        ongoing = Signal(reset=1)
        self.sync += \
            If(sink.stb & sink.ack,
                If(sink.eop,
                    ongoing.eq(1)
                ).Elif(sink.last_be,
                    ongoing.eq(0)
                )
            )
        self.comb += [
            source.stb.eq(sink.stb & ongoing),
            source.eop.eq(sink.last_be),
            source.data.eq(sink.data),
            sink.ack.eq(source.ack)
        ]
Example #17
0
    def __init__(self):
        self.sink = sink = stream.Endpoint(eth_phy_layout(8))
        self.source = source = stream.Endpoint(eth_phy_layout(8))

        # # #

        ongoing = Signal(reset=1)
        self.sync += \
            If(sink.stb & sink.ack,
                If(sink.eop,
                    ongoing.eq(1)
                ).Elif(sink.last_be,
                    ongoing.eq(0)
                )
            )
        self.comb += [
            source.stb.eq(sink.stb & ongoing),
            source.eop.eq(sink.last_be),
            source.data.eq(sink.data),
            sink.ack.eq(source.ack)
        ]
Example #18
0
    def __init__(self):
        self.sink = sink = stream.Endpoint(eth_phy_layout(8))
        self.source = source = stream.Endpoint(eth_phy_layout(8))

        # # #

        preamble = Signal(64, reset=eth_preamble)
        cnt = Signal(max=8)
        clr_cnt = Signal()
        inc_cnt = Signal()

        self.sync += \
            If(clr_cnt,
                cnt.eq(0)
            ).Elif(inc_cnt,
                cnt.eq(cnt+1)
            )

        fsm = FSM(reset_state="IDLE")
        self.submodules += fsm
        fsm.act("IDLE", sink.ack.eq(1), clr_cnt.eq(1),
                If(
                    sink.stb,
                    sink.ack.eq(0),
                    NextState("INSERT"),
                ))
        fsm.act(
            "INSERT", source.stb.eq(1), chooser(preamble, cnt, source.data),
            If(cnt == 7, If(source.ack,
                            NextState("COPY"))).Else(inc_cnt.eq(source.ack)))

        self.comb += [
            source.data.eq(sink.data),
            source.last_be.eq(sink.last_be)
        ]
        fsm.act("COPY", sink.connect(source, omit={"data", "last_be"}),
                If(
                    sink.stb & sink.eop & source.ack,
                    NextState("IDLE"),
                ))
Example #19
0
File: sram.py Project: m-labs/misoc
    def __init__(self, dw, depth, nslots=2):
        self.source = source = stream.Endpoint(eth_phy_layout(dw))

        slotbits = max(log2_int(nslots), 1)
        lengthbits = bits_for(depth*4)  # length in bytes
        self.lengthbits = lengthbits

        self._start = CSR()
        self._ready = CSRStatus()
        self._slot = CSRStorage(slotbits)
        self._length = CSRStorage(lengthbits)

        self.submodules.ev = EventManager()
        self.ev.done = EventSourcePulse()
        self.ev.finalize()

        # # #

        # command fifo
        fifo = stream.SyncFIFO([("slot", slotbits), ("length", lengthbits)], nslots)
        self.submodules += fifo
        self.comb += [
            fifo.sink.stb.eq(self._start.re),
            fifo.sink.slot.eq(self._slot.storage),
            fifo.sink.length.eq(self._length.storage),
            self._ready.status.eq(fifo.sink.ack)
        ]

        # length computation
        counter = Signal(lengthbits)
        counter_reset = Signal()
        counter_ce = Signal()
        self.sync += \
            If(counter_reset,
                counter.eq(0)
            ).Elif(counter_ce,
                counter.eq(counter + 4)
            )


        # fsm
        last  = Signal()
        last_d = Signal()

        fsm = FSM(reset_state="IDLE")
        self.submodules += fsm

        fsm.act("IDLE",
            counter_reset.eq(1),
            If(fifo.source.stb,
                NextState("CHECK")
            )
        )
        fsm.act("CHECK",
            If(~last_d,
                NextState("SEND"),
            ).Else(
                NextState("END"),
            )
        )
        length_lsb = fifo.source.length[0:2]
        self.comb += [
            If(last,
                If(length_lsb == 3,
                    source.last_be.eq(0b0010)
                ).Elif(length_lsb == 2,
                    source.last_be.eq(0b0100)
                ).Elif(length_lsb == 1,
                    source.last_be.eq(0b1000)
                ).Else(
                    source.last_be.eq(0b0001)
                )
            )
        ]
        fsm.act("SEND",
            source.stb.eq(1),
            source.eop.eq(last),
            If(source.ack,
                counter_ce.eq(~last),
                NextState("CHECK")
            )
        )
        fsm.act("END",
            fifo.source.ack.eq(1),
            self.ev.done.trigger.eq(1),
            NextState("IDLE")
        )

        # last computation
        self.comb += last.eq((counter + 4) >= fifo.source.length)
        self.sync += last_d.eq(last)

        # memory
        rd_slot = fifo.source.slot

        mems = [None]*nslots
        ports = [None]*nslots
        for n in range(nslots):
            mems[n] = Memory(dw, depth)
            ports[n] = mems[n].get_port()
            self.specials += ports[n]
        self.mems = mems

        cases = {}
        for n, port in enumerate(ports):
            self.comb += ports[n].adr.eq(counter[2:])
            cases[n] = [source.data.eq(port.dat_r)]
        self.comb += Case(rd_slot, cases)
Example #20
0
    def __init__(self, dw, depth, nslots=2):
        self.sink = sink = stream.Endpoint(eth_phy_layout(dw))
        self.crc_error = Signal()

        slotbits = max(log2_int(nslots), 1)
        lengthbits = 32

        self._slot = CSRStatus(slotbits)
        self._length = CSRStatus(lengthbits)

        self.submodules.ev = EventManager()
        self.ev.available = EventSourceLevel()
        self.ev.finalize()

        # # #

        # packet dropped if no slot available
        sink.ack.reset = 1

        # length computation
        increment = Signal(3)
        self.comb += \
            If(sink.last_be[3],
                increment.eq(1)
            ).Elif(sink.last_be[2],
                increment.eq(2)
            ).Elif(sink.last_be[1],
                increment.eq(3)
            ).Else(
                increment.eq(4)
            )
        counter = Signal(lengthbits)
        counter_reset = Signal()
        counter_ce = Signal()
        self.sync += \
            If(counter_reset,
                counter.eq(0)
            ).Elif(counter_ce,
                counter.eq(counter + increment)
            )

        # slot computation
        slot = Signal(slotbits)
        slot_ce = Signal()
        self.sync += If(slot_ce, slot.eq(slot + 1))

        ongoing = Signal()

        # status fifo
        fifo = stream.SyncFIFO([("slot", slotbits), ("length", lengthbits)],
                               nslots)
        self.submodules += fifo

        # fsm
        fsm = FSM(reset_state="IDLE")
        self.submodules += fsm

        fsm.act(
            "IDLE",
            If(
                sink.stb,
                If(fifo.sink.ack, ongoing.eq(1), counter_ce.eq(1),
                   NextState("WRITE"))))
        fsm.act(
            "WRITE",
            If(
                sink.stb,
                If(counter == eth_mtu, NextState("DISCARD_REMAINING")).Else(
                    counter_ce.eq(1), ongoing.eq(1)),
                If(
                    sink.eop,
                    If((sink.error & sink.last_be) != 0,
                       NextState("DISCARD")).Else(NextState("TERMINATE")))))
        fsm.act("DISCARD", counter_reset.eq(1), NextState("IDLE"))
        fsm.act("DISCARD_REMAINING",
                If(sink.stb & sink.eop, NextState("TERMINATE")))
        self.comb += [fifo.sink.slot.eq(slot), fifo.sink.length.eq(counter)]
        fsm.act("TERMINATE", counter_reset.eq(1), slot_ce.eq(1),
                fifo.sink.stb.eq(1), NextState("IDLE"))
        self.comb += [
            fifo.source.ack.eq(self.ev.available.clear),
            self.ev.available.trigger.eq(fifo.source.stb),
            self._slot.status.eq(fifo.source.slot),
            self._length.status.eq(fifo.source.length),
        ]

        # memory
        mems = [None] * nslots
        ports = [None] * nslots
        for n in range(nslots):
            mems[n] = Memory(dw, depth)
            ports[n] = mems[n].get_port(write_capable=True)
            self.specials += ports[n]
        self.mems = mems

        cases = {}
        for n, port in enumerate(ports):
            cases[n] = [
                ports[n].adr.eq(counter[2:]), ports[n].dat_w.eq(sink.data),
                If(sink.stb & ongoing, ports[n].we.eq(0xf))
            ]
        self.comb += Case(slot, cases)
Example #21
0
    def __init__(self, dw, depth, nslots=2):
        self.source = source = stream.Endpoint(eth_phy_layout(dw))

        slotbits = max(log2_int(nslots), 1)
        lengthbits = bits_for(depth * 4)  # length in bytes
        self.lengthbits = lengthbits

        self._start = CSR()
        self._ready = CSRStatus()
        self._slot = CSRStorage(slotbits)
        self._length = CSRStorage(lengthbits)

        self.submodules.ev = EventManager()
        self.ev.done = EventSourcePulse()
        self.ev.finalize()

        # # #

        # command fifo
        fifo = stream.SyncFIFO([("slot", slotbits), ("length", lengthbits)],
                               nslots)
        self.submodules += fifo
        self.comb += [
            fifo.sink.stb.eq(self._start.re),
            fifo.sink.slot.eq(self._slot.storage),
            fifo.sink.length.eq(self._length.storage),
            self._ready.status.eq(fifo.sink.ack)
        ]

        # length computation
        counter = Signal(lengthbits)
        counter_reset = Signal()
        counter_ce = Signal()
        self.sync += \
            If(counter_reset,
                counter.eq(0)
            ).Elif(counter_ce,
                counter.eq(counter + 4)
            )

        # fsm
        last = Signal()
        last_d = Signal()

        fsm = FSM(reset_state="IDLE")
        self.submodules += fsm

        fsm.act("IDLE", counter_reset.eq(1),
                If(fifo.source.stb, NextState("CHECK")))
        fsm.act("CHECK",
                If(
                    ~last_d,
                    NextState("SEND"),
                ).Else(NextState("END"), ))
        length_lsb = fifo.source.length[0:2]
        self.comb += [
            If(
                last,
                If(length_lsb == 3, source.last_be.eq(0b0010)).Elif(
                    length_lsb == 2, source.last_be.eq(0b0100)).Elif(
                        length_lsb == 1, source.last_be.eq(0b1000)).Else(
                            source.last_be.eq(0b0001)))
        ]
        fsm.act("SEND", source.stb.eq(1), source.eop.eq(last),
                If(source.ack, counter_ce.eq(~last), NextState("CHECK")))
        fsm.act("END", fifo.source.ack.eq(1), self.ev.done.trigger.eq(1),
                NextState("IDLE"))

        # last computation
        self.comb += last.eq((counter + 4) >= fifo.source.length)
        self.sync += last_d.eq(last)

        # memory
        rd_slot = fifo.source.slot

        mems = [None] * nslots
        ports = [None] * nslots
        for n in range(nslots):
            mems[n] = Memory(dw, depth)
            ports[n] = mems[n].get_port()
            self.specials += ports[n]
        self.mems = mems

        cases = {}
        for n, port in enumerate(ports):
            self.comb += ports[n].adr.eq(counter[2:])
            cases[n] = [source.data.eq(port.dat_r)]
        self.comb += Case(rd_slot, cases)
Example #22
0
File: sram.py Project: m-labs/misoc
    def __init__(self, dw, depth, nslots=2):
        self.sink = sink = stream.Endpoint(eth_phy_layout(dw))

        slotbits = max(log2_int(nslots), 1)
        lengthbits = 32

        self._slot = CSRStatus(slotbits)
        self._length = CSRStatus(lengthbits)

        self.errors = CSRStatus(32)

        self.submodules.ev = EventManager()
        self.ev.available = EventSourceLevel()
        self.ev.finalize()

        # # #

        # packet dropped if no slot available
        sink.ack.reset = 1

        # length computation
        increment = Signal(3)
        self.comb += \
            If(sink.last_be[3],
                increment.eq(1)
            ).Elif(sink.last_be[2],
                increment.eq(2)
            ).Elif(sink.last_be[1],
                increment.eq(3)
            ).Else(
                increment.eq(4)
            )
        counter = Signal(lengthbits)
        counter_reset = Signal()
        counter_ce = Signal()
        self.sync += \
            If(counter_reset,
                counter.eq(0)
            ).Elif(counter_ce,
                counter.eq(counter + increment)
            )

        # slot computation
        slot = Signal(slotbits)
        slot_ce = Signal()
        self.sync += If(slot_ce, slot.eq(slot + 1))

        ongoing = Signal()

        # status fifo
        fifo = stream.SyncFIFO([("slot", slotbits), ("length", lengthbits)], nslots)
        self.submodules += fifo

        # fsm
        fsm = FSM(reset_state="IDLE")
        self.submodules += fsm

        fsm.act("IDLE",
            If(sink.stb,
                If(fifo.sink.ack,
                    ongoing.eq(1),
                    counter_ce.eq(1),
                    NextState("WRITE")
                ).Else(
                    NextState("DISCARD_REMAINING")
                )
            )
        )
        fsm.act("WRITE",
            If(sink.stb,
                If(counter == eth_mtu,
                    NextState("DISCARD_REMAINING")
                ).Else(
                    counter_ce.eq(1),
                    ongoing.eq(1)
                ),
                If(sink.eop,
                    If((sink.error & sink.last_be) != 0,
                        counter_reset.eq(1),
                        NextState("IDLE")
                    ).Else(
                        NextState("COMPLETE")
                    )
                )
            )
        )
        fsm.act("DISCARD_REMAINING",
            counter_reset.eq(1),
            If(sink.stb & sink.eop,
                NextValue(self.errors.status, self.errors.status + 1),
                NextState("IDLE")
            )
        )
        self.comb += [
            fifo.sink.slot.eq(slot),
            fifo.sink.length.eq(counter)
        ]
        fsm.act("COMPLETE",
            counter_reset.eq(1),
            slot_ce.eq(1),
            fifo.sink.stb.eq(1),
            NextState("IDLE")
        )
        self.comb += [
            fifo.source.ack.eq(self.ev.available.clear),
            self.ev.available.trigger.eq(fifo.source.stb),
            self._slot.status.eq(fifo.source.slot),
            self._length.status.eq(fifo.source.length),
        ]

        # memory
        mems = [None]*nslots
        ports = [None]*nslots
        for n in range(nslots):
            mems[n] = Memory(dw, depth)
            ports[n] = mems[n].get_port(write_capable=True)
            self.specials += ports[n]
        self.mems = mems

        cases = {}
        for n, port in enumerate(ports):
            cases[n] = [
                ports[n].adr.eq(counter[2:]),
                ports[n].dat_w.eq(sink.data),
                If(sink.stb & ongoing,
                    ports[n].we.eq(0xf)
                )
            ]
        self.comb += Case(slot, cases)
Example #23
0
    def __init__(self, dw):
        self.sink = stream.Endpoint(eth_phy_layout(dw))
        self.source = stream.Endpoint(eth_phy_layout(dw))

        # # #

        preamble = Signal(64, reset=eth_preamble)
        cnt_max = (64//dw) - 1
        cnt = Signal(max=cnt_max+1)
        clr_cnt = Signal()
        inc_cnt = Signal()

        self.sync += \
            If(clr_cnt,
                cnt.eq(0)
            ).Elif(inc_cnt,
                cnt.eq(cnt+1)
            )

        discard = Signal()
        clr_discard = Signal()
        set_discard = Signal()

        self.sync += \
            If(clr_discard,
                discard.eq(0)
            ).Elif(set_discard,
                discard.eq(1)
            )

        ref = Signal(dw)
        match = Signal()
        self.comb += [
            chooser(preamble, cnt, ref),
            match.eq(self.sink.data == ref)
        ]

        fsm = FSM(reset_state="IDLE")
        self.submodules += fsm

        fsm.act("IDLE",
            self.sink.ack.eq(1),
            clr_cnt.eq(1),
            clr_discard.eq(1),
            If(self.sink.stb,
                clr_cnt.eq(0),
                inc_cnt.eq(1),
                clr_discard.eq(0),
                set_discard.eq(~match),
                NextState("CHECK"),
            )
        )
        fsm.act("CHECK",
            self.sink.ack.eq(1),
            If(self.sink.stb,
                set_discard.eq(~match),
                If(cnt == cnt_max,
                    If(discard | (~match),
                        NextState("IDLE")
                    ).Else(
                        NextState("COPY")
                    )
                ).Else(
                    inc_cnt.eq(1)
                )
            )
        )
        self.comb += [
            self.source.data.eq(self.sink.data),
            self.source.last_be.eq(self.sink.last_be)
        ]
        fsm.act("COPY",
            self.sink.connect(self.source, leave_out=set(["data", "last_be"])),
            If(self.source.stb & self.source.eop & self.source.ack,
                NextState("IDLE"),
            )
        )
Example #24
0
    def __init__(self, dw):
        self.sink = stream.Endpoint(eth_phy_layout(dw))
        self.source = stream.Endpoint(eth_phy_layout(dw))

        # # #

        preamble = Signal(64, reset=eth_preamble)
        cnt_max = (64 // dw) - 1
        cnt = Signal(max=cnt_max + 1)
        clr_cnt = Signal()
        inc_cnt = Signal()

        self.sync += \
            If(clr_cnt,
                cnt.eq(0)
            ).Elif(inc_cnt,
                cnt.eq(cnt+1)
            )

        discard = Signal()
        clr_discard = Signal()
        set_discard = Signal()

        self.sync += \
            If(clr_discard,
                discard.eq(0)
            ).Elif(set_discard,
                discard.eq(1)
            )

        ref = Signal(dw)
        match = Signal()
        self.comb += [
            chooser(preamble, cnt, ref),
            match.eq(self.sink.data == ref)
        ]

        fsm = FSM(reset_state="IDLE")
        self.submodules += fsm

        fsm.act(
            "IDLE", self.sink.ack.eq(1), clr_cnt.eq(1), clr_discard.eq(1),
            If(
                self.sink.stb,
                clr_cnt.eq(0),
                inc_cnt.eq(1),
                clr_discard.eq(0),
                set_discard.eq(~match),
                NextState("CHECK"),
            ))
        fsm.act(
            "CHECK", self.sink.ack.eq(1),
            If(
                self.sink.stb, set_discard.eq(~match),
                If(
                    cnt == cnt_max,
                    If(discard | (~match), NextState("IDLE")).Else(
                        NextState("COPY"))).Else(inc_cnt.eq(1))))
        self.comb += [
            self.source.data.eq(self.sink.data),
            self.source.last_be.eq(self.sink.last_be)
        ]
        fsm.act(
            "COPY",
            self.sink.connect(self.source, omit=set(["data", "last_be"])),
            If(
                self.source.stb & self.source.eop & self.source.ack,
                NextState("IDLE"),
            ))