cores/xadc: Re-arrange and simplify code a bit.

This commit is contained in:
Florent Kermarrec 2023-02-10 10:08:16 +01:00
parent 92032b446c
commit 8b36649c89
1 changed files with 197 additions and 168 deletions

View File

@ -2,7 +2,7 @@
# This file is part of LiteX. # This file is part of LiteX.
# #
# Copyright (c) 2014-2015 Robert Jordens <jordens@gmail.com> # Copyright (c) 2014-2015 Robert Jordens <jordens@gmail.com>
# Copyright (c) 2019-2021 Florent Kermarrec <florent@enjoy-digital.fr> # Copyright (c) 2019-2023 Florent Kermarrec <florent@enjoy-digital.fr>
# Copyright (c) 2019 bunnie <bunnie@kosagi.com> # Copyright (c) 2019 bunnie <bunnie@kosagi.com>
# Copyright (c) 2021 Vamsi K Vytla <vamsi.vytla@gmail.com> # Copyright (c) 2021 Vamsi K Vytla <vamsi.vytla@gmail.com>
# Copyright (c) 2022 Sylvain Munaut <tnt@246tNt.com> # Copyright (c) 2022 Sylvain Munaut <tnt@246tNt.com>
@ -10,15 +10,28 @@
from migen import * from migen import *
from litex.gen import LiteXModule
from litex.soc.interconnect.csr import * from litex.soc.interconnect.csr import *
# Layouts ----------------------------------------------------------------------------------------- # Layouts -----------------------------------------------------------------------------------------
analog_layout = [("vauxp", 16), ("vauxn", 16), ("vp", 1), ("vn", 1)] analog_layout = [("vauxp", 16), ("vauxn", 16), ("vp", 1), ("vn", 1)]
# Xilinx System Monitor DRP ------------------------------------------------------------------------ # Xilinx System Monitor ----------------------------------------------------------------------------
class XilinxSystemMonitorChannel:
def __init__(self, name, addr, bits, desc):
self.name = name
self.addr = addr
self.bits = bits
self.desc = "\n".join(desc) if isinstance(desc, list) else desc
class XilinxSystemMonitor(LiteXModule):
def add_channel(self, channel):
setattr(self, channel.name, CSRStatus(channel.bits, name=channel.name, description=channel.desc))
channel.status = getattr(self, channel.name).status
class SystemMonitorDRP(Module, AutoCSR):
def expose_drp(self): def expose_drp(self):
self.drp_enable = CSRStorage() # Set to 1 to use DRP and disable auto-sampling. self.drp_enable = CSRStorage() # Set to 1 to use DRP and disable auto-sampling.
self.drp_read = CSR() self.drp_read = CSR()
@ -53,25 +66,34 @@ class SystemMonitorDRP(Module, AutoCSR):
# Xilinx 7-Series System Monitor ------------------------------------------------------------------- # Xilinx 7-Series System Monitor -------------------------------------------------------------------
class S7SystemMonitor(SystemMonitorDRP, AutoCSR): S7SystemMonitorChannels = [
dadr_size = 7 XilinxSystemMonitorChannel(name="temperature", addr=0x0, bits=12, desc=[
"Raw Temperature value from XADC.",
"Temperature (°C) = ``Value`` x 503.975 / 4096 - 273.15.",
]),
XilinxSystemMonitorChannel(name="vccint", addr=0x1, bits=12, desc=[
"Raw VCCINT value from XADC.",
"VCCINT (V) = ``Value`` x 3 / 4096.",
]),
XilinxSystemMonitorChannel(name="vccaux", addr=0x2, bits=12, desc=[
"Raw VCCAUX value from XADC.",
"VCCAUX (V) = ``Value`` x 3 / 4096.",
]),
XilinxSystemMonitorChannel(name="vccbram", addr=0x6, bits=12, desc=[
"Raw VCCBRAM value from XADC.",
"VCCBRAM (V) = ``Value`` x 3 / 4096.",
]),
]
def __init__(self, analog_pads=None): class S7SystemMonitor(XilinxSystemMonitor):
# Temperature def __init__(self, channels=S7SystemMonitorChannels, analog_pads=None):
self.temperature = CSRStatus(12, description="""Raw Temperature value from XADC.\n # Channels.
Temperature (°C) = ``Value`` x 503.975 / 4096 - 273.15.""") for channel in channels:
self.add_channel(channel)
# Voltages
self.vccint = CSRStatus(12, description="""Raw VCCINT value from XADC.\n
VCCINT (V) = ``Value`` x 3 / 4096.""")
self.vccaux = CSRStatus(12, description="""Raw VCCAUX value from XADC.\n
VCCAUX (V) = ``Value`` x 3 / 4096.""")
self.vccbram = CSRStatus(12, description="""Raw VCCBRAM value from XADC.\n
VCCBRAM (V) = ``Value`` x 3 / 4096.""")
# End of Convertion/Sequence # End of Convertion/Sequence
self.eoc = CSRStatus(description="End of Convertion Status, ``1``: Convertion Done.") self.eoc = CSRStatus(description="End of Convertion Status, ``1``: Convertion Done.")
self.eos = CSRStatus(description="End of Sequence Status, ``1``: Sequence Done.") self.eos = CSRStatus(description="End of Sequence Status, ``1``: Sequence Done.")
# Alarms # Alarms
self.alarm = Signal(8) self.alarm = Signal(8)
@ -85,25 +107,25 @@ class S7SystemMonitor(SystemMonitorDRP, AutoCSR):
eos = Signal() eos = Signal()
# XADC instance. # XADC instance.
self.dwe = Signal() self.dwe = Signal()
self.den = Signal() self.den = Signal()
self.drdy = Signal() self.drdy = Signal()
self.dadr = Signal(7) self.dadr = Signal(7)
self.di = Signal(16) self.di = Signal(16)
self.do = Signal(16) self.do = Signal(16)
self.drp_en = Signal() self.drp_en = Signal()
self.specials += Instance("XADC", self.specials += Instance("XADC",
# From UG480 # From UG480
p_INIT_40=0x9000, p_INIT_41=0x2ef0, p_INIT_42=0x0400, p_INIT_40 = 0x9000, p_INIT_41 = 0x2ef0, p_INIT_42 = 0x0400,
p_INIT_48=0x4701, p_INIT_49=0x000f, p_INIT_48 = 0x4701, p_INIT_49 = 0x000f,
p_INIT_4A=0x4700, p_INIT_4B=0x0000, p_INIT_4A = 0x4700, p_INIT_4B = 0x0000,
p_INIT_4C=0x0000, p_INIT_4D=0x0000, p_INIT_4C = 0x0000, p_INIT_4D = 0x0000,
p_INIT_4E=0x0000, p_INIT_4F=0x0000, p_INIT_4E = 0x0000, p_INIT_4F = 0x0000,
p_INIT_50=0xb5ed, p_INIT_51=0x5999, p_INIT_50 = 0xb5ed, p_INIT_51 = 0x5999,
p_INIT_52=0xa147, p_INIT_53=0xdddd, p_INIT_52 = 0xa147, p_INIT_53 = 0xdddd,
p_INIT_54=0xa93a, p_INIT_55=0x5111, p_INIT_54 = 0xa93a, p_INIT_55 = 0x5111,
p_INIT_56=0x91eb, p_INIT_57=0xae4e, p_INIT_56 = 0x91eb, p_INIT_57 = 0xae4e,
p_INIT_58=0x5999, p_INIT_5C=0x5111, p_INIT_58 = 0x5999, p_INIT_5C = 0x5111,
o_ALM = self.alarm, o_ALM = self.alarm,
o_OT = self.ot, o_OT = self.ot,
o_BUSY = busy, o_BUSY = busy,
@ -116,8 +138,8 @@ class S7SystemMonitor(SystemMonitorDRP, AutoCSR):
i_VN = 0 if analog_pads is None else analog_pads.vn, i_VN = 0 if analog_pads is None else analog_pads.vn,
i_CONVST = 0, i_CONVST = 0,
i_CONVSTCLK = 0, i_CONVSTCLK = 0,
i_RESET = ResetSignal(), i_RESET = ResetSignal("sys"),
i_DCLK = ClockSignal(), i_DCLK = ClockSignal("sys"),
i_DWE = self.dwe, i_DWE = self.dwe,
i_DEN = self.den, i_DEN = self.den,
o_DRDY = self.drdy, o_DRDY = self.drdy,
@ -125,49 +147,58 @@ class S7SystemMonitor(SystemMonitorDRP, AutoCSR):
i_DI = self.di, i_DI = self.di,
o_DO = self.do o_DO = self.do
) )
self.comb += [
If(~self.drp_en, # DRP.
self.den.eq(eoc), self.comb += If(~self.drp_en,
self.dadr.eq(channel), self.den.eq(eoc),
) self.dadr.eq(channel),
] )
# Channels update. # Channels update.
channels = { channel_cases = dict(zip(
0x0 : self.temperature, [c.addr for c in channels],
0x1 : self.vccint, [c.status.eq(self.do >> 4) for c in channels],
0x2 : self.vccaux, ))
0x6 : self.vccbram self.sync += If(self.drdy, Case(channel, channel_cases))
}
self.sync += [
If(self.drdy,
Case(channel, dict(
(k, v.status.eq(self.do >> 4))
for k, v in channels.items()))
)
]
# End of Convertion/Sequence update. # End of Conversion/Sequence update.
self.sync += [ self.sync += [
self.eoc.status.eq((self.eoc.status & ~self.eoc.we) | eoc), self.eoc.status.eq((self.eoc.status & ~self.eoc.we) | eoc),
self.eos.status.eq((self.eos.status & ~self.eos.we) | eos), self.eos.status.eq((self.eos.status & ~self.eos.we) | eos),
] ]
class XADC(S7SystemMonitor): pass class XADC(S7SystemMonitor): pass # For compat.
# Xilinx Ultrascale System Monitor ----------------------------------------------------------------- # Xilinx Ultrascale System Monitor -----------------------------------------------------------------
class USFamilySystemMonitor(SystemMonitorDRP, AutoCSR): USSystemMonitorChannels = [
dadr_size = 8 XilinxSystemMonitorChannel(name="temperature", addr=0x0, bits=10, desc=[
"Raw Temperature value from SYSMONE1.",
"Temperature (°C) = ``Value`` x 503.975 / 1024 - 273.15.",
]),
XilinxSystemMonitorChannel(name="vccint", addr=0x1, bits=10, desc=[
"Raw VCCINT value from SYSMONE1.",
"VCCINT (V) = ``Value`` x 3 / 1024.",
]),
XilinxSystemMonitorChannel(name="vccaux", addr=0x2, bits=10, desc=[
"Raw VCCAUX value from SYSMONE1.",
"VCCAUX (V) = ``Value`` x 3 / 1024.",
]),
XilinxSystemMonitorChannel(name="vccbram", addr=0x6, bits=10, desc=[
"Raw VCCBRAM value from SYSMONE1.",
"VCCBRAM (V) = ``Value`` x 3 / 1024.",
]),
]
def __init__(self, analog_pads=None): class USSystemMonitor(XilinxSystemMonitor):
# Channels CSRs def __init__(self, channels=USSystemMonitorChannels, primitive="SYSMONE1", sim_device="ULTRASCALE", analog_pads=None):
for reg_addr, name, desc in self._channels: # Channels.
setattr(self, name, CSRStatus(10, name=name, description=desc)) for channel in channels:
self.add_channel(channel)
# End of Convertion/Sequence # End of Convertion/Sequence
self.eoc = CSRStatus(description="End of Conversion Status, ``1``: Conversion Done.") self.eoc = CSRStatus(description="End of Conversion Status, ``1``: Conversion Done.")
self.eos = CSRStatus(description="End of Sequence Status, ``1``: Sequence Done.") self.eos = CSRStatus(description="End of Sequence Status, ``1``: Sequence Done.")
# Alarms # Alarms
self.alarm = Signal(16) self.alarm = Signal(16)
@ -176,71 +207,68 @@ class USFamilySystemMonitor(SystemMonitorDRP, AutoCSR):
# # # # # #
busy = Signal() busy = Signal()
channel = Signal(self.dadr_size) channel = Signal(8)
eoc = Signal() eoc = Signal()
eos = Signal() eos = Signal()
# SYSMONE1 instance ------------------------------------------------------------------------ # SYSMOM instance.
self.dwe = Signal() self.dwe = Signal()
self.den = Signal() self.den = Signal()
self.drdy = Signal() self.drdy = Signal()
self.dadr = Signal(self.dadr_size) self.dadr = Signal(8)
self.di = Signal(16) self.di = Signal(16)
self.do = Signal(16) self.do = Signal(16)
self.drp_en = Signal() self.drp_en = Signal()
self.params = dict()
params = dict( if sim_device is not None:
self.params.update(p_SIM_DEVICE=sim_device)
self.params.update(
# From UG580 # From UG580
p_INIT_40=0x9000, p_INIT_41=0x2fd0, p_INIT_42=0x1000, p_INIT_40 = 0x9000, p_INIT_41 = 0x2fd0, p_INIT_42 = 0x1000,
p_INIT_46=0x000f, p_INIT_48=0x4701, p_INIT_49=0x000f, p_INIT_46 = 0x000f, p_INIT_48 = 0x4701, p_INIT_49 = 0x000f,
p_INIT_47=0x000f, p_INIT_4A=0x47e0, p_INIT_4B=0x0000, p_INIT_47 = 0x000f, p_INIT_4A = 0x47e0, p_INIT_4B = 0x0000,
p_INIT_4C=0x0000, p_INIT_4D=0x0000, p_INIT_4C = 0x0000, p_INIT_4D = 0x0000,
p_INIT_4E=0x0000, p_INIT_4F=0x0000, p_INIT_4E = 0x0000, p_INIT_4F = 0x0000,
p_INIT_50=0xb5ed, p_INIT_51=0x5999, p_INIT_50 = 0xb5ed, p_INIT_51 = 0x5999,
p_INIT_52=0xa147, p_INIT_53=0xdddd, p_INIT_52 = 0xa147, p_INIT_53 = 0xdddd,
p_INIT_54=0xa93a, p_INIT_55=0x5111, p_INIT_54 = 0xa93a, p_INIT_55 = 0x5111,
p_INIT_56=0x91eb, p_INIT_57=0xae4e, p_INIT_56 = 0x91eb, p_INIT_57 = 0xae4e,
p_INIT_58=0x5999, p_INIT_5C=0x5111, p_INIT_58 = 0x5999, p_INIT_5C = 0x5111,
o_ALM = self.alarm, o_ALM = self.alarm,
o_OT = self.ot, o_OT = self.ot,
o_BUSY = busy, o_BUSY = busy,
o_CHANNEL = channel, o_CHANNEL = channel,
o_EOC = eoc, o_EOC = eoc,
o_EOS = eos, o_EOS = eos,
i_VAUXP = 0 if analog_pads is None else analog_pads.vauxp, i_VAUXP = 0 if analog_pads is None else analog_pads.vauxp,
i_VAUXN = 0 if analog_pads is None else analog_pads.vauxn, i_VAUXN = 0 if analog_pads is None else analog_pads.vauxn,
i_VP = 0 if analog_pads is None else analog_pads.vp, i_VP = 0 if analog_pads is None else analog_pads.vp,
i_VN = 0 if analog_pads is None else analog_pads.vn, i_VN = 0 if analog_pads is None else analog_pads.vn,
i_CONVST = 0, i_CONVST = 0,
i_CONVSTCLK = 0, i_CONVSTCLK = 0,
i_RESET = ResetSignal(), i_RESET = ResetSignal("sys"),
i_DCLK = ClockSignal(), i_DCLK = ClockSignal("sys"),
i_DWE = self.dwe, i_DWE = self.dwe,
i_DEN = self.den, i_DEN = self.den,
o_DRDY = self.drdy, o_DRDY = self.drdy,
i_DADDR = self.dadr, i_DADDR = self.dadr,
i_DI = self.di, i_DI = self.di,
o_DO = self.do o_DO = self.do
) )
if self._sim_device is not None: self.specials += Instance(primitive, self.params)
params['p_SIM_DEVICE'] = self._sim_device
self.specials += Instance(self._block_name, **params)
self.comb += [ # DRP.
If(~self.drp_en, self.comb += If(~self.drp_en,
self.den.eq(eoc), self.den.eq(eoc),
self.dadr.eq(channel), self.dadr.eq(channel),
) )
]
# Channels update. # Channels update.
self.sync += [ channel_cases = dict(zip(
If(self.drdy, [c.addr for c in channels],
Case(channel, dict( [c.status.eq((self.do >> 6) & 0x3ff) for c in channels],
(reg_addr, getattr(self, name).status.eq((self.do >> 6) & 0x3ff)) ))
for reg_addr, name, desc in self._channels)) self.sync += If(self.drdy, Case(channel, channel_cases))
)
]
# End of Convertion/Sequence update. # End of Convertion/Sequence update.
self.sync += [ self.sync += [
@ -248,55 +276,56 @@ class USFamilySystemMonitor(SystemMonitorDRP, AutoCSR):
self.eos.status.eq((self.eos.status & ~self.eos.we) | eos), self.eos.status.eq((self.eos.status & ~self.eos.we) | eos),
] ]
# Xilinx Ultrascale+ System Monitor ----------------------------------------------------------------- # Xilinx Ultrascale Plus System Monitor ------------------------------------------------------------
class USSystemMonitor(USFamilySystemMonitor): USPSystemMonitorChannels = [
XilinxSystemMonitorChannel(name="temperature", addr=0x0, bits=10, desc=[
"Raw Temperature value from SYSMONE4.",
"Temperature (°C) = ``Value`` x 507.5921310 / 1024 - 279.42657680."
]),
XilinxSystemMonitorChannel(name="vccint", addr=0x1, bits=10, desc=[
"Raw VCCINT value from SYSMONE4.",
"VCCINT (V) = ``Value`` x 3 / 1024."
]),
XilinxSystemMonitorChannel(name="vccaux", addr=0x2, bits=10, desc=[
"Raw VCCAUX value from SYSMONE4.",
"VCCAUX (V) = ``Value`` x 3 / 1024."
]),
XilinxSystemMonitorChannel(name="vccbram", addr=0x6, bits=10, desc=[
"Raw VCCBRAM value from SYSMONE4.",
"VCCBRAM (V) = ``Value`` x 3 / 1024."
]),
]
_block_name = 'SYSMONE1' ZynqUSPSystemMonitorChannels = USPSystemMonitorChannels + [
_sim_device = None XilinxSystemMonitorChannel(name="vccpsintlp", addr=0xd, bits=10, desc=[
_channels = [ "Raw VCCPSINTLP value from SYSMONE4.",
( 0x0, 'temperature', "VCCPSINTLP (V) = ``Value`` x 3 / 1024.",
"Raw Temperature value from SYSMONE1.\n Temperature (°C) = ``Value`` x 503.975 / 1024 - 273.15."), ]),
( 0x1, 'vccint', XilinxSystemMonitorChannel(name="vccpsintfp", addr=0xe, bits=10, desc=[
"Raw VCCINT value from SYSMONE1.\n VCCINT (V) = ``Value`` x 3 / 1024."), "Raw VCCPSINTFP value from SYSMONE4.",
( 0x2, 'vccaux', "VCCPSINTFP (V) = ``Value`` x 3 / 1024.",
"Raw VCCAUX value from SYSMONE1.\n VCCAUX (V) = ``Value`` x 3 / 1024."), ]),
( 0x6, 'vccbram', XilinxSystemMonitorChannel(name="vccpsaux", addr=0xf, bits=10, desc=[
"Raw VCCBRAM value from SYSMONE1.\n VCCBRAM (V) = ``Value`` x 3 / 1024."), "Raw VCCPSAUX value from SYSMONE4.",
] "VCCPSAUX (V) = ``Value`` x 3 / 1024.",
]),
]
class USPSystemMonitor(USFamilySystemMonitor): class USPSystemMonitor(USSystemMonitor):
def __init__(self, analog_pads=None):
USSystemMonitor.__init__(self,
channels = USPSystemMonitorChannels,
primitive = "SYSMONE4",
sim_device = "ULTRASCALE_PLUS",
analog_pads = analog_pads,
)
_block_name = 'SYSMONE4' class ZyncUSPSystemMonitor(USSystemMonitor):
_sim_device = 'ULTRASCALE_PLUS' def __init__(self, analog_pads=None):
_channels = [ USSystemMonitor.__init__(self,
( 0x0, 'temperature', channels = ZyncUSPSystemMonitorChannels,
"Raw Temperature value from SYSMONE4.\n Temperature (°C) = ``Value`` x 507.5921310 / 1024 - 279.42657680."), primitive = "SYSMONE4",
( 0x1, 'vccint', sim_device = "ZYNQ_ULTRASCALE",
"Raw VCCINT value from SYSMONE4.\n VCCINT (V) = ``Value`` x 3 / 1024."), analog_pads = analog_pads,
( 0x2, 'vccaux', )
"Raw VCCAUX value from SYSMONE4.\n VCCAUX (V) = ``Value`` x 3 / 1024."),
( 0x6, 'vccbram',
"Raw VCCBRAM value from SYSMONE4.\n VCCBRAM (V) = ``Value`` x 3 / 1024."),
]
class ZynqUSPSystemMonitor(USFamilySystemMonitor):
_block_name = 'SYSMONE4'
_sim_device = 'ZYNQ_ULTRASCALE'
_channels = [
( 0x0, 'temperature',
"Raw Temperature value from SYSMONE4.\n Temperature (°C) = ``Value`` x 507.5921310 / 1024 - 279.42657680."),
( 0x1, 'vccint',
"Raw VCCINT value from SYSMONE4.\n VCCINT (V) = ``Value`` x 3 / 1024."),
( 0x2, 'vccaux',
"Raw VCCAUX value from SYSMONE4.\n VCCAUX (V) = ``Value`` x 3 / 1024."),
( 0x6, 'vccbram',
"Raw VCCBRAM value from SYSMONE4.\n VCCBRAM (V) = ``Value`` x 3 / 1024."),
( 0xd, 'vccpsintlp',
"Raw VCCPSINTLP value from SYSMONE4.\n VCCPSINTLP (V) = ``Value`` x 3 / 1024."),
( 0xe, 'vccpsintfp',
"Raw VCCPSINTFP value from SYSMONE4.\n VCCPSINTFP (V) = ``Value`` x 3 / 1024."),
( 0xf, 'vccpsaux',
"Raw VCCPSAUX value from SYSMONE4.\n VCCPSAUX (V) = ``Value`` x 3 / 1024."),
]