soc/core/xadc: cleanup, simplify and add expose_drp method - keep CSR ordering with...
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Sat, 4 Jan 2020 22:59:04 +0000 (23:59 +0100)
committerbunnie <bunnie@kosagi.com>
Sun, 5 Jan 2020 01:13:14 +0000 (09:13 +0800)
litex/soc/cores/xadc.py

index 5244b8fe09e92093415add0c4b21c2c9de8fb991..551738ac6e5118a6fdca5198adddac759c330feb 100644 (file)
@@ -1,4 +1,6 @@
-# Copyright 2014-2015 Robert Jordens <jordens@gmail.com>
+# This file is Copyright (c) 2014-2015 Robert Jordens <jordens@gmail.com>
+# This file is Copyright (c) 2019 bunnie <bunnie@kosagi.com>
+# This file is Copyright (c) 2019 Florent Kermarrec <florent@enjoy-digital.fr>
 # License: BSD
 
 from migen import *
@@ -7,76 +9,45 @@ from litex.soc.interconnect.csr import *
 
 # XADC ---------------------------------------------------------------------------------------------
 
-analog_layout = [("vauxp", 16), ("vauxn", 16), ("vp", 1), ("vn", 1)]
-
 class XADC(Module, AutoCSR):
-    def __init__(self, analog=None):
-        # add a CSR bank for controlling the XADC DRP. Adds bloat to the gateware
-        # if you're not using this feature, but makes the code more elegant.
-        self.drp_enable = CSRStorage()  # must set this to 1 to use DRP, otherwise auto-sample
-        self.drp_read = CSR()
-        self.drp_write = CSR()
-        self.drp_drdy = CSRStatus()
-        self.drp_adr = CSRStorage(7)
-        self.drp_dat_w = CSRStorage(16)
-        self.drp_dat_r = CSRStatus(16)
-
-        # monitor EOC/EOS so we can poll if the ADC has been updated
-        self.eoc = CSRStatus()
-        self.eos = CSRStatus()
-        # TODO: hook up the alarm as interrupt
-
-        drp_drdy = Signal()
-
-        if analog == None:
-            analog = Record(analog_layout)
-            self.comb += [
-                analog.vauxp.eq(0),
-                analog.vauxn.eq(0),
-                analog.vp.eq(0),
-                analog.vn.eq(0),
-            ]
-
-        self.sync += [
-            If(self.drp_read.re | self.drp_write.re,
-               self.drp_drdy.status.eq(0)
-            ).Elif(drp_drdy,
-               self.drp_drdy.status.eq(1)
-            )
-        ]
-
+    def __init__(self):
         # Temperature(°C) = adc_value*503.975/4096 - 273.15
         self.temperature = CSRStatus(12)
 
-        # Voltage(V) =  as uadc_value*)/4096*3
+        # Voltage(V) = adc_value*)/4096*3
         self.vccint  = CSRStatus(12)
         self.vccaux  = CSRStatus(12)
         self.vccbram = CSRStatus(12)
 
+        # End of Convertion/Sequence
+        self.eoc = CSRStatus()
+        self.eos = CSRStatus()
+
         # Alarms
         self.alarm = Signal(8)
         self.ot    = Signal()
 
+        # Analog
+        self.analog = Record([("vauxp", 16), ("vauxn", 16), ("vp", 1), ("vn", 1)])
+        self.analog.vauxp.reset = 1
+        self.analog.vp.reset    = 1
+
         # # #
 
         busy    = Signal()
         channel = Signal(7)
         eoc     = Signal()
         eos     = Signal()
-        data    = Signal(16)
 
-        auto = Signal()
-        self.comb += auto.eq(~self.drp_enable.storage)
-        adr = Signal(7)
-        self.comb += [
-            If(auto,
-               adr.eq(channel),
-            ).Else(
-               adr.eq(self.drp_adr.storage)
-            )
-        ]
+        # XADC instance ----------------------------------------------------------------------------
+        self.dwe  = Signal()
+        self.den  = Signal()
+        self.drdy = Signal()
+        self.dadr = Signal(7)
+        self.di   = Signal(16)
+        self.do   = Signal(16)
         self.specials += Instance("XADC",
-            # from ug480
+            # From ug480
             p_INIT_40=0x9000, p_INIT_41=0x2ef0, p_INIT_42=0x0400,
             p_INIT_48=0x4701, p_INIT_49=0x000f,
             p_INIT_4A=0x4700, p_INIT_4B=0x0000,
@@ -87,39 +58,77 @@ class XADC(Module, AutoCSR):
             p_INIT_54=0xa93a, p_INIT_55=0x5111,
             p_INIT_56=0x91eb, p_INIT_57=0xae4e,
             p_INIT_58=0x5999, p_INIT_5C=0x5111,
-            o_ALM=self.alarm, o_OT=self.ot,
-            o_BUSY=busy, o_CHANNEL=channel, o_EOC=eoc, o_EOS=eos,
-            i_VAUXN=analog.vauxn, i_VAUXP=analog.vauxp, i_VN=analog.vn, i_VP=analog.vp,
-            i_CONVST=0, i_CONVSTCLK=0, i_RESET=ResetSignal(),
-            o_DO=data, o_DRDY=drp_drdy, i_DADDR=adr, i_DCLK=ClockSignal(),
-            i_DEN=(auto & eoc) | (~auto & (self.drp_read.re | self.drp_write.re)),
-            i_DI=self.drp_dat_w.storage, i_DWE=self.drp_write.re,
-            # o_JTAGBUSY=, o_JTAGLOCKED=, o_JTAGMODIFIED=, o_MUXADDR=,
+            o_ALM       = self.alarm,
+            o_OT        = self.ot,
+            o_BUSY      = busy,
+            o_CHANNEL   = channel,
+            o_EOC       = eoc,
+            o_EOS       = eos,
+            i_VAUXN     = self.analog.vauxn,
+            i_VAUXP     = self.analog.vauxp,
+            i_VN        = self.analog.vn,
+            i_VP        = self.analog.vp,
+            i_CONVST    = 0,
+            i_CONVSTCLK = 0,
+            i_RESET     = ResetSignal(),
+            i_DCLK      = ClockSignal(),
+            i_DWE       = self.dwe,
+            i_DEN       = self.den,
+            o_DRDY      = self.drdy,
+            i_DADDR     = self.dadr,
+            i_DI        = self.di,
+            o_DO        = self.do
         )
-        self.sync += [
-            If(drp_drdy,
-               self.drp_dat_r.status.eq(data),
-            ).Else(
-               self.drp_dat_r.status.eq(self.drp_dat_r.status),
-            )
-        ]
-
-        self.sync += [
-            self.eoc.status.eq((~self.eoc.we & self.eoc.status) | eoc),
-            self.eos.status.eq((~self.eos.we & self.eos.status) | eos),
+        self.comb += [
+            self.den.eq(eoc),
+            self.dadr.eq(channel),
         ]
 
+        # Channels update --------------------------------------------------------------------------
         channels = {
             0: self.temperature,
             1: self.vccint,
             2: self.vccaux,
             6: self.vccbram
         }
-
         self.sync += [
-                If(drp_drdy & auto,
+                If(self.drdy,
                     Case(channel, dict(
-                        (k, v.status.eq(data >> 4))
+                        (k, v.status.eq(self.do >> 4))
                     for k, v in channels.items()))
                 )
         ]
+
+        # End of Convertion/Sequence update --------------------------------------------------------
+        self.sync += [
+            self.eoc.status.eq((self.eoc.status & ~self.eoc.we) | eoc),
+            self.eos.status.eq((self.eos.status & ~self.eos.we) | eos),
+        ]
+
+    def expose_drp(self):
+        self.drp_enable = CSRStorage() # Set to 1 to use DRP and disable auto-sampling
+        self.drp_read   = CSR()
+        self.drp_write  = CSR()
+        self.drp_drdy   = CSRStatus()
+        self.drp_adr    = CSRStorage(7)
+        self.drp_dat_w  = CSRStorage(16)
+        self.drp_dat_r  = CSRStatus(16)
+
+        # # #
+
+        self.comb += [
+            self.dwe.eq(self.drp_write.re),
+            self.di.eq(self.drp_dat_w.storage),
+            self.drp_dat_r.status.eq(self.do),
+            If(self.drp_enable.storage,
+                self.den.eq(self.drp_read.re | self.drp_write.re),
+                self.dadr.eq(self.drp_adr.storage),
+            ),
+        ]
+        self.sync += [
+            If(self.drp_read.re | self.drp_write.re,
+                self.drp_drdy.status.eq(0)
+            ).Elif(self.drdy,
+                self.drp_drdy.status.eq(1)
+            )
+        ]