Exemplo n.º 1
0
    def __init__(self, master, cycles):
        self.error = Signal()
        wr_error   = Signal()
        rd_error   = Signal()

        # # #

        self.comb += self.error.eq(wr_error | rd_error)

        wr_timer = WaitTimer(int(cycles))
        rd_timer = WaitTimer(int(cycles))
        self.submodules += wr_timer, rd_timer

        def channel_fsm(timer, wait_cond, error, response):
            fsm = FSM(reset_state="WAIT")
            fsm.act("WAIT",
                timer.wait.eq(wait_cond),
                # done is updated in `sync`, so we must make sure that `ready` has not been issued
                # by slave during that single cycle, by checking `timer.wait`.
                If(timer.done & timer.wait,
                    error.eq(1),
                    NextState("RESPOND")
                )
            )
            fsm.act("RESPOND", *response)
            return fsm

        self.submodules.wr_fsm = channel_fsm(
            timer     = wr_timer,
            wait_cond = (master.aw.valid & ~master.aw.ready) | (master.w.valid & ~master.w.ready),
            error     = wr_error,
            response  = [
                master.aw.ready.eq(master.aw.valid),
                master.w.ready.eq(master.w.valid),
                master.b.valid.eq(~master.aw.valid & ~master.w.valid),
                master.b.resp.eq(RESP_SLVERR),
                If(master.b.valid & master.b.ready,
                    NextState("WAIT")
                )
            ])

        self.submodules.rd_fsm = channel_fsm(
            timer     = rd_timer,
            wait_cond = master.ar.valid & ~master.ar.ready,
            error     = rd_error,
            response  = [
                master.ar.ready.eq(master.ar.valid),
                master.r.valid.eq(~master.ar.valid),
                master.r.last.eq(1),
                master.r.resp.eq(RESP_SLVERR),
                master.r.data.eq(2**len(master.r.data) - 1),
                If(master.r.valid & master.r.ready,
                    NextState("WAIT")
                )
            ])
Exemplo n.º 2
0
    def __init__(self, clk_freq, timeout=10):
        self.sink = sink = stream.Endpoint(phy_description(32))
        self.source = source = stream.Endpoint(user_description(32))

        # # #

        count = Signal(len(source.length))
        length = Signal(len(source.length))

        # Packet description
        #   - preamble : 4 bytes
        #   - length   : 4 bytes
        #   - payload

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

        timer = WaitTimer(clk_freq * timeout)
        self.submodules += timer

        fsm.act(
            "PREAMBLE", sink.ready.eq(1),
            If(sink.valid & (sink.data == 0x5aa55aa5), NextState("LENGTH")))
        fsm.act(
            "LENGTH", sink.ready.eq(1),
            If(sink.valid, NextValue(count, 0), NextValue(length, sink.data),
               NextState("DATA")), timer.wait.eq(1))
        fsm.act(
            "DATA", source.valid.eq(sink.valid),
            source.last.eq(count == (length[2:] - 1)),
            source.length.eq(length), source.data.eq(sink.data),
            sink.ready.eq(source.ready),
            If(timer.done, NextState("PREAMBLE")).Elif(
                source.valid & source.ready, NextValue(count, count + 1),
                If(source.last, NextState("PREAMBLE"))), timer.wait.eq(1))
    def __init__(self, width, idomain, odomain, timeout=128):
        self.i = Signal(width)
        self.o = Signal(width, reset_less=True)

        if width == 1:
            self.specials += MultiReg(self.i, self.o, odomain)
        else:
            sync_i = getattr(self.sync, idomain)
            sync_o = getattr(self.sync, odomain)

            starter = Signal(reset=1)
            sync_i += starter.eq(0)
            self.submodules._ping = PulseSynchronizer(idomain, odomain)
            # Extra flop on i->o to avoid race between data and request
            # https://github.com/m-labs/nmigen/pull/40#issuecomment-484166790
            ping_o = Signal()
            sync_o += ping_o.eq(self._ping.o)
            self.submodules._pong = PulseSynchronizer(odomain, idomain)
            self.submodules._timeout = ClockDomainsRenamer(idomain)(
                WaitTimer(timeout))
            self.comb += [
                self._timeout.wait.eq(~self._ping.i),
                self._ping.i.eq(starter | self._pong.o | self._timeout.done),
                self._pong.i.eq(ping_o)
            ]

            ibuffer = Signal(width, reset_less=True)
            obuffer = Signal(width)  # registered reset_less by MultiReg
            sync_i += If(self._pong.o, ibuffer.eq(self.i))
            ibuffer.attr.add("no_retiming")
            self.specials += MultiReg(ibuffer, obuffer, odomain)
            sync_o += If(ping_o, self.o.eq(obuffer))
Exemplo n.º 4
0
Arquivo: cdc.py Projeto: bunnie/migen
    def __init__(self, width, idomain, odomain, timeout=128):
        self.i = Signal(width)
        self.o = Signal(width, reset_less=True)

        if width == 1:
            self.specials += MultiReg(self.i, self.o, odomain)
        else:
            sync_i = getattr(self.sync, idomain)
            sync_o = getattr(self.sync, odomain)

            starter = Signal(reset=1)
            sync_i += starter.eq(0)
            self.submodules._ping = PulseSynchronizer(idomain, odomain)
            self.submodules._pong = PulseSynchronizer(odomain, idomain)
            self.submodules._timeout = ClockDomainsRenamer(idomain)(
                WaitTimer(timeout))
            self.comb += [
                self._timeout.wait.eq(~self._ping.i),
                self._ping.i.eq(starter | self._pong.o | self._timeout.done),
                self._pong.i.eq(self._ping.i)
            ]

            ibuffer = Signal(width, reset_less=True)
            obuffer = Signal(width)  # registered reset_less by MultiReg
            sync_i += If(self._pong.o, ibuffer.eq(self.i))
            ibuffer.attr.add("no_retiming")
            self.specials += MultiReg(ibuffer, obuffer, odomain)
            sync_o += If(self._ping.o, self.o.eq(obuffer))
Exemplo n.º 5
0
    def __init__(self, endianness="big"):
        self.source = source = stream.Endpoint(spi_core2phy_layout)
        self.sink = sink = stream.Endpoint(spi_phy2core_layout)
        self.bus = bus = wishbone.Interface()
        self.cs = cs = Signal()

        # # #

        # Burst Control.
        burst_cs = Signal()
        burst_adr = Signal(len(bus.adr), reset_less=True)
        burst_timeout = WaitTimer(MMAP_DEFAULT_TIMEOUT)
        self.submodules += burst_timeout

        # FSM.
        self.submodules.fsm = fsm = FSM(reset_state="IDLE")
        fsm.act(
            "IDLE",
            # Keep CS active after Burst for Timeout.
            burst_timeout.wait.eq(1),
            NextValue(burst_cs, burst_cs & ~burst_timeout.done),
            cs.eq(burst_cs),
            # On Bus Read access...
            If(
                bus.cyc & bus.stb & ~bus.we,
                # If CS is still active and Bus address matches previous Burst address:
                # Just continue the current Burst.
                If(burst_cs & (bus.adr == burst_adr),
                   NextState("BURST-REQ")
                   # Otherwise initialize a new Burst.
                   ).Else(cs.eq(0), NextState("BURST-CMD"))))
        fsm.act(
            "BURST-CMD",
            cs.eq(1),
            source.valid.eq(1),
            source.cmd.eq(CMD),
            source.data.eq(Cat(Signal(2), bus.adr)),  # Words to Bytes.
            NextValue(burst_cs, 1),
            NextValue(burst_adr, bus.adr),
            If(
                source.ready,
                NextState("BURST-REQ"),
            ))
        fsm.act("BURST-REQ", cs.eq(1), source.valid.eq(1), source.cmd.eq(READ),
                source.last.eq(1), If(
                    source.ready,
                    NextState("BURST-DAT"),
                ))
        fsm.act(
            "BURST-DAT", cs.eq(1), sink.ready.eq(1),
            bus.dat_r.eq({
                "big": sink.data,
                "little": reverse_bytes(sink.data)
            }[endianness]),
            If(
                sink.valid,
                bus.ack.eq(1),
                NextValue(burst_adr, burst_adr + 1),
                NextState("IDLE"),
            ))
Exemplo n.º 6
0
    def __init__(self, platform, sys_clk_freq, clk_external):
        self.clock_domains.cd_sys = ClockDomain()
        self.rst = CSR()

        # # #

        # Delay software reset by 10us to ensure write has been acked on PCIe.
        rst_delay = WaitTimer(int(10e-6 * sys_clk_freq))
        self.submodules += rst_delay
        self.sync += If(self.rst.re, rst_delay.wait.eq(1))

        if clk_external:
            platform.add_extension(get_clkin_ios())
            self.comb += self.cd_sys.clk.eq(platform.request("clk"))
            self.specials += AsyncResetSynchronizer(
                self.cd_sys,
                platform.request("rst") | rst_delay.done)
        else:
            platform.add_extension(get_clkout_ios())
            self.comb += self.cd_sys.clk.eq(ClockSignal("pcie"))
            self.specials += AsyncResetSynchronizer(self.cd_sys,
                                                    rst_delay.done)
            self.comb += [
                platform.request("clk125").eq(ClockSignal()),
                platform.request("rst125").eq(ResetSignal()),
            ]
Exemplo n.º 7
0
    def __init__(self, platform, sys_clk_freq):
        self.rst = CSR()

        self.clock_domains.cd_sys       = ClockDomain()
        self.clock_domains.cd_sys4x     = ClockDomain(reset_less=True)
        self.clock_domains.cd_sys4x_dqs = ClockDomain(reset_less=True)
        self.clock_domains.cd_clk200    = ClockDomain()

        # Clk/Rst
        clk200 = platform.request("clk200")

        # Delay software reset by 10us to ensure write has been acked on PCIe.
        rst_delay = WaitTimer(int(10e-6*sys_clk_freq))
        self.submodules += rst_delay
        self.sync += If(self.rst.re, rst_delay.wait.eq(1))

        # PLL
        self.submodules.pll = pll = S7PLL()
        self.comb += pll.reset.eq(rst_delay.done)
        pll.register_clkin(clk200, 200e6)
        pll.create_clkout(self.cd_sys,       sys_clk_freq)
        pll.create_clkout(self.cd_sys4x,     4*sys_clk_freq)
        pll.create_clkout(self.cd_sys4x_dqs, 4*sys_clk_freq, phase=90)
        pll.create_clkout(self.cd_clk200,    200e6)

        self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_clk200)
Exemplo n.º 8
0
Arquivo: spi.py Projeto: olsonse/pdq
    def __init__(self, cycles=1):
        self.i = Signal()
        self.o = Signal()

        ###

        timer = WaitTimer(cycles - 1)
        self.submodules += timer
        new = Signal()
        rst = Signal(reset=1)
        self.sync += [
            If(
                timer.wait,
                If(
                    timer.done,
                    timer.wait.eq(0),
                    new.eq(~new),
                ),
            ).Elif(
                self.i == new,
                timer.wait.eq(1),
            ),
            If(
                rst,
                rst.eq(0),
                timer.wait.eq(0),
                new.eq(~self.i),
            ),
        ]
        self.comb += [
            self.o.eq(Mux(timer.wait, new, self.i)),
        ]
Exemplo n.º 9
0
    def __init__(self, sys_clk_freq, lfps_clk_freq):
        # Control
        self.start = Signal()  # i
        self.done = Signal()  # o
        self.length = Signal(32)  # i

        # Transceiver
        self.tx_idle = Signal(reset=1)  # o
        self.tx_pattern = Signal(20)  # o

        # # #

        # Assertions -------------------------------------------------------------------------------
        # The LFPS Burst has a minimum and maximum allowed period.
        assert lfps_clk_freq >= lfps_clk_freq_min
        assert lfps_clk_freq <= lfps_clk_freq_max

        # LFPS Burst Clock generation --------------------------------------------------------------
        clk = Signal()
        clk_timer = WaitTimer(ceil(sys_clk_freq / (2 * lfps_clk_freq)) - 1)
        clk_timer = ResetInserter()(clk_timer)
        self.submodules += clk_timer
        self.comb += clk_timer.wait.eq(~clk_timer.done)
        self.sync += If(clk_timer.done, clk.eq(~clk))

        # LFPS Burst generation --------------------------------------------------------------------
        count = Signal.like(self.length)
        self.submodules.fsm = fsm = FSM(reset_state="IDLE")
        fsm.act("IDLE", self.done.eq(1), clk_timer.reset.eq(1),
                NextValue(count, self.length),
                If(self.start, NextState("BURST")))
        fsm.act("BURST", self.tx_idle.eq(0),
                self.tx_pattern.eq(Replicate(clk, 20)),
                NextValue(count, count - 1), If(count == 0, NextState("IDLE")))
Exemplo n.º 10
0
    def __init__(self, settings):
        # 1st command 1 cycle after assertion of ready
        self.cmd = cmd = stream.Endpoint(cmd_request_rw_layout(settings.geom.addressbits,
                                                               settings.geom.bankbits))

        # # #

        # Refresh sequence generator:
        # PRECHARGE ALL --(tRP)--> AUTO REFRESH --(tRFC)--> done
        seq_start = Signal()
        seq_done = Signal()
        self.sync += [
            cmd.a.eq(2**10),
            cmd.ba.eq(0),
            cmd.cas.eq(0),
            cmd.ras.eq(0),
            cmd.we.eq(0),
            seq_done.eq(0)
        ]
        self.sync += timeline(seq_start, [
            (1, [
                cmd.ras.eq(1),
                cmd.we.eq(1)
            ]),
            (1+settings.timing.tRP, [
                cmd.cas.eq(1),
                cmd.ras.eq(1)
            ]),
            (1+settings.timing.tRP+settings.timing.tRFC, [
                seq_done.eq(1)
            ])
        ])

        # Periodic refresh counter
        self.submodules.timer = WaitTimer(settings.timing.tREFI)
        self.comb += self.timer.wait.eq(settings.with_refresh & ~self.timer.done)

        # Control FSM
        self.submodules.fsm = fsm = FSM()
        fsm.act("IDLE",
            If(self.timer.done,
                NextState("WAIT_GRANT")
            )
        )
        fsm.act("WAIT_GRANT",
            cmd.valid.eq(1),
            If(cmd.ready,
                seq_start.eq(1),
                NextState("WAIT_SEQ")
            )
        )
        fsm.act("WAIT_SEQ",
            If(seq_done,
                cmd.last.eq(1),
                NextState("IDLE")
            ).Else(
                cmd.valid.eq(1)
            )
        )
    def __init__(self, phy_dw, with_scrambling=True):
        self.bitslip_value = bitslip_value = Signal(6)
        self.sink = sink = stream.Endpoint([("data", phy_dw)])
        self.source = source = stream.Endpoint([("data", 32)])
        self.idle = idle = Signal()
        self.comma = comma = Signal()

        # # #

        # converter
        self.submodules.converter = converter = stream.Converter(phy_dw, 40)

        # bitslip
        self.submodules.bitslip = bitslip = _Bitslip()
        self.comb += bitslip.value.eq(bitslip_value)

        # line coding
        self.submodules.decoder = decoder = _8b10bDecoder()

        # descrambler
        if with_scrambling:
            self.submodules.descrambler = descrambler = Descrambler()

        # dataflow
        self.comb += [
            sink.connect(converter.sink),
            converter.source.connect(bitslip.sink),
            bitslip.source.connect(decoder.sink)
        ]
        if with_scrambling:
            self.comb += [
                decoder.source.connect(descrambler.sink),
                descrambler.source.connect(source)
            ]
        else:
            self.comb += [
                decoder.source.connect(source, omit={"d", "k"}),
                source.data.eq(decoder.source.d)
            ]

        # idle decoding
        idle_timer = WaitTimer(32)
        self.submodules += idle_timer
        self.sync += [
            If(
                converter.source.valid,
                idle_timer.wait.eq((converter.source.data == 0)
                                   | (converter.source.data == (2**40 - 1)))),
            idle.eq(idle_timer.done)
        ]
        # comma decoding
        self.sync += \
            If(decoder.source.valid,
                comma.eq((decoder.source.k == 1) & (decoder.source.d == K(28, 5)))
            )
Exemplo n.º 12
0
    def __init__(self, data_width, depth=16):
        self.sink = sink = stream.Endpoint(core_layout(data_width))
        self.source = source = stream.Endpoint(core_layout(data_width))

        self.enable = CSRStorage()
        self.done = CSRStatus()

        self.mem_write = CSR()
        self.mem_mask = CSRStorage(data_width)
        self.mem_value = CSRStorage(data_width)
        self.mem_full = CSRStatus()

        # # #

        # Control re-synchronization
        enable = Signal()
        enable_d = Signal()
        self.specials += MultiReg(self.enable.storage, enable, "scope")
        self.sync.scope += enable_d.eq(enable)

        # Status re-synchronization
        done = Signal()
        self.specials += MultiReg(done, self.done.status)

        # Memory and configuration
        mem = stream.AsyncFIFO([("mask", data_width), ("value", data_width)],
                               depth)
        mem = ClockDomainsRenamer({"write": "sys", "read": "scope"})(mem)
        self.submodules += mem
        self.comb += [
            mem.sink.valid.eq(self.mem_write.re),
            mem.sink.mask.eq(self.mem_mask.storage),
            mem.sink.value.eq(self.mem_value.storage),
            self.mem_full.status.eq(~mem.sink.ready)
        ]

        # Hit and memory read/flush
        hit = Signal()
        flush = WaitTimer(2 * depth)
        flush = ClockDomainsRenamer("scope")(flush)
        self.submodules += flush
        self.comb += [
            flush.wait.eq(~(~enable & enable_d)),  # flush when disabling
            hit.eq((sink.data & mem.source.mask) == (mem.source.value
                                                     & mem.source.mask)),
            mem.source.ready.eq((enable & hit) | ~flush.done),
        ]

        # Output
        self.comb += [
            sink.connect(source),
            # Done when all triggers have been consumed
            done.eq(~mem.source.valid),
            source.hit.eq(done)
        ]
Exemplo n.º 13
0
    def __init__(self, master, cycles):
        self.error = Signal()

        # # #

        timer = WaitTimer(int(cycles))
        self.submodules += timer
        self.comb += [
            timer.wait.eq(master.stb & master.cyc & ~master.ack),
            If(timer.done, master.dat_r.eq((2**len(master.dat_w)) - 1),
               master.ack.eq(1), self.error.eq(1))
        ]
Exemplo n.º 14
0
    def __init__(self,
                 sys_clk_freq=int(50e6),
                 with_etherbone=True,
                 ip_address=None,
                 mac_address=None):
        platform = colorlight_5a_75b.Platform(revision="7.0")

        # CRG --------------------------------------------------------------------------------------
        self.submodules.crg = _CRG(platform, sys_clk_freq)

        # SoCMini ----------------------------------------------------------------------------------
        SoCMini.__init__(self, platform, clk_freq=sys_clk_freq)

        # Etherbone --------------------------------------------------------------------------------
        if with_etherbone:
            self.submodules.ethphy = LiteEthPHYRGMII(
                clock_pads=self.platform.request("eth_clocks"),
                pads=self.platform.request("eth"),
                tx_delay=0e-9)
            self.add_etherbone(
                phy=self.ethphy,
                ip_address=ip_address,
                mac_address=mac_address,
                data_width=32,
            )

        # SPIFlash ---------------------------------------------------------------------------------
        self.submodules.spiflash = ECP5SPIFlash(
            pads=platform.request("spiflash"),
            sys_clk_freq=sys_clk_freq,
            spi_clk_freq=5e6,
        )

        # Led --------------------------------------------------------------------------------------
        self.submodules.leds = LedChaser(
            pads=platform.request_all("user_led_n"), sys_clk_freq=sys_clk_freq)

        # GPIOs ------------------------------------------------------------------------------------
        platform.add_extension(_gpios)

        # Power switch
        power_sw_pads = platform.request("gpio", 0)
        power_sw_gpio = Signal()
        power_sw_timer = WaitTimer(
            2 * sys_clk_freq)  # Set Power switch high after power up for 2s.
        self.comb += power_sw_timer.wait.eq(1)
        self.submodules += power_sw_timer
        self.submodules.gpio0 = GPIOOut(power_sw_gpio)
        self.comb += power_sw_pads.eq(power_sw_gpio | ~power_sw_timer.done)

        # Reset Switch
        reset_sw_pads = platform.request("gpio", 1)
        self.submodules.gpio1 = GPIOOut(reset_sw_pads)
Exemplo n.º 15
0
    def __init__(self, clock_pads, pads):
        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 = self._reset.storage
        self.comb += pads.rst_n.eq(~reset)
        self.specials += [
            AsyncResetSynchronizer(self.cd_eth_tx, reset),
            AsyncResetSynchronizer(self.cd_eth_rx, reset),
        ]
Exemplo n.º 16
0
    def __init__(self, identifier, depth=128):
        self.submodules.buf = buf = stream.SyncFIFO(wrap_description(32),
                                                    depth + 1)
        self.sink = sink = buf.sink
        self.source = source = stream.Endpoint(usb_description(32))

        # # #

        count = Signal(32)

        self.submodules.timer = WaitTimer(int(1e6))

        self.comb += [
            source.dst.eq(identifier),
        ]

        fsm = FSM()
        self.submodules.fsm = fsm

        fsm.act(
            "BUFFER",
            If(
                buf.level > 0,
                self.timer.wait.eq(1),
            ),

            # if buffer full or timeout elapsed
            If(
                (buf.level >= depth) | self.timer.done,
                NextValue(count, buf.level),
                NextState("TRANSFER"),
            ))

        fsm.act(
            "TRANSFER",
            source.length.eq(Cat(C(0, 2), count)),
            source.valid.eq(buf.source.valid),
            source.last.eq(count == 1),
            source.data.eq(buf.source.data),
            buf.source.ready.eq(source.ready),
            If(
                source.valid & source.ready,
                If(
                    source.last,
                    # if enough data stay in transfer state
                    If(
                        buf.level - 1 >= depth,
                        NextValue(count, buf.level - 1),
                    ).Else(NextState("BUFFER"), ),
                ).Else(NextValue(count, count - 1), )),
        )
Exemplo n.º 17
0
    def __init__(self, jesd_settings, n=0):
        self.jsync = Signal()  # Input
        self.jref = Signal()  # Input
        self.lmfc_zero = Signal()  # Input
        self.ready = Signal()  # Output

        self.sink = sink = Record([("data", jesd_settings.LINK_DW)])
        self.source = source = Record(link_layout(jesd_settings.LINK_DW))

        # # #

        # Code Group Synchronization
        cgs = CGSGenerator(jesd_settings.LINK_DW)
        self.submodules.cgs = cgs

        # Initial Lane Alignment Sequence
        jesd_settings.LID = n
        jesd_settings.calc_fchk()
        ilas = ILASGenerator(jesd_settings)
        self.submodules.ilas = ilas

        # Datapath
        datapath = LiteJESD204BLinkTXDapath(jesd_settings)
        self.submodules.datapath = datapath
        self.comb += datapath.sink.eq(sink)

        # Sync
        jsync_timer = WaitTimer(
            4)  # Distinguish errors reporting / re-synchronization requests.
        self.submodules += jsync_timer
        self.comb += jsync_timer.wait.eq(~self.jsync)

        # FSM
        self.submodules.fsm = fsm = FSM(reset_state="SEND-CGS")
        fsm.act(
            "SEND-CGS",
            ilas.reset.eq(1),
            datapath.scrambler.reset.eq(1),
            datapath.framer.reset.eq(1),
            source.data.eq(cgs.source.data),
            source.ctrl.eq(cgs.source.ctrl),
            # Start ILAS on first LMFC after jsync is asserted
            If(self.lmfc_zero & self.jsync, NextState("SEND-ILAS")))
        fsm.act("SEND-ILAS", datapath.framer.reset.eq(1),
                source.data.eq(ilas.source.data),
                source.ctrl.eq(ilas.source.ctrl),
                If(ilas.source.last, NextState("SEND-DATA")))
        fsm.act("SEND-DATA", self.ready.eq(1), source.eq(datapath.source),
                If(jsync_timer.done, NextState("SEND-CGS")))
Exemplo n.º 18
0
    def __init__(self, phy_dw, with_scrambling=False):
        self.shift = shift = Signal(6)
        self.sink = sink = stream.Endpoint([("data", phy_dw)])
        self.source = source = stream.Endpoint([("data", 32)])
        self.idle = idle = Signal()
        self.comma = comma = Signal()

        # # #

        # Aligner
        self.submodules.aligner = aligner = RXAligner(phy_dw, shift)

        # Converter
        self.submodules.converter = converter = stream.Converter(phy_dw, 40)

        # Line Coding
        self.submodules.decoder = decoder = StreamDecoder(nwords=4)

        # Descrambler
        if with_scrambling:
            self.submodules.descrambler = descrambler = Descrambler()

        # Dataflow
        self.comb += [
            sink.connect(aligner.sink),
            aligner.source.connect(converter.sink),
            converter.source.connect(decoder.sink),
        ]
        if with_scrambling:
            self.comb += decoder.source.connect(descrambler.sink)
            self.comb += descrambler.source.connect(source)
        else:
            self.comb += decoder.source.connect(source, omit={"d", "k"})
            self.comb += source.data.eq(decoder.source.d)

        # Decode Idle
        idle_timer = WaitTimer(32)
        self.submodules += idle_timer
        self.sync += If(
            converter.source.valid,
            idle_timer.wait.eq((converter.source.data == 0)
                               | (converter.source.data == (2**40 - 1))))
        self.comb += idle.eq(idle_timer.done)

        # Decode Comma
        self.sync += If(
            decoder.source.valid,
            comma.eq((decoder.source.k == 1) & (decoder.source.d == K(28, 5))))
Exemplo n.º 19
0
    def __init__(self, clk_freq, timeout=10):
        self.sink = sink = stream.Endpoint(phy_description(32))
        self.source = source = stream.Endpoint(user_description(32))

        # # #

        # Packet description
        #   - preamble : 4 bytes
        #   - length   : 4 bytes
        #   - payload

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

        self.submodules.timer = WaitTimer(clk_freq*timeout)
        self.comb += self.timer.wait.eq(~fsm.ongoing("IDLE"))

        fsm.act("IDLE",
            sink.ack.eq(1),
            If(sink.stb & (sink.data == 0x5aa55aa5),
                   NextState("RECEIVE_LENGTH")
            )
        )
        fsm.act("RECEIVE_LENGTH",
            sink.ack.eq(1),
            If(sink.stb,
                NextValue(source.length, sink.data),
                NextState("COPY")
            )
        )
        eop = Signal()
        cnt = Signal(32)
        fsm.act("COPY",
            source.stb.eq(sink.stb),
            source.eop.eq(eop),
            source.data.eq(sink.data),
            sink.ack.eq(source.ack),
            If((source.stb & source.ack & eop) | self.timer.done,
                NextState("IDLE")
            )
        )
        self.sync += \
            If(fsm.ongoing("IDLE"),
                cnt.eq(0)
            ).Elif(source.stb & source.ack,
                cnt.eq(cnt + 1)
            )
        self.comb += eop.eq(cnt == source.length[2:] - 1)
Exemplo n.º 20
0
    def add_auto_tx_flush(self, sys_clk_freq, timeout=1e-2, interval=2):
        # Add automatic TX flush when ready is not active for a long time (timeout), this can prevent
        # stalling the UART (and thus CPU) when the PHY is not operational at startup.

        flush_ep = stream.Endpoint([("data", 8)])
        flush_count = Signal(int(log2(interval)))

        # Insert Flush Endpoint between TX FIFO and Source.
        self.comb += self.tx_fifo.source.connect(flush_ep)
        self.comb += flush_ep.connect(self.source)

        # Flush TX FIFO when Source.ready is inactive for timeout (with interval cycles between
        # each ready).
        self.submodules.timer = timer = WaitTimer(int(timeout * sys_clk_freq))
        self.comb += timer.wait.eq(~self.source.ready)
        self.sync += flush_count.eq(flush_count + 1)
        self.comb += If(timer.done, flush_ep.ready.eq(flush_count == 0))
Exemplo n.º 21
0
    def __init__(self, platform, sys_clk_freq):
        self.rst = CSR()

        self.clock_domains.cd_sys = ClockDomain()

        # # #

        # Delay software reset by 10us to ensure write has been acked on PCIe.
        rst_delay = WaitTimer(int(10e-6*sys_clk_freq))
        self.submodules += rst_delay
        self.sync += If(self.rst.re, rst_delay.wait.eq(1))

        # PLL
        self.submodules.pll = pll = S7MMCM(speedgrade=-2)
        self.comb += pll.reset.eq(rst_delay.done)
        pll.register_clkin(platform.request("clk200"), 200e6)
        pll.create_clkout(self.cd_sys, sys_clk_freq)
Exemplo n.º 22
0
    def __init__(self, pads, sys_clk_freq, period=1e0):
        self._out = CSRStorage(len(pads), description="Led Output(s) Control.")

        # # #

        n = len(pads)
        chaser = Signal(n)
        mode = Signal(reset=_CHASER_MODE)
        timer = WaitTimer(int(period * sys_clk_freq / (2 * n)))
        self.submodules += timer
        self.comb += timer.wait.eq(~timer.done)
        self.sync += If(timer.done, chaser.eq(Cat(~chaser[-1], chaser)))
        self.sync += If(self._out.re, mode.eq(_CONTROL_MODE))
        self.comb += [
            If(mode == _CONTROL_MODE,
               pads.eq(self._out.storage)).Else(pads.eq(chaser))
        ]
Exemplo n.º 23
0
    def __init__(self):
        self.sink = sink = stream.Endpoint(phy_description(32))

        # # #

        self.submodules.timer = WaitTimer(256 * 16)

        charisk_match = sink.charisk == 0b0001
        data_match = sink.data == primitives["ALIGN"]

        self.comb += \
            If(sink.valid &
              (sink.charisk == 0b0001) &
              (sink.data == primitives["ALIGN"]),
                self.timer.wait.eq(0)
            ).Else(
                self.timer.wait.eq(1),
            )
Exemplo n.º 24
0
    def __init__(self, platform, sys_clk_freq, with_usb_pll=False):
        self.rst = Signal()
        self.clock_domains.cd_por = ClockDomain(reset_less=True)
        self.clock_domains.cd_sys = ClockDomain()

        # # #

        # Clk / Rst
        clk48 = platform.request("clk48")
        rst_n = platform.request("usr_btn", loose=True)
        if rst_n is None: rst_n = 1

        # Power on reset
        por_count = Signal(16, reset=2**16 - 1)
        por_done = Signal()
        self.comb += self.cd_por.clk.eq(clk48)
        self.comb += por_done.eq(por_count == 0)
        self.sync.por += If(~por_done, por_count.eq(por_count - 1))

        # PLL
        self.submodules.pll = pll = ECP5PLL()
        self.comb += pll.reset.eq(~por_done | ~rst_n | self.rst)
        pll.register_clkin(clk48, 48e6)
        pll.create_clkout(self.cd_sys, sys_clk_freq)

        # USB PLL
        if with_usb_pll:
            self.clock_domains.cd_usb_12 = ClockDomain()
            self.clock_domains.cd_usb_48 = ClockDomain()
            usb_pll = ECP5PLL()
            self.submodules += usb_pll
            self.comb += usb_pll.reset.eq(~por_done)
            usb_pll.register_clkin(clk48, 48e6)
            usb_pll.create_clkout(self.cd_usb_48, 48e6)
            usb_pll.create_clkout(self.cd_usb_12, 12e6)

        # FPGA Reset (press usr_btn for 1 second to fallback to bootloader)
        reset_timer = WaitTimer(int(48e6))
        reset_timer = ClockDomainsRenamer("por")(reset_timer)
        self.submodules += reset_timer
        self.comb += reset_timer.wait.eq(~rst_n)
        self.comb += platform.request("rst_n").eq(~reset_timer.done)
Exemplo n.º 25
0
    def __init__(self, serdes, timeout):
        self.ready = Signal()
        self.error = Signal()

        # # #

        # Shift
        self.shift = shift = Signal(max=40)

        # Timer
        self.submodules.timer = timer = WaitTimer(timeout)

        # FSM
        self.submodules.fsm = fsm = FSM(reset_state="IDLE")
        fsm.act("IDLE", NextValue(shift, 0), NextState("RESET-SLAVE"),
                serdes.tx.idle.eq(1))
        fsm.act("RESET-SLAVE", timer.wait.eq(1),
                If(timer.done, timer.wait.eq(0), NextState("SEND-PATTERN")),
                serdes.tx.idle.eq(1))
        fsm.act(
            "SEND-PATTERN",
            If(~serdes.rx.idle, timer.wait.eq(1),
               If(timer.done, NextState("CHECK-PATTERN"))),
            serdes.tx.comma.eq(1))
        fsm.act("WAIT-STABLE", timer.wait.eq(1),
                If(timer.done, timer.wait.eq(0), NextState("CHECK-PATTERN")),
                serdes.tx.comma.eq(1))
        fsm.act(
            "CHECK-PATTERN",
            If(serdes.rx.comma, timer.wait.eq(1),
               If(timer.done,
                  NextState("READY"))).Else(NextState("INC-SHIFT")),
            serdes.tx.comma.eq(1))
        fsm.act(
            "INC-SHIFT", NextState("WAIT-STABLE"),
            If(shift == (40 - 1),
               NextState("ERROR")).Else(serdes.rx.shift.eq(1),
                                        NextValue(shift, shift + 1)),
            serdes.tx.comma.eq(1))
        fsm.act("READY", self.ready.eq(1))
        fsm.act("ERROR", self.error.eq(1))
Exemplo n.º 26
0
    def __init__(self, platform, clk_freq):
        switches = Signal(1)
        leds = Signal(2)

        self.reset = Signal()

        # # #

        self.submodules.switches = GPIOIn(switches)
        self.submodules.leds = GPIOOut(leds)
        self.comb += [
           switches[0].eq(~platform.request("pwrsw")),
           platform.request("hdled").eq(~leds[0]),
           platform.request("pwled").eq(~leds[1]),
        ]

        # generate a reset when power switch is pressed for 1 second
        self.submodules.reset_timer = WaitTimer(clk_freq)
        self.comb += [
            self.reset_timer.wait.eq(switches[0]),
            self.reset.eq(self.reset_timer.done)
        ]
Exemplo n.º 27
0
    def __init__(self, core, sys_clk_freq):
        self.enable = CSRStorage()
        self.ready = CSRStatus()

        self.stpl_enable = CSRStorage()
        self.stpl_errors = CSRStatus(32)

        self.jsync = CSRStatus()

        # # #

        self.specials += [
            MultiReg(self.enable.storage, core.enable, "jesd"),
            MultiReg(self.stpl_enable.storage, core.stpl_enable, "jesd"),
            MultiReg(core.stpl.errors, self.stpl_errors.status, "sys"),
            MultiReg(core.ready, self.ready.status, "sys")
        ]

        jsync_timer = WaitTimer(int(1e-3 * sys_clk_freq))
        self.submodules += jsync_timer
        self.specials += MultiReg(core.jsync, jsync_timer.wait, "sys")
        self.comb += self.jsync.status.eq(jsync_timer.done)
    def __init__(self, serdes, timeout):
        self.ready = Signal()
        self.error = Signal()

        # # #

        self.bitslip = bitslip = Signal(max=40)

        self.submodules.timer = timer = WaitTimer(timeout)

        self.submodules.fsm = fsm = FSM(reset_state="IDLE")
        # reset
        fsm.act("IDLE", NextValue(bitslip, 0), timer.wait.eq(1),
                If(
                    timer.done,
                    timer.wait.eq(0),
                    NextState("WAIT_STABLE"),
                ), serdes.tx.idle.eq(1))
        fsm.act("WAIT_STABLE", timer.wait.eq(1),
                If(timer.done, timer.wait.eq(0), NextState("CHECK_PATTERN")),
                serdes.tx.idle.eq(1))
        fsm.act(
            "CHECK_PATTERN",
            If(serdes.rx.comma, timer.wait.eq(1),
               If(timer.done,
                  NextState("SEND_PATTERN"))).Else(NextState("INC_BITSLIP")),
            serdes.tx.idle.eq(1))
        self.comb += serdes.rx.bitslip_value.eq(bitslip)
        fsm.act(
            "INC_BITSLIP", NextState("WAIT_STABLE"),
            If(bitslip == (40 - 1),
               NextState("ERROR")).Else(NextValue(bitslip, bitslip + 1)),
            serdes.tx.idle.eq(1))
        fsm.act("SEND_PATTERN", timer.wait.eq(1),
                If(timer.done, If(~serdes.rx.comma, NextState("READY"))),
                serdes.tx.comma.eq(1))
        fsm.act("READY", self.ready.eq(1))
        fsm.act("ERROR", self.error.eq(1))
Exemplo n.º 29
0
    def __init__(self, n_in, n_state=23, taps=[17, 22]):
        self.i = Signal(n_in)
        self.errors = Signal(n_in)

        # # #

        # LFSR Update / Check.
        state = Signal(n_state, reset=1)
        curval = [state[i] for i in range(n_state)]
        for i in reversed(range(n_in)):
            correctv = reduce(xor, [curval[tap] for tap in taps])
            self.comb += self.errors[i].eq(self.i[i] != correctv)
            curval.insert(0, self.i[i])
            curval.pop()
        self.sync += state.eq(Cat(*curval[:n_state]))

        # Idle Check.
        i_last = Signal(n_in)
        idle_timer = WaitTimer(1024)
        self.submodules += idle_timer
        self.sync += i_last.eq(self.i)
        self.comb += idle_timer.wait.eq(self.i == i_last)
        self.comb += If(idle_timer.done, self.errors.eq(2**n_in - 1))
Exemplo n.º 30
0
    def __init__(self, tx_lol, rx_lol, rx_los, rx_lsm):
        self.rrst = Signal()
        self.lane_rx_rst = Signal()

        # # #

        _tx_lol = Signal()
        _rx_lol = Signal()
        _rx_los = Signal()
        _rx_lsm = Signal()
        _rx_lsm_seen = Signal()
        self.specials += [
            MultiReg(tx_lol, _tx_lol),
            MultiReg(rx_lol, _rx_lol),
            MultiReg(rx_los, _rx_los),
            MultiReg(rx_lsm, _rx_lsm),
        ]

        timer = WaitTimer(int(4e5))
        self.submodules += timer

        self.submodules.fsm = fsm = FSM(reset_state="IDLE")
        fsm.act("IDLE", self.lane_rx_rst.eq(1),
                If(~_tx_lol, NextState("RESET-ALL")))
        fsm.act("RESET-ALL", self.rrst.eq(1), self.lane_rx_rst.eq(1),
                NextState("RESET-PCS"))
        fsm.act(
            "RESET-PCS", self.lane_rx_rst.eq(1),
            timer.wait.eq(~_rx_lol & ~_rx_los),
            If(timer.done, timer.wait.eq(0), NextValue(_rx_lsm_seen, 0),
               NextState("CHECK-LSM")))
        fsm.act(
            "CHECK-LSM", NextValue(_rx_lsm_seen, _rx_lsm_seen | _rx_lsm),
            timer.wait.eq(1), If(_rx_lsm_seen & ~_rx_lsm, NextState("IDLE")),
            If(timer.done,
               If(_rx_lsm, NextState("READY")).Else(NextState("IDLE"))))
        fsm.act("READY", If(_tx_lol | _rx_lol | _rx_los, NextState("IDLE")))