Ejemplo n.º 1
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)
Ejemplo n.º 2
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
Ejemplo n.º 3
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
Ejemplo n.º 4
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