@@ -36,6 +36,8 @@ class SAR(ADC):
36
36
Sets or returns the capacitor weighting of the array. Default is binary weighting.
37
37
mismatch : float
38
38
Sets or returns the stdev of the mismatch of the converter. Default is no mismatch.
39
+ comp_noise : float
40
+ Sets or returns the stdev of the comparator noise. Default is no noise.
39
41
offset : tuple of float
40
42
Sets the (mean, stdev) of the offset of the converter. Default is no offset.
41
43
gain_error : tuple of float
@@ -57,25 +59,28 @@ def __init__(self, nbits=8, fs=1, vref=1, seed=1, **kwargs):
57
59
super ().__init__ (nbits , fs , vref , seed )
58
60
59
61
self ._mismatch = None
62
+ self ._comp_noise = 0
60
63
61
64
# Get keyword arguments
62
65
self ._weights = kwargs .get ("weights" , None )
63
-
66
+
64
67
@property
65
68
def weights (self ):
66
69
"""Returns capacitor unit weights."""
67
70
if self ._weights is None :
68
- self ._weights = np .flip (2 ** np .linspace (0 , self .nbits - 1 , self .nbits ))
71
+ self ._weights = np .flip (2 ** np .linspace (0 , self .nbits - 1 , self .nbits ))
69
72
return np .array (self ._weights )
70
73
71
74
@weights .setter
72
75
def weights (self , values ):
73
76
"""Sets the capacitor unit weights."""
74
77
self ._weights = np .array (values )
75
78
if self ._weights .size < self .nbits :
76
- print (f"WARNING: Capacitor weight array size is { self ._weights .size } for { self .nbits } -bit ADC." )
79
+ print (
80
+ f"WARNING: Capacitor weight array size is { self ._weights .size } for { self .nbits } -bit ADC."
81
+ )
77
82
self .mismatch = self .err ["mismatch" ]
78
-
83
+
79
84
@property
80
85
def mismatch (self ):
81
86
"""Return noise stdev."""
@@ -90,24 +95,34 @@ def mismatch(self, stdev):
90
95
self ._mismatch = np .random .normal (0 , stdev , self .weights .size )
91
96
self ._mismatch /= np .sqrt (self .weights )
92
97
98
+ @property
99
+ def comp_noise (self ):
100
+ """Returns the noise of the comparator."""
101
+ return self ._comp_noise
102
+
103
+ @comp_noise .setter
104
+ def comp_noise (self , value ):
105
+ """Sets the noise of the comparator."""
106
+ self ._comp_noise = value
107
+
93
108
def run_step (self ):
94
109
"""Run a single ADC step."""
95
110
vinx = self .vin
96
-
111
+
97
112
cweights = self .weights * (1 + self .mismatch )
98
113
cdenom = sum (cweights ) + 1
99
-
100
- comp_noise = np .random .normal (0 , self .err [ "noise" ] , cweights .size )
101
-
114
+
115
+ comp_noise = np .random .normal (0 , self .comp_noise , cweights .size )
116
+
102
117
# Bit cycling
103
118
vdac = vinx
104
- for n in range ( len ( cweights ) ):
105
- vcomp = vdac - self .vref / 2
119
+ for n , _ in enumerate ( cweights ):
120
+ vcomp = vdac - self .vref / 2 + comp_noise [ n ]
106
121
compout = vcomp * 1e6
107
122
compout = - 1 if compout <= 0 else 1
108
123
self .dbits [n ] = max (0 , compout )
109
124
vdac -= compout * self .vref / 2 * cweights [n ] / cdenom
110
-
125
+
111
126
# Re-scale the data
112
127
scalar = 2 ** self .nbits / cdenom
113
- self .dval = min (2 ** self .nbits - 1 , scalar * sum (self .weights * self .dbits ))
128
+ self .dval = min (2 ** self .nbits - 1 , scalar * sum (self .weights * self .dbits ))
0 commit comments