Ejemplo n.º 1
0
    def __init__(self, leds_raw, leds_muxes=None, active=1):

        leds = Signal(flen(leds_raw))

        self._out = description.CSRStorage(flen(leds), atomic_write=True)

        if leds_muxes:
            assert len(leds_muxes) == flen(leds)
            for n in range(flen(leds)):
                name = "mux_%d" % n
                attr = description.CSRStorage(8, atomic_write=True, name=name)
                setattr(self, "_%s" % name, attr)

                mux_vals = [self._out.storage[n]]

                if leds_muxes[n]:
                    mux_vals.extend(leds_muxes[n])

                cases = {k: leds[n].eq(v) for k, v in enumerate(mux_vals)}

                self.comb += [
                        leds[n].eq(0),
                        Case(attr.storage, cases)
                        ]

        else:
            self.comb += [
                leds.eq(self._out.storage),
            ]

        self.comb += [
            leds_raw.eq(leds if active else ~leds)
        ]
Ejemplo n.º 2
0
    def __init__(self):
        self._size = description.CSRStorage(8, reset=8)
        self._cfg = description.CSRStorage(1, reset=0)

        self.source = Source([('d', 8), ('last', 1)])

        START_BYTE = 0xAA

        self.lfsr_state = Signal(17)
        self.lfsr_state_next = Signal(17)

        self.sync += If(~self._cfg.storage[0], self.lfsr_state.eq(1)).Else(
            self.lfsr_state.eq(self.lfsr_state_next))

        self.bytecount = Signal(8)
        self.bytecount_next = Signal(8)
        self.comb += [
            self.lfsr_state_next.eq(self.lfsr_state),
            self.bytecount_next.eq(self.bytecount),
            self.source.payload.last.eq(0)
        ]
        self.sync += self.bytecount.eq(self.bytecount_next)

        self.submodules.fsm = FSM()

        self.fsm.act("IDLE", If(self._cfg.storage[0], NextState("SEND_HEAD")))

        self.fsm.act("SEND_HEAD", self.source.payload.d.eq(0xAA),
                     self.source.stb.eq(1),
                     If(self.source.ack, NextState("SEND_SIZE")))

        self.fsm.act(
            "SEND_SIZE",
            self.source.payload.d.eq(self._size.storage),
            self.source.stb.eq(1),
            If(self.source.ack, self.bytecount_next.eq(0),
               NextState("SEND_DATA")),
        )

        self.fsm.act(
            "SEND_DATA", self.source.payload.d.eq(self.lfsr_state),
            self.source.stb.eq(1),
            If(self.bytecount + 1 == self._size.storage,
               self.source.payload.last.eq(1)),
            If(
                self.source.ack,
                self.lfsr_state_next.eq(
                    Cat(
                        self.lfsr_state[16] ^ self.lfsr_state[14]
                        ^ self.lfsr_state[13] ^ self.lfsr_state[11],
                        self.lfsr_state)),
                self.bytecount_next.eq(self.bytecount + 1),
                If(self.bytecount + 1 == self._size.storage,
                   NextState("IDLE"))))
Ejemplo n.º 3
0
    def __init__(self, ninputs=32, noutputs=32):
        r_o = description.CSRStorage(noutputs, atomic_write=True)
        r_i = description.CSRStatus(ninputs)

        self.submodules.bank = csrgen.Bank([r_o, r_i])
        self.gpio_in = Signal(ninputs)
        self.gpio_out = Signal(ninputs)

        ###

        gpio_in_s = Signal(ninputs)
        self.specials += MultiReg(self.gpio_in, gpio_in_s)
        self.comb += [self.gpio_out.eq(r_o.storage), r_i.status.eq(gpio_in_s)]
Ejemplo n.º 4
0
    def __init__(self, clk, cd_rst, ulpi_rst, ulpi_stp_ovr, ulpi_reg):

        # TESTING - UCFG_RST register
        #  - BRST: reseting of code in the ULPI cd
        #  - URST: reset of external phy
        #  - FSTP: Force assert of STP during reset
        #   (should be part of ULPI cd bringup code)
        #
        # Format:
        #
        #    7    6    5    4    3    2    1    0
        #    ---------------------------------------
        #    0    0    0    0    0    FSTP BRST URST
        #

        self._rst = description.CSRStorage(3)
        self.comb += ulpi_rst.eq(self._rst.storage[0])
        self.comb += cd_rst.eq(self._rst.storage[1])
        self.comb += ulpi_stp_ovr.eq(self._rst.storage[2])

        # TESTING - UCFG_STAT register
        #
        # CKACT: single status bit that indicates whether
        # the ULPI phy is providing a 60mhz clock signal on clk
        #
        # Format:
        #
        #    7    6    5    4    3    2    1    0
        #    ----------------------------------------
        #    0    0    0    0    0    0    0    CKACT
        #

        self._stat = description.CSRStatus(1)

        ulpi_clk_act_cd = Signal(8)

        # Resample ulpi_clk in sys
        sys_ulpi_clk = Signal(1)
        self.specials += MultiReg(clk, sys_ulpi_clk)

        # Edge detect the ULPI clk
        last_ulpi_clk = Signal(1)
        self.sync += [
            last_ulpi_clk.eq(sys_ulpi_clk),

            # On detected transistions, reset the countdown
            If(last_ulpi_clk != sys_ulpi_clk, ulpi_clk_act_cd.eq(0)).Elif(
                ulpi_clk_act_cd < 0xFF,
                ulpi_clk_act_cd.eq(ulpi_clk_act_cd + 1))
        ]

        self.comb += self._stat.status.eq(ulpi_clk_act_cd != 0xFF)

        # ULPI_xDATA and xCMD registers
        #
        # Used for reading/writing ULPI regs
        #
        # ULPI_xDATA Format: just 8 bit data reg
        #
        # ULPI_xCMD Format:
        #
        #    7    6    5    4    3    2    1    0
        #    ----------------------------------------
        #    GO   0    UA5  UA4  UA3  UA2  UA1  UA0
        #
        # GO:
        #    - write 1 to start ULPI reg transaction
        #    - stays 1 while transaction in progress
        #    - clears to 0 when transaction complete
        #
        # UA5..0 - ULPI register address

        # To do a write: write UCFG_WDATA with the value
        # and then write ULPI_WCMD with GO | addr
        #
        # To read: write ULPI_RCMD with GO | addr, poll
        # until GO clear, then read ULPI_RDATA

        self._wdata = description.CSRStorage(8)
        self._wcmd = _ULPI_cmd_reg(ulpi_reg.wreq, ulpi_reg.wack,
                                   ulpi_reg.waddr)
        self.submodules += self._wcmd
        self.comb += ulpi_reg.wdata.eq(self._wdata.storage)

        self._rdata = description.CSRStatus(8)
        self._rcmd = _ULPI_cmd_reg(ulpi_reg.rreq, ulpi_reg.rack,
                                   ulpi_reg.raddr)
        self.submodules += self._rcmd
        self.sync += If(ulpi_reg.rack, self._rdata.status.eq(ulpi_reg.rdata))
Ejemplo n.º 5
0
    def __init__(self, hostif, max_burst_length=256):
        width = flen(hostif.d_write)
        assert width == 16

        awidth = flen(hostif.i_addr) + 1

        self.sink = Sink([('d', 8), ('last', 1)])

        self.submodules.sdram_fifo = SyncFIFO(width, max_burst_length)

        self.submodules.fifo_write_fsm = FSM()

        self.wptr = Signal(awidth)

        # rptr (from SDRAM Source)
        self.rptr = Signal(awidth)

        # CSRs

        self._ptr_read = CSRStorageEx(1)
        ptr_read = self._ptr_read.re
        self._wptr = description.CSRStatus(awidth)
        self.sync += If(ptr_read, self._wptr.status.eq(self.wptr))
        self._rptr = description.CSRStatus(awidth)
        self.sync += If(ptr_read, self._rptr.status.eq(self.rptr))

        self._ring_base = description.CSRStorage(awidth)
        self._ring_end = description.CSRStorage(awidth)
        self._go = description.CSRStorage(1)

        go = self._go.storage[0]

        # 'go'-signal edge detect
        gor = Signal()
        self.sync += gor.eq(go)

        self._wrap_count = Perfcounter(ptr_read, go & ~gor)

        # wptr wrap around

        wrap = Signal()
        self.comb += wrap.eq(self.wptr == self._ring_end.storage)
        wptr_next = Signal(awidth)
        self.comb += If(wrap, wptr_next.eq(self._ring_base.storage)).Else(
            wptr_next.eq(self.wptr + 1))

        # debug

        self._debug_ctl = CSRStorageEx(1)
        snapshot = self._debug_ctl.re
        perf_reset = self._debug_ctl.storage[0]
        self._debug_i_stb = Perfcounter(snapshot, perf_reset)
        self._debug_i_ack = Perfcounter(snapshot, perf_reset)
        self._debug_d_stb = Perfcounter(snapshot, perf_reset)
        self._debug_d_term = Perfcounter(snapshot, perf_reset)
        self._debug_s0 = Perfcounter(snapshot, perf_reset)
        self._debug_s1 = Perfcounter(snapshot, perf_reset)
        self._debug_s2 = Perfcounter(snapshot, perf_reset)
        self._perf_busy = Perfcounter(snapshot, perf_reset)

        self.comb += If(hostif.i_stb, self._debug_i_stb.inc())
        self.comb += If(hostif.i_ack, self._debug_i_ack.inc())
        self.comb += If(hostif.d_stb, self._debug_d_stb.inc())
        self.comb += If(hostif.d_term, self._debug_d_term.inc())
        self.comb += If(~self.sdram_fifo.writable, self._perf_busy.inc())

        # FSM to move FIFO data to SDRAM

        burst_rem = Signal(max=max_burst_length)
        burst_rem_next = Signal(max=max_burst_length)

        self.comb += burst_rem_next.eq(burst_rem)
        self.sync += burst_rem.eq(burst_rem_next)

        self.comb += hostif.i_wr.eq(1)

        blocked = Signal()

        self.comb += blocked.eq(self.rptr == wptr_next)

        # start writing data if
        # - 'go'-signal set, and
        # - input data available
        # - not blocked

        self.fifo_write_fsm.act(
            "IDLE", self._debug_s0.inc(),
            If(self.sdram_fifo.readable & go & ~blocked,
               hostif.i_addr.eq(self.wptr), hostif.i_stb.eq(1),
               burst_rem_next.eq(max_burst_length - 1)),
            If(hostif.i_ack, NextState("WRITE")))

        self.comb += hostif.d_write.eq(self.sdram_fifo.dout)

        # stop writing if
        # - max burst length reached, or
        # - no more input data, or
        # - wrap
        # - blocked

        self.fifo_write_fsm.act(
            "WRITE", self._debug_s1.inc(),
            hostif.d_term.eq((burst_rem == 0) | ~self.sdram_fifo.readable
                             | wrap | blocked),
            self.sdram_fifo.re.eq(hostif.d_stb & ~hostif.d_term),
            If(~hostif.d_term & hostif.d_stb,
               burst_rem_next.eq(burst_rem_next - 1)),
            If(hostif.d_term & ~hostif.d_stb,
               NextState("WAIT")).Elif(hostif.d_term & hostif.d_stb,
                                       NextState("IDLE")))

        self.fifo_write_fsm.act("WAIT", self._debug_s2.inc(),
                                hostif.d_term.eq(1),
                                If(hostif.d_stb, NextState("IDLE")))

        # wrap around counter
        self.comb += If(wrap & hostif.d_stb & ~hostif.d_term,
                        self._wrap_count.inc())

        # update wptr
        self.sync += If(
            go & ~gor,
            self.wptr.eq(self._ring_base.storage),
        ).Elif((hostif.d_stb & ~hostif.d_term) | wrap, self.wptr.eq(wptr_next))

        # sink into fifo

        self.submodules.fifo_fsm = FSM()

        capture_low = Signal()
        din_low = Signal(8)

        self.comb += self.sdram_fifo.din.eq(Cat(din_low, self.sink.payload.d))

        self.sync += If(capture_low, din_low.eq(self.sink.payload.d))

        self.fifo_fsm.act("READ_LOW", capture_low.eq(1), self.sink.ack.eq(1),
                          If(self.sink.stb, NextState("READ_HI")))

        self.fifo_fsm.act(
            "READ_HI", self.sdram_fifo.we.eq(self.sink.stb),
            self.sink.ack.eq(self.sdram_fifo.writable),
            If(self.sink.ack & self.sink.stb, NextState("READ_LOW")))
Ejemplo n.º 6
0
    def __init__(self, hostif, host_burst_length = 16):
        width = flen(hostif.d_write)
        assert width == 16
        awidth = flen(hostif.i_addr) + 1

        self.source = Source([('d', 8), ('last', 1)])

        go = Signal()
        gor = Signal()
        rptr = Signal(awidth)
        self.rptr = rptr
        rptr_w = Signal(awidth)
        rptr_we = Signal()
        self.wptr = Signal(awidth)

        # CSRs

        ##

        self._debug_i_stb = description.CSRStatus(32)
        self._debug_i_ack = description.CSRStatus(32)
        self._debug_d_stb = description.CSRStatus(32)
        self._debug_d_term = description.CSRStatus(32)
        self._debug_s0 = description.CSRStatus(32)
        self._debug_s1 = description.CSRStatus(32)
        self._debug_s2 = description.CSRStatus(32)

        self.submodules.i_stb_acc = Acc_inc(32)
        self.submodules.i_ack_acc = Acc_inc(32)
        self.submodules.d_stb_acc = Acc_inc(32)
        self.submodules.d_term_acc = Acc_inc(32)

        self.comb += self._debug_i_stb.status.eq(self.i_stb_acc.v)
        self.comb += self._debug_i_ack.status.eq(self.i_ack_acc.v)
        self.comb += self._debug_d_stb.status.eq(self.d_stb_acc.v)
        self.comb += self._debug_d_term.status.eq(self.d_term_acc.v)
        self.comb += If(hostif.i_stb, self.i_stb_acc.inc())
        self.comb += If(hostif.i_ack, self.i_ack_acc.inc())
        self.comb += If(hostif.d_stb, self.d_stb_acc.inc())
        self.comb += If(hostif.d_term, self.d_term_acc.inc())

        self.submodules.s0_acc = Acc_inc(32)
        self.submodules.s1_acc = Acc_inc(32)
        self.submodules.s2_acc = Acc_inc(32)

        self.comb += self._debug_s0.status.eq(self.s0_acc.v)
        self.comb += self._debug_s1.status.eq(self.s1_acc.v)
        self.comb += self._debug_s2.status.eq(self.s2_acc.v)

        ##

        self._ring_base = description.CSRStorage(awidth)
        self._ring_end = description.CSRStorage(awidth)

        # rptr readback
        self._rptr_status = description.CSRStatus(awidth)
        self.comb += self._rptr_status.status.eq(rptr)

        # 'go' bit

        self._go = description.CSRStorage(1)

        self.comb += go.eq(self._go.storage[0])
        self.sync += gor.eq(go)

        # state machine to read

        self.submodules.sdram_read_fsm = FSM()

        sdram_fifo = SyncFIFO(width, host_burst_length)
        self.submodules += sdram_fifo

        # we always read (never write)
        self.comb += hostif.i_wr.eq(0)

        # blocked

        blocked = Signal()
        self.comb += blocked.eq(rptr == self.wptr)

        # wait until there's data and go, and then when the fifo has space, issue request.

        self.sdram_read_fsm.act("BLOCKED",
            self.s2_acc.inc(),
            If(go & ~blocked, NextState("IDLE"))
        )

        self.sdram_read_fsm.act("IDLE",
            self.s0_acc.inc(),
            hostif.i_addr.eq(rptr),
            hostif.i_stb.eq(sdram_fifo.writable),
            If (hostif.i_stb & hostif.i_ack,
                NextState("DATA")
            )
        )

        # read until fifo is full; when fifo is not writable but data was received,
        # abort SDRAM read request.

        wrap = Signal()
        self.comb += wrap.eq(self.rptr == self._ring_end.storage)

        self.sdram_read_fsm.act("DATA",
            self.s1_acc.inc(),
            hostif.d_term.eq(~sdram_fifo.writable | ~go | blocked | wrap),
            If (hostif.d_term,
                If (hostif.d_stb,
                    NextState("BLOCKED")
                ).Else(
                    NextState("WAIT")
                )
            )
        )

        self.sdram_read_fsm.act("WAIT",
            hostif.d_term.eq(1),
            If (hostif.d_stb,
                NextState("BLOCKED")
            )
        )

        # allow rptr to be updated via CSR. Otherwise,
        # increment read point whenever valid data is fed into the fifo.

        rptr_next = Signal(awidth)
        self.comb += If(wrap, rptr_next.eq(self._ring_base.storage)).Else(rptr_next.eq(self.rptr + 1))

        self.sync += \
            If(go &~ gor, 
                rptr.eq(self._ring_base.storage),
            ).Elif(hostif.d_stb &~hostif.d_term | wrap, 
                rptr.eq(rptr_next))

        self.comb += sdram_fifo.we.eq(hostif.d_stb &~ hostif.d_term)
        self.comb += sdram_fifo.din.eq(hostif.d_read)

        # fifo to host interface

        self.submodules.host_write_fsm = FSM()

        burst_rem = Signal(max = host_burst_length) 
        burst_rem_next = Signal(max = host_burst_length)

        self.comb += burst_rem_next.eq(burst_rem)
        self.sync += burst_rem.eq(burst_rem_next)

        # when the sdram_fifo is not anymore writable, start bursting out that data.

        self.host_write_fsm.act("IDLE",
            self.source.payload.d.eq(0xD0),
            self.source.stb.eq(sdram_fifo.readable &~ sdram_fifo.writable),
            If(self.source.ack & self.source.stb,
                NextState("SEND_HEADER")
            )
        )

        self.host_write_fsm.act("SEND_HEADER",
            self.source.payload.d.eq(host_burst_length - 1),
            self.source.stb.eq(1),
            If(self.source.ack & self.source.stb,
                burst_rem_next.eq(host_burst_length - 1),
                NextState("SEND_DATA_ODD")
            )
        )

        # when byte available, write low byte until ack'ed.

        self.host_write_fsm.act("SEND_DATA_ODD",
            self.source.payload.d.eq(sdram_fifo.dout[0:8]),
            self.source.stb.eq(sdram_fifo.readable),
            If (self.source.stb & self.source.ack,
                NextState("SEND_DATA_EVEN")
            )
        )

        # write high byte. when ack'ed, read next byte, unless we hit the burst length limit.

        self.host_write_fsm.act("SEND_DATA_EVEN",
            self.source.payload.d.eq(sdram_fifo.dout[8:16]),
            self.source.payload.last.eq(burst_rem == 0),
            self.source.stb.eq(1),
            sdram_fifo.re.eq(self.source.ack),
            If (self.source.ack, 
                If (burst_rem != 0,
                    NextState("SEND_DATA_ODD"),
                    burst_rem_next.eq(burst_rem - 1)
                ).Else(
                    NextState("IDLE")
                )
            )
        )