Esempio n. 1
0
    def __init__(self, i2s_resource, output_bit_depth=16, i2s_domain="i2s"):
        self.output_bit_depth = output_bit_depth
        self.i2s_resource = i2s_resource
        self.i2s_domain = i2s_domain

        self.l_output = BasicStream(output_bit_depth)
        self.r_output = BasicStream(output_bit_depth)
Esempio n. 2
0
    def __init__(self, input, output_width):
        self.input = input
        self.output_width = output_width

        self.word_alignment = StatusSignal(range(output_width))

        self.output = BasicStream(output_width)
Esempio n. 3
0
    def test_packetizer_output_stream_contract(self):
        length_input = BasicStream(4)
        data_input = BasicStream(64)

        dut = StreamPacketizer(length_input, data_input)
        verify_stream_output_contract(
            dut, support_modules=(LegalStreamSource(data_input), LegalStreamSource(length_input))
        )
Esempio n. 4
0
    def test_burster_data_output_stream_contract(self):
        data_input = BasicStream(64)
        address_input = BasicStream(32)

        dut = AxiWriterBurster(address_input, data_input)
        verify_stream_output_contract(
            dut, stream_output=dut.data_output,
            support_modules=(LegalStreamSource(data_input), LegalStreamSource(address_input))
        )
Esempio n. 5
0
    def __init__(self, input: BasicStream, core_producer, fifo_depth=128):
        self.fifo_depth = fifo_depth
        self.input = input

        self.core_input = BasicStream(input.payload.shape())
        self.core = core_producer(self.core_input)
        self.core_output = self.core.output

        self.output = self.input.clone()
        self.output.payload = Signal(len(self.core_output.payload)) @ DOWNWARDS
Esempio n. 6
0
    def test_basic(self):
        platform = SimPlatform()
        axi = AxiEndpoint(addr_bits=32, data_bits=64, lite=False, id_bits=12)

        data_stream = BasicStream(64)
        address_stream = BasicStream(32)

        write_sequence = [
            (0, 1),
            (0, 2),
            (0, 3),
            (0, 4),
            (1, 5),
            (2, 6),

            *[(a, a) for a in range(10, 1000, 8)],

            (1000, 1),
            (1000, 2),
            (1000, 3),
            (1000, 4),
            (1001, 5),
            (1002, 6),
        ]

        golden_memory = {}
        for addr, data in write_sequence:
            golden_memory[addr] = data

        dut = AxiWriter(address_stream, data_stream, axi)

        def write_address_process():
            for addr, data in write_sequence:
                yield from write_to_stream(address_stream, payload=addr)
        platform.add_process(write_address_process, "sync")

        def write_data_process():
            for addr, data in write_sequence:
                yield from write_to_stream(data_stream, payload=data)
        platform.add_process(write_data_process, "sync")

        def axi_answer_process():
            memory = {}
            while len(memory) < len(golden_memory):
                # print("m", len(memory), memory)
                written, accepted = (yield from answer_write_burst(axi))
                print("w", len(written), written)
                memory.update(written)
            self.assertEqual(golden_memory, memory)
        platform.add_process(axi_answer_process, "sync")

        platform.add_sim_clock("sync", 100e6)
        platform.sim(dut)
Esempio n. 7
0
class I2S_RX(Elaboratable):
    def __init__(self, i2s_resource, output_bit_depth=16, i2s_domain="i2s"):
        self.output_bit_depth = output_bit_depth
        self.i2s_resource = i2s_resource
        self.i2s_domain = i2s_domain

        self.l_output = BasicStream(output_bit_depth)
        self.r_output = BasicStream(output_bit_depth)

    def elaborate(self, platform):
        m = Module()

        i2s_domain = ClockDomain(self.i2s_domain)
        m.domains += i2s_domain
        m.d.comb += i2s_domain.clk.eq(self.i2s_resource.sck)

        l_buffer_input = BasicStream(self.output_bit_depth)
        r_buffer_input = BasicStream(self.output_bit_depth)

        delayed_ws = delay_by(self.i2s_resource.ws, 1, m)
        with m.FSM():
            for i in range(self.output_bit_depth + 1):
                with m.State(f'bit_{i}'):
                    with m.If(delayed_ws != self.i2s_resource.ws):
                        m.next = "bit_0"
                    with m.Else():
                        if i < self.output_bit_depth:
                            m.next = f"bit_{i + 1}"
                    if i < self.output_bit_depth:
                        with m.If(delayed_ws):
                            m.d.sync += r_buffer_input.payload[
                                self.output_bit_depth - i - 1].eq(
                                    self.i2s_resource.sd)
                        with m.Else():
                            m.d.sync += l_buffer_input.payload[
                                self.output_bit_depth - i - 1].eq(
                                    self.i2s_resource.sd)
                    if i == 0:
                        with m.If(delayed_ws):
                            m.d.comb += r_buffer_input.valid.eq(1)
                        with m.Else():
                            m.d.comb += l_buffer_input.valid.eq(1)

        l_buffer = m.submodules.buffer_l = StreamBuffer(l_buffer_input)
        m.d.comb += self.l_output.connect_upstream(l_buffer.output)
        r_buffer = m.submodules.buffer_r = StreamBuffer(r_buffer_input)
        m.d.comb += self.r_output.connect_upstream(r_buffer.output)

        return DomainRenamer(self.i2s_domain)(m)
Esempio n. 8
0
    def __init__(
        self,
        address_source: BasicStream,
        axi=None,
        axi_data_width=64,
    ):
        self.address_source = address_source
        self.axi = axi

        self.output = BasicStream(axi_data_width,
                                  name="buffer_reader_output_stream")
        self.output.payload = Signal(axi_data_width)

        self.last_resp = StatusSignal(AxiResponse)
        self.error_count = StatusSignal(32)
Esempio n. 9
0
 def __init__(self, pins, width: int, ddr_domain, reset):
     self.pins = pins
     self.reset = reset
     self.input = BasicStream(width)
     self.idle = Signal(width)
     self.is_idle = Signal()
     self.ddr_domain = ddr_domain
Esempio n. 10
0
    def __init__(self, plugin, domain_name="sync"):
        self.plugin = plugin
        self.output = BasicStream(32)
        self.domain_name = domain_name

        self.trained = ControlSignal()
        self.valid = StatusSignal()
Esempio n. 11
0
    def elaborate(self, platform):
        m = Module()
        address_burster = m.submodules.address_burster = AxiReaderBurster(
            self.address_input, self.word_bytes, self.max_burst_length,
            self.burst_creation_timeout)
        burst_tee = m.submodules.burst_tee = StreamTee(address_burster.output)
        m.d.comb += self.address_output.connect_upstream(
            burst_tee.get_output())

        burst_stream = burst_tee.get_output()
        packet_length_stream = BasicStream(burst_stream.burst_len.shape())
        m.d.comb += packet_length_stream.valid.eq(burst_stream.valid)
        m.d.comb += burst_stream.ready.eq(packet_length_stream.ready)
        m.d.comb += packet_length_stream.payload.eq(burst_stream.burst_len)

        data_fifo = m.submodules.data_fifo = BufferedSyncStreamFIFO(
            self.data_input, self.data_fifo_depth)
        stream_packetizer = m.submodules.stream_packetizer = StreamPacketizer(
            packet_length_stream, data_fifo.output)
        m.d.comb += self.data_output.connect_upstream(stream_packetizer.output,
                                                      allow_partial=True)
        m.d.comb += self.data_output.id.eq(self.data_output.id.reset)
        m.d.comb += self.data_output.byte_strobe.eq(-1)

        return m
Esempio n. 12
0
    def __init__(self, address_input: BasicStream, memory: Memory):
        assert len(address_input.payload) == bits_for(memory.depth)
        self.address_input = address_input
        self.memory = memory

        self.output = address_input.clone()
        self.output.payload = Signal(memory.width)
Esempio n. 13
0
class GenericMetadataWrapper(Elaboratable):
    def __init__(self, input: BasicStream, core_producer, fifo_depth=128):
        self.fifo_depth = fifo_depth
        self.input = input

        self.core_input = BasicStream(input.payload.shape())
        self.core = core_producer(self.core_input)
        self.core_output = self.core.output

        self.output = self.input.clone()
        self.output.payload = Signal(len(self.core_output.payload)) @ DOWNWARDS

    def elaborate(self, platform):
        m = Module()
        m.submodules.core = self.core
        tee = m.submodules.tee = StreamTee(self.input)

        m.d.comb += self.core_input.connect_upstream(tee.get_output(),
                                                     allow_partial=True)

        metadata_fifo_input = Stream()
        for name, s in self.input.out_of_band_signals.items():
            setattr(metadata_fifo_input, name, Signal.like(s) @ DOWNWARDS)
        m.d.comb += metadata_fifo_input.connect_upstream(tee.get_output(),
                                                         allow_partial=True)
        metadata_fifo = m.submodules.metadata_fifo = BufferedSyncStreamFIFO(
            metadata_fifo_input, self.fifo_depth)

        combiner = m.submodules.combiner = StreamCombiner(
            self.core_output, metadata_fifo.output)
        m.d.comb += self.output.connect_upstream(combiner.output)

        return m
Esempio n. 14
0
    def test_gearbox_12_to_48_to_64(self):
        m = Module()
        platform = SimPlatform()
        input = BasicStream(12)

        tee = m.submodules.tee = StreamTee(input)
        gear_12_to_48 = m.submodules.gear_12_to_48 = StreamGearbox(tee.get_output(), 48)
        gear_48_to_64 = m.submodules.gear_48_to_64 = StreamGearbox(gear_12_to_48.output, 64)

        gear_12_to_64 = m.submodules.gear_12_to_64 = StreamGearbox(tee.get_output(), 64)

        def writer():
            yield Passive()
            random.seed(0)
            while True:
                yield from write_to_stream(input, payload=random.randrange(0, 2**12))
        platform.add_process(writer, "sync")

        def reader():
            for _ in range(100):
                a = yield from read_from_stream(gear_12_to_64.output)
                b = yield from read_from_stream(gear_48_to_64.output)
                print(f"{a:064b}")
                self.assertEqual(a, b)
        platform.add_process(reader, "sync")

        platform.add_sim_clock("sync", 100e6)
        platform.sim(m)
Esempio n. 15
0
    def elaborate(self, platform):
        m = Module()
        m.submodules.core = self.core

        last_fifo_input = BasicStream(self.last_rle_bits)
        last_fifo = m.submodules.last_fifo = BufferedSyncStreamFIFO(
            last_fifo_input, self.last_fifo_depth)

        overflow_word = (2**self.last_rle_bits - 1)

        rle_input_counter = StatusSignal(self.last_rle_bits)
        with m.If(self.input.valid & last_fifo_input.ready):
            m.d.comb += self.core_input.valid.eq(1)
            m.d.comb += self.core_input.payload.eq(self.input.payload)

            with m.If(self.core_input.ready):
                m.d.comb += self.input.ready.eq(1)

                with m.If(self.input.last
                          | (rle_input_counter == overflow_word - 1)):
                    with m.If(~self.input.last
                              & (rle_input_counter == overflow_word - 1)):
                        m.d.comb += last_fifo_input.payload.eq(overflow_word)
                    with m.Else():
                        m.d.comb += last_fifo_input.payload.eq(
                            rle_input_counter)
                    m.d.comb += last_fifo_input.valid.eq(1)
                    m.d.sync += rle_input_counter.eq(0)
                with m.Else():
                    m.d.sync += rle_input_counter.eq(rle_input_counter + 1)

        rle_output_counter = StatusSignal(self.last_rle_bits)
        with m.If(self.core_output.valid):
            m.d.comb += self.output.valid.eq(1)
            m.d.comb += self.output.payload.eq(self.core_output.payload)

            overflow = (last_fifo.output.payload == overflow_word) & (
                rle_output_counter == (overflow_word - 1))
            with m.If((
                (rle_output_counter == last_fifo.output.payload) | overflow)
                      & last_fifo.output.valid):
                with m.If(~overflow):
                    m.d.comb += self.output.last.eq(1)
                with m.If(self.output.ready):
                    m.d.sync += rle_output_counter.eq(0)
                    m.d.comb += last_fifo.output.ready.eq(1)
                    m.d.comb += self.core_output.ready.eq(1)
            with m.Elif((rle_output_counter > last_fifo.output.payload)
                        & last_fifo.output.valid):
                with m.If(self.output.ready):
                    m.d.comb += self.core_output.ready.eq(1)
                    m.d.sync += self.error.eq(self.error + 1)
            with m.Else():
                with m.If(self.output.ready):
                    m.d.comb += self.core_output.ready.eq(1)
                    m.d.sync += rle_output_counter.eq(rle_output_counter + 1)

        return m
Esempio n. 16
0
    def __init__(self, input: BasicStream, target_width):
        self.input = input
        self.output = input.clone(name="gearbox_output")
        self.output.payload = Signal(target_width) @ DOWNWARDS

        self.input_width = len(self.input.payload)
        self.output_width = target_width
        self.division_factor = self.input_width / target_width

        assert target_width < self.input_width
        assert self.division_factor % 1 == 0
        self.division_factor = int(self.division_factor)
Esempio n. 17
0
    def __init__(self, input: PacketizedStream, packet_len):
        self.input = input
        self.output = BasicStream(input.payload.shape())

        # we calculate everything in bytes to make it easier to reason about
        buffer_size = 2048 * 4
        blanking = buffer_size
        aligned_len = ceil((packet_len + blanking) / buffer_size) * buffer_size
        print("ft60x paddnig:", (aligned_len - packet_len),
              (aligned_len - packet_len) // 4)

        self.padding = ControlSignal(16, reset=(aligned_len - packet_len) // 4)
        self.frame_len = StatusSignal(32)
        self.frame_len_changed = StatusSignal(32)
Esempio n. 18
0
    def test_basic(self):
        platform = SimPlatform()

        memory = {i: i + 100 for i in range(1000)}
        read_sequence = [
            0,
            100,
            108,
            116,
            2,
            7,
            *[i + 100 for i in range(0, 400, 8)],
            0,
            100,
            108,
            116,
            2,
            7,
        ]
        golden_read_result = [memory[addr] for addr in read_sequence]

        axi = AxiEndpoint(addr_bits=32, data_bits=64, lite=False, id_bits=12)
        address_stream = BasicStream(32)
        dut = AxiReader(address_stream, axi)

        def write_address_process():
            for addr in read_sequence:
                yield from write_to_stream(address_stream, payload=addr)

        platform.add_process(write_address_process, "sync")

        def read_data_process():
            read_result = []
            while len(read_result) < len(golden_read_result):
                read = yield from read_from_stream(dut.output)
                read_result.append(read)
            self.assertEqual(read_result, golden_read_result)

        platform.add_process(read_data_process, "sync")

        def axi_answer_process():
            yield Passive()
            while True:
                yield from answer_read_burst(axi, memory)

        platform.add_process(axi_answer_process, "sync")

        platform.add_sim_clock("sync", 100e6)
        platform.sim(dut)
Esempio n. 19
0
    def elaborate(self, platform):
        m = Module()

        cw = ControlChannelWord(self.control_lane)

        lane_top_streams_buffered = []
        for i, signal in enumerate(self.top_lanes):
            stream = BasicStream(self.n_bits)
            m.d.comb += stream.payload.eq(signal)
            m.d.comb += stream.valid.eq(cw.data_valid)

            fifo = m.submodules[f"fifo_top{i}"] = BufferedSyncStreamFIFO(
                stream, depth=128 * (self.lines_to_buffer + 1))
            lane_top_streams_buffered.append(fifo.output)

        return m
Esempio n. 20
0
    def __init__(self,
                 input: PacketizedStream,
                 core_producer,
                 last_fifo_depth=3,
                 last_rle_bits=10):
        self.last_fifo_depth = last_fifo_depth
        self.last_rle_bits = last_rle_bits
        assert hasattr(input, "last")
        self.input = input

        self.core_input = BasicStream(input.payload.shape())
        self.core = core_producer(self.core_input)
        self.core_output = self.core.output

        self.error = StatusSignal(32)

        self.output = PacketizedStream(len(self.core_output.payload))
Esempio n. 21
0
class InputGearbox(Elaboratable):
    def __init__(self, input, output_width):
        self.input = input
        self.output_width = output_width

        self.word_alignment = StatusSignal(range(output_width))

        self.output = BasicStream(output_width)

    def elaborate(self, platform):
        m = Module()

        gearbox = m.submodules.gearbox = StreamGearbox(self.input,
                                                       self.output_width)
        window = m.submodules.window = StreamWindow(gearbox.output,
                                                    window_words=2)
        select = m.submodules.select = StreamSelect(
            window.output, output_width=self.output_width)
        m.d.comb += self.output.connect_upstream(select.output)

        return m
Esempio n. 22
0
class AxiReader(Elaboratable):
    def __init__(
        self,
        address_source: BasicStream,
        axi=None,
        axi_data_width=64,
    ):
        self.address_source = address_source
        self.axi = axi

        self.output = BasicStream(axi_data_width,
                                  name="buffer_reader_output_stream")
        self.output.payload = Signal(axi_data_width)

        self.last_resp = StatusSignal(AxiResponse)
        self.error_count = StatusSignal(32)

    def elaborate(self, platform):
        m = Module()

        axi = if_none_get_zynq_hp_port(self.axi, m, platform)
        assert len(self.output.payload) == axi.data_bits
        assert len(self.address_source.payload) == axi.addr_bits
        for fifo_signal_name in [
                "read_address_fifo_level", "read_data_fifo_level"
        ]:
            if hasattr(axi, fifo_signal_name):
                axi_fifo_signal = axi[fifo_signal_name]
                fifo_signal = StatusSignal(axi_fifo_signal.shape(),
                                           name=f"axi_{fifo_signal_name}")
                m.d.comb += fifo_signal.eq(axi_fifo_signal)
                setattr(self, f"axi_{fifo_signal_name}", fifo_signal)

        burster = m.submodules.burster = AxiReaderBurster(
            self.address_source, data_bytes=axi.data_bytes)
        m.d.comb += axi.read_address.connect_upstream(burster.output)
        m.d.comb += self.output.connect_upstream(axi.read_data,
                                                 allow_partial=True)

        return m
Esempio n. 23
0
    def elaborate(self, platform):
        m = Module()

        self.delayf = m.submodules.delayf = DelayF(self.pin.i)
        iddr = m.submodules.iddr = DomainRenamer(self.qdr_domain)(IDDRX2F(
            self.delayf.o, self.ddr_domain))
        iddr_stream = BasicStream(4)
        m.d.comb += iddr_stream.valid.eq(1)
        m.d.comb += iddr_stream.payload.eq(iddr.output)
        gearbox = m.submodules.gearbox = DomainRenamer(self.qdr_domain)(
            StreamGearbox(iddr_stream, target_width=10))
        fifo = m.submodules.fifo = BufferedAsyncStreamFIFO(
            gearbox.output, 32, i_domain=self.qdr_domain, o_domain="sync")
        window = m.submodules.window = StreamWindow(fifo.output,
                                                    window_words=2)
        self.select = select = m.submodules.select = StreamSelect(
            window.output, output_width=10)

        m.d.comb += select.output.ready.eq(1)
        with m.If(~select.output.valid):
            # ths should never happen if the clock domains are correctly set up
            m.d.sync += self.not_valid_cnt.eq(self.not_valid_cnt + 1)

        m.d.comb += self.raw_word.eq(select.output.payload)
        tmds = m.submodules.tmds = TmdsDecoder(self.raw_word
                                               ^ Repl(self.invert, 10))
        m.d.comb += self.data.eq(tmds.data)
        m.d.comb += self.data_enable.eq(tmds.data_enable)
        m.d.comb += self.control.eq(tmds.control)

        blanking_ctr = Signal.like(self.blanking_threshold)
        with m.If(~self.data_enable):
            with m.If(blanking_ctr < self.blanking_threshold):
                m.d.sync += blanking_ctr.eq(blanking_ctr + 1)
            with m.If(blanking_ctr == (self.blanking_threshold - 1)):
                m.d.sync += self.blankings_hit.eq(self.blankings_hit + 1)
        with m.Else():
            m.d.sync += blanking_ctr.eq(0)

        return m
Esempio n. 24
0
    def test_gearbox_3_to_7(self):
        input = BasicStream(3)
        dut = StreamGearbox(input, 7)

        def writer():
            yield from write_to_stream(input, payload=0b001)
            yield from write_to_stream(input, payload=0b010)
            yield from write_to_stream(input, payload=0b100)
            yield from write_to_stream(input, payload=0b011)
            yield from write_to_stream(input, payload=0b110)
            yield from write_to_stream(input, payload=0b111)
            yield from write_to_stream(input, payload=0b000)

        def reader():
            self.assertEqual((yield from read_from_stream(dut.output)), 0b0_010_001)
            self.assertEqual((yield from read_from_stream(dut.output)), 0b10_011_10)
            self.assertEqual((yield from read_from_stream(dut.output)), 0b000_111_1)

        platform = SimPlatform()
        platform.add_sim_clock("sync", 100e6)
        platform.add_process(writer, "sync")
        platform.add_process(reader, "sync")
        platform.sim(dut)
Esempio n. 25
0
    def test_dont_loose_data(self):
        input = BasicStream(16)
        dut = StreamGearbox(input, 8)

        def writer():
            for i in range(0, 100, 2):
                yield from write_to_stream(input, payload=(((i + 1) << 8) | i))
                if i % 7 == 0:
                    yield from do_nothing()

        def reader():
            for i in range(100):
                got = (yield from read_from_stream(dut.output, extract="payload"))
                print(got)
                self.assertEqual(got, i)
                if i % 3 == 0:
                    yield from do_nothing()

        platform = SimPlatform()
        platform.add_sim_clock("sync", 100e6)
        platform.add_process(writer, "sync")
        platform.add_process(reader, "sync")
        platform.sim(dut)
Esempio n. 26
0
    def __init__(self, width, count_if_not_ready=False):
        self.output = BasicStream(width, name="counter_stream")

        self.count_if_not_ready = ControlSignal(reset=count_if_not_ready)
Esempio n. 27
0
 def test_output_stream_contract(self):
     input = BasicStream(8)
     verify_stream_output_contract(SimpleStreamGearbox(input, 4), support_modules=(LegalStreamSource(input),))
Esempio n. 28
0
 def test_output_stream_contract(self):
     input = BasicStream(7)
     verify_stream_output_contract(StreamGearbox(input, 3))
Esempio n. 29
0
 def test_reader_stream_output(self):
     axi = AxiEndpoint(addr_bits=32, data_bits=64, lite=False, id_bits=12)
     verify_stream_output_contract(AxiReader(BasicStream(32), axi),
                                   support_modules=(LegalStreamSource(
                                       axi.read_data), ))
Esempio n. 30
0
 def test_burster_stream_output(self):
     i = BasicStream(32)
     verify_stream_output_contract(AxiReaderBurster(i),
                                   support_modules=(LegalStreamSource(i), ))