Beispiel #1
0
class Arbiter(Module):
    """Simple arbiter for two framed data streams.
    Uses end-of-packet (eop) to detect that :attr:`sink0` is inactive
    and yields to :attr:`sink1`.
    """
    def __init__(self, width=8):
        self.sink0 = Endpoint(bus_layout)
        self.sink1 = Endpoint(bus_layout)
        self.source = Endpoint(bus_layout)

        ###

        self.comb += [
            If(
                ~self.sink0.eop,  # has priority
                self.sink0.connect(self.source),
            ).Else(self.sink1.connect(self.source), )
        ]
Beispiel #2
0
class InterpolateChannel(Module):
    def __init__(self):
        h_fir = [24, -85, 281, -1314, 55856, -1314, 281, -85, 24]
        # ciccomp: cic droop and gain, rate 1/10, gain 2**9/5**4 ~ 0.9, 9 taps
        self.submodules.ciccomp = MAC_SYM_FIR(h_fir, width_d=24, width_coef=16)
        h_hbf0 = [
            -167, 0, 428, 0, -931, 0, 1776, 0, -3115, 0, 5185, 0, -8442, 0,
            14028, 0, -26142, 0, 82873, 131072, 82873, 0, -26142, 0, 14028, 0,
            -8442, 0, 5185, 0, -3115, 0, 1776, 0, -931, 0, 428, 0, -167
        ]
        # hbf1: rate 1/10 -> 1/5, gain=1, 39 taps
        self.submodules.hbf0 = MAC_HBF_Upsampler(h_hbf0,
                                                 width_d=24,
                                                 width_coef=17)
        h_hbf1 = [
            294, 0, -1865, 0, 6869, 0, -20436, 0, 80679, 131072, 80679, 0,
            -20436, 0, 6869, 0, -1865, 0, 294
        ]
        # hbf1: rate 1/5 -> 2/5, gain=1, 19 taps
        self.submodules.hbf1 = MAC_HBF_Upsampler(h_hbf1,
                                                 width_d=24,
                                                 width_coef=17)
        # cic: rate 2/5 -> 2/1, gain=5**4
        # the CIC doesn't cope with FIR overshoot and baseband data must be
        # band limited and/or backed off. Maybe TODO: clipping
        self.submodules.cic = SuperCIC(n=5, r=5, width=16)
        # buffer the odd/even stutter of the HBFs
        self.submodules.buf0 = MiniFIFO((len(self.hbf1.input.data), True))
        self.submodules.buf1 = MiniFIFO((len(self.cic.input.data), True))

        self.input = Endpoint([("data", (14, True))])
        self.output = Endpoint([("data0", (16, True)), ("data1", (16, True))])
        # align MACs to MSB to save power, keep one bit headroom for FIR
        # overshoot.
        scale_in = len(self.ciccomp.input.data) - len(self.input.data) - 1
        scale_out = len(self.hbf1.output.data) - len(self.cic.input.data) - 1
        bias_out = (1 << scale_out - 1) - 1  # round half down bias
        # cic gain is r**(n-1) = 5**4, compensate with 2**-9,
        # the rest (2**9/5**4) is applied by ciccomp
        scale_cic = 9
        bias_cic = (1 << scale_cic - 1) - 1  # round half down bias
        self.comb += [
            self.input.connect(self.hbf0.input, omit=["data"]),
            self.ciccomp.input.data.eq(self.input.data << scale_in),
            self.ciccomp.output.connect(self.hbf0.input),
            self.hbf0.output.connect(self.buf0.input),
            self.buf0.output.connect(self.hbf1.input),
            self.hbf1.output.connect(self.buf1.input, omit=["data"]),
            self.buf1.input.data.eq((self.hbf1.output.data +
                                     bias_out) >> scale_out),
            self.buf1.output.connect(self.cic.input),
            self.cic.output.connect(self.output, omit=["data0", "data1"]),
            self.output.data0.eq((self.cic.output.data0 +
                                  bias_cic) >> scale_cic),
            self.output.data1.eq((self.cic.output.data1 +
                                  bias_cic) >> scale_cic),
        ]
Beispiel #3
0
class Arbiter(Module):
    """Simple arbiter for two framed data streams.
    Uses end-of-packet (eop) to detect that :attr:`sink0` is inactive
    and yields to :attr:`sink1`.
    """
    def __init__(self, width=8):
        self.sink0 = Endpoint(bus_layout)
        self.sink1 = Endpoint(bus_layout)
        self.source = Endpoint(bus_layout)

        ###

        self.comb += [
            If(~self.sink0.eop,  # has priority
                self.sink0.connect(self.source),
            ).Else(
                self.sink1.connect(self.source),
            )
        ]
Beispiel #4
0
class FTDI2SPI(Module):
    """Converts parallel data stream from FTDI chip into framed
    SPI-like data.

    It uses the :class:`Unescaper` to to detect escaped start-of-frame SOF
    and EOF characters.

    Attributes:
        sink (Endpoint): Raw data from FTDI parallel bus.
        source (Endpoint): Framed data stream (eop asserted when there is no
            active frame).
    """
    def __init__(self):
        self.sink = Endpoint(bus_layout)
        self.source = Endpoint(bus_layout)
        self.source.eop.reset = 1

        ###

        unesc = Unescaper(bus_layout)
        self.submodules += unesc
        self.sync += [
            If(
                unesc.source1.stb,
                Case(unesc.source1.data, {
                    0x02: self.source.eop.eq(0),
                    0x03: self.source.eop.eq(1),
                }),
            )
        ]
        self.comb += [
            self.sink.connect(unesc.sink),
            self.source.data.eq(unesc.source0.data),
            self.source.stb.eq(unesc.source0.stb),
            unesc.source0.ack.eq(self.source.ack),
            unesc.source1.ack.eq(1),
        ]
Beispiel #5
0
class FTDI2SPI(Module):
    """Converts parallel data stream from FTDI chip into framed
    SPI-like data.

    It uses the :class:`Unescaper` to to detect escaped start-of-frame SOF
    and EOF characters.

    Attributes:
        sink (Endpoint): Raw data from FTDI parallel bus.
        source (Endpoint): Framed data stream (eop asserted when there is no
            active frame).
    """
    def __init__(self):
        self.sink = Endpoint(bus_layout)
        self.source = Endpoint(bus_layout)
        self.source.eop.reset = 1

        ###

        unesc = Unescaper(bus_layout)
        self.submodules += unesc
        self.sync += [
            If(unesc.source1.stb,
                Case(unesc.source1.data, {
                    0x02: self.source.eop.eq(0),
                    0x03: self.source.eop.eq(1),
                }),
            )
        ]
        self.comb += [
            self.sink.connect(unesc.sink),
            self.source.data.eq(unesc.source0.data),
            self.source.stb.eq(unesc.source0.stb),
            unesc.source0.ack.eq(self.source.ack),
            unesc.source1.ack.eq(1),
        ]