Пример #1
0
    def elaborate(self, platform):
        m = Module()

        sink = StreamEndpoint.like(self.input,
                                   is_sink=True,
                                   name="plugin_module_streamer_sink")
        m.d.comb += sink.connect(self.input)

        m.d.comb += self.plugin_lvds.valid.eq(sink.valid & ~self.do_training)
        m.d.comb += sink.ready.eq(1)

        m.d.comb += self.plugin_lvds.clk_word.eq(ClockSignal())

        for i in range(4):
            value = Signal()
            m.submodules["lane{}".format(i)] = DDRSerializer(
                self.plugin_lvds["lvds{}".format(i)],
                value,
                ddr_clockdomain=self.bitclk_domain)
            with m.If(self.plugin_lvds.valid):
                m.d.comb += value.eq(sink.payload[0 + (i * 8):8 + (i * 8)])
            with m.Else():
                m.d.comb += value.eq(self.training_pattern)

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

        hdmi = m.submodules.hdmi = Hdmi(self.hdmi_plugin, self.modeline)

        in_pix_domain = DomainRenamer("pix")

        addr_gen = m.submodules.addr_gen = in_pix_domain(
            AddressGenerator(self.ring_buffer))
        m.d.comb += addr_gen.next_frame.eq(hdmi.timing_generator.vsync)
        m.d.comb += addr_gen.line_words_read.eq(hdmi.timing_generator.width)

        reader = m.submodules.reader = in_pix_domain(
            AxiBufferReader(addr_gen.output))
        output = StreamEndpoint.like(reader.output,
                                     is_sink=True,
                                     name="hdmi_reader_output_sink")
        m.d.comb += output.connect(reader.output)

        ctr = Signal(range(4))
        with m.If(ctr == 3):
            m.d.comb += output.ready.eq(1)
            m.d.pix += ctr.eq(0)
        with m.Else():
            m.d.pix += ctr.eq(ctr + 1)
        value = Signal(8)
        for i in range(4):
            with m.If(ctr == i):
                m.d.comb += value.eq(output.payload[i * 12:i * 12 + 8])

        m.d.comb += hdmi.rgb.r.eq(value)
        m.d.comb += hdmi.rgb.g.eq(value)
        m.d.comb += hdmi.rgb.b.eq(value)

        return m
Пример #3
0
    def elaborate(self, platform):
        m = Module()

        sink = StreamEndpoint.like(self.input_stream,
                                   is_sink=True,
                                   name="ft601_sink")
        m.d.comb += sink.connect(self.input_stream)

        ft = self.ft_601_resource

        m.d.comb += ft.be.oe.eq(1)
        m.d.comb += ft.be.o.eq(0b1111)  # everything we write is valid

        m.d.comb += ft.oe.eq(0)  # we are driving the data bits all the time
        m.d.comb += ft.data.oe.eq(1)
        m.d.comb += platform.request("led", 0).eq(ft.write)

        if self.safe_to_begin_new_transaction is None:
            m.d.comb += ft.data.o.eq(sink.payload)
            m.d.comb += sink.ready.eq(ft.txe)
            m.d.comb += ft.write.eq(sink.valid)
        else:
            in_transaction = Signal()
            m.d.sync += in_transaction.eq(ft.write)
            with m.If(in_transaction):
                m.d.comb += ft.write.eq(sink.valid & ft.txe)
                m.d.comb += sink.ready.eq(ft.txe)
            with m.Else():
                m.d.comb += ft.write.eq(sink.valid
                                        & self.safe_to_begin_new_transaction)
                m.d.comb += sink.ready.eq(ft.txe
                                          & self.safe_to_begin_new_transaction)
            m.d.comb += ft.data.o.eq(sink.payload)

        return m
Пример #4
0
    def __init__(self,
                 input: StreamEndpoint,
                 depth: int,
                 buffered=True,
                 fwtf=False):
        assert input.is_sink is False
        self.input = input
        self.output = StreamEndpoint.like(input, name="stream_fifo_output")
        self.depth = depth
        self.buffered = buffered
        self.fwtf = fwtf

        self.max_w_level = StatusSignal(range(depth))
        self.overflow_cnt = StatusSignal(32)
        self.underrun_cnt = StatusSignal(32)
        self.r_level = StatusSignal(range(depth + 1))
        self.w_level = StatusSignal(range(depth + 1))
Пример #5
0
    def elaborate(self, platform):
        m = Module()

        input_sink = StreamEndpoint.like(self.input,
                                         is_sink=True,
                                         name="stream_fifo_input")
        m.d.comb += input_sink.connect(self.input)
        if input_sink.has_last:
            fifo_data = Cat(input_sink.payload, input_sink.last)
        else:
            fifo_data = input_sink.payload

        if self.buffered:
            assert not self.fwtf
            fifo = m.submodules.fifo = SyncFIFOBuffered(width=len(fifo_data),
                                                        depth=self.depth)
        else:
            fifo = m.submodules.fifo = SyncFIFO(width=len(fifo_data),
                                                depth=self.depth,
                                                fwft=self.fwtf)

        m.d.comb += self.r_level.eq(fifo.r_level)
        m.d.comb += self.w_level.eq(fifo.w_level)

        with m.If(self.w_level > self.max_w_level):
            m.d.sync += self.max_w_level.eq(self.w_level)

        m.d.comb += input_sink.ready.eq(fifo.w_rdy)
        m.d.comb += fifo.w_data.eq(fifo_data)
        m.d.comb += fifo.w_en.eq(input_sink.valid)

        with m.If(input_sink.valid & (~input_sink.ready)):
            m.d.sync += self.overflow_cnt.eq(self.overflow_cnt + 1)
        with m.If(self.output.ready & (~self.output.valid)):
            m.d.sync += self.underrun_cnt.eq(self.underrun_cnt + 1)

        if self.output.has_last:
            m.d.comb += Cat(self.output.payload,
                            self.output.last).eq(fifo.r_data)
        else:
            m.d.comb += self.output.payload.eq(fifo.r_data)
        m.d.comb += self.output.valid.eq(fifo.r_rdy)
        m.d.comb += fifo.r_en.eq(self.output.ready)

        return m
Пример #6
0
    def __init__(self,
                 input,
                 depth,
                 r_domain,
                 w_domain,
                 buffered=True,
                 exact_depth=False):
        assert input.is_sink is False
        self.input = input
        self.output = StreamEndpoint.like(input, name="stream_fifo_output")

        self.r_domain = r_domain
        self.w_domain = w_domain
        self.depth = depth
        self.exact_depth = exact_depth
        self.buffered = buffered

        self.overflow_cnt = StatusSignal(32)
        self.underrun_cnt = StatusSignal(32)
        self.r_level = StatusSignal(range(depth + 1))
        self.w_level = StatusSignal(range(depth + 1))
Пример #7
0
    def elaborate(self, platform):
        m = Module()

        input_sink = StreamEndpoint.like(self.input,
                                         is_sink=True,
                                         name="stream_fifo_input")
        m.d.comb += input_sink.connect(self.input)
        if input_sink.has_last:
            fifo_data = Cat(input_sink.payload, input_sink.last)
        else:
            fifo_data = input_sink.payload

        fifo_type = AsyncFIFOBuffered if self.buffered else AsyncFIFO
        fifo = m.submodules.fifo = fifo_type(width=len(fifo_data),
                                             depth=self.depth,
                                             r_domain=self.r_domain,
                                             w_domain=self.w_domain,
                                             exact_depth=self.exact_depth)

        m.d.comb += self.r_level.eq(fifo.r_level)
        m.d.comb += self.w_level.eq(fifo.w_level)

        m.d.comb += input_sink.ready.eq(fifo.w_rdy)
        m.d.comb += fifo.w_data.eq(fifo_data)
        m.d.comb += fifo.w_en.eq(input_sink.valid)

        with m.If(input_sink.valid & (~input_sink.ready)):
            m.d[self.w_domain] += self.overflow_cnt.eq(self.overflow_cnt + 1)
        with m.If(self.output.ready & (~self.output.valid)):
            m.d[self.r_domain] += self.underrun_cnt.eq(self.underrun_cnt + 1)

        if self.output.has_last:
            m.d.comb += Cat(self.output.payload,
                            self.output.last).eq(fifo.r_data)
        else:
            m.d.comb += self.output.payload.eq(fifo.r_data)
        m.d.comb += self.output.valid.eq(fifo.r_rdy)
        m.d.comb += fifo.r_en.eq(self.output.ready)

        return m
Пример #8
0
    def elaborate(self, platform):
        m = Module()

        if self.axi_slave is not None:
            assert not self.axi_slave.is_lite
            assert not self.axi_slave.is_master
            axi_slave = self.axi_slave
        else:
            clock_signal = Signal()
            m.d.comb += clock_signal.eq(ClockSignal())
            axi_slave = platform.ps7.get_axi_hp_slave(clock_signal)
        axi = AxiEndpoint.like(axi_slave, master=True)
        m.d.comb += axi.connect_slave(axi_slave)

        assert len(self.output.payload) == axi.data_bits

        address_stream = StreamEndpoint.like(self.address_source, is_sink=True, name="address_sink")
        m.d.comb += address_stream.connect(self.address_source)
        assert len(address_stream.payload) == axi.addr_bits

        # we dont generate bursts for now
        m.d.comb += axi.read_address.valid.eq(address_stream.valid)
        m.d.comb += axi.read_address.value.eq(address_stream.payload)
        m.d.comb += address_stream.ready.eq(axi.read_address.ready)
        m.d.comb += axi.read_address.burst_len.eq(0)

        m.d.comb += axi.read_data.ready.eq(self.output.ready)
        m.d.comb += axi.read_data.last.eq(1)
        m.d.comb += self.output.valid.eq(axi.read_data.valid)
        m.d.comb += self.output.payload.eq(axi.read_data.value)

        m.d.sync += self.last_resp.eq(axi.read_data.resp)
        with m.If(axi.read_data.valid & (axi.read_data.resp != Response.OKAY)):
            m.d.sync += self.error_count.eq(self.error_count + 1)

        return m
Пример #9
0
    def elaborate(self, platform):
        m = Module()

        highest_bit = 0
        for i, stream in enumerate(self._streams):
            sink = StreamEndpoint.like(
                stream, is_sink=True, name="stream_combiner_sink_{}".format(i))
            sink.connect(stream)
            m.d.comb += stream.ready.eq(self.output.ready)
            m.d.comb += self.output.payload[highest_bit:highest_bit +
                                            len(stream.payload)].eq(
                                                stream.payload)
            highest_bit += len(stream.payload)

            m.d.comb += self.output.valid.eq(stream.valid)
            with m.If(self.output.valid != stream.valid):
                m.d.sync += self.different_valid_error.eq(1)

            if self.has_last:
                m.d.comb += self.output.last.eq(stream.last)
                with m.If(self.output.last != stream.last):
                    m.d.sync += self.different_last_error.eq(1)

        return m
Пример #10
0
    def elaborate(self, platform):
        m = Module()

        if self.axi_slave is not None:
            assert not self.axi_slave.is_lite
            assert not self.axi_slave.is_master
            axi_slave = self.axi_slave
        else:
            clock_signal = Signal()
            m.d.comb += clock_signal.eq(ClockSignal())
            axi_slave = platform.ps7.get_axi_hp_slave(clock_signal)
        axi = AxiEndpoint.like(axi_slave, master=True)
        m.d.comb += axi.connect_slave(axi_slave)

        address_generator = m.submodules.address_generator = AddressGenerator(
            self.ringbuffer, axi.addr_bits, max_incr=self.max_burst_length * axi.data_bytes
        )

        data_fifo = m.submodules.data_fifo = SyncStreamFifo(self.stream_source, depth=self.fifo_depth, buffered=False)
        data = StreamEndpoint.like(data_fifo.output, is_sink=True, name="data_sink")
        m.d.comb += data.connect(data_fifo.output)

        assert len(data.payload) <= axi.data_bits

        # we do not currently care about the write responses
        m.d.comb += axi.write_response.ready.eq(1)

        current_burst_length_minus_one = Signal(range(self.max_burst_length))
        with m.FSM():
            def idle_state():
                # having the idle state in a function is a hack to be able to duplicate its logic
                m.d.comb += self.state.eq(0)
                m.d.sync += self.burst_position.eq(0)
                m.d.comb += address_generator.request.eq(1)
                with m.If(address_generator.valid & data.valid):
                    # we are doing a full transaction
                    next_burst_length = Signal(range(self.max_burst_length + 1))
                    m.d.comb += next_burst_length.eq(nMax(data_fifo.r_level, self.max_burst_length))
                    m.d.sync += current_burst_length_minus_one.eq(next_burst_length - 1)
                    m.d.sync += address_generator.inc.eq(mul_by_pot(next_burst_length, axi.data_bytes))
                    m.next = "ADDRESS"

            with m.State("IDLE"):
                idle_state()

            with m.State("ADDRESS"):
                m.d.comb += self.state.eq(1)
                m.d.comb += axi.write_address.value.eq(address_generator.addr)
                m.d.comb += axi.write_address.burst_len.eq(current_burst_length_minus_one)
                m.d.comb += axi.write_address.burst_type.eq(BurstType.INCR)
                m.d.comb += axi.write_address.valid.eq(1)
                with m.If(axi.write_address.ready):
                    m.next = "TRANSFER_DATA"
                    m.d.comb += data.ready.eq(1)
                    m.d.comb += address_generator.done.eq(1)

            def last_logic():
                # shared between TRANSFER_DATA and FLUSH
                with m.If(self.burst_position == current_burst_length_minus_one):
                    m.d.comb += axi.write_data.last.eq(1)
                    m.next = "IDLE"
                    idle_state()

            with m.State("TRANSFER_DATA"):
                m.d.comb += self.state.eq(2)

                with m.If(data.last):
                    m.d.sync += self.buffers_written.eq(self.buffers_written + 1)
                    m.d.comb += address_generator.change_buffer.eq(1)
                    m.next = "FLUSH"

                m.d.comb += axi.write_data.value.eq(data.payload)
                m.d.comb += axi.write_data.valid.eq(1)

                with m.If(axi.write_data.ready):
                    m.d.sync += self.words_written.eq(self.words_written + 1)
                    m.d.sync += self.burst_position.eq(self.burst_position + 1)
                    with m.If((self.burst_position < current_burst_length_minus_one) & ~data.last):
                        m.d.comb += data.ready.eq(1)
                        with m.If((~data.valid)):
                            # we have checked this earlier so this should never be a problem
                            m.d.sync += self.error.eq(1)
                last_logic()
            with m.State("FLUSH"):
                m.d.comb += axi.write_data.byte_strobe.eq(0)
                m.d.comb += axi.write_data.valid.eq(1)
                with m.If(axi.write_data.ready):
                    m.d.sync += self.words_written.eq(self.words_written + 1)
                    m.d.sync += self.burst_position.eq(self.burst_position + 1)
                last_logic()

        return m