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))
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))
def test_ds_hann(self): """Test function for ds_hann()""" self.assertTrue( np.allclose(self.res, np.hanning(10) - ds.ds_hann(10), atol=1e-8, rtol=1e-5))
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)
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
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)
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))
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))
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)
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
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)
def test_ds_hann(self): """Test function for ds_hann()""" self.assertTrue(np.allclose(self.res, np.hanning(10) - ds.ds_hann(10), atol=1e-8, rtol=1e-5))
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()