def __init__(self):
     transport_tx = LiteJESD204BTransportTX(jesd_settings,
                                            converter_data_width)
     transport_rx = LiteJESD204BTransportRX(jesd_settings,
                                            converter_data_width)
     self.comb += transport_rx.sink.eq(transport_tx.source)
     self.submodules += transport_tx, transport_rx
     self.sink, self.source = transport_tx.sink, transport_rx.source
    def transport_tx_test(self, nlanes, nconverters, converter_data_width):
        jesd_settings = JESD204BSettings(L=nlanes,
                                         M=nconverters,
                                         N=16,
                                         NP=16,
                                         F=2,
                                         S=1,
                                         K=16,
                                         CS=1,
                                         DID=0X5A,
                                         BID=0X5)
        jesd_settings.calc_fchk()

        transport = LiteJESD204BTransportTX(jesd_settings)

        input_samples = [[j + i * 256 for j in range(16)]
                         for i in range(nconverters)]
        reference_lanes = samples_to_lanes(samples_per_frame=1,
                                           nlanes=nlanes,
                                           nconverters=nconverters,
                                           nbits=16,
                                           samples=input_samples)

        output_lanes = [[] for i in range(nlanes)]

        octets_per_lane = jesd_settings.F
        lane_data_width = len(transport.source.lane0)

        def generator(dut):
            for i in range(4):
                for c in range(nconverters):
                    converter_data = getattr(dut.sink, "converter" + str(c))
                    for j in range(converter_data_width //
                                   jesd_settings.phy.n):
                        yield converter_data[16 * j:16 * (j + 1)].eq(
                            input_samples[c][4 * i + j])
                yield

        def checker(dut):
            yield
            for i in range(4):
                for l in range(nlanes):
                    lane_data = (yield getattr(dut.source, "lane" + str(l)))
                    for f in range(lane_data_width // (octets_per_lane * 8)):
                        frame = [(lane_data >>
                                  (f * 8 * octets_per_lane) + 8 * k) & 0xff
                                 for k in range(octets_per_lane)]
                        output_lanes[l].append(frame)
                yield

        run_simulation(transport, [generator(transport), checker(transport)])
        return reference_lanes, output_lanes
    def transport_tx_test(self, nlanes, nconverters, converter_data_width):
        ps = JESD204BPhysicalSettings(l=nlanes, m=nconverters, n=16, np=16)
        ts = JESD204BTransportSettings(f=2, s=1, k=16, cs=1)
        jesd_settings = JESD204BSettings(ps, ts, did=0x5a, bid=0x5)

        transport = LiteJESD204BTransportTX(jesd_settings,
                                            converter_data_width)

        input_samples = [[j + i * 256 for j in range(16)]
                         for i in range(nconverters)]
        reference_lanes = samples_to_lanes(samples_per_frame=1,
                                           nlanes=nlanes,
                                           nconverters=nconverters,
                                           nbits=16,
                                           samples=input_samples)

        output_lanes = [[] for i in range(nlanes)]

        octets_per_lane = jesd_settings.octets_per_lane
        lane_data_width = len(transport.source.lane0)

        def generator(dut):
            for i in range(4):
                for c in range(nconverters):
                    converter_data = getattr(dut.sink, "converter" + str(c))
                    for j in range(converter_data_width //
                                   jesd_settings.phy.n):
                        yield converter_data[16 * j:16 * (j + 1)].eq(
                            input_samples[c][4 * i + j])
                yield

        def checker(dut):
            yield
            for i in range(4):
                for l in range(nlanes):
                    lane_data = (yield getattr(dut.source, "lane" + str(l)))
                    for f in range(lane_data_width // (octets_per_lane * 8)):
                        frame = [(lane_data >>
                                  (f * 8 * octets_per_lane) + 8 * k) & 0xff
                                 for k in range(octets_per_lane)]
                        output_lanes[l].append(frame)
                yield

        run_simulation(transport, [generator(transport), checker(transport)])
        return reference_lanes, output_lanes
    def transport_tx_test(self, settings):
        transport = LiteJESD204BTransportTX(settings)

        # generate random test data:  samples[converter][sample]
        input_samples = []
        for m in range(settings.M):
            # input_samples.append([randint(0, 2**settings.N - 1) for _ in range(32)])
            input_samples.append([(0x0A + m << 8) | i
                                  for i in range(16)])  # index values

        # Get reference output
        tl = TransportLayer(settings)

        # reference_lanes[lane][octet]
        reference_lanes = flatten_results(tl.encode(input_samples))

        # output_lanes[lane][octet]
        output_lanes = [[] for i in range(settings.L)]

        def generator(dut):
            while len(input_samples[0]) > 0:
                for m, (converter, _) in enumerate(dut.sink.iter_flat()):
                    temp = 0
                    # There might be multiple samples per clock
                    for s in range(len(converter) // settings.N):
                        temp |= (input_samples[m].pop(0)) << (settings.N * s)
                    conv_bytes = temp.to_bytes(len(converter) // 8, 'little')
                    print('conv {:d}: {:}'.format(m, hex_str(conv_bytes)))
                    yield converter.eq(temp)
                yield
                # print()

                for l, (lane, _) in enumerate(dut.source.iter_flat()):
                    lane_data = (yield lane)
                    # Need to split lane_data up into octets
                    lane_bytes = lane_data.to_bytes(len(lane) // 8, 'little')
                    print('lane {:d}: {:}'.format(l, hex_str(lane_bytes)))
                    output_lanes[l].extend(lane_bytes)
                print()

        run_simulation(transport, [generator(transport)])
        return reference_lanes, output_lanes
Exemple #5
0
    def __init__(self, phys, jesd_settings, converter_data_width):
        self.enable = Signal()
        self.jsync = Signal()
        self.ready = Signal()
        self.restart = Signal()

        self.prbs_config = Signal(4)
        self.stpl_enable = Signal()

        self.sink = Record([("converter" + str(i), converter_data_width)
                            for i in range(jesd_settings.nconverters)])

        # # #

        # restart when disabled or on re-synchronization request
        self.comb += self.restart.eq(~self.enable | self.ready & ~self.jsync)

        # transport layer
        transport = LiteJESD204BTransportTX(jesd_settings,
                                            converter_data_width)
        self.submodules.transport = transport

        # stpl
        stpl = LiteJESD204BSTPLGenerator(jesd_settings, converter_data_width)
        self.submodules += stpl
        stpl_enable = Signal()
        self.specials += \
            MultiReg(self.stpl_enable, stpl_enable)
        self.comb += \
            If(stpl_enable,
                transport.sink.eq(stpl.source)
            ).Else(
                transport.sink.eq(self.sink)
            )

        links = []
        for n, (phy, lane) in enumerate(zip(phys, transport.source.flatten())):
            phy_name = "phy{}".format(n)
            phy_cd = phy_name + "_tx"

            # claim the phy
            setattr(self.submodules, phy_name, phy)

            ebuf = ElasticBuffer(len(phy.data), 4, "sys", phy_cd)
            setattr(self.submodules, "ebuf{}".format(n), ebuf)

            link = LiteJESD204BLinkTX(len(phy.data), jesd_settings, n)
            link = ClockDomainsRenamer(phy_cd)(link)
            links.append(link)
            self.comb += link.jsync.eq(self.jsync)
            self.submodules += link

            # connect data
            self.comb += [
                ebuf.din.eq(lane),
                link.sink.data.eq(ebuf.dout),
                phy.data.eq(link.source.data),
                phy.ctrl.eq(link.source.ctrl)
            ]

            # connect control
            self.comb += phy.transmitter.init.restart.eq(
                self.restart & (self.prbs_config == 0))

            self.specials += MultiReg(self.prbs_config,
                                      phy.transmitter.prbs_config, phy_cd)
        ready = Signal()
        self.comb += ready.eq(reduce(and_, [link.ready for link in links]))
        self.specials += MultiReg(ready, self.ready)
Exemple #6
0
    def __init__(self, phys, jesd_settings, converter_data_width):
        self.enable  = Signal()
        self.jsync   = Signal()
        self.jref    = Signal()
        self.ready   = Signal()
        self.restart = Signal()

        self.stpl_enable = Signal()

        self.sink = Record([("converter"+str(i), converter_data_width)
            for i in range(jesd_settings.nconverters)])

        # # #

        # Restart when disabled...
        self.comb += If(~self.enable, self.restart.eq(1))

        # ... or on re-synchronization request from the DAC.
        jsync = Signal()
        jsync_timer = ClockDomainsRenamer("jesd")(WaitTimer(256))
        self.submodules += jsync_timer
        self.comb += jsync_timer.wait.eq(~jsync)
        self.specials += MultiReg(self.jsync, jsync, "jesd")
        self.comb += If(self.ready & jsync_timer.done, self.restart.eq(1))

        # transport layer
        transport = LiteJESD204BTransportTX(jesd_settings, converter_data_width)
        transport = ClockDomainsRenamer("jesd")(transport)
        self.submodules.transport = transport

        # stpl
        stpl = LiteJESD204BSTPLGenerator(jesd_settings, converter_data_width)
        stpl = ClockDomainsRenamer("jesd")(stpl)
        self.submodules.stpl = stpl
        self.comb += \
            If(self.stpl_enable,
                transport.sink.eq(stpl.source)
            ).Else(
                transport.sink.eq(self.sink)
            )

        self.links = links = []
        for n, (phy, lane) in enumerate(zip(phys, transport.source.flatten())):
            phy_name = "jesd_phy{}".format(n if not hasattr(phy, "n") else phy.n)
            phy_cd   = phy_name + "_tx"

            cdc = LiteJESD204BTXCDC(phy, phy_cd)
            setattr(self.submodules, "cdc"+str(n), cdc)

            link = LiteJESD204BLinkTX(32, jesd_settings, n)
            link = ClockDomainsRenamer("jesd")(link)
            self.submodules += link
            links.append(link)
            self.comb += [
                link.reset.eq(self.restart),
                link.jsync.eq(self.jsync),
                link.jref.eq(self.jref)
            ]

            # connect data
            self.comb += [
                link.sink.data.eq(lane),
                cdc.sink.valid.eq(1),
                cdc.sink.data.eq(link.source.data),
                cdc.sink.ctrl.eq(link.source.ctrl),
                cdc.source.connect(phy.sink)
            ]

        self.sync.jesd += self.ready.eq(reduce(and_, [link.ready for link in links]))
Exemple #7
0
    def __init__(self, phys, jesd_settings):
        self.enable  = Signal()
        self.jsync   = Signal()
        self.jref    = Signal()
        self.phy_ready   = Signal()
        self.ready   = Signal()

        self.stpl_enable = Signal()

        self.sink = Record(jesd_settings.get_dsp_layout())

        # # #

        # Transport layer
        transport = LiteJESD204BTransportTX(jesd_settings)
        transport = ClockDomainsRenamer("jesd")(transport)
        self.submodules.transport = transport

        # STPL
        stpl = LiteJESD204BSTPLGenerator(jesd_settings)
        stpl = ClockDomainsRenamer("jesd")(stpl)
        self.submodules.stpl = stpl
        self.comb += \
            If(self.stpl_enable,
                transport.sink.eq(stpl.source)
            ).Else(
                transport.sink.eq(self.sink)
            )

        # LMFC
        lmfc = LMFC(jesd_settings, load=(1 + 4)) # jref + ebuf latency
        lmfc = ClockDomainsRenamer("jesd")(lmfc)
        self.submodules.lmfc = lmfc
        self.sync.jesd += lmfc.jref.eq(self.jref)

        # Links
        self.links = links = []
        lanes = transport.source.flatten()
        for n, (phy, lane) in enumerate(zip(phys, lanes)):
            phy_name = "jesd_phy{}".format(n if not hasattr(phy, "n") else phy.n)
            setattr(self.submodules, phy_name, phy)
            if len(lanes) > 1:
                phy_cd = phy_name + "_tx"
            else:
                phy_cd = "tx"

            cdc = LiteJESD204BTXCDC(phy, phy_cd)
            setattr(self.submodules, "cdc"+str(n), cdc)

            link = LiteJESD204BLinkTX(jesd_settings, n)
            link = ClockDomainsRenamer("jesd")(link)
            setattr(self.submodules, 'link{:d}'.format(n), link)
            links.append(link)
            self.comb += [
                link.reset.eq(~self.enable),
                link.jsync.eq(self.jsync),
                link.jref.eq(self.jref),
                link.lmfc_zero.eq(self.lmfc.zero),
            ]

            # connect data
            self.comb += [
                link.sink.data.eq(lane),
                cdc.sink.valid.eq(1),
                cdc.sink.data.eq(link.source.data),
                cdc.sink.ctrl.eq(link.source.ctrl),
                cdc.source.connect(phy.sink)
            ]

        self.comb += [
            self.phy_ready.eq(reduce(and_, [phy.transmitter.init.done for phy in phys])),
            self.ready.eq(reduce(and_, [link.ready for link in links]))
        ]