Exemple #1
0
    def test_fir_design(self):
        in_sign = Signature("in", True, bits=9)
        out_sign = Signature("out", True, bits=9)

        s = FirSim(in_sign=in_sign, out_sign=out_sign)
        taps = [int(t) for t in s.design(48e3, 12e3, 1e3, 40.0)]

        in_c = s.input_signal()
        in_t = arange(len(in_c))
        in_i = [int(i.real * (2**8-1)) for i in in_c]
        in_q = [int(i.imag * (2**8-1)) for i in in_c]

        s.verify_design()

        coeff_ram = Ram2(s.clearn, s.clock, s.clock, data=taps)
        delay_line_i_ram = Ram(s.clearn, s.clock, s.clock)
        delay_line_q_ram = Ram(s.clearn, s.clock, s.clock)
        bypass = Signal(bool(0))
        bank1 = Signal(bool(0))
        bank0 = Signal(bool(0))
        N = Signal(intbv(len(taps), min=0, max=2**7-1))

        def test_fir_design():
            load_coeff_ram_addr = coeff_ram.port['b'].addr
            load_coeff_ram_blk = coeff_ram.port['b'].blk
            load_coeff_ram_wen = coeff_ram.port['b'].wen
            fir_0 = fir(s.clearn, s.clock, s.input, s.output,
                    coeff_ram.port['a'].addr,
                    coeff_ram.port['a'].din[0],
                    coeff_ram.port['a'].din[1],
                    coeff_ram.port['a'].blk,
                    coeff_ram.port['a'].wen,
                    coeff_ram.port['a'].dout[0],
                    coeff_ram.port['a'].dout[1],
                    delay_line_i_ram.port['a'].addr,
                    delay_line_i_ram.port['a'].din,
                    delay_line_i_ram.port['a'].blk,
                    delay_line_i_ram.port['a'].wen,
                    delay_line_i_ram.port['a'].dout,
                    delay_line_q_ram.port['a'].addr,
                    delay_line_q_ram.port['a'].din,
                    delay_line_q_ram.port['a'].blk,
                    delay_line_q_ram.port['a'].wen,
                    delay_line_q_ram.port['a'].dout,
                    bypass, bank1, bank0, N,
                    sim=s)

            return fir_0, coeff_ram.rama, coeff_ram.ramb, delay_line_i_ram.ram, delay_line_q_ram.ram

        out_i, out_q = s.simulate_quadrature(in_i, in_q, test_fir_design, interp=128)
        out_t = arange(0, out_i.shape[0])

        new_shape = tuple([in_t.shape[i] for i in range(len(in_t.shape))])
        assert out_t.shape == new_shape
        f = figure("fir_output")
        title("fir filter output")
        f_out = figure_discrete_quadrature('FIR Filter Output', (1, 1, 1), f, s.input, out_t, out_i / (2.**8-1), out_q / (2.**8-1))
        savefig('output.png')
Exemple #2
0
    def test_fir_bypass(self):
        in_sign = Signature("in", True, bits=9)
        out_sign = Signature("out", True, bits=9)

        s = FirSim(in_sign=in_sign, out_sign=out_sign)
        s.design(48e3, 6e3, 1e3, 40.0)
        s.input_signal()

        taps = (4 << COEFF_SHIFT, 3 << COEFF_SHIFT, 2 << COEFF_SHIFT, 1 << COEFF_SHIFT)
        coeff_ram = Ram2(s.clearn, s.clock, s.clock, data=taps)
        delay_line_i_ram = Ram(s.clearn, s.clock, s.clock)
        delay_line_q_ram = Ram(s.clearn, s.clock, s.clock)
        bypass = Signal(bool(1))
        bank1 = Signal(bool(0))
        bank0 = Signal(bool(0))
        N = Signal(intbv(4, min=0, max=2**7-1))

        def test_fir_bypass():
            load_coeff_ram_addr = coeff_ram.port['b'].addr
            load_coeff_ram_blk = coeff_ram.port['b'].blk
            load_coeff_ram_wen = coeff_ram.port['b'].wen
            fir_0 = fir(s.clearn, s.clock, s.input, s.output,
                    coeff_ram.port['a'].addr,
                    coeff_ram.port['a'].din[0],
                    coeff_ram.port['a'].din[1],
                    coeff_ram.port['a'].blk,
                    coeff_ram.port['a'].wen,
                    coeff_ram.port['a'].dout[0],
                    coeff_ram.port['a'].dout[1],
                    delay_line_i_ram.port['a'].addr,
                    delay_line_i_ram.port['a'].din,
                    delay_line_i_ram.port['a'].blk,
                    delay_line_i_ram.port['a'].wen,
                    delay_line_i_ram.port['a'].dout,
                    delay_line_q_ram.port['a'].addr,
                    delay_line_q_ram.port['a'].din,
                    delay_line_q_ram.port['a'].blk,
                    delay_line_q_ram.port['a'].wen,
                    delay_line_q_ram.port['a'].dout,
                    bypass, bank1, bank0, N,
                    sim=s)

            return fir_0, coeff_ram.ram, delay_line_i_ram.ram, delay_line_q_ram.ram

        in_t = arange(0, 8)

        in_c = 0*in_t + 1j * 0*in_t
        in_i = 0*in_t
        in_q = 0*in_t
        in_i[0] = 1 << COEFF_SHIFT
        in_i[4] = 1 << COEFF_SHIFT

        out_i, out_q = s.simulate_quadrature(in_i, in_q, test_fir_bypass, interp=128)
        out_t = arange(0, out_i.shape[0])

        new_shape = tuple([in_t.shape[i] for i in range(len(in_t.shape))])
        assert out_t.shape == new_shape
        assert array_equal(out_i >> 5, array([1, 0, 0, 0, 1, 0, 0, 0]))
Exemple #3
0
    def test_fir_impulse(self):
        in_sign = Signature("in", True, bits=9)
        out_sign = Signature("out", True, bits=9)

        s = FirSim(in_sign=in_sign, out_sign=out_sign)
        #s.design(48e3, 6e3, 1e3, 40.0)
        taps = (4 << COEFF_SHIFT, 3 << COEFF_SHIFT, 2 << COEFF_SHIFT,
                1 << COEFF_SHIFT)
        coeff_ram = Ram(s.clearn,
                        s.clock,
                        s.clock,
                        data=taps,
                        width=18,
                        depth=512)
        delay_line_i_ram = Ram(s.clearn, s.clock, s.clock, width=9, depth=512)
        delay_line_q_ram = Ram(s.clearn, s.clock, s.clock, width=9, depth=512)
        enable = Signal(bool(1))
        bank1 = Signal(bool(0))
        bank0 = Signal(bool(0))
        N = Signal(intbv(4, min=0, max=2**7 - 1))

        coeff_ram_inst = coeff_ram.instance_type()(
            **coeff_ram.instance_signals())
        delay_line_i_ram_inst = delay_line_i_ram.instance_type()(
            **delay_line_i_ram.instance_signals())
        delay_line_q_ram_inst = delay_line_q_ram.instance_type()(
            **delay_line_q_ram.instance_signals())

        def test_fir_impulse():
            load_coeff_ram_addr = coeff_ram.port['b'].addr
            load_coeff_ram_blk = coeff_ram.port['b'].blk
            load_coeff_ram_wen = coeff_ram.port['b'].wen
            fir_0 = fir(s.clearn,
                        s.clock,
                        s.input,
                        s.output,
                        coeff_ram.port['a'].addr,
                        coeff_ram.port['a'].din,
                        coeff_ram.port['a'].blk,
                        coeff_ram.port['a'].wen,
                        coeff_ram.port['a'].dout,
                        delay_line_i_ram.port['a'].addr,
                        delay_line_i_ram.port['a'].din,
                        delay_line_i_ram.port['a'].blk,
                        delay_line_i_ram.port['a'].wen,
                        delay_line_i_ram.port['a'].dout,
                        delay_line_q_ram.port['a'].addr,
                        delay_line_q_ram.port['a'].din,
                        delay_line_q_ram.port['a'].blk,
                        delay_line_q_ram.port['a'].wen,
                        delay_line_q_ram.port['a'].dout,
                        enable,
                        bank1,
                        bank0,
                        N,
                        sim=s)

            return fir_0, coeff_ram_inst, delay_line_i_ram_inst, delay_line_q_ram_inst

        in_t = arange(0, 8)

        in_c = 0 * in_t + 1j * 0 * in_t
        in_i = 0 * in_t
        in_q = 0 * in_t
        in_i[0] = 1 << 5
        in_i[4] = 1 << 5

        out_i, out_q = s.simulate(in_i, in_q, test_fir_impulse, 128, coeff_ram,
                                  taps)
        out_t = arange(0, out_i.shape[0])

        new_shape = tuple([in_t.shape[i] for i in range(len(in_t.shape))])
        assert out_t.shape == new_shape
        print 'out_i', out_i
        assert array_equal(out_i, [4, 3, 2, 1, 4, 3, 2, 1])
Exemple #4
0
def cic_decim(clearn, clock,
        in_sign,
        out_sign,
        decim,
        #shift,
        cic_order=4, cic_delay=2, **kwargs):
    """A cic decimating filter with given order and delay.

    :param clearn: Reset the filter.
    :param clock: The clock.
    :param in_sign: The input signature.
    :param out_sign: The output signature.
    :param decim: The decimation of the cic filter.
    :param shift: How much to shift the result.
    :param cic_order: The order of the CIC filter.
    :param cic_delay: The delay of the CIC comb elements.
    :returns: A synthesizable MyHDL instance.
    """
    in_valid = in_sign.valid
    in_i = in_sign.i
    in_q = in_sign.q
    in_last = in_sign.last
    out_last = out_sign.last
    out_valid = out_sign.valid
    out_i = out_sign.i
    out_q = out_sign.q
    rates = kwargs.get('rates', [decim])
    max_rate = max(rates)

    accumed = [Signature('accumed_%d' % i, True, bits=cic_decim_register_width(
            len(in_i), len(out_i), max_rate, cic_order, cic_delay,
            i)) for i in range(1, cic_order + 1)]
    print 'accumed', accumed
    combed = [Signature('combed_%d' % i, True, bits=cic_decim_register_width(
            len(in_i), len(out_i), max_rate, cic_order, cic_delay,
            cic_order + i)) for i in range(1, cic_order + 1)]
    print 'combed', combed

    accums = []
    for n in range(cic_order):
        if n == 0:
            i = in_sign
        else:
            i = accumed[n - 1]

        o = accumed[n]

        print 'accum in=%d, out=%d' % (len(i.q), len(o.q))
        accums.append(accumulator(clearn, clock, i, o, n))  # TODO truncate

    decimated = accumed[cic_order - 1].copy('decimated')
    decimator_0 = downsampler(clearn, clock,
        accumed[cic_order - 1], decimated,
        decim)

    combs = []
    for n in range(cic_order):
        if n == 0:
            i = decimated
        else:
            i = combed[n - 1]

        o = combed[n]

        print 'comb in=%d, out=%d' % (len(i.q), len(o.q))
        combs.append(comb(clearn, clock, cic_delay, i, o))  # TODO truncate
    
    # TODO: does this need a shifter?  yeah.
    truncator_0 = truncator(clearn, clock,
        combed[cic_order - 1], out_sign)

    instances = accums, decimator_0, combs, truncator_0

    if kwargs.get('sim', None):
        sim = kwargs['sim']
        sim.record(in_sign)
        [sim.record(a) for a in accumed]
        sim.record(decimated)
        [sim.record(c) for c in combed]
        sim.record(out_sign)

    return instances
Exemple #5
0
def duc(clearn, dac_clock, dac2x_clock, loopen, loopback, fifo_empty, fifo_re,
        fifo_dvld, fifo_rdata, fifo_underflow, system_txen, system_txstop,
        system_ddsen, system_filteren, system_interp, system_shift, system_fcw,
        system_correct_i, system_correct_q, system_gain_i, system_gain_q,
        underrun, sample, dac_en, dac_data, dac_last, rx_fifo_full, rx_fifo_we,
        rx_fifo_wdata, rxen, rxstop, rxfilteren, decim, system_rx_correct_i,
        system_rx_correct_q, rx_overrun, rx_sample, adc_idata, adc_qdata,
        adc_last, fir_coeff_ram_addr, fir_coeff_ram_din0, fir_coeff_ram_din1,
        fir_coeff_ram_blk, fir_coeff_ram_wen, fir_coeff_ram_dout0,
        fir_coeff_ram_dout1, fir_delay_line_i_ram_addr,
        fir_delay_line_i_ram_din, fir_delay_line_i_ram_blk,
        fir_delay_line_i_ram_wen, fir_delay_line_i_ram_dout,
        fir_delay_line_q_ram_addr, fir_delay_line_q_ram_din,
        fir_delay_line_q_ram_blk, fir_delay_line_q_ram_wen,
        fir_delay_line_q_ram_dout, system_firen, system_fir_bank1,
        system_fir_bank0, system_fir_N, **kwargs):
    """The Digital Up Converter.    

    :param clearn: Reset signal, completely resets the dsp chain.
    :param dac_clock: The sampling clock.
    :param dac2x_clock: Twice the sampling clock.
    :param loopen: Enable the loopback device.
    :param loopback: The loopback signature to the digital down converter.
    :param fifo_empty: Input signal that the fifo is empty.
    :param fifo_re: Output signal to enable a sample read.
    :param fifo_dvld: Input signal that FIFO data is valid.
    :param fifo_rdata: Input sample data.
    :param fifo_underflow: Input signal that fifo underflowed.
    :param system_txen: Enable transmit.
    :param system_txstop: Stop the transmitter.
    :param system_ddsen: Enable the DDS.
    :param system_filteren: Enable the CIC filter.
    :param system_interp: Interpolation rate.
    :param system_fcw: Set the frequency control word of the DDS.
    :param system_correct_i: Set the i-Channel AQM DC Offset Correction.
    :param system_correct_q: Set the q-Channel AQM DC Offset Correction.
    :param system_gain_i: Set the i-channel AQM gain correction.
    :param system_gain_q: Set the q-channel AQM gain correction.
    :param underrun: Output of number of underruns to RFE.
    :param sample: The sample.
    :param dac_en: Enable DAC on valid data signal.
    :param dac_data: The interleaved DAC data.
    :param dac_last: The last sample going out on the DAC, stops the transmit.
    :returns: A MyHDL synthesizable module.
    """

    dspsim = kwargs.get('dspsim', None)

    # DIGIAL UP CONVERTER
    interp_default = kwargs.get('interp', 1)

    sync_txen = Signal(bool(0))
    txen = Signal(bool(0))
    sync_txstop = Signal(bool(0))
    txstop = Signal(bool(0))
    sync_ddsen = Signal(bool(0))
    ddsen = Signal(bool(0))
    sync_filteren = Signal(bool(0))
    filteren = Signal(bool(0))
    sync_interp = Signal(intbv(interp_default)[len(system_interp):])
    interp = Signal(intbv(interp_default)[len(system_interp):])
    sync_shift = Signal(intbv(0)[len(system_shift):])
    shift = Signal(intbv(0)[len(system_shift):])
    sync_firen = Signal(bool(0))
    firen = Signal(bool(0))
    sync_fir_bank0 = Signal(bool(0))
    fir_bank0 = Signal(bool(0))
    sync_fir_bank1 = Signal(bool(0))
    fir_bank1 = Signal(bool(0))
    sync_fir_N = Signal(intbv(0, min=system_fir_N.min, max=system_fir_N.max))
    fir_N = Signal(intbv(0, min=system_fir_N.min, max=system_fir_N.max))
    sync_fcw = Signal(intbv(0)[len(system_fcw):])
    fcw = Signal(intbv(0)[len(system_fcw):])
    sync_correct_i = Signal(intbv(0)[len(system_correct_i):])
    correct_i = Signal(intbv(0)[len(system_correct_i):])
    sync_correct_q = Signal(intbv(0)[len(system_correct_q):])
    correct_q = Signal(intbv(0)[len(system_correct_q):])
    sync_gain_i = Signal(intbv(int(1.0 * 2**9 + .5))[10:])
    gain_i = Signal(intbv(int(1.0 * 2**9 + .5))[10:])
    sync_gain_q = Signal(intbv(int(1.0 * 2**9 + .5))[10:])
    gain_q = Signal(intbv(int(1.0 * 2**9 + .5))[10:])
    sync_rx_correct_i = Signal(intbv(0)[len(system_rx_correct_i):])
    rx_correct_i = Signal(intbv(0)[len(system_rx_correct_i):])
    sync_rx_correct_q = Signal(intbv(0)[len(system_rx_correct_q):])
    rx_correct_q = Signal(intbv(0)[len(system_rx_correct_q):])

    sample_valid = sample.valid
    sample_last = sample.last
    sample_i = sample.i
    sample_q = sample.q

    rx_sample_valid = rx_sample.valid
    rx_sample_last = rx_sample.last
    rx_sample_i = rx_sample.i
    rx_sample_q = rx_sample.q

    adc_sample = Signature("adc",
                           True,
                           bits=10,
                           valid=rxen,
                           last=adc_last,
                           i=adc_idata,
                           q=adc_qdata)

    truncated_1 = Signature("truncated1", True, bits=9)
    truncator_1 = truncator(clearn, dac_clock, sample, truncated_1)
    duc_chain = (truncator_1, )

    if kwargs.get('dds_enable', True):
        if_out = Signature("if_out", True, bits=9)
        dds_args = clearn, dac_clock, ddsen, truncated_1, if_out, fcw
        dds = DDS(*dds_args, num_samples=DDS_NUM_SAMPLES)
        duc_chain = duc_chain + (dds, )
    else:
        if_out = truncated_1

    if kwargs.get('fir_enable', True):
        filtered = Signature("filtered", True, bits=9)
        fir_0 = FIR(clearn, dac_clock, if_out, filtered, fir_coeff_ram_addr,
                    fir_coeff_ram_din0, fir_coeff_ram_din1, fir_coeff_ram_blk,
                    fir_coeff_ram_wen, fir_coeff_ram_dout0,
                    fir_coeff_ram_dout1, fir_delay_line_i_ram_addr,
                    fir_delay_line_i_ram_din, fir_delay_line_i_ram_blk,
                    fir_delay_line_i_ram_wen, fir_delay_line_i_ram_dout,
                    fir_delay_line_q_ram_addr, fir_delay_line_q_ram_din,
                    fir_delay_line_q_ram_blk, fir_delay_line_q_ram_wen,
                    fir_delay_line_q_ram_dout, firen, fir_bank1, fir_bank0,
                    fir_N)
        duc_chain = duc_chain + (fir_0, )
    else:
        filtered = if_out

    upsampled = Signature("upsampled", True, bits=9)
    upsampler_0 = upsampler(clearn, dac_clock, filtered, upsampled, interp)
    duc_chain = duc_chain + (upsampler_0, )

    if kwargs.get('cic_enable', True):
        rate_changed = Signature("rate_changed", True, bits=10)
        cic_0 = cic(clearn,
                    dac_clock,
                    filtered,
                    rate_changed,
                    interp,
                    shift,
                    cic_order=kwargs.get('cic_order', 4),
                    cic_delay=kwargs.get('cic_delay', 1),
                    sim=dspsim)
        duc_chain = duc_chain + (cic_0, )

        processed = Signature("processed", True, bits=10)
        processed_mux = iqmux(clearn, dac_clock, filteren, upsampled,
                              rate_changed, processed)
        duc_chain = duc_chain + (processed_mux, )
    else:
        processed = upsampled

    rf_out = processed

    tx_loopback = pass_through_with_enable(clearn, dac_clock, rf_out, loopback,
                                           loopen)
    duc_chain = duc_chain + (tx_loopback, )

    if kwargs.get('conditioning_enable', True):
        gain_corrected = Signature("gain_corrected", True, bits=10)
        gain_corrector_0 = gain_corrector(clearn, dac_clock, gain_i, gain_q,
                                          rf_out, gain_corrected)
        duc_chain = duc_chain + (gain_corrector_0, )

        corrected = Signature("offset_corrected", True, bits=10)
        offset_corrector_0 = offset_corrector(clearn, dac_clock, correct_i,
                                              correct_q, gain_corrected,
                                              corrected)
        duc_chain = duc_chain + (offset_corrector_0, )

    else:
        corrected = rf_out

    offset = Signature("binary_offset", False, bits=10)
    offseter = binary_offseter(clearn, dac_clock, corrected, offset)
    duc_chain = duc_chain + (offseter, )

    interleaver_0 = interleaver(clearn, dac_clock, dac2x_clock, offset, dac_en,
                                dac_data, dac_last)
    duc_chain = duc_chain + (interleaver_0, )

    # DIGITAL DOWN CONVERTER
    rx_offset_corrected = Signature("rx_offset_corrected", True, bits=10)
    rx_offset_corrector = offset_corrector(clearn, dac_clock, rx_correct_i,
                                           rx_correct_q, adc_sample,
                                           rx_offset_corrected)
    ddc_chain = (rx_offset_corrector, )

    downsampled = Signature("downsampled", True, bits=10)
    downsampled_i = downsampled.i
    downsampled_q = downsampled.q
    downsampled_valid = downsampled.valid
    downsampler_0 = downsampler(clearn, dac_clock, rx_offset_corrected,
                                downsampled, decim)
    ddc_chain = ddc_chain + (downsampler_0, )

    @always_seq(dac_clock.posedge, reset=clearn)
    def synchronizer():
        sync_txen.next = system_txen
        txen.next = sync_txen
        sync_txstop.next = system_txstop
        txstop.next = sync_txstop
        sync_ddsen.next = system_ddsen
        ddsen.next = sync_ddsen
        sync_filteren.next = system_filteren
        filteren.next = sync_filteren
        sync_interp.next = system_interp
        interp.next = sync_interp
        sync_shift.next = system_shift
        shift.next = sync_shift
        sync_firen.next = system_firen
        firen.next = sync_firen
        sync_fir_bank1.next = system_fir_bank1
        fir_bank1.next = sync_fir_bank1
        sync_fir_bank0.next = system_fir_bank0
        fir_bank0.next = sync_fir_bank0
        sync_fir_N.next = system_fir_N
        fir_N.next = sync_fir_N
        sync_fcw.next = system_fcw
        fcw.next = sync_fcw
        sync_correct_i.next = system_correct_i
        correct_i.next = sync_correct_i
        sync_correct_q.next = system_correct_q
        correct_q.next = sync_correct_q
        sync_gain_i.next = system_gain_i
        gain_i.next = sync_gain_i
        sync_gain_q.next = system_gain_q
        gain_q.next = sync_gain_q
        sync_rx_correct_i.next = system_rx_correct_i
        rx_correct_i.next = sync_rx_correct_i
        sync_rx_correct_q.next = system_rx_correct_q
        rx_correct_q.next = sync_rx_correct_q

    interp_counter = Signal(intbv(0)[32:])
    done = Signal(bool(0))

    decim_counter = Signal(intbv(0)[32:])
    rx_done = Signal(bool(0))

    @always_seq(dac_clock.posedge, reset=clearn)
    def consumer():
        if txen:
            if interp_counter == 0:
                interp_counter.next = interp - 1
                if fifo_empty:
                    if txstop:
                        done.next = True
                        fifo_re.next = False
                    else:
                        underrun.next = underrun + 1
                        done.next = False
                        fifo_re.next = False
                else:
                    done.next = False
                    fifo_re.next = True
            else:
                interp_counter.next = interp_counter - 1
                fifo_re.next = False

    @always_seq(dac_clock.posedge, reset=clearn)
    def producer():
        if rxen and downsampled_valid:
            if rx_fifo_full:
                if rxstop:
                    rx_done.next = True
                    rx_fifo_we.next = False
                else:
                    rx_overrun.next = rx_overrun + 1
                    rx_done.next = False
                    rx_fifo_we.next = False
            else:
                rx_done.next = False
                rx_fifo_we.next = True
        else:
            rx_done.next = False
            rx_fifo_we.next = False

    @always_seq(dac_clock.posedge, reset=clearn)
    def sampler():
        if txen:
            if done:
                sample_i.next = 0
                sample_q.next = 0
                sample_valid.next = True
                sample_last.next = True
            elif fifo_dvld:
                sample_i.next = fifo_rdata[16:].signed()
                sample_q.next = fifo_rdata[32:16].signed()
                sample_valid.next = True
                sample_last.next = False
            else:
                sample_i.next = 0
                sample_q.next = 0
                sample_valid.next = False
                sample_last.next = False
        else:
            sample_i.next = 0
            sample_q.next = 0
            sample_valid.next = False
            sample_last.next = False

        if rxen and downsampled_valid:
            rx_fifo_wdata.next = concat(downsampled_q[9], downsampled_q[9],
                                        downsampled_q[9], downsampled_q[9],
                                        downsampled_q[9], downsampled_q[9],
                                        downsampled_q[10:], downsampled_i[9],
                                        downsampled_i[9], downsampled_i[9],
                                        downsampled_i[9], downsampled_i[9],
                                        downsampled_i[9], downsampled_i[10:])
        else:
            rx_fifo_wdata.next = 0

    return (
        synchronizer,
        consumer,
        producer,
        sampler,
    ) + duc_chain + ddc_chain
Exemple #6
0
def cic(clearn,
        clock,
        in_sign,
        out_sign,
        interp,
        shift,
        cic_order=4,
        cic_delay=2,
        **kwargs):
    """A cic filter with given order, delay, and interpolation.

    :param clearn: The reset the accumulator.
    :param clock: The clock.
    :param in_sign: The input signature.
    :param out_sign: The output signature.
    :param interp: The interpolation of the cic filter.
    :param cic_order: The order of the CIC filter.
    :param cic_delay: The delay of the CIC comb elements.
    :returns: A synthesizable MyHDL instance.
    """
    in_valid = in_sign.valid
    in_i = in_sign.i
    in_q = in_sign.q
    in_last = in_sign.last
    out_last = out_sign.last
    out_valid = out_sign.valid
    out_i = out_sign.i
    out_q = out_sign.q
    rates = kwargs.get('rates', [interp])
    max_rate = max(rates)

    #print 'CIC order=%d delay=%d interp=%d' % (cic_order, cic_delay, interp)

    combed = [
        Signature('combed_%d' % i,
                  True,
                  bits=cic_bit_width(len(in_i), max_rate, cic_order, cic_delay,
                                     i)) for i in range(1, cic_order + 1)
    ]
    accumed = [
        Signature('accumed_%d' % i,
                  True,
                  bits=cic_bit_width(len(in_i), max_rate, cic_order, cic_delay,
                                     cic_order + i))
        for i in range(1, cic_order + 1)
    ]

    combs = []
    for n in range(cic_order):
        if n == 0:
            i = in_sign  # interpolated
        else:
            i = combed[n - 1]

        o = combed[n]

        #print 'comb stage', n, i, '->', o

        combs.append(comb(clearn, clock, cic_delay, i, o))

    interpolated = combed[cic_order - 1].copy('interpolated')
    interpolator_0 = interpolator(clearn, clock, combed[cic_order - 1],
                                  interpolated, interp)

    #print 'interpolator', combed[cic_order - 1], '->', interpolated

    accums = []
    for n in range(cic_order):
        if n == 0:
            i = interpolated  #combed[cic_order - 1]
        else:
            i = accumed[n - 1]

        o = accumed[n]

        #print 'accum stage', n, i, '->', o

        accums.append(accumulator(clearn, clock, i, o))

    #print 'decimated', accumed[cic_order - 1], '->', out_sign

    #truncator_2 = truncator(clearn, clock,
    #    accumed[cic_order - 1], out_sign, debug=True)
    shifter_0 = shifting_truncator(clearn, clock, accumed[cic_order - 1],
                                   out_sign, shift)

    instances = combs, interpolator_0, accums, shifter_0  #truncator_2

    # NOTE: This only works when used with MyHDL's Simulation
    # feature, not Cosimulation with an external Verilog tool.
    # So, for the Whitebox codebase, this means DSP tests can use
    # it but not Cosimulations of the Whitebox toplevel HDL.
    if kwargs.get('sim', None):
        sim = kwargs['sim']
        sim.record(in_sign)
        [sim.record(c) for c in combed]
        sim.record(interpolated)
        [sim.record(a) for a in accumed]
        sim.record(out_sign)

    return instances
Exemple #7
0
def whitebox(
        resetn,
        pclk,
        paddr,
        psel,
        penable,
        pwrite,
        pwdata,
        pready,
        prdata,
        #pslverr,
        clearn,
        clear_enable,
        dac_clock,
        dac2x_clock,
        dac_en,
        dac_data,
        adc_idata,
        adc_qdata,
        tx_status_led,
        tx_dmaready,
        rx_status_led,
        rx_dmaready,
        tx_fifo_re,
        tx_fifo_rdata,
        tx_fifo_we,
        tx_fifo_wdata,
        tx_fifo_full,
        tx_fifo_afull,
        tx_fifo_empty,
        tx_fifo_aempty,
        tx_fifo_afval,
        tx_fifo_aeval,
        tx_fifo_wack,
        tx_fifo_dvld,
        tx_fifo_overflow,
        tx_fifo_underflow,
        tx_fifo_rdcnt,
        tx_fifo_wrcnt,
        rx_fifo_re,
        rx_fifo_rdata,
        rx_fifo_we,
        rx_fifo_wdata,
        rx_fifo_full,
        rx_fifo_afull,
        rx_fifo_empty,
        rx_fifo_aempty,
        rx_fifo_afval,
        rx_fifo_aeval,
        rx_fifo_wack,
        rx_fifo_dvld,
        rx_fifo_overflow,
        rx_fifo_underflow,
        rx_fifo_rdcnt,
        rx_fifo_wrcnt,
        fir_coeff_ram_addr,
        fir_coeff_ram_din0,
        fir_coeff_ram_din1,
        fir_coeff_ram_blk,
        fir_coeff_ram_wen,
        fir_coeff_ram_dout0,
        fir_coeff_ram_dout1,
        fir_load_coeff_ram_addr,
        fir_load_coeff_ram_din0,
        fir_load_coeff_ram_din1,
        fir_load_coeff_ram_blk,
        fir_load_coeff_ram_wen,
        fir_load_coeff_ram_dout0,
        fir_load_coeff_ram_dout1,
        fir_delay_line_i_ram_addr,
        fir_delay_line_i_ram_din,
        fir_delay_line_i_ram_blk,
        fir_delay_line_i_ram_wen,
        fir_delay_line_i_ram_dout,
        fir_delay_line_q_ram_addr,
        fir_delay_line_q_ram_din,
        fir_delay_line_q_ram_blk,
        fir_delay_line_q_ram_wen,
        fir_delay_line_q_ram_dout,
        **kwargs):
    """The whitebox.

    :param resetn: Reset the whole radio front end.
    :param clearn: Clear the DSP Chain
    :param dac_clock: Clock running at DAC rate
    :param dac2x_clock: Clock running at double DAC rate
    :param pclk: The system bus clock
    :param paddr: The bus assdress
    :param psel: The bus slave select
    :param penable: The bus slave enable line
    :param pwrite: The bus read/write flag
    :param pwdata: The bus write data
    :param pready: The bus slave ready signal
    :param prdata: The bus read data
    :param pslverr: The bus slave error flag
    :param dac_clock: The DAC clock
    :param dac_data: The DAC data
    :param dac_en: Enable DAC output
    :param status_led: Output pin for whitebox status
    :param dmaready: Ready signal to DMA controller
    :param txirq: Almost empty interrupt to CPU
    :param clear_enable: To reset controller, set this high for reset
    """
    dspsim = kwargs.get('dspsim', None)
    interp_default = kwargs.get('interp', 1)
    fcw_bitwidth = kwargs.get('fcw_bitwidth', 25)

    ######### VARS AND FLAGS ###########
    print 'interp=', interp_default

    interp = Signal(intbv(interp_default)[11:])
    shift = Signal(intbv(0, min=0, max=21))
    firen = Signal(bool(0))
    fir_bank1 = Signal(bool(0))
    fir_bank0 = Signal(bool(0))
    fir_N = Signal(intbv(0, min=0, max=2**7))

    tx_correct_i = Signal(intbv(0, min=-2**9, max=2**9))
    tx_correct_q = Signal(intbv(0, min=-2**9, max=2**9))
    tx_gain_i = Signal(intbv(int(1.0 * 2**9 + .5))[10:])
    tx_gain_q = Signal(intbv(int(1.0 * 2**9 + .5))[10:])
    fcw = Signal(intbv(1)[fcw_bitwidth:])
    txen = Signal(bool(0))
    txstop = Signal(bool(0))
    txfilteren = Signal(bool(0))
    ddsen = Signal(bool(False))
    loopen = Signal(bool(False))

    decim = Signal(intbv(interp_default)[11:])
    rx_correct_i = Signal(intbv(0, min=-2**9, max=2**9))
    rx_correct_q = Signal(intbv(0, min=-2**9, max=2**9))
    rxen = Signal(bool(0))
    rxstop = Signal(bool(0))
    rxfilteren = Signal(bool(0))

    ########### DIGITAL SIGNAL PROCESSING #######
    loopback = Signature("loopback", False, bits=10)
    duc_underrun = Signal(modbv(0, min=0, max=2**16))
    dac_last = Signal(bool(0))

    ddc_overrun = Signal(modbv(0, min=0, max=2**16))
    ddc_flags = Signal(intbv(0)[4:])
    adc_last = Signal(bool(0))

    tx_sample = Signature("tx_sample", True, bits=16)
    tx_sample_valid = tx_sample.valid
    tx_sample_last = tx_sample.last
    tx_sample_i = tx_sample.i
    tx_sample_q = tx_sample.q

    rx_sample = Signature("rx_sample", True, bits=16)
    rx_sample_valid = rx_sample.valid
    rx_sample_last = rx_sample.last
    rx_sample_i = rx_sample.i
    rx_sample_q = rx_sample.q

    duc_args = (
        clearn,
        dac_clock,
        dac2x_clock,
        loopen,
        loopback,
        tx_fifo_empty,
        tx_fifo_re,
        tx_fifo_dvld,
        tx_fifo_rdata,
        tx_fifo_underflow,
        txen,
        txstop,
        ddsen,
        txfilteren,
        interp,
        shift,
        fcw,
        tx_correct_i,
        tx_correct_q,
        tx_gain_i,
        tx_gain_q,
        duc_underrun,
        tx_sample,
        dac_en,
        dac_data,
        dac_last,
        rx_fifo_full,
        rx_fifo_we,
        rx_fifo_wdata,
        rxen,
        rxstop,
        rxfilteren,
        decim,
        rx_correct_i,
        rx_correct_q,
        ddc_overrun,
        rx_sample,
        adc_idata,
        adc_qdata,
        adc_last,
        fir_coeff_ram_addr,
        fir_coeff_ram_din0,
        fir_coeff_ram_din1,
        fir_coeff_ram_blk,
        fir_coeff_ram_wen,
        fir_coeff_ram_dout0,
        fir_coeff_ram_dout1,
        fir_delay_line_i_ram_addr,
        fir_delay_line_i_ram_din,
        fir_delay_line_i_ram_blk,
        fir_delay_line_i_ram_wen,
        fir_delay_line_i_ram_dout,
        fir_delay_line_q_ram_addr,
        fir_delay_line_q_ram_din,
        fir_delay_line_q_ram_blk,
        fir_delay_line_q_ram_wen,
        fir_delay_line_q_ram_dout,
        firen,
        fir_bank1,
        fir_bank0,
        fir_N,
    )

    duc_kwargs = dict(dspsim=dspsim,
                      interp=interp_default,
                      cic_enable=kwargs.get('cic_enable', True),
                      cic_order=kwargs.get('cic_order', 4),
                      cic_delay=kwargs.get('cic_delay', 1),
                      fir_enable=kwargs.get('fir_enable', True),
                      dds_enable=kwargs.get('dds_enable', True),
                      conditioning_enable=kwargs.get('conditioning_enable',
                                                     True))
    if kwargs.get("duc_enable", True):
        duc = DUC(*duc_args, **duc_kwargs)
    else:
        duc = None

    ########### RADIO FRONT END ##############
    rfe_args = (
        resetn,
        pclk,
        paddr,
        psel,
        penable,
        pwrite,
        pwdata,
        pready,
        prdata,  #pslverr,
        clearn,
        clear_enable,
        loopen,
        tx_status_led,
        tx_dmaready,
        rx_status_led,
        rx_dmaready,
        tx_fifo_we,
        tx_fifo_wdata,
        tx_fifo_empty,
        tx_fifo_full,
        tx_fifo_afval,
        tx_fifo_aeval,
        tx_fifo_afull,
        tx_fifo_aempty,
        tx_fifo_wack,
        tx_fifo_dvld,
        tx_fifo_overflow,
        tx_fifo_underflow,
        tx_fifo_rdcnt,
        tx_fifo_wrcnt,
        rx_fifo_re,
        rx_fifo_rdata,
        rx_fifo_empty,
        rx_fifo_full,
        rx_fifo_afval,
        rx_fifo_aeval,
        rx_fifo_afull,
        rx_fifo_aempty,
        rx_fifo_wack,
        rx_fifo_dvld,
        rx_fifo_overflow,
        rx_fifo_underflow,
        rx_fifo_rdcnt,
        rx_fifo_wrcnt,
        fir_load_coeff_ram_addr,
        fir_load_coeff_ram_din0,
        fir_load_coeff_ram_din1,
        fir_load_coeff_ram_blk,
        fir_load_coeff_ram_wen,
        fir_load_coeff_ram_dout0,
        fir_load_coeff_ram_dout1,
        firen,
        fir_bank1,
        fir_bank0,
        fir_N,
        interp,
        shift,
        fcw,
        tx_correct_i,
        tx_correct_q,
        tx_gain_i,
        tx_gain_q,
        txen,
        txstop,
        ddsen,
        txfilteren,
        decim,
        rx_correct_i,
        rx_correct_q,
        rxen,
        rxstop,
        rxfilteren,
        duc_underrun,
        dac_last,
        ddc_overrun,
        adc_last)

    rfe = RFE(*rfe_args)

    return rfe, duc