コード例 #1
0
    def test_logsmooth(self):
        """Test function for logsmooth()"""
        f0 = 1./8
        OSR = 64
        order = 8
        N = 8192
        H = synthesizeNTF(order, OSR, 1, 1.5, f0)
        # fB = int(np.ceil(N/(2. * OSR)))
        quadrature = False
        M = 1
        f1, f2 = ds_f1f2(OSR, f0, quadrature)
        Amp = undbv(-3)
        f = .3
        fin = np.round(((1 - f)/2*f1 + (f + 1)/2 * f2) * N)
        t = np.arange(0, N).reshape((1, -1))
        u = Amp * M * np.cos((2*np.pi/N)*fin*t)
        v, _, _, _ = simulateDSM(u, H, M + 1)

        window = ds_hann(N)
        # NBW = 1.5/N
        spec0 = fft(v * window) / (M*N/4)

        ### -1 is really important THIS IS NOT MATLAB!!
        fl, pl = logsmooth(spec0, fin - 1)

        fname = pkg_resources.resource_filename(__name__,
                                                "test_data/test_logsmooth.mat")
        data = scipy.io.loadmat(fname)
        self.assertTrue(np.allclose(fl, data['fl'], atol=1e-8, rtol=1e-5))
        self.assertTrue(np.allclose(pl, data['pl'], atol=1e-8, rtol=1e-5))
コード例 #2
0
    def test_logsmooth(self):
        """Test function for logsmooth()"""
        f0 = 1. / 8
        OSR = 64
        order = 8
        N = 8192
        H = synthesizeNTF(order, OSR, 1, 1.5, f0)
        # fB = int(np.ceil(N/(2. * OSR)))
        quadrature = False
        M = 1
        f1, f2 = ds_f1f2(OSR, f0, quadrature)
        Amp = undbv(-3)
        f = .3
        fin = np.round(((1 - f) / 2 * f1 + (f + 1) / 2 * f2) * N)
        t = np.arange(0, N).reshape((1, -1))
        u = Amp * M * np.cos((2 * np.pi / N) * fin * t)
        v, _, _, _ = simulateDSM(u, H, M + 1)

        window = ds_hann(N)
        # NBW = 1.5/N
        spec0 = fft(v * window) / (M * N / 4)

        ### -1 is really important THIS IS NOT MATLAB!!
        fl, pl = logsmooth(spec0, fin - 1)

        fname = pkg_resources.resource_filename(
            __name__, "test_data/test_logsmooth.mat")
        data = scipy.io.loadmat(fname)
        self.assertTrue(np.allclose(fl, data['fl'], atol=1e-8, rtol=1e-5))
        self.assertTrue(np.allclose(pl, data['pl'], atol=1e-8, rtol=1e-5))
コード例 #3
0
 def test_plotSpectrum(self):
     """Test function for plotSpectrum()"""
     f0 = 0
     osr = 32
     quadrature = False
     Hinf = 1.5
     order = 3
     ntf = ds.synthesizeNTF(order, osr, 0, Hinf, f0)
     f1, f2 = ds.ds_f1f2(osr, f0, quadrature)
     delta = 2
     Amp = ds.undbv(-3)
     f = 0.3
     N = 2**12
     f1_bin = np.round(f1*N)
     f2_bin = np.round(f2*N)
     fin = np.round(((1 - f)/2*f1 + (f + 1)/2*f2) * N)
     t = np.arange(0, N)
     u = Amp*np.cos((2*np.pi/N)*fin*t)
     v, xn, xmax, y = ds.simulateDSM(u, ntf, 2)
     window = ds.ds_hann(N)
     NBW = 1.5/N
     spec0 = fft(v * window)/(N/4)
     freq = np.linspace(0, 0.5, N/2 + 1)
     # plotting
     plt.subplot(211)
     plt.plot(freq, ds.dbv(spec0[:N/2 + 1]), 'c', linewidth=1, label='$S$')
     plt.hold(True)
     spec_smoothed = ds.circ_smooth(np.abs(spec0)**2., 16)
     plt.plot(freq, ds.dbp(spec_smoothed[:N/2 + 1]), 'b--', linewidth=2,
              label='$\\mathrm{circ\\_smooth}(S)$')
     ds.plotSpectrum(spec0, fin, 'r', linewidth=2,
                     label='$\\mathrm{plotSpectrum}(S)$')
     Snn = np.abs(ds.evalTF(ntf, np.exp(2j*np.pi*freq)))**2 * 2/12*(delta)**2
     plt.plot(freq, ds.dbp(Snn*NBW), 'm', linewidth=1.5,
              label='$\mathrm{from\\ NTF}$')
     plt.text(0.5, -3, 'NBW = %.1e ' % NBW, horizontalalignment='right',
              verticalalignment='top')
     ds.figureMagic((0, 0.5), None, None, (-140, 0), 20, None)
     plt.ylabel('Spectrum [dB]')
     ax = plt.gca()
     ax.set_title('Smoothing and plotting for LOG and LIN axes')
     plt.legend(loc=4)
     plt.subplot(212)
     plt.plot(freq, ds.dbv(spec0[:N/2 + 1]), 'c', linewidth=1, label='$S$')
     plt.hold(True)
     ds.plotSpectrum(spec0, fin, '--r', linewidth=2,
                     label='$\\mathrm{plotSpectrum}(S)$')
     plt.plot(freq, ds.dbp(spec_smoothed[:N/2 + 1]), 'b', linewidth=2,
              label='$\\mathrm{circ\\_smooth}(S)$')
     plt.plot(freq, ds.dbp(Snn*NBW), 'm', linewidth=1.5,
              label='$\mathrm{from\\ NTF}$')
     plt.text(0.5, -3, 'NBW = %.1e ' % NBW, horizontalalignment='right',
              verticalalignment='top')
     ds.figureMagic((0, 0.5), None, None, (-140, 0), 20, None)
     ax = plt.gca()
     ax.set_xscale('linear')
     plt.ylabel('Spectrum [dB]')
     plt.xlabel('Normalized frequency ($f_s \\rightarrow 1$)')
     plt.legend(loc=4)
コード例 #4
0
    def testMultipleQ2(self):
        """Test function for DS simulation with nq>1 2/2"""
        # filtering and simulation
        filtM1 = [0., 0., 0., 2., -1.]
        filtM2 = [1., -2., 1.]
        ntf_eq = zpk_multiply(self.ntfs[1, 1], self.ntfs[1, 1])
        M = self.nlev[0] - 1
        osr = 64
        f0 = 0.
        f1, f2 = ds.ds_f1f2(OSR=64, f0=0., complex_flag=False)
        delta = 2
        Amp = ds.undbv(-3)  # Test tone amplitude, relative to full-scale.
        f = 0.3  # will be adjusted to a bin
        N = 2**12
        f1_bin = int(np.round(f1 * N))
        f2_bin = int(np.round(f2 * N))
        fin = np.round(((1 - f) / 2 * f1 + (f + 1) / 2 * f2) * N)
        # input sine
        t = np.arange(0, N).reshape((1, -1))
        u = Amp * M * np.cos((2 * np.pi / N) * fin * t)
        vx, _, xmax, y = ds.simulateDSM(u, self.ABCD, nlev=self.nlev)
        # separate output #1 and output #2
        v1 = vx[0, :]
        v2 = vx[1, :]
        # filter and combine
        vf = lfilter(filtM1, [1.], v1) + lfilter(filtM2, [1.], v2)
        # compute the spectra
        window = ds.ds_hann(N)
        NBW = 1.5 / N
        spec0 = np.fft.fft(vf * window) / (M * N / 2) / ds.undbv(-6)
        spec1 = np.fft.fft(v1 * window) / (M * N / 2) / ds.undbv(-6)
        spec2 = np.fft.fft(v1 * window) / (M * N / 2) / ds.undbv(-6)
        freq = np.linspace(0, 0.5, N // 2 + 1)

        # smooth, calculate the theorethical response and the SNR for VF
        spec0_smoothed = ds.circ_smooth(np.abs(spec0)**2., 16)
        Snn0 = np.abs(ds.evalTF(ntf_eq, np.exp(
            2j * np.pi * freq)))**2 * 2 / 12 * (delta / M)**2
        snr0 = ds.calculateSNR(spec0[f1_bin:f2_bin + 1], fin - f1_bin)

        # smooth, calculate the theorethical response and the SNR for V1
        spec1_smoothed = ds.circ_smooth(np.abs(spec1)**2., 16)
        Snn1 = np.abs(ds.evalTF(self.ntfs[0, 0], np.exp(
            2j * np.pi * freq)))**2 * 2 / 12 * (delta / M)**2
        snr1 = ds.calculateSNR(spec1[f1_bin:f2_bin + 1], fin - f1_bin)

        assert snr0 > 40
        assert snr1 > 40
        assert snr0 - snr1 > 40
コード例 #5
0
 def setUp(self):
     fname = pkg_resources.resource_filename(
         __name__, "test_data/test_bplogsmooth.mat")
     self.data = scipy.io.loadmat(fname)
     f0 = 1./8
     OSR = 64
     order = 8
     N = 8192
     H = ds.synthesizeNTF(order, OSR, 1, 1.5, f0)
     fB = int(np.ceil(N/(2. * OSR)))
     ftest = int(mround(f0*N + 1./3*fB))
     u = 0.5*np.sin(2*np.pi*ftest/N*np.arange(N))
     v, xn, xmax, y = ds.simulateDSM(u, H)
     spec = np.fft.fft(v*ds.ds_hann(N))/(N/4)
     X = spec[:N//2 + 1]
     self.f, self.p = ds.bplogsmooth(X, ftest, f0)
コード例 #6
0
 def test_bilogplot(self):
     """Test function for bilogplot()"""
     f0 = 1./8
     OSR = 64
     order = 8
     N = 8192
     H = ds.synthesizeNTF(order, OSR, 1, 1.5, f0)
     fB = int(np.ceil(N/(2. * OSR)))
     ftest = int(np.round(f0*N + 1./3 * fB))
     u = 0.5*np.sin(2*np.pi*ftest/N*np.arange(N))
     v, xn, xmax, y = ds.simulateDSM(u, H)
     spec = np.fft.fft(v*ds.ds_hann(N))/(N/4)
     X = spec[:N/2 + 1]
     plt.figure()
     # graphical function: we check it doesn't fail
     ds.bilogplot(X, f0*N, ftest, (.03, .3, .3), (-140, 0, 10, 20))
コード例 #7
0
 def test_bilogplot(self):
     """Test function for bilogplot()"""
     f0 = 1. / 8
     OSR = 64
     order = 8
     N = 8192
     H = ds.synthesizeNTF(order, OSR, 1, 1.5, f0)
     fB = int(np.ceil(N / (2. * OSR)))
     ftest = int(np.round(f0 * N + 1. / 3 * fB))
     u = 0.5 * np.sin(2 * np.pi * ftest / N * np.arange(N))
     v, xn, xmax, y = ds.simulateDSM(u, H)
     spec = np.fft.fft(v * ds.ds_hann(N)) / (N / 4)
     X = spec[:N / 2 + 1]
     plt.figure()
     # graphical function: we check it doesn't fail
     ds.bilogplot(X, f0 * N, ftest, (.03, .3, .3), (-140, 0, 10, 20))
コード例 #8
0
 def setUp(self):
     fname = pkg_resources.resource_filename(
         __name__, "test_data/test_bplogsmooth.mat")
     self.data = scipy.io.loadmat(fname)
     f0 = 1./8
     OSR = 64
     order = 8
     N = 8192
     H = ds.synthesizeNTF(order, OSR, 1, 1.5, f0)
     fB = int(np.ceil(N/(2. * OSR)))
     ftest = int(mround(f0*N + 1./3*fB))
     u = 0.5*np.sin(2*np.pi*ftest/N*np.arange(N))
     v, xn, xmax, y = ds.simulateDSM(u, H)
     spec = np.fft.fft(v*ds.ds_hann(N))/(N/4)
     X = spec[:N/2 + 1]
     self.f, self.p = ds.bplogsmooth(X, ftest, f0)
コード例 #9
0
    def testMultipleQ2(self):
        """Test function for DS simulation with nq>1 2/2"""
        # filtering and simulation
        filtM1 = [0., 0., 0., 2., -1.]
        filtM2 = [1., -2., 1.]
        ntf_eq = zpk_multiply(self.ntfs[1, 1], self.ntfs[1, 1])
        M = self.nlev[0] - 1
        osr = 64
        f0 = 0.
        f1, f2 = ds.ds_f1f2(OSR=64, f0=0., complex_flag=False)
        delta = 2
        Amp = ds.undbv(-3) # Test tone amplitude, relative to full-scale.
        f = 0.3 # will be adjusted to a bin
        N = 2**12
        f1_bin = np.round(f1*N)
        f2_bin = np.round(f2*N)
        fin = np.round(((1 - f)/2*f1 + (f + 1)/2*f2) * N)
        # input sine
        t = np.arange(0, N).reshape((1, -1))
        u = Amp*M*np.cos((2*np.pi/N)*fin*t)
        vx, _, xmax, y = ds.simulateDSM(u, self.ABCD, nlev=self.nlev)
        # separate output #1 and output #2
        v1 = vx[0, :]
        v2 = vx[1, :]
        # filter and combine
        vf = lfilter(filtM1, [1.], v1) + lfilter(filtM2, [1.], v2)
        # compute the spectra
        window = ds.ds_hann(N)
        NBW = 1.5/N
        spec0 = np.fft.fft(vf*window)/(M*N/2)/ds.undbv(-6)
        spec1 = np.fft.fft(v1*window)/(M*N/2)/ds.undbv(-6)
        spec2 = np.fft.fft(v1*window)/(M*N/2)/ds.undbv(-6)
        freq = np.linspace(0, 0.5, N/2 + 1)

        # smooth, calculate the theorethical response and the SNR for VF
        spec0_smoothed = ds.circ_smooth(np.abs(spec0)**2., 16)
        Snn0 = np.abs(ds.evalTF(ntf_eq, np.exp(2j*np.pi*freq)))**2 * 2/12*(delta/M)**2
        snr0 = ds.calculateSNR(spec0[f1_bin:f2_bin + 1], fin - f1_bin)

        # smooth, calculate the theorethical response and the SNR for V1
        spec1_smoothed = ds.circ_smooth(np.abs(spec1)**2., 16)
        Snn1 = np.abs(ds.evalTF(self.ntfs[0, 0], np.exp(2j*np.pi*freq)))**2 * 2/12*(delta/M)**2
        snr1 = ds.calculateSNR(spec1[f1_bin:f2_bin + 1], fin - f1_bin)

        assert snr0 > 40
        assert snr1 > 40
        assert snr0-snr1 > 40
コード例 #10
0
 def test_plotSpectrum(self):
     """Test function for plotSpectrum()"""
     f0 = 0
     osr = 32
     quadrature = False
     Hinf = 1.5
     order = 3
     ntf = ds.synthesizeNTF(order, osr, 0, Hinf, f0)
     f1, f2 = ds.ds_f1f2(osr, f0, quadrature)
     delta = 2
     Amp = ds.undbv(-3)
     f = 0.3
     N = 2**12
     f1_bin = np.round(f1 * N)
     f2_bin = np.round(f2 * N)
     fin = np.round(((1 - f) / 2 * f1 + (f + 1) / 2 * f2) * N)
     t = np.arange(0, N)
     u = Amp * np.cos((2 * np.pi / N) * fin * t)
     v, xn, xmax, y = ds.simulateDSM(u, ntf, 2)
     window = ds.ds_hann(N)
     NBW = 1.5 / N
     spec0 = fft(v * window) / (N / 4)
     freq = np.linspace(0, 0.5, N // 2 + 1)
     # plotting
     plt.subplot(211)
     plt.plot(freq,
              ds.dbv(spec0[:N // 2 + 1]),
              'c',
              linewidth=1,
              label='$S$')
     #plt.hold(True)
     spec_smoothed = ds.circ_smooth(np.abs(spec0)**2., 16)
     plt.plot(freq,
              ds.dbp(spec_smoothed[:N // 2 + 1]),
              'b--',
              linewidth=2,
              label='$\\mathrm{circ\\_smooth}(S)$')
     ds.plotSpectrum(spec0,
                     fin,
                     'r',
                     linewidth=2,
                     label='$\\mathrm{plotSpectrum}(S)$')
     Snn = np.abs(ds.evalTF(ntf, np.exp(
         2j * np.pi * freq)))**2 * 2 / 12 * (delta)**2
     plt.plot(freq,
              ds.dbp(Snn * NBW),
              'm',
              linewidth=1.5,
              label='$\\mathrm{from\\ NTF}$')
     plt.text(0.5,
              -3,
              'NBW = %.1e ' % NBW,
              horizontalalignment='right',
              verticalalignment='top')
     ds.figureMagic((0, 0.5), None, None, (-140, 0), 20, None)
     plt.ylabel('Spectrum [dB]')
     ax = plt.gca()
     ax.set_title('Smoothing and plotting for LOG and LIN axes')
     plt.legend(loc=4)
     plt.subplot(212)
     plt.plot(freq,
              ds.dbv(spec0[:N // 2 + 1]),
              'c',
              linewidth=1,
              label='$S$')
     #plt.hold(True)
     ds.plotSpectrum(spec0,
                     fin,
                     '--r',
                     linewidth=2,
                     label='$\\mathrm{plotSpectrum}(S)$')
     plt.plot(freq,
              ds.dbp(spec_smoothed[:N // 2 + 1]),
              'b',
              linewidth=2,
              label='$\\mathrm{circ\\_smooth}(S)$')
     plt.plot(freq,
              ds.dbp(Snn * NBW),
              'm',
              linewidth=1.5,
              label='$\\mathrm{from\\ NTF}$')
     plt.text(0.5,
              -3,
              'NBW = %.1e ' % NBW,
              horizontalalignment='right',
              verticalalignment='top')
     ds.figureMagic((0, 0.5), None, None, (-140, 0), 20, None)
     ax = plt.gca()
     ax.set_xscale('linear')
     plt.ylabel('Spectrum [dB]')
     plt.xlabel('Normalized frequency ($f_s \\rightarrow 1$)')
     plt.legend(loc=4)
コード例 #11
0
ファイル: pyfda_fix_lib.py プロジェクト: huangqi412/pyfda
    def fixp(self, y, scaling='mult'):
        """
        Return fixed-point integer or fractional representation for `y`
        (scalar or array-like) with the same shape as `y`.

        Saturation / two's complement wrapping happens outside the range +/- MSB,
        requantization (round, floor, fix, ...) is applied on the ratio `y / LSB`.

        Parameters
        ----------
        y: scalar or array-like object
            input value (floating point format) to be quantized

        scaling: String
            Determine the scaling before and after quantizing / saturation

            *'mult'* float in, int out:
                `y` is multiplied by `self.scale` *before* quantizing / saturating
            **'div'**: int in, float out:
                `y` is divided by `self.scale` *after* quantizing / saturating.
            **'multdiv'**: float in, float out (default):
                both of the above

            For all other settings, `y` is transformed unscaled.

        Returns
        -------
        float scalar or ndarray
            with the same shape as `y`, in the range
            `-2*self.MSB` ... `2*self.MSB-self.LSB`

        Examples
        --------

        >>> q_obj_a = {'WI':1, 'WF':6, 'ovfl':'sat', 'quant':'round'}
        >>> myQa = Fixed(q_obj_a) # instantiate fixed-point object myQa
        >>> myQa.resetN()  # reset overflow counter
        >>> a = np.arange(0,5, 0.05) # create input signal

        >>> aq = myQa.fixed(a) # quantize input signal
        >>> plt.plot(a, aq) # plot quantized vs. original signal
        >>> print(myQa.N_over, "overflows!") # print number of overflows

        >>> # Convert output to same format as input:
        >>> b = np.arange(200, dtype = np.int16)
        >>> btype = np.result_type(b)
        >>> # MSB = 2**7, LSB = 2**(-2):
        >>> q_obj_b = {'WI':7, 'WF':2, 'ovfl':'wrap', 'quant':'round'}
        >>> myQb = Fixed(q_obj_b) # instantiate fixed-point object myQb
        >>> bq = myQb.fixed(b)
        >>> bq = bq.astype(btype) # restore original variable type
        """

        #======================================================================
        # (1) : INITIALIZATION
        #       Convert input argument into proper floating point scalars /
        #       arrays and initialize flags
        #======================================================================
        scaling = scaling.lower()
        if np.shape(y):
            # Input is an array:
            #   Create empty arrays for result and overflows with same shape as y
            #   for speedup, test for invalid types
            SCALAR = False
            y = np.asarray(y)  # convert lists / tuples / ... to numpy arrays
            yq = np.zeros(y.shape)
            over_pos = over_neg = np.zeros(y.shape, dtype=bool)
            self.ovr_flag = np.zeros(y.shape, dtype=int)

            if np.issubdtype(y.dtype, np.number):  # numpy number type
                self.N += y.size
            elif y.dtype.kind in {'U', 'S'}:  # string or unicode
                try:
                    y = y.astype(np.float64)  # try to convert to float
                    self.N += y.size
                except (TypeError, ValueError):
                    try:
                        np.char.replace(y, ' ', '')  # remove all whitespace
                        y = y.astype(complex)  # try to convert to complex
                        self.N += y.size * 2
                    except (TypeError, ValueError
                            ) as e:  # try converting elements recursively
                        y = np.asarray(
                            list(
                                map(
                                    lambda y_scalar: self.fixp(
                                        y_scalar, scaling=scaling),
                                    y)))  # was: list()
                        self.N += y.size
            else:
                logger.error("Argument '{0}' is of type '{1}',\n"
                             "cannot convert to float.".format(y, y.dtype))
                y = np.zeros(y.shape)
        else:
            # Input is a scalar
            SCALAR = True
            # get rid of errors that have occurred upstream
            if y is None or str(y) == "":
                y = 0
            # If y is not a number, remove whitespace and try to convert to
            # to float and or to complex format:
            elif not np.issubdtype(type(y), np.number):
                y = qstr(y)
                y = y.replace(' ', '')  # remove all whitespace
                try:
                    y = float(y)
                except (TypeError, ValueError):
                    try:
                        y = complex(y)
                    except (TypeError, ValueError) as e:
                        logger.error("Argument '{0}' yields \n {1}".format(
                            y, e))
                        y = 0.0
            over_pos = over_neg = yq = 0
            self.ovr_flag = 0
            self.N += 1

        # convert pseudo-complex (imag = 0) and complex values to real
        y = np.real_if_close(y)
        if np.iscomplexobj(y):
            logger.warning(
                "Casting complex values to real before quantization!")
            # quantizing complex objects is not supported yet
            y = y.real

        y_in = y  # y before scaling / quantizing
        #======================================================================
        # (2) : INPUT SCALING
        #       Multiply by `scale` factor before requantization and saturation
        #       when `scaling=='mult'`or 'multdiv'
        #======================================================================
        if scaling in {'mult', 'multdiv'}:
            y = y * self.scale

        #======================================================================
        # (3) : QUANTIZATION
        #       Divide by LSB to obtain an intermediate format where the
        #       quantization step size = 1.
        #       Next, apply selected quantization method to convert
        #       floating point inputs to "fixpoint integers".
        #       Finally, multiply by LSB to restore original scale.
        #=====================================================================
        y = y / self.LSB

        if self.quant == 'floor':
            yq = np.floor(y)
            # largest integer i, such that i <= x (= binary truncation)
        elif self.quant == 'round':
            yq = np.round(y)
            # rounding, also = binary rounding
        elif self.quant == 'fix':
            yq = np.fix(y)
            # round to nearest integer towards zero ("Betragsschneiden")
        elif self.quant == 'ceil':
            yq = np.ceil(y)
            # smallest integer i, such that i >= x
        elif self.quant == 'rint':
            yq = np.rint(y)
            # round towards nearest int
        elif self.quant == 'dsm':
            if DS:
                # Synthesize DSM loop filter,
                # TODO: parameters should be adjustable via quantizer dict
                H = synthesizeNTF(order=3, osr=64, opt=1)
                # Calculate DSM stream and shift/scale it from -1 ... +1 to
                # 0 ... 1 sequence
                yq = (simulateDSM(y * self.LSB, H)[0] + 1) / (2 * self.LSB)
                # returns four ndarrays:
                # v: quantizer output (-1 or 1)
                # xn: modulator states.
                # xmax: maximum value that each state reached during simulation
                # y: The quantizer input (ie the modulator output).
            else:
                raise Exception(
                    '"deltasigma" Toolbox not found.\n'
                    'Try installing it with "pip install deltasigma".')
        elif self.quant == 'none':
            yq = y
            # return unquantized value
        else:
            raise Exception('Unknown Requantization type "%s"!' % (self.quant))
        yq = yq * self.LSB
        # logger.debug("y_in={0} | y={1} | yq={2}".format(y_in, y, yq))

        #======================================================================
        # (4) : Handle Overflow / saturation w.r.t. to the MSB, returning a
        #       result in the range MIN = -2*MSB ... + 2*MSB-LSB = MAX
        #=====================================================================
        if self.ovfl == 'none':
            pass
        else:
            # Bool. vectors with '1' for every neg./pos overflow:
            over_neg = (yq < self.MIN)
            over_pos = (yq > self.MAX)
            # create flag / array of flags for pos. / neg. overflows
            self.ovr_flag = over_pos.astype(int) - over_neg.astype(int)
            # No. of pos. / neg. / all overflows occured since last reset:
            self.N_over_neg += np.sum(over_neg)
            self.N_over_pos += np.sum(over_pos)
            self.N_over = self.N_over_neg + self.N_over_pos

            # Replace overflows with Min/Max-Values (saturation):
            if self.ovfl == 'sat':
                yq = np.where(over_pos, self.MAX, yq)  # (cond, true, false)
                yq = np.where(over_neg, self.MIN, yq)
            # Replace overflows by two's complement wraparound (wrap)
            elif self.ovfl == 'wrap':
                yq = np.where(
                    over_pos | over_neg, yq - 4. * self.MSB * np.fix(
                        (np.sign(yq) * 2 * self.MSB + yq) / (4 * self.MSB)),
                    yq)
            else:
                raise Exception('Unknown overflow type "%s"!' % (self.ovfl))
                return None
        #======================================================================
        # (5) : OUTPUT SCALING
        #       Divide result by `scale` factor when `scaling=='div'`or 'multdiv'
        #       to obtain correct scaling for floats
        #       - frmt2float() always returns float
        #       - input_coeffs when quantizing the coefficients
        #       float2frmt passes on the scaling argument
        #======================================================================

        if scaling in {'div', 'multdiv'}:
            yq = yq / self.scale

        if SCALAR and isinstance(yq, np.ndarray):
            yq = yq.item()  # convert singleton array to scalar

        return yq
コード例 #12
0
    def test_dsdemo3(self):
        """dsdemo3 test: Delta sigma modulator synthesis"""
        order = 5
        R = 42
        opt = 1
        H = ds.synthesizeNTF(order, R, opt)

        # ## Evaluation of the coefficients for a CRFB topology
        a, g, b, c = ds.realizeNTF(H)

        # Use a single feed-in for the input
        # Lets check that stuffABCD understands that if b is scalar it means 1 feed-in.
        ABCD = ds.stuffABCD(a, g, b[0], c)
        # for passing the assertion below, we need b to have the trailing zeros
        b = np.concatenate((np.atleast_1d(b[0]), np.zeros((b.shape[0] - 1, ))))
        u = np.linspace(0, 0.6, 30)
        N = 1e4
        T = np.ones((1, N))
        maxima = np.zeros((order, len(u)))
        for i in range(len(u)):
            ui = u[i]
            v, xn, xmax, _ = ds.simulateDSM(ui * T, ABCD)
            maxima[:, i] = np.squeeze(xmax)
            if any(xmax > 1e2):
                umax = ui
                u = u[:i + 1]
                maxima = maxima[:, :i]
                break
        # save the maxima
        prescale_maxima = np.copy(maxima)

        # ## Scaled modulator
        # ### Calculate the scaled coefficients
        ABCDs, umax, _ = ds.scaleABCD(ABCD, N_sim=1e5)
        as_, gs, bs, cs = ds.mapABCD(ABCDs)
        # ### Calculate the state maxima
        u = np.linspace(0, umax, 30)
        N = 1e4
        T = np.ones((N, ))
        maxima = np.zeros((order, len(u)))
        for i in range(len(u)):
            ui = u[i]
            v, xn, xmax, _ = ds.simulateDSM(ui * T, ABCDs)
            maxima[:, i] = xmax.squeeze()
            if any(xmax > 1e2):
                umax = ui
                u = u[:i]
                maxima = maxima[:, :i]
                break

        self.assertTrue(np.allclose(ABCD, self.data['ABCD']))
        self.assertTrue(
            np.allclose(ABCDs, self.data['ABCDs'], atol=1e-2, rtol=5e-2))
        self.assertTrue(np.allclose(a, self.data['a'], atol=1e-5, rtol=1e-3))
        self.assertTrue(np.allclose(b, self.data['b'], atol=1e-5, rtol=1e-3))
        self.assertTrue(np.allclose(g, self.data['g'], atol=1e-5, rtol=1e-3))
        self.assertTrue(np.allclose(c, self.data['c'], atol=1e-5, rtol=1e-3))
        self.assertTrue(np.allclose(as_, self.data['as'], atol=1e-2,
                                    rtol=5e-3))
        self.assertTrue(np.allclose(bs, self.data['bs'], atol=5e-3, rtol=5e-3))
        self.assertTrue(np.allclose(gs, self.data['gs'], atol=5e-3, rtol=5e-3))
        self.assertTrue(np.allclose(cs, self.data['cs'], atol=3e-2, rtol=3e-2))
        self.assertTrue(
            np.allclose(umax, self.data['umax'], atol=5e-3, rtol=5e-3))
        self.assertTrue(
            np.allclose(maxima, self.data['maxima'], atol=2e-2, rtol=5e-2))
コード例 #13
0
    def test_dsdemo3(self):
        """dsdemo3 test: Delta sigma modulator synthesis"""
        order = 5
        R = 42
        opt = 1
        H = ds.synthesizeNTF(order, R, opt)

        # ## Evaluation of the coefficients for a CRFB topology
        a, g, b, c = ds.realizeNTF(H)

        # Use a single feed-in for the input
        # Lets check that stuffABCD understands that if b is scalar it means 1 feed-in.
        ABCD = ds.stuffABCD(a, g, b[0], c)
        # for passing the assertion below, we need b to have the trailing zeros
        b = np.concatenate((np.atleast_1d(b[0]), 
                            np.zeros((b.shape[0] - 1,))))
        u = np.linspace(0, 0.6, 30)
        N = 1e4
        T = np.ones((1, N))
        maxima = np.zeros((order, len(u)))
        for i in range(len(u)):
            ui = u[i]
            v, xn, xmax, _ = ds.simulateDSM(ui*T, ABCD);
            maxima[:, i] = np.squeeze(xmax)
            if any(xmax > 1e2):
                umax = ui
                u = u[:i+1]
                maxima = maxima[:, :i]
                break
        # save the maxima
        prescale_maxima = np.copy(maxima)

        # ## Scaled modulator
        # ### Calculate the scaled coefficients
        ABCDs, umax, _ = ds.scaleABCD(ABCD, N_sim=1e5)
        as_, gs, bs, cs = ds.mapABCD(ABCDs)
        # ### Calculate the state maxima
        u = np.linspace(0, umax, 30)
        N = 1e4
        T = np.ones((N,))
        maxima = np.zeros((order, len(u)))
        for i in range(len(u)):
            ui = u[i]
            v, xn, xmax, _ = ds.simulateDSM(ui*T, ABCDs)
            maxima[:, i] = xmax.squeeze()
            if any(xmax > 1e2):
                umax = ui;
                u = u[:i]
                maxima = maxima[:, :i]
                break

        self.assertTrue(np.allclose(ABCD, self.data['ABCD']))
        self.assertTrue(np.allclose(ABCDs, self.data['ABCDs'], atol=1e-2, rtol=5e-2))
        self.assertTrue(np.allclose(a, self.data['a'], atol=1e-5, rtol=1e-3))
        self.assertTrue(np.allclose(b, self.data['b'], atol=1e-5, rtol=1e-3))
        self.assertTrue(np.allclose(g, self.data['g'], atol=1e-5, rtol=1e-3))
        self.assertTrue(np.allclose(c, self.data['c'], atol=1e-5, rtol=1e-3))
        self.assertTrue(np.allclose(as_, self.data['as'], atol=1e-2, rtol=5e-3))
        self.assertTrue(np.allclose(bs, self.data['bs'], atol=5e-3, rtol=5e-3))
        self.assertTrue(np.allclose(gs, self.data['gs'], atol=5e-3, rtol=5e-3))
        self.assertTrue(np.allclose(cs, self.data['cs'], atol=3e-2, rtol=3e-2))
        self.assertTrue(np.allclose(umax, self.data['umax'], atol=5e-3, rtol=5e-3))
        self.assertTrue(np.allclose(maxima, self.data['maxima'], atol=2e-2, rtol=5e-2))
コード例 #14
0
    def test_sim_noiseshaper(self):
        fmt = Q(8, 18)
        input = fmt.Signal()
        dut = Noiseshaper(input, order=8, n_lev=64)

        sim = Simulator(dut)
        sim.add_clock(1 / 100e6)

        input_hist = []
        output_hist = []
        integrators_hist = [[] for _ in dut.stages]

        n = 8192
        f_nyquist = int(np.ceil(n / (2. * dut.osr)))
        f_test = np.floor(2. / 3. * f_nyquist)
        u = dut.n_lev * 0.5 * np.sin(2 * np.pi * f_test / n * np.arange(n))

        def testbench():
            for x in u:
                yield input.eq(x)

                input_hist.append(fmt.to_float((yield input.value)))
                output_hist.append(
                    fmt.to_float((yield dut.quantized_value.value)))
                for i, integrator in enumerate(dut.stages):
                    integrators_hist[i].append(
                        fmt.to_float((yield integrator.value)))

                yield

        sim.add_sync_process(testbench)

        sim.run()

        from matplotlib import pyplot as plt
        plt.plot(np.arange(n), output_hist, linewidth=1, label="output")
        plt.plot(np.arange(n), input_hist, label="input")
        plt.legend()
        plt.show()
        for i, integrator_hist in reversed(list(enumerate(integrators_hist))):
            plt.plot(np.arange(n),
                     integrator_hist,
                     linewidth=1,
                     label="integrator {}".format(i))
        plt.legend()
        plt.show()

        import deltasigma as ds
        f = np.linspace(0, 0.5, int(n / 2. + 1))

        v, xn, xmax, y = ds.simulateDSM(u,
                                        dut.h,
                                        nlev=len(dut.quantization_values))

        spec = np.fft.fft(v * ds.ds_hann(n)) / (n / 4)
        plt.plot(f, ds.dbv(spec[:int(n / 2. + 1)]), 'b', label='Simulation DS')

        spec = np.fft.fft(output_hist * ds.ds_hann(n)) / (n / 4)
        plt.plot(f,
                 ds.dbv(spec[:int(n / 2. + 1)]),
                 'g',
                 label='Simulation HW',
                 alpha=0.7)
        ds.figureMagic([0, 0.5], 0.05, None, [-160, 0], 20, None, (16, 6),
                       'Output Spectrum')
        plt.xlabel('Normalized Frequency')
        plt.ylabel('dBFS')
        snr = ds.calculateSNR(spec[2:f_nyquist + 1], f_test - 2)
        plt.text(0.05,
                 -10,
                 'SNR = %4.1fdB @ OSR = %d' % (snr, dut.osr),
                 verticalalignment='center')
        NBW = 1.5 / n
        Sqq = 4 * ds.evalTF(dut.h, np.exp(2j * np.pi * f))**2 / 3.
        plt.plot(f, ds.dbp(Sqq * NBW), 'm', linewidth=2, label='Expected PSD')
        plt.text(0.49,
                 -90,
                 'NBW = %4.1E x $f_s$' % NBW,
                 horizontalalignment='right')
        plt.legend(loc=4)
        plt.show()

        pwm_out = py_pwm.modulate(np.array(output_hist) + 32,
                                  n_bits=6,
                                  oversampling_ratio=1)
        n = n * 64
        f = np.linspace(0, 0.5, int(n / 2. + 1))
        spec = np.fft.fft(pwm_out * ds.ds_hann(n)) / (n / 4)
        plt.plot(f, ds.dbv(spec[:int(n / 2. + 1)]), 'b', label='PWM')
        ds.figureMagic([0, 0.5], 0.05, None, [-160, 0], 20, None, (16, 6),
                       'Output Spectrum')
        plt.xlabel('Normalized Frequency')
        plt.ylabel('dBFS')
        snr = ds.calculateSNR(spec[2:f_nyquist + 1], f_test - 2)
        plt.text(0.05,
                 -10,
                 'SNR = %4.1fdB @ OSR = %d' % (snr, dut.osr),
                 verticalalignment='center')
        plt.legend(loc=4)
        plt.show()