milkymist/adc/__init__.py: CounterADC - simple counter-based ADC
authorWerner Almesberger <werner@almesberger.net>
Thu, 18 Apr 2013 16:33:25 +0000 (13:33 -0300)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Fri, 19 Apr 2013 10:29:17 +0000 (12:29 +0200)
This is a revised version of the counter-based ADC.

milkymist/adc/__init__.py [new file with mode: 0644]

diff --git a/milkymist/adc/__init__.py b/milkymist/adc/__init__.py
new file mode 100644 (file)
index 0000000..d4c790f
--- /dev/null
@@ -0,0 +1,57 @@
+from migen.fhdl.structure import *
+from migen.fhdl.module import Module
+from migen.bank.description import *
+from migen.genlib.misc import optree
+
+class CounterADC(Module, AutoCSR):
+       def __init__(self, charge, sense, width = 24):
+               if not isinstance(sense, collections.Iterable):
+                       sense = [sense]
+
+               channels = len(sense)
+
+               self._start_busy = CSR()
+               self._overflow = CSRStatus(channels)
+               self._polarity = CSRStorage()
+
+               count = Signal(width)
+               busy = Signal(channels)
+
+               res = []
+               for i in range(channels):
+                       res.append(CSRStatus(width, name="res"+str(i)))
+                       setattr(self, "_res"+str(i), res[-1])
+
+               any_busy = Signal()
+               self.comb += [
+                       any_busy.eq(optree("|",
+                           [busy[i] for i in range(channels)])),
+                       self._start_busy.w.eq(any_busy)
+               ]
+
+               carry = Signal()
+
+               self.sync += [
+                       If(self._start_busy.re,
+                               count.eq(0),
+                               busy.eq((1 << channels)-1),
+                               self._overflow.status.eq(0),
+                               charge.eq(~self._polarity.storage)
+                       ).Elif(any_busy,
+                               Cat(count, carry).eq(count + 1),
+                               If(carry,
+                                       self._overflow.status.eq(busy),
+                                       busy.eq(0)
+                               )
+                       ).Else(
+                               charge.eq(self._polarity.storage)
+                       )
+               ]
+
+               for i in range(channels):
+                       self.sync += If(busy[i],
+                               If(sense[i] != self._polarity.storage,
+                                       res[i].status.eq(count),
+                                       busy[i].eq(0)
+                               )
+                       )