#!/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("%.6f | " % col)
except(ValueError):
html.append("%s | " % col)
html.append("
")
html.append("
")
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')