Abstract
In this chapter, switching schemes commonly employed in SAR ADCs are revisited and compared. A summary indicates that the CS scheme shows compelling features for LVLP applications. Finally, the state of the art in CS-ADCs is reviewed.
Access this chapter
Tax calculation will be finalised at checkout
Purchases are for personal use only
Notes
- 1.
Python is a widely used high-level, general-purpose, interpreted programming language that emphasizes code readability and allows programmers to express concepts in fewer lines of code. Open-source libraries are available to deal with numeric and symbolic computations.
References
J. McCreary, P. Gray, All-MOS charge redistribution analog-to-digital conversion techniques. I. IEEE J. Solid-State Circuits 10 (6), 371–379 (1975). doi:10.1109/JSSC.1975.1050629
C.-C. Liu, S.-J. Chang, G.-Y. Huang, Y.-Z. Lin, A 10-bit 50-MS/s SAR ADC with a monotonic capacitor switching procedure. IEEE J. Solid-State Circuits 45 (4), 731–740 (2010). doi:10.1109/JSSC.2010. 2042254
X. Song, Y. Xiao, Z. Zhu, VCM-based monotonic capacitor switching scheme for SAR ADC. Electron. Lett. 49 (5), 327–329, February 2013. doi:10.1049/el.2012.3332
V. Hariprasath, J. Guerber S.-H. Lee, U.-K. Moon, Merged capacitor switching based SAR ADC with highest switching energy-efficiency. Electron. Lett. 46 (9), 620 (2010). doi:10.1049/el.2010.0706
Y. Zhu, C.-H. Chan, U.-F. Chio, S.-W. Sin, U. Seng-Pan, R.P. Martins, F. Maloberti, A 10-bit 100-MS/s reference-free SAR ADC in 90 nm CMOS. IEEE J. Solid-State Circuits 45 (6), 1111–1121 (2010). doi:10.1109/JSSC.2010.2048498
E. Rahimi, M. Yavari, Energy-efficient high-accuracy switching method for SAR ADCs. Electron. Lett. 50 (7), 499–501 (2014). doi:10.1049/el.2013.3451
C. Yuan, Y. Lam, Low-energy and area-efficient tri-level switching scheme for SAR ADC. Electron. Lett. 48 (9), 482 (2012). doi:10.1049/el.2011.4001
J. Craninckx, G. van der Plas, A 65 fJ/conversion-step 0-to-50 MS/s 0- to-0.7 mW 9b charge-sharing SAR ADC in 90 nm digital CMOS, in IEEE International Solid-State Circuits Conference (ISSCC) IEEE, February 2007, pp. 246–600. doi: 10.1109/ISSCC.2007.373386
B. Malki, T. Yamamoto, B. Verbruggen, P. Wambacq, J. Craninckx, A 70 dB DR 10b 0-to-80 MS/s current-integrating SAR ADC with adaptive dynamic range”, in IEEE Int. Solid-State Circuits Conf (ISSCC) IEEE, February 2012, pp. 470–472. doi:1.1109/ISSCC.2012.6177095
V. Giannini, P. Nuzzo, V. Chironi, A. Baschirotto, G. Van der Plas, J. Craninckx, An 82 μw 9b 40 MS/s noise-tolerant dynamic-SAR ADC in 90 nm digital CMOS, in IEEE International Solid-State Circuits Conference (ISSCC) IEEE, February 2008, pp. 238–610. doi:10.1109/ISSCC.2008.4523145
J.-H. Tsai, Y.-J. Chen, M.-H. Shen, P.-C. Huang, 1-V, 8b, 40 MS/s, 113 μW charge-recycling SAR ADC with a 14 μW asynchronous controller, in IEEE Symposium VLSI Circuits 2011, pp. 264–265
B. Malki, T. Yamamoto, B. Verbruggen, P. Wambacq, J. Craninckx, A 70 dB DR 10b 0-to-80 MS/s current-integrating SAR ADC with adaptive dynamic range. IEEE J. Solid-State Circuits 49 (5), 1173–1183 (2014). doi:10.1109/JSSC.2014.2309086
Author information
Authors and Affiliations
Appendix: Voltage and Energy in CR ADCs
Appendix: Voltage and Energy in CR ADCs
We developed a simplified and a general model for calculation of voltage and energy in capacitive DAC topologies. These models were used for the calculations presented in this chapter. The Python codes for these models are given at the end of this appendix.
3.1.1 Models for Voltage and Energy in CR ADCs
We consider that the comparator inputs present infinite impedance and, therefore, drain no current from the DAC outputs. Following this assumption, the comparator is removed from the analysis, without compromising the accuracy of the models. Most of the switching schemes use only two voltage levels as reference voltages in the DAC arrangement, namely ground and VREF . For these topologies, we may rely on a simplified model to compute the DAC output voltage and the energy. Some other switching schemes, on the other hand, use another intermediate reference voltage, such as VCM . For the latter, we devise a general model that supports an arbitrary number of references and concurrent switching of multiple capacitors.
3.1.1.1 Simplified Voltage Model for CR DACs
Since the CR DACs are based on switched capacitors, they do not present static power consumption. Therefore, we are only interested in the power consumption that takes place in the transitions between states. The circuit in Fig. 3.19 provides a good representation of a CR DAC transitioning between arbitrary states. In the diagram, C T represents the sum of capacitances that has the bottom plate connected to VREF and remain in this condition during the transition. The capacitor C B represents the sum of capacitances with bottom plates connected to ground that is left unchanged during the transition. The remaining capacitor, C X, represents the capacitance being switched. The switch S 1 is initially connected to ground and is switched to VREF at time t = 0. All the voltages and currents on the circuit totally settle at time t s . We can discretize the time domain and define V X(0) ≡ V X[i − 1] and V X(t s ) ≡ V X[i]. Since there is no current path for the top plates of the capacitors, the charge at the node V X is conserved.
Equation (3.18) can be rewritten as follows:
Solving (3.19) for V X[i] leads to
Similarly, if C X is switched from VREF to ground, (3.20) becomes
To quantify the energy consumed from the reference source when S 1 switches ground to VREF , let us again consider the simple circuit of Fig. 3.19, assuming that at the instant t = 0, V X is equal to V X(0) and S 1 is disconnected from ground and connected to VREF . The energy spent to switch the bottom plate of C X to VREF is given in (3.22), considering that VREF is a dc voltage source and the current flowing through its terminals is IREF .
The current IREF can be described in terms of the charge drainded to the capacitors connected to VREF . This is seen in (3.23), where \(Q_{C_{\mathrm{X}}}\) and \(Q_{C_{\mathrm{T}}}\) are the charges stored in C X and C T, respectively.
Rewriting (3.22) in terms of (3.23) yields in
Integrating, we arrive at
Solving (3.27) leads to
Plugging (3.20) into (3.28) yields in
Equations (3.20) and (3.29) may be readily used to calculate the top-plate voltage and the energy in the DAC topologies based on the principle of charge redistribution, respectively, if only VREF and ground are employed as references. Additionally, the model is only valid if only one capacitor is switched at each transition.
3.1.1.2 General Voltage Model for CR DACs
In order to develop a broader model, consider the capacitive array in Fig. 3.20, where the bottom plates of k capacitors are switched at the same time from their initial voltages \(V _{0}[i - 1],V _{1}[i - 1]\ldots V _{k}[i - 1]\) to arbitrary voltage levels V 0[i], V 1[i]… V k [i]. Again, the principle of charge conservation holds, and the charge of the i-th cycle is the same as the previous cycle:
By expanding (3.30) similarly as in (3.18) and solving for V X[i], we arrive at (3.31).
By collecting the similar terms together, (3.31) may be rewritten as (3.32), wherein N indicates the total number of reference sources employed.
In order to compute the energy, we assume that the only voltage levels allowed on the bottom plates of the capacitors are the reference voltages. This simplification does not pose any limitation on the analysis, as this happens naturally in a charge-redistribution DAC. These voltages may comprehend any finite number of voltage sources V REF0, V REF1 … V REF, k , even though practical implementations of charge-redistribution DACs use 2 or 3 (i.e., VDD , ground and the common-mode voltage VCM ). In the model for voltage in the DAC, we considered that the capacitances are fixed and that the voltages on their bottom plates vary in time. On the other hand, for the energy model, we will use the assumption of fixed and known voltage levels and compute the variation of the capacitance connected to each one of those voltage sources. This analogy is depicted in Fig. 3.21 and simplifies the calculation of energy when multiple references or capacitors are switched concurrently. Also, this change of standpoint is not harmful to the analysis because we care most about the amount of energy that is spent from VREF , and have limited interest in the distribution of currents among the capacitors.
For every state-transition in the DAC, the capacitance connected to a given voltage source V REF, j can be split up into two components: C j, s, which is the capacitance that was maintained static since the previous cycle; and C j, d, which is the capacitance that was just connected to the reference voltage in the current cycle. Additionally, C j, d is further subdivided according to the voltage that was previously applied to the bottom plate of these capacitors, so that C j, d1 corresponds to all the capacitors previously connected to V REF1, C j, d2 corresponds to all the capacitors previously connected to V REF2, and so on. Note that if a capacitor is disconnected from the voltage source in the transition of states, it does not contribute to its energy consumption. The assignment of capacitance values is exemplified for V REF0 in Fig. 3.22.
At each cycle, the energy drawn from V REF, j is the sum of the energies spent to charge C j, s and C j, d0, C j, d1 … C j, d, k . Thus, the energy consumed in the i-th cycle is given by
Following a similar reasoning to that presented in Sect. 3.6.5, (3.33) may be rewritten as
By solving and simplifying, we arrive at
The total energy consumed during a transition is found summing the contribution of all the reference sources.
Therefore, (3.32), (3.35), and (3.36) can be employed in order to find the total energy consumption and the contribution of all the reference sources in the ADC.
The general model requires solving slightly more complicated equations than the proposed simplified model to compute the energy of switching schemes. On the other hand, this general model is easier to be implemented algorithmically on a computer, which makes it a good alternative to automate the computations. One of the advantages of automating the calculations is that it makes easier to extend the analysis to new switching schemes as they appear. Based on the general model, we wrote a software library that takes care of the low-level computations once the switching scheme is algorithmically described. This library was employed to perform the behavioral simulations and extract the results of Chap. 3 The codes are listed in the next section.
Codes
Listing 3.1 cap_array.py
1 # -*- coding: utf-8 -*-
2 """
3 Generalized model of energy and voltage in a CR DAC.
4 @author: Taimur Rabuske
5 """
6
7 class cap_array:
8 def __init__(self):
9 self.ct=0
10 self.cb=0
11 self.c=dict([])
12 self.v=dict([])
13 #Add ground node
14 self.v["gnd"]={"value":0,"energy":0}
15 self.prev_vout=0
16 self.vout=0
17
18 #Add a capacitor to the array
19 def addC(self,name,value,initial="gnd"):
20 self.c[name]={"value":value, "node":initial, "initial":initial}
21 return 0
22
23 #Add a voltage source (reference) to the array.
24 def addV(self,name,value, energy=0):
25 self.v[name]={"value":value, "energy":energy}
26
27 #Reset all bottom plates to their initial conditions
28 def resetAll(self):
29 for cap in self.c:
30 self.c[cap]["node"]= self.c[cap]["initial"]
31
32 #Sample a voltage into the top plate
33 def sampleTopPlate(self,vin):
34 self.vout=vin
35 return vin
36
37 #Process the charge. The input of this function is a pair of values in the form [C,N], where C is the name of the capacitor to be switched, and N is the node to which it is switched, e.g. Vref or gnd. The method returns the DAC voltage and energy spent in the current cycle.
38 def switchC(self,*args):
39 #Store previous voltage to the prev_node key in the dictionary.
40 for i in self.c:
41 self.c[i]["prev_node"]=self.c[i]["node"]
42 #Connect capacitances to assigned nodes
43 for i in args:
44 cap=i[0]
45 v=i[1]
46 if v not in self.v:
47 print "Voltage␣source␣does␣not␣exist"
48 self.c[cap]["node"]=v
49
50 # Compute the new voltage in the DAC, given by:
51 # x
52 # ___
53 # \
54 # \ (V_DAC0.C0(i) + C(i).V_ref(i) - C0(i).V_ref0(i))
55 # /
56 # /__
57 #
58 # i = 0
59 # V_DAC= ______________________________________________________
60 # x
61 # ___
62 # \
63 # \ C(i)
64 # /
65 # /__
66 #
67 # i = 0
68 tmp=0
69 #compute the summation in the numerator
70 for i in self.c:
71 tmp=tmp + self.c[i]["value"] * (self.v[self.c[i]["node"]]["value"] - self.v[self.c[i]["prev_node"]]["value"] + self.vout)
72 #compute denominator
73 c_total=sum([self.c[j]["value"] for j in self.c])
74 #store previous dac voltage
75 self.prev_vout=self.vout
76 #set output voltage
77 self.vout=tmp/c_total
78
79 #Calculate the energy spent in charging the DAC
80 E=dict([])
81 E_total=0
82 #Enumerate all the capacitors connected to each one of the voltage sources, and calculate all the parameters for each one of them.
83 for vs in self.v:
84 #c_just_connected is an array with all the capacitors that were connected on the actual clock cycle
85 c_just_connected=[]
86 #c_still is the capacitance that was already connected on previous cycle
87 c_still=[]
88 #find C_just_connected and c_still
89 for cap in self.c:
90 if self.c[cap]["node"]==vs:
91 if self.c[cap]["prev_node"]==vs:
92 c_still.append(self.c[cap])
93 else:
94 c_just_connected.append(self.c[cap])
95 c_still_sum=sum([k["value"] for k in c_still])
96 #E_still is the energy required to move the already connected capacitors from V_dac0 to V_dac
97 E_still= self.v[vs]["value"] * c_still_sum * (self.prev_vout-(self.vout))
98 #E_just_connected is the energy required to charge the bottom plate of the just connected capacitor from the previous voltage (e.g. ground) to the reference voltage.
99 E_just_connected=0
100 for j in c_just_connected:
101 E_just_connected= E_just_connected - self.v[vs]["value"]*j["value"] * (self.vout-self.v[vs]["value"] - (self.prev_vout-self.v[j["prev_node"]] ["value"]))
102 E[vs]=E_just_connected+E_still
103 #E_total is the total energy drained from all the reference sources.
104 E_total=E_total+E[vs]
105 self.v[vs]["energy"]=self.v[vs]["energy"]+E[vs]
106 return self.vout,E_total
Listing 3.2 sar_adc_conventional.py
1 #!/usr/bin/env python2.7
2 # -*- coding: utf-8 -*-
3 """
4 Model of Conventional CR SAR switching scheme
5 @author: Taimur Rabuske
6 """
7
8 from __future__ import division
9 from sympy import symbols, simplify
10 from cap_array import cap_array
11
12 class sar_adc_conventional:
13 def __init__(self,Vref=1.0,bits=3,Cu=1e-15):
14 self.Vref=Vref
15 self.bits=bits
16 self.Cu=Cu
17 self.cap_arrayP=cap_array()
18 self.cap_arrayN=cap_array()
19 self.cap_arrayP.addV("vref",self.Vref)
20 self.cap_arrayN.addV("vref",self.Vref)
21 self.cap_arrayP.addC("dummy",self.Cu,"gnd")
22 self.cap_arrayN.addC("dummy",self.Cu,"vref")
23 for i in xrange(self.bits):
24 self.cap_arrayP.addC(i,2**i*self.Cu,"gnd")
25 self.cap_arrayN.addC(i,2**i*self.Cu,"vref")
26 def convert(self,Vin,return_dac=0):
27 out=0
28 Etot=0
29 dac=[]
30 step=-1
31 self.cap_arrayP.resetAll()
32 self.cap_arrayN.resetAll()
33 VdacP=self.cap_arrayP.sampleTopPlate(-Vin/2-self.Vref/2)
34 VdacN=self.cap_arrayN.sampleTopPlate(Vin/2+self.Vref/2)
35 dac.append([step,"sample",self.Vref/2,self.Vref/2])
36 step=step+1
37 switch_backP=0
38 switch_backN=0
39 for k in range(self.bits-1,-1,-1):
40 if switch_backP:
41 VdacP,EP=self.cap_arrayP.switchC([k,"vref"], switch_backP)
42 VdacN,EN=self.cap_arrayN.switchC([k,"gnd"], switch_backN)
43 else:
44 VdacP,EP=self.cap_arrayP.switchC([k,"vref"])
45 VdacN,EN=self.cap_arrayN.switchC([k,"gnd"])
46 if VdacP-VdacN<0:
47 out=out+2**k
48 switch_backP=0
49 switch_backN=0
50 else:
51 switch_backP=[k,"gnd"]
52 switch_backN=[k,"vref"]
53 Etot=Etot+EP+EN
54 dac.append([step,"b_"+str(k), self.Vref/2+VdacP, self.Vref/2+VdacN])
55 step=step+1
56 dac.append([step,"", self.Vref/2+VdacP, self.Vref/2+VdacN])
57 if return_dac:
58 return dac
59 else:
60 return out,Etot
Listing 3.3 sar_adc_mcs.py
1 #!/usr/bin/env python2.7
2 # -*- coding: utf-8 -*-
3 """
4 Model of MCS CR SAR switching scheme
5 @author: Taimur Rabuske
6 """
7 from __future__ import division
8 from sympy import symbols, simplify
9 from cap_array import cap_array
10
11 class sar_adc_mcs:
12 def __init__(self,Vref=1.0,bits=3,Cu=1e-15):
13 vref,vin=symbols("vref,vin")
14 self.Vref=Vref
15 vref=self.Vref
16 self.bits=bits
17 self.Cu=Cu
18 self.cap_arrayP=cap_array()
19 self.cap_arrayN=cap_array()
20 self.cap_arrayP.addV("vref",self.Vref)
21 self.cap_arrayN.addV("vref",self.Vref)
22 self.cap_arrayP.addV("vcm",self.Vref/2)
23 self.cap_arrayN.addV("vcm",self.Vref/2)
24 self.cap_arrayP.addC("dummy",self.Cu,"vcm")
25 self.cap_arrayN.addC("dummy",self.Cu,"vcm")
26 for i in xrange(self.bits-1):
27 self.cap_arrayP.addC(i,2**i*self.Cu,"vcm")
28 self.cap_arrayN.addC(i,2**i*self.Cu,"vcm")
29 def convert(self,Vin,return_dac=0):
30 out=0
31 Etot=0
32 dac=[]
33 step=0
34 self.cap_arrayP.resetAll()
35 self.cap_arrayN.resetAll()
36 VdacP=self.cap_arrayP.sampleTopPlate(Vin/2)
37 VdacN=self.cap_arrayN.sampleTopPlate(-Vin/2)
38 dac.append([step, "+b_9", self.Vref/2+VdacP, self.Vref/2+VdacN])
39 step=step+1
40 for k in range(self.bits-2,-1,-1):
41 if VdacP-VdacN<0:
42 VdacP,EP=self.cap_arrayP.switchC([k,"vref"])
43 VdacN,EN=self.cap_arrayN.switchC([k,"gnd"])
44 else:
45 out=out+2**(k+1)
46 VdacP,EP=self.cap_arrayP.switchC([k,"gnd"])
47 VdacN,EN=self.cap_arrayN.switchC([k,"vref"])
48 Etot=Etot+EP+EN
49 dac.append([step, "b_"+str(k), self.Vref/2+VdacP, self.Vref/2+VdacN])
50 step=step+1
51 dac.append([step,"", self.Vref/2+VdacP, self.Vref/2+VdacN])
52 if VdacP-VdacN>0:
53 out=out+2**0
54 if return_dac:
55 return dac
56 else:
57 return out,Etot
Listing 3.4 sar_adc_monotonic.py
1 #!/usr/bin/env python2.7
2 # -*- coding: utf-8 -*-
3 """
4 Model of Monotonic CR SAR switching scheme
5 @author: Taimur Rabuske
6 """
7 from __future__ import division
8 from sympy import symbols, simplify
9 from cap_array import cap_array
10
11 class sar_adc_monotonic:
12 def __init__(self,Vref=1.0,bits=3,Cu=1e-15):
13 self.Vref=Vref
14 self.bits=bits
15 self.Cu=Cu
16 self.cap_arrayP=cap_array()
17 self.cap_arrayN=cap_array()
18 self.cap_arrayP.addV("vref",self.Vref)
19 self.cap_arrayN.addV("vref",self.Vref)
20 self.cap_arrayP.addC("dummy",self.Cu,"vref")
21 self.cap_arrayN.addC("dummy",self.Cu,"vref")
22 for i in xrange(self.bits-1):
23 self.cap_arrayP.addC(i,2**i*self.Cu,"vref")
24 self.cap_arrayN.addC(i,2**i*self.Cu,"vref")
25 def convert(self,Vin,return_dac=0):
26 out=0
27 Etot=0
28 dac=[]
29 step=0
30 self.cap_arrayP.resetAll()
31 self.cap_arrayN.resetAll()
32 VdacP=self.cap_arrayP.sampleTopPlate(-Vin/2)
33 VdacN=self.cap_arrayN.sampleTopPlate(Vin/2)
34 dac.append([step,"+b_9", self.Vref/2+VdacP, self.Vref/2+VdacN])
35 step=step+1
36 for k in range(self.bits-2,-1,-1):
37 if VdacP-VdacN<0:
38 out=out+2**(k+1)
39 VdacN,EN=self.cap_arrayN.switchC([k,"gnd"])
40 EP=0
41 else:
42 VdacP,EP=self.cap_arrayP.switchC([k,"gnd"])
43 EN=0
44 Etot=Etot+EP+EN
45 dac.append([step,"b_"+str(k), self.Vref/2+VdacP, self.Vref/2+VdacN])
46 step=step+1
47 dac.append([step,"", self.Vref/2+VdacP, self.Vref/2+VdacN])
48 if VdacP-VdacN<0:
49 out=out+2**0
50 if return_dac:
51 return dac
52 else:
53 return out,Etot
Listing 3.5 sar_adc_cs.py
1 #!/usr/bin/env python2.7
2 # -*- coding: utf-8 -*-
3 """
4 Model of CS SAR switching scheme
5 @author: Taimur Rabuske
6 """
7 from __future__ import division
8 from sympy import symbols, simplify
9
10 class sar_adc_cs:
11 def __init__(self,Vref=1.0,bits=3,Cu=1e-15):
12 self.Vref=Vref
13 self.bits=bits
14 self.Cu=Cu
15 self.Cth=2**(bits-1)*Cu
16 self.c=[]
17 for i in xrange(self.bits-1):
18 self.c.append(2**i*self.Cu)
19 def convert(self,Vin,return_dac=0):
20 out=0
21 Etot=0
22 dac=[]
23 step=0
24 Qth=self.Cth*Vin
25 Qtotal=Qth
26 Ctotal=self.Cth
27 Vdac=Vin
28 dac.append([step,"+b_9", self.Vref/2+Vin/2, self.Vref/2-Vin/2])
29 step=step+1
30 Etot=sum(self.c)*(self.Vref)**2
31 for k in range(self.bits-2,-1,-1):
32 if Vdac>0:
33 out=out+2**(k+1)
34 Qtotal=Qtotal-self.c[k]*self.Vref
35 Ctotal=Ctotal+self.c[k]
36 else:
37 Qtotal=Qtotal+self.c[k]*self.Vref
38 Ctotal=Ctotal+self.c[k]
39 Vdac=Qtotal/Ctotal
40 dac.append([step,"b_"+str(k), self.Vref/2+Vdac/2, self.Vref/2-Vdac/2])
41 step=step+1
42 dac.append([step,"", self.Vref/2+Vdac/2, self.Vref/2-Vdac/2])
43 if Vdac>0:
44 out=out+2**0
45 if return_dac:
46 return dac
47 else:
48 return out,Etot
Listing 3.6 sim_e.py
1 #!/usr/bin/env python2.7
2 # -*- coding: utf-8 -*-
3 """
4 Script used to simulate the energy of the SAR ADCs as function of the output codes.
5 @author: Taimur Rabuske
6 """
7
8 from __future__ import division
9 import numpy
10 import matplotlib.pyplot as plt
11 from sar_adc_conventional import sar_adc_conventional
12 from sar_adc_monotonic import sar_adc_monotonic
13 from sar_adc_mcs import sar_adc_mcs
14 from sar_adc_cs import sar_adc_cs
15 from multiprocessing import Pool, Lock
16
17 #Simulation parameters
18 samplingrate=1000.0e3
19 fin=54.6875e3
20 pts=2048
21 window="no"
22
23 #ADC characteristics
24 BITS=10
25 VREF=1.0
26
27 sar_adc_conventional=sar_adc_conventional(bits=BITS, Vref=VREF, Cu=1)
28 sar_adc_monotonic=sar_adc_monotonic(bits=BITS, Vref=VREF, Cu=1)
29 sar_adc_mcs=sar_adc_mcs(bits=BITS, Vref=VREF, Cu=1)
30 sar_adc_cs=sar_adc_cs(bits=BITS, Vref=VREF, Cu=1)
31
32 #mp=multiprocessing
33 mp=1
34 plot_results=1
35
36 PTS_SIM=2**BITS
37
38 y=numpy.linspace(-VREF, VREF, num=PTS_SIM)
39
40 print "\n\nSimulating␣ADCs..."
41 def convert_adc(zipped_args):
42 adc_instance,argument= zipped_args
43 result,E=adc_instance.convert(argument)
44 return result,E
45
46 pool=Pool(processes=8)
47 if mp:
48 out_conventional=pool.map(convert_adc, zip(len(y)*[sar_adc_conventional], y))
49 out_monotonic=pool.map(convert_adc, zip(len(y)*[sar_adc_monotonic], y))
50 out_mcs=pool.map(convert_adc, zip(len(y)*[sar_adc_mcs], y))
51 out_cs=pool.map(convert_adc, zip(len(y)*[sar_adc_cs], y))
52 else:
53 out_conventional=map(convert_adc, zip(len(y)*[sar_adc_conventional], y))
54 out_monotonic=map(convert_adc, zip(len(y)*[sar_adc_monotonic], y))
55 out_mcs=map(convert_adc, zip(len(y)*[sar_adc_mcs], y))
56 out_cs=map(convert_adc, zip(len(y)*[sar_adc_cs], y))
57 out_sar_adc_conventional= numpy.transpose(out_conventional)[0]
58 out_sar_adc_monotonic= numpy.transpose(out_monotonic)[0]
59 out_sar_adc_mcs= numpy.transpose(out_mcs)[0]
60 out_sar_adc_cs= numpy.transpose(out_cs)[0]
61 E_conventional= numpy.transpose(out_conventional)[1]
62 E_monotonic= numpy.transpose(out_monotonic)[1]
63 E_mcs= numpy.transpose(out_mcs)[1]
64 E_cs= numpy.transpose(out_cs)[1]
65
66 numpy.savetxt("E_conventional.csv", E_conventional, delimiter=",")
67 numpy.savetxt("E_monotonic.csv", E_monotonic, delimiter=",")
68 numpy.savetxt("E_mcs.csv", E_mcs, delimiter=",")
69 numpy.savetxt("E_cs.csv", E_cs, delimiter=",")
70
71 if plot_results:
72 plt.figure(0)
73 plt.xlabel("Vin␣(V)")
74 plt.ylabel("Dout")
75 plt.subplot(211)
76 plt.plot(y,out_sar_adc_conventional)
77 plt.plot(y,out_sar_adc_monotonic)
78 plt.plot(y,out_sar_adc_mcs)
79 plt.plot(y,out_sar_adc_cs)
80 plt.grid(True)
81 plt.subplot(212)
82 plt.plot(out_sar_adc_conventional,E_conventional)
83 plt.plot(out_sar_adc_monotonic,E_monotonic)
84 plt.plot(out_sar_adc_mcs,E_mcs)
85 plt.plot(out_sar_adc_conventional,E_cs)
86 plt.grid(True)
87 plt.show()
Listing 3.7 sim_wf.py
1 #!/usr/bin/env python2.7
2 # -*- coding: utf-8 -*-
3 """
4 Script used to plot the waveforms for a given input voltage.
5 @author: Taimur Rabuske
6 """
7
8 from __future__ import division
9 import numpy
10 from sar_adc_conventional import sar_adc_conventional
11 from sar_adc_monotonic import sar_adc_monotonic
12 from sar_adc_mcs import sar_adc_mcs
13 from sar_adc_cs import sar_adc_cs
14
15 from multiprocessing import Pool, Lock
16
17 #Simulation parameters
18 samplingrate=1000.0e3
19 fin=54.6875e3
20 pts=2048
21 window="no"
22
23 #ADC characteristics
24 BITS=8
25 VREF=1.0
26
27 sar_adc_conventional=sar_adc_conventional(bits=BITS, Vref=VREF, Cu=1)
28 sar_adc_monotonic=sar_adc_monotonic(bits=BITS, Vref=VREF, Cu=1)
29 sar_adc_mcs=sar_adc_mcs(bits=BITS, Vref=VREF, Cu=1)
30 sar_adc_cs=sar_adc_cs(bits=BITS, Vref=VREF, Cu=1)
31
32 #mp=multiprocessing
33 mp=1
34
35 PTS_SIM=2**BITS
36
37 # ADC input voltage to simulate
38 y=0.8
39
40 print "\n\nSimulating␣ADCs..."
41
42 dac_conventional=sar_adc_conventional.convert(y,return_dac=1)
43 dac_monotonic=sar_adc_monotonic.convert(y,return_dac=1)
44 dac_mcs=sar_adc_mcs.convert(y,return_dac=1)
45 dac_cs=sar_adc_cs.convert(y,return_dac=1)
46
47 numpy.savetxt("dac_conventional.csv", dac_conventional, delimiter=",", fmt="%s")
48 numpy.savetxt("dac_monotonic.csv", dac_monotonic, delimiter=",", fmt="%s")
49 numpy.savetxt("dac_mcs.csv", dac_mcs, delimiter=",", fmt="%s")
50 numpy.savetxt("dac_cs.csv", dac_cs, delimiter=",", fmt="%s")
Rights and permissions
Copyright information
© 2017 Springer International Publishing Switzerland
About this chapter
Cite this chapter
Rabuske, T., Fernandes, J. (2017). Review of SAR ADC Switching Schemes. In: Charge-Sharing SAR ADCs for Low-Voltage Low-Power Applications . Analog Circuits and Signal Processing. Springer, Cham. https://doi.org/10.1007/978-3-319-39624-8_3
Download citation
DOI: https://doi.org/10.1007/978-3-319-39624-8_3
Published:
Publisher Name: Springer, Cham
Print ISBN: 978-3-319-39623-1
Online ISBN: 978-3-319-39624-8
eBook Packages: EngineeringEngineering (R0)