Ejemplo n.º 1
0
    def __init__(self, pads, rd_timing, wr_timing):
        self.bus = wishbone.Interface()

        ###

        data = TSTriple(16)
        lsb = Signal()

        self.specials += data.get_tristate(pads.d)
        self.comb += [
            data.oe.eq(pads.oe_n),
            pads.ce_n.eq(0)
        ]

        load_lo = Signal()
        load_hi = Signal()
        store = Signal()

        pads.oe_n.reset, pads.we_n.reset = 1, 1
        self.sync += [
            pads.oe_n.eq(1),
            pads.we_n.eq(1),

            # Register data/address to avoid off-chip glitches
            If(self.bus.cyc & self.bus.stb,
                pads.adr.eq(Cat(lsb, self.bus.adr)),
                If(self.bus.we,
                    # Only 16-bit writes are supported. Assume sel=0011 or 1100.
                    If(self.bus.sel[0],
                        data.o.eq(self.bus.dat_w[:16])
                    ).Else(
                        data.o.eq(self.bus.dat_w[16:])
                    )
                ).Else(
                    pads.oe_n.eq(0)
                )
            ),

            If(load_lo, self.bus.dat_r[:16].eq(data.i)),
            If(load_hi, self.bus.dat_r[16:].eq(data.i)),
            If(store, pads.we_n.eq(0))
        ]

        # Typical timing of the flash chips:
        #  - 110ns address to output
        #  - 50ns write pulse width
        counter = Signal(max=max(rd_timing, wr_timing)+1)
        counter_en = Signal()
        counter_wr_mode = Signal()
        counter_done = Signal()
        self.comb += counter_done.eq(counter == Mux(counter_wr_mode, wr_timing, rd_timing))
        self.sync += If(counter_en & ~counter_done,
                counter.eq(counter + 1)
            ).Else(
                counter.eq(0)
            )

        fsm = FSM()
        self.submodules += fsm

        fsm.act("IDLE",
            If(self.bus.cyc & self.bus.stb,
                If(self.bus.we,
                    NextState("WR")
                ).Else(
                    NextState("RD_HI")
                )
            )
        )
        fsm.act("RD_HI",
            lsb.eq(0),
            counter_en.eq(1),
            If(counter_done,
                load_hi.eq(1),
                NextState("RD_LO")
            )
        )
        fsm.act("RD_LO",
            lsb.eq(1),
            counter_en.eq(1),
            If(counter_done,
                load_lo.eq(1),
                NextState("ACK")
            )
        )
        fsm.act("WR",
            # supported cases: sel=0011 [lsb=1] and sel=1100 [lsb=0]
            lsb.eq(self.bus.sel[0]),
            counter_wr_mode.eq(1),
            counter_en.eq(1),
            store.eq(1),
            If(counter_done, NextState("ACK"))
        )
        fsm.act("ACK",
            self.bus.ack.eq(1),
            NextState("IDLE")
        )
Ejemplo n.º 2
0
    def __init__(self, clock_pads, pads, with_hw_init_reset):
        self._reset = CSRStorage()

        # # #

        self.clock_domains.cd_eth_rx = ClockDomain()
        self.clock_domains.cd_eth_tx = ClockDomain()


        # RX
        dcm_reset = Signal()
        dcm_locked = Signal()

        timer = WaitTimer(1024)
        fsm = FSM(reset_state="DCM_RESET")
        self.submodules += timer, fsm

        fsm.act("DCM_RESET",
            dcm_reset.eq(1),
            timer.wait.eq(1),
            If(timer.done,
                timer.wait.eq(0),
                NextState("DCM_WAIT")
            )
        )
        fsm.act("DCM_WAIT",
            timer.wait.eq(1),
            If(timer.done,
                NextState("DCM_CHECK_LOCK")
            )
        )
        fsm.act("DCM_CHECK_LOCK",
            If(~dcm_locked,
                NextState("DCM_RESET")
            )
        )

        clk90_rx = Signal()
        clk0_rx = Signal()
        clk0_rx_bufg = Signal()
        self.specials += Instance("DCM",
                i_CLKIN=clock_pads.rx,
                i_CLKFB=clk0_rx_bufg,
                o_CLK0=clk0_rx,
                o_CLK90=clk90_rx,
                o_LOCKED=dcm_locked,
                i_PSEN=0,
                i_PSCLK=0,
                i_PSINCDEC=0,
                i_RST=dcm_reset
        )

        self.specials += Instance("BUFG", i_I=clk0_rx, o_O=clk0_rx_bufg)
        self.specials += Instance("BUFG", i_I=clk90_rx, o_O=self.cd_eth_rx.clk)

        # TX
        self.specials += DDROutput(1, 0, clock_pads.tx, ClockSignal("eth_tx"))
        self.specials += Instance("BUFG", i_I=self.cd_eth_rx.clk, o_O=self.cd_eth_tx.clk)

        # Reset
        reset = Signal()
        if with_hw_init_reset:
            self.submodules.hw_reset = LiteEthPHYHWReset()
            self.comb += reset.eq(self._reset.storage | self.hw_reset.reset)
        else:
            self.comb += reset.eq(self._reset.storage)

        self.comb += pads.rst_n.eq(~reset)
        self.specials += [
            AsyncResetSynchronizer(self.cd_eth_tx, reset),
            AsyncResetSynchronizer(self.cd_eth_rx, reset),
        ]
Ejemplo n.º 3
0
    def __init__(self, sink_description, source_description, header):
        self.sink = sink = stream.Endpoint(sink_description)
        self.source = source = stream.Endpoint(source_description)
        self.header = Signal(header.length*8)

        # # #

        dw = len(self.sink.data)

        header_reg = Signal(header.length*8)
        header_words = (header.length*8)//dw
        load = Signal()
        shift = Signal()
        counter = Signal(max=max(header_words, 2))
        counter_reset = Signal()
        counter_ce = Signal()
        self.sync += \
            If(counter_reset,
                counter.eq(0)
            ).Elif(counter_ce,
                counter.eq(counter + 1)
            )

        self.comb += header.encode(sink, self.header)
        if header_words == 1:
            self.sync += [
                If(load,
                    header_reg.eq(self.header)
                )
            ]
        else:
            self.sync += [
                If(load,
                    header_reg.eq(self.header)
                ).Elif(shift,
                    header_reg.eq(Cat(header_reg[dw:], Signal(dw)))
                )
            ]

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

        if header_words == 1:
            idle_next_state = "COPY"
        else:
            idle_next_state = "SEND_HEADER"

        fsm.act("IDLE",
            sink.ready.eq(1),
            counter_reset.eq(1),
            If(sink.valid,
                sink.ready.eq(0),
                source.valid.eq(1),
                source.last.eq(0),
                source.data.eq(self.header[:dw]),
                If(source.valid & source.ready,
                    load.eq(1),
                    NextState(idle_next_state)
                )
            )
        )
        if header_words != 1:
            fsm.act("SEND_HEADER",
                source.valid.eq(1),
                source.last.eq(0),
                source.data.eq(header_reg[dw:2*dw]),
                If(source.valid & source.ready,
                    shift.eq(1),
                    counter_ce.eq(1),
                    If(counter == header_words-2,
                        NextState("COPY")
                    )
                )
            )
        fsm.act("COPY",
            source.valid.eq(sink.valid),
            source.last.eq(sink.last),
            source.data.eq(sink.data),
            source.error.eq(sink.error),
            If(source.valid & source.ready,
                sink.ready.eq(1),
                If(source.last,
                    NextState("IDLE")
                )
            )
        )
Ejemplo n.º 4
0
    def __init__(self, sink_description, source_description, header):
        self.sink = sink = stream.Endpoint(sink_description)
        self.source = source = stream.Endpoint(source_description)
        self.header = Signal(header.length*8)

        # # #

        dw = len(sink.data)

        header_words = (header.length*8)//dw

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

        if header_words == 1:
            self.sync += \
                If(shift,
                    self.header.eq(sink.data)
                )
        else:
            self.sync += \
                If(shift,
                    self.header.eq(Cat(self.header[dw:], sink.data))
                )

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

        if header_words == 1:
            idle_next_state = "COPY"
        else:
            idle_next_state = "RECEIVE_HEADER"

        fsm.act("IDLE",
            sink.ready.eq(1),
            counter_reset.eq(1),
            If(sink.valid,
                shift.eq(1),
                NextState(idle_next_state)
            )
        )
        if header_words != 1:
            fsm.act("RECEIVE_HEADER",
                sink.ready.eq(1),
                If(sink.valid,
                    counter_ce.eq(1),
                    shift.eq(1),
                    If(counter == header_words-2,
                        NextState("COPY")
                    )
                )
            )
        no_payload = Signal()
        self.sync += \
            If(fsm.before_entering("COPY"),
                no_payload.eq(sink.last)
            )

        if hasattr(sink, "error"):
            self.comb += source.error.eq(sink.error)
        self.comb += [
            source.last.eq(sink.last | no_payload),
            source.data.eq(sink.data),
            header.decode(self.header, source)
        ]
        fsm.act("COPY",
            sink.ready.eq(source.ready),
            source.valid.eq(sink.valid | no_payload),
            If(source.valid & source.ready & source.last,
                NextState("IDLE")
            )
        )
Ejemplo n.º 5
0
    def __init__(self, dram_port, nslots):
        bus_aw = dram_port.aw
        bus_dw = dram_port.dw
        alignment_bits = bits_for(bus_dw//8) - 1

        fifo_word_width = bus_dw
        self.frame = stream.Endpoint([("sof", 1), ("pixels", fifo_word_width)])
        self._frame_size = CSRStorage(bus_aw + alignment_bits,
                                      alignment_bits=alignment_bits)
        self.submodules._slot_array = _SlotArray(nslots, bus_aw, alignment_bits)
        self.ev = self._slot_array.ev

        # # #

        # address generator + maximum memory word count to prevent DMA buffer
        # overrun
        reset_words = Signal()
        count_word = Signal()
        last_word = Signal()
        current_address = Signal(bus_aw)
        mwords_remaining = Signal(bus_aw)
        self.comb += [
            self._slot_array.address_reached.eq(current_address),
            last_word.eq(mwords_remaining == 1)
        ]
        self.sync += [
            If(reset_words,
                current_address.eq(self._slot_array.address),
                mwords_remaining.eq(self._frame_size.storage)
            ).Elif(count_word,
                current_address.eq(current_address + 1),
                mwords_remaining.eq(mwords_remaining - 1)
            )
        ]

        memory_word = Signal(bus_dw)
        pixbits = []
        for i in range(bus_dw//16):
            pixbits.append(self.frame.pixels)
        self.comb += memory_word.eq(Cat(*pixbits))

        # bus accessor
        self.submodules._bus_accessor = LiteDRAMDMAWriter(dram_port)
        self.comb += [
            self._bus_accessor.sink.address.eq(current_address),
            self._bus_accessor.sink.data.eq(memory_word)
        ]

        # control FSM
        fsm = FSM()
        self.submodules += fsm

        fsm.act("WAIT_SOF",
            reset_words.eq(1),
            self.frame.ready.eq(~self._slot_array.address_valid |
                                ~self.frame.sof),
            If(self._slot_array.address_valid &
               self.frame.sof &
               self.frame.valid,
               NextState("TRANSFER_PIXELS")
            )
        )
        fsm.act("TRANSFER_PIXELS",
            self.frame.ready.eq(self._bus_accessor.sink.ready),
            If(self.frame.valid,
                self._bus_accessor.sink.valid.eq(1),
                If(self._bus_accessor.sink.ready,
                    count_word.eq(1),
                    If(last_word,
                        NextState("EOF")
                    )
                )
            )
        )
        fsm.act("EOF",
            If(~dram_port.wdata.valid,
                self._slot_array.address_done.eq(1),
                NextState("WAIT_SOF")
            )
        )