#!/usr/bin/env python # coding: utf-8 # In[1]: get_ipython().run_line_magic('pylab', 'inline') # In[2]: from __future__ import print_function from deltasigma import * from IPython.core.display import Image # In[3]: # skip this, this is just to display nice tables. from itertools import izip_longest class Table(list): def _repr_html_(self): html = [""] for row in self: html.append("") for col in row: try: float(col) html.append("" % col) except(ValueError): html.append("" % col) html.append("") html.append("
%.6f%s
") return ''.join(html) # # Modulator realization and dynamic range scaling - # demo3 # In this ipython notebook, the following is demonstrated: # # * A 5th order delta sigma modulator is synthesized, with optimized zeros and an OSR equal to 42. # # * We then convert the synthesized NTF into `a`, `g`, `b`, `c` coefficients for the `CRFB` modulator structure. # # * The maxima for each state are evaluated. # # * The `ABCD` matrix is scaled so that the state maxima are less than the specified limit. # # * The state maxima are re-evaluated and limit compliance is checked. # # **NOTE:** This is an ipython port of `dsdemo3.m`, from the **[MATLAB Delta Sigma Toolbox](http://www.mathworks.com/matlabcentral/fileexchange/19-delta-sigma-toolbox)**, written by Richard Schreier. # ## Delta sigma modulator synthesis # In[4]: order = 5 R = 42 opt = 1 H = synthesizeNTF(order, R, opt) # Let's inspect the NTF, printing out the transfer function and plotting poles and zeros with respect to the unit circle. # In[5]: print(pretty_lti(H)) # In[6]: figure(figsize=(10, 5)) plotPZ(H, showlist=True) title('NTF'); # ## Evaluation of the coefficients for a CRFB topology # The CRFB topology is depicted in the following diagram. # In[7]: Image(url='http://python-deltasigma.readthedocs.org/en/latest/_images/CRFB.png', retina=True) # Since the modulator order is 5, we're interested in the topology for odd order modulators. # ## Unscaled modulator # ### Calculate the coefficients # In[8]: a, g, b, c = realizeNTF(H) # ### Feed-in selection # We'll use a single feed-in for the input, to have a maximally flat STF. # # This means setting $\ b_n = 0, \ \forall n > 1$. # In[9]: b = np.concatenate((b[0].reshape((1, )), np.zeros((b.shape[0] - 1, ))), axis=0) # In[10]: t = Table() ilabels = ['#1', '#2', '#3', '#4', '#5', '#6'] t.append(['Coefficients', 'DAC feedback', 'Resonator feedback', 'Feed-in', 'Interstage']) t.append(['', 'a(n)', 'g(n)', ' b(n)', ' c(n)']) [t.append(x) for x in izip_longest(ilabels, a.tolist(), g.tolist(), b.tolist(), c.tolist(), fillvalue="")] t # ### Calculate the state maxima # In[11]: ABCD = stuffABCD(a, g, b, c); 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, _ = simulateDSM(ui*T, ABCD); maxima[:, i] = np.squeeze(xmax) if any(xmax > 1e2): umax = ui; u = u[:i]; maxima = maxima[:, :i] break; # save the maxima prescale_maxima = np.copy(maxima) print('The state maxima have been evaluated through simulation.') # ### Plot of the state maxima # In[12]: for i in range(order): semilogy(u, maxima[i, :], 'o-', label=('State %d' % (i+1))) if not i: hold(True) grid(True) title('State Maxima'); ylabel('Peak value'); xlabel('DC input') xlim([0, 0.6]); ylim([1e-6, 10]); legend(loc=4); # ## Scaled modulator # ### Calculate the scaled coefficients # In[13]: ABCDs, umax, _ = scaleABCD(ABCD, N_sim=1e5) as_, gs, bs, cs = mapABCD(ABCDs) print('\nScaled modulator, umax = %.2f\n' % umax) # In[14]: t = Table() ilabels = ['#1', '#2', '#3', '#4', '#5', '#6'] t.append(['Coefficients', 'DAC feedback', 'Resonator feedback', 'Feed-in', 'Interstage']) t.append(['', 'a(n)', 'g(n)', ' b(n)', ' c(n)']) [t.append(x) for x in izip_longest(ilabels, as_.tolist(), gs.tolist(), bs.tolist(), cs.tolist(), fillvalue="")] t # ### Calculate the state maxima # In[15]: 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, _ = simulateDSM(ui*T, ABCDs) maxima[:, i] = xmax.squeeze() if any(xmax > 1e2): umax = ui; u = u[:i] maxima = maxima[:, :i] break print('The state maxima have been re-evaluated through simulation.') print("The maximum input was found to be %.6f" % umax) # ### Plot of the state maxima after scaling # In[16]: for i in range(order): semilogy(u, maxima[i, :], 'o-', label=('State %d' % (i+1))) if not i: hold(True) grid(True) title('State Maxima'); ylabel('Peak value'); xlabel('DC input') xlim([0, 0.6]); ylim([6e-2, 1.2]); legend(loc=4); # ### System version information # In[17]: #%install_ext http://raw.github.com/jrjohansson/version_information/master/version_information.py get_ipython().run_line_magic('load_ext', 'version_information') get_ipython().run_line_magic('reload_ext', 'version_information') get_ipython().run_line_magic('version_information', 'numpy, scipy, matplotlib, deltasigma')