Skip to main content

Part of the book series: Analog Circuits and Signal Processing ((ACSP))

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.

This is a preview of subscription content, log in via an institution to check access.

Access this chapter

Chapter
USD 29.95
Price excludes VAT (USA)
  • Available as PDF
  • Read on any device
  • Instant download
  • Own it forever
eBook
USD 84.99
Price excludes VAT (USA)
  • Available as EPUB and PDF
  • Read on any device
  • Instant download
  • Own it forever
Softcover Book
USD 109.99
Price excludes VAT (USA)
  • Compact, lightweight edition
  • Dispatched in 3 to 5 business days
  • Free shipping worldwide - see info
Hardcover Book
USD 109.99
Price excludes VAT (USA)
  • Durable hardcover edition
  • Dispatched in 3 to 5 business days
  • Free shipping worldwide - see info

Tax calculation will be finalised at checkout

Purchases are for personal use only

Institutional subscriptions

Notes

  1. 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

  1. 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

  2. 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

    Article  Google Scholar 

  3. 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

  4. 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

  5. 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

  6. 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

    Article  Google Scholar 

  7. 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

  8. 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

  9. 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

    Google Scholar 

  10. 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

  11. 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

    Google Scholar 

  12. 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

Download references

Author information

Authors and Affiliations

Authors

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.

$$\displaystyle{ Q_{X}[0] = Q_{X}[1]. }$$
(3.18)
Fig. 3.19
figure 19

Circuit representation of a CR DAC transitioning between arbitrary states

Equation (3.18) can be rewritten as follows:

$$\displaystyle\begin{array}{rcl} & & C_{\mathrm{X}}V _{\mathrm{X}}[i - 1] + C_{\mathrm{T}}\left (V _{\mathrm{X}}[i - 1] - V _{\mathrm{REF}}\right ) + C_{\mathrm{B}}V _{\mathrm{X}}[i - 1] \\ & & \qquad = C_{\mathrm{X}}\left (V _{\mathrm{X}}[i] - V _{\mathrm{REF}}\right ) + C_{\mathrm{T}}\left (V _{\mathrm{X}}[i] - V _{\mathrm{REF}}\right ) + C_{\mathrm{B}}V _{\mathrm{X}}[i].{}\end{array}$$
(3.19)

Solving (3.19) for V X[i] leads to

$$\displaystyle{ V _{\mathrm{X}}[i] = V _{\mathrm{X}}[i - 1] + \frac{C_{\mathrm{X}}} {C_{\mathrm{X}} + C_{\mathrm{T}} + C_{\mathrm{B}}}V _{\mathrm{REF}}. }$$
(3.20)

Similarly, if C X is switched from VREF to ground, (3.20) becomes

$$\displaystyle{ V _{\mathrm{X}}[i] = V _{\mathrm{X}}[i - 1] - \frac{C_{\mathrm{X}}} {C_{\mathrm{X}} + C_{\mathrm{T}} + C_{\mathrm{B}}}V _{\mathrm{REF}}. }$$
(3.21)

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 .

$$\displaystyle{ E_{\mathrm{REF}} = V _{\mathrm{REF}}\int _{0}^{t_{s} }I_{\mathrm{REF}}\mathrm{\,}dt. }$$
(3.22)

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.

$$\displaystyle{ I_{\mathrm{REF}}(t) = -\left (\frac{\mathrm{d}Q_{C_{\mathrm{X}}}} {\mathrm{d}t} + \frac{\mathrm{d}Q_{C_{\mathrm{T}}}} {\mathrm{d}t} \right ). }$$
(3.23)

Rewriting (3.22) in terms of (3.23) yields in

$$\displaystyle\begin{array}{rcl} E_{\mathrm{REF}}\left [i\right ] = -V _{\mathrm{REF}}\int _{0}^{t_{s} }\left (\frac{\mathrm{d}Q_{C_{\mathrm{X}}}} {\mathrm{d}t} + \frac{\mathrm{d}Q_{C_{\mathrm{T}}}} {\mathrm{d}t} \right )\mathrm{d}t& &{}\end{array}$$
(3.24)
$$\displaystyle\begin{array}{rcl} = -V _{\mathrm{REF}}\left (\int _{Q_{C_{ \mathrm{X}}}(0)}^{Q_{C_{\mathrm{X}}}(t_{s})}\mathrm{d}Q_{ C_{\mathrm{X}}} +\int _{ Q_{C_{\mathrm{T}}}(0)}^{Q_{C_{\mathrm{T}}}(t_{s})}\mathrm{d}Q_{ C_{\mathrm{T}}}\right ).& &{}\end{array}$$
(3.25)

Integrating, we arrive at

$$\displaystyle\begin{array}{rcl} E_{\mathrm{REF}}\left [i\right ]& =& -V _{\mathrm{REF}}\left [\left (Q_{C_{\mathrm{X}}}[i] - Q_{C_{\mathrm{X}}}[i - 1]\right ) + \left (Q_{C_{\mathrm{T}}}[i] - Q_{C_{\mathrm{T}}}[i - 1]\right )\right ].{}\end{array}$$
(3.26)
$$\displaystyle\begin{array}{rcl} E_{\mathrm{REF}}\left [i\right ]& =& -V _{\mathrm{REF}}C_{\mathrm{X}}\left [\left (V _{\mathrm{X}}(t_{s}) - V _{\mathrm{REF}}\right ) -\left (V _{\mathrm{X}}[i - 1]\right )\right ] \\ & & -V _{\mathrm{REF}}C_{\mathrm{T}}\left [\left (V _{\mathrm{X}}[i] - V _{\mathrm{REF}}\right ) -\left (V _{\mathrm{X}}[i - 1] - V _{\mathrm{REF}}\right )\right ].{}\end{array}$$
(3.27)

Solving (3.27) leads to

$$\displaystyle{ E_{\mathrm{REF}}\left [i\right ] = V _{\mathrm{REF}}C_{\mathrm{X}}\left (V _{\mathrm{REF}} + V _{\mathrm{X}}[i - 1] - V _{\mathrm{X}}[i]\right )+V _{\mathrm{REF}}C_{\mathrm{T}}\left (V _{\mathrm{X}}[i - 1] - V _{\mathrm{X}}[i]\right ). }$$
(3.28)

Plugging (3.20) into (3.28) yields in

$$\displaystyle{ E_{\mathrm{REF}}\left [i\right ] = \frac{C_{\mathrm{B}}C_{\mathrm{X}}} {C_{\mathrm{B}} + C_{\mathrm{T}} + C_{\mathrm{X}}}V _{\mathrm{REF}}^{2}. }$$
(3.29)

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:

$$\displaystyle{ Q_{X}[i] = Q_{X}[i - 1]. }$$
(3.30)
Fig. 3.20
figure 20

Circuit used to develop the general voltage model for CR DACs

By expanding (3.30) similarly as in (3.18) and solving for V X[i], we arrive at (3.31).

$$\displaystyle\begin{array}{rcl} V _{\mathrm{X}}[i] = \frac{C_{0}\left (V _{0}[i] - V _{0}[i - 1] + V _{\mathrm{X}}[i - 1]\right ) +\ldots +C_{k}\left (V _{k}[i] - V _{k}[i - 1] + V _{\mathrm{X}}[i - 1]\right )} {C_{0} + C_{1} +\ldots +C_{k}}.& &{}\end{array}$$
(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.

$$\displaystyle{ V _{\mathrm{X}}[i] = \dfrac{\sum _{j=0}^{N-1}C_{j}(V _{\mathrm{X}}[i - 1] + V _{j}[i] - V _{j}[i - 1])} {\sum _{j=0}^{N-1}C_{j}}. }$$
(3.32)

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.

Fig. 3.21
figure 21

Circuit used to develop the general energy model for CR DACs

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.

Fig. 3.22
figure 22

Example of capacitance values assignment for V REF0

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

$$\displaystyle{ E_{\mathrm{REF},j}[i] = E_{j,\mathrm{s}}[i] +\sum \limits _{ k=0}^{N-1}E_{ j,\mathrm{d},k}[i]. }$$
(3.33)

Following a similar reasoning to that presented in Sect. 3.6.5, (3.33) may be rewritten as

$$\displaystyle{ E_{\mathrm{REF},j}[i] = -V _{\mathrm{REF},j}\left (\int _{Q_{C_{ j,\mathrm{s}}}[i-1]}^{Q_{C_{j,s}}[i]}\mathrm{d}Q_{ C_{j,s}} +\sum \limits _{ k=0}^{N-1}\int _{ Q_{C_{j,\mathrm{d},k}}[i-1]}^{Q_{C_{j,\mathrm{d},k}}[i]}\mathrm{d}Q_{ C_{j,\mathrm{d},k}}\right ). }$$
(3.34)

By solving and simplifying, we arrive at

$$\displaystyle\begin{array}{rcl} & & E_{\mathrm{REF},j}[i] = -V _{\mathrm{REF},j}\left (C_{j,\mathrm{s}}\left (V _{\mathrm{X}}[i - 1] - V _{\mathrm{X}}[i]\right ) +\sum \limits _{ k=0}^{N-1}C_{ j,\mathrm{d},k}\left (V _{j,\mathrm{d},k}[i - 1]\right.\right. \\ & & \qquad \qquad \left.\left.+V _{\mathrm{X}}[i] - V _{\mathrm{X}}[i - 1] - V _{\mathrm{REF},j}\right )\right ). {}\end{array}$$
(3.35)

The total energy consumed during a transition is found summing the contribution of all the reference sources.

$$\displaystyle{ E_{\mathrm{total}} =\sum \limits _{ j=0}^{N-1}E_{\mathrm{ REF},j}. }$$
(3.36)

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

Reprints 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)

Publish with us

Policies and ethics