From 71f7ce6a5772773164294a77ee99d9d83312be70 Mon Sep 17 00:00:00 2001 From: Vamsi Vytla Date: Tue, 2 Mar 2021 20:31:52 -0800 Subject: [PATCH 1/6] soc/cores/ussysmon.py: Xilinx XADC like thingy for UltraScale devices --- litex/soc/cores/ussysmon.py | 147 ++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 litex/soc/cores/ussysmon.py diff --git a/litex/soc/cores/ussysmon.py b/litex/soc/cores/ussysmon.py new file mode 100644 index 000000000..04dc8d099 --- /dev/null +++ b/litex/soc/cores/ussysmon.py @@ -0,0 +1,147 @@ + +from migen import * + +from litex.soc.interconnect.csr import * + +# SYSMONE1 --------------------------------------------------------------------------------------------- + +analog_layout = [("vauxp", 16), ("vauxn", 16), ("vp", 1), ("vn", 1)] + +class USSYSMON(Module, AutoCSR): + def __init__(self, analog_pads=None): + # Temperature + self.temperature = CSRStatus(10, description="""Raw Temperature value from SYSMONE1.\n + Temperature (°C) = ``Value`` x 503.975 / 1024 - 273.15.""") + + # Voltages + self.vccint = CSRStatus(10, description="""Raw VCCINT value from SYSMONE1.\n + VCCINT (V) = ``Value`` x 3 / 1024.""") + self.vccaux = CSRStatus(10, description="""Raw VCCAUX value from SYSMONE1.\n + VCCAUX (V) = ``Value`` x 3 / 1024.""") + self.vccbram = CSRStatus(10, description="""Raw VCCBRAM value from SYSMONE1.\n + VCCBRAM (V) = ``Value`` x 3 / 1024.""") + self.vccpsintlp = CSRStatus(10, description="""Raw VCCPSINTLP value from SYSMONE1.\n + VCCPSINTLP (V) = ``Value`` x 3 / 1024.""") + self.vccpsintfp = CSRStatus(10, description="""Raw VCCPSINTFP value from SYSMONE1.\n + VCCPSINTFP (V) = ``Value`` x 3 / 1024.""") + self.vccpsaux = CSRStatus(10, description="""Raw VCCPSAUX value from SYSMONE1.\n + VCCPSAUX (V) = ``Value`` x 3 / 1024.""") + + # End of Convertion/Sequence + self.eoc = CSRStatus(description="End of Conversion Status, ``1``: Conversion Done.") + self.eos = CSRStatus(description="End of Sequence Status, ``1``: Sequence Done.") + + # Alarms + self.alarm = Signal(16) + self.ot = Signal() + + # # # + + busy = Signal() + channel = Signal(7) + eoc = Signal() + eos = Signal() + + # SYSMONE1 instance ---------------------------------------------------------------------------- + self.dwe = Signal() + self.den = Signal() + self.drdy = Signal() + self.dadr = Signal(7) + self.di = Signal(16) + self.do = Signal(16) + self.drp_en = Signal() + self.specials += Instance("SYSMONE1", + # From ug580 + 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_47=0x000f, p_INIT_4A=0x47e0, p_INIT_4B=0x0000, + p_INIT_4C=0x0000, p_INIT_4D=0x0000, + p_INIT_4E=0x0000, p_INIT_4F=0x0000, + p_INIT_50=0xb5ed, p_INIT_51=0x5999, + p_INIT_52=0xa147, p_INIT_53=0xdddd, + 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_VAUXP = 0 if analog_pads is None else analog_pads.vauxp, + 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_VN = 0 if analog_pads is None else analog_pads.vn, + 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.comb += [ + If(~self.drp_en, + self.den.eq(eoc), + self.dadr.eq(channel), + ) + ] + + # Channels update -------------------------------------------------------------------------- + channels = { + 0: self.temperature, + 1: self.vccint, + 2: self.vccaux, + 6: self.vccbram, + 0xd: self.vccpsintlp, + 0xe: self.vccpsintfp, + 0xf: self.vccpsaux, + } + 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 -------------------------------------------------------- + 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, reset_less=True) + self.drp_dat_w = CSRStorage(16, reset_less=True) + self.drp_dat_r = CSRStatus(16) + + # # # + + den_pipe = Signal() # add a register to ease timing closure of den + + self.comb += [ + self.di.eq(self.drp_dat_w.storage), + self.drp_dat_r.status.eq(self.do), + If(self.drp_en, + self.den.eq(den_pipe), + self.dadr.eq(self.drp_adr.storage), + ) + ] + self.sync += [ + self.dwe.eq(self.drp_write.re), + self.drp_en.eq(self.drp_enable.storage), + den_pipe.eq(self.drp_read.re | self.drp_write.re), + If(self.drp_read.re | self.drp_write.re, + self.drp_drdy.status.eq(0) + ).Elif(self.drdy, + self.drp_drdy.status.eq(1) + ) + ] From 922f85e64b5609eb74012d7bc7d883756276fe46 Mon Sep 17 00:00:00 2001 From: Vamsi Vytla Date: Wed, 3 Mar 2021 10:50:58 -0800 Subject: [PATCH 2/6] litex/soc/cores/ussysmon.py: ADC transfer function --- litex/soc/cores/ussysmon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/litex/soc/cores/ussysmon.py b/litex/soc/cores/ussysmon.py index 04dc8d099..9fd4da3c4 100644 --- a/litex/soc/cores/ussysmon.py +++ b/litex/soc/cores/ussysmon.py @@ -103,7 +103,7 @@ class USSYSMON(Module, AutoCSR): self.sync += [ If(self.drdy, Case(channel, dict( - (k, v.status.eq(self.do >> 4)) + (k, v.status.eq(self.do >> 6)) for k, v in channels.items())) ) ] From 1793efb50b85cc2ef847b31801d3d22258819e84 Mon Sep 17 00:00:00 2001 From: Vamsi Vytla Date: Wed, 3 Mar 2021 14:38:27 -0800 Subject: [PATCH 3/6] litex/soc/cores/ussysmon.py: dadr address space bump --- litex/soc/cores/ussysmon.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/litex/soc/cores/ussysmon.py b/litex/soc/cores/ussysmon.py index 9fd4da3c4..62e8140da 100644 --- a/litex/soc/cores/ussysmon.py +++ b/litex/soc/cores/ussysmon.py @@ -46,7 +46,7 @@ class USSYSMON(Module, AutoCSR): self.dwe = Signal() self.den = Signal() self.drdy = Signal() - self.dadr = Signal(7) + self.dadr = Signal(8) self.di = Signal(16) self.do = Signal(16) self.drp_en = Signal() @@ -103,7 +103,7 @@ class USSYSMON(Module, AutoCSR): self.sync += [ If(self.drdy, Case(channel, dict( - (k, v.status.eq(self.do >> 6)) + (k, v.status.eq((self.do >> 6) & 0x3ff)) for k, v in channels.items())) ) ] @@ -119,7 +119,7 @@ class USSYSMON(Module, AutoCSR): self.drp_read = CSR() self.drp_write = CSR() self.drp_drdy = CSRStatus() - self.drp_adr = CSRStorage(7, reset_less=True) + self.drp_adr = CSRStorage(8, reset_less=True) self.drp_dat_w = CSRStorage(16, reset_less=True) self.drp_dat_r = CSRStatus(16) From ae5f67f6f0316cd173a8ac34da2b13048f8d45e2 Mon Sep 17 00:00:00 2001 From: Vamsi Vytla Date: Wed, 3 Mar 2021 14:47:52 -0800 Subject: [PATCH 4/6] litex/soc/cores/ussysmon.py: minor bug --- litex/soc/cores/ussysmon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/litex/soc/cores/ussysmon.py b/litex/soc/cores/ussysmon.py index 62e8140da..0616ce836 100644 --- a/litex/soc/cores/ussysmon.py +++ b/litex/soc/cores/ussysmon.py @@ -38,7 +38,7 @@ class USSYSMON(Module, AutoCSR): # # # busy = Signal() - channel = Signal(7) + channel = Signal(8) eoc = Signal() eos = Signal() From 647d3eb51a4f93a286a4ecb689f256e655dc4402 Mon Sep 17 00:00:00 2001 From: Vamsi Vytla Date: Sat, 6 Mar 2021 08:14:13 -0800 Subject: [PATCH 5/6] soc/cores/xadc.py: Move ussysmon here --- litex/soc/cores/xadc.py | 160 ++++++++++++++++++++++++++++++++++------ 1 file changed, 137 insertions(+), 23 deletions(-) diff --git a/litex/soc/cores/xadc.py b/litex/soc/cores/xadc.py index 3760d2ab7..f74c507e8 100644 --- a/litex/soc/cores/xadc.py +++ b/litex/soc/cores/xadc.py @@ -14,7 +14,43 @@ from litex.soc.interconnect.csr import * analog_layout = [("vauxp", 16), ("vauxn", 16), ("vp", 1), ("vn", 1)] -class XADC(Module, AutoCSR): +class _XADC(Module, AutoCSR): + 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(self.dadr_size, reset_less=True) + self.drp_dat_w = CSRStorage(16, reset_less=True) + self.drp_dat_r = CSRStatus(16) + + # # # + + den_pipe = Signal() # add a register to ease timing closure of den + + self.comb += [ + self.di.eq(self.drp_dat_w.storage), + self.drp_dat_r.status.eq(self.do), + If(self.drp_en, + self.den.eq(den_pipe), + self.dadr.eq(self.drp_adr.storage), + ) + ] + self.sync += [ + self.dwe.eq(self.drp_write.re), + self.drp_en.eq(self.drp_enable.storage), + den_pipe.eq(self.drp_read.re | self.drp_write.re), + If(self.drp_read.re | self.drp_write.re, + self.drp_drdy.status.eq(0) + ).Elif(self.drdy, + self.drp_drdy.status.eq(1) + ) + ] + + +class XADC(_XADC, AutoCSR): + dadr_size = 7 + def __init__(self, analog_pads=None): # Temperature self.temperature = CSRStatus(12, description="""Raw Temperature value from XADC.\n @@ -112,34 +148,112 @@ class XADC(Module, AutoCSR): 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, reset_less=True) - self.drp_dat_w = CSRStorage(16, reset_less=True) - self.drp_dat_r = CSRStatus(16) + +class USSYSMON(_XADC, AutoCSR): + dadr_size = 8 + + def __init__(self, analog_pads=None): + # Temperature + self.temperature = CSRStatus(10, description="""Raw Temperature value from SYSMONE1.\n + Temperature (°C) = ``Value`` x 503.975 / 1024 - 273.15.""") + + # Voltages + self.vccint = CSRStatus(10, description="""Raw VCCINT value from SYSMONE1.\n + VCCINT (V) = ``Value`` x 3 / 1024.""") + self.vccaux = CSRStatus(10, description="""Raw VCCAUX value from SYSMONE1.\n + VCCAUX (V) = ``Value`` x 3 / 1024.""") + self.vccbram = CSRStatus(10, description="""Raw VCCBRAM value from SYSMONE1.\n + VCCBRAM (V) = ``Value`` x 3 / 1024.""") + self.vccpsintlp = CSRStatus(10, description="""Raw VCCPSINTLP value from SYSMONE1.\n + VCCPSINTLP (V) = ``Value`` x 3 / 1024.""") + self.vccpsintfp = CSRStatus(10, description="""Raw VCCPSINTFP value from SYSMONE1.\n + VCCPSINTFP (V) = ``Value`` x 3 / 1024.""") + self.vccpsaux = CSRStatus(10, description="""Raw VCCPSAUX value from SYSMONE1.\n + VCCPSAUX (V) = ``Value`` x 3 / 1024.""") + + # End of Convertion/Sequence + self.eoc = CSRStatus(description="End of Conversion Status, ``1``: Conversion Done.") + self.eos = CSRStatus(description="End of Sequence Status, ``1``: Sequence Done.") + + # Alarms + self.alarm = Signal(16) + self.ot = Signal() # # # - den_pipe = Signal() # add a register to ease timing closure of den + busy = Signal() + channel = Signal(self.dadr_size) + eoc = Signal() + eos = Signal() + # SYSMONE1 instance ---------------------------------------------------------------------------- + self.dwe = Signal() + self.den = Signal() + self.drdy = Signal() + self.dadr = Signal(self.dadr_size) + self.di = Signal(16) + self.do = Signal(16) + self.drp_en = Signal() + self.specials += Instance("SYSMONE1", + # From ug580 + 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_47=0x000f, p_INIT_4A=0x47e0, p_INIT_4B=0x0000, + p_INIT_4C=0x0000, p_INIT_4D=0x0000, + p_INIT_4E=0x0000, p_INIT_4F=0x0000, + p_INIT_50=0xb5ed, p_INIT_51=0x5999, + p_INIT_52=0xa147, p_INIT_53=0xdddd, + 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_VAUXP = 0 if analog_pads is None else analog_pads.vauxp, + 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_VN = 0 if analog_pads is None else analog_pads.vn, + 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.comb += [ - self.di.eq(self.drp_dat_w.storage), - self.drp_dat_r.status.eq(self.do), - If(self.drp_en, - self.den.eq(den_pipe), - self.dadr.eq(self.drp_adr.storage), + If(~self.drp_en, + self.den.eq(eoc), + self.dadr.eq(channel), ) ] + + # Channels update -------------------------------------------------------------------------- + channels = { + 0: self.temperature, + 1: self.vccint, + 2: self.vccaux, + 6: self.vccbram, + 0xd: self.vccpsintlp, + 0xe: self.vccpsintfp, + 0xf: self.vccpsaux, + } self.sync += [ - self.dwe.eq(self.drp_write.re), - self.drp_en.eq(self.drp_enable.storage), - den_pipe.eq(self.drp_read.re | self.drp_write.re), - If(self.drp_read.re | self.drp_write.re, - self.drp_drdy.status.eq(0) - ).Elif(self.drdy, - self.drp_drdy.status.eq(1) - ) + If(self.drdy, + Case(channel, dict( + (k, v.status.eq((self.do >> 6) & 0x3ff)) + 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), ] From 6bb0541f9ad5d30d85067a1d86415b9380397ebb Mon Sep 17 00:00:00 2001 From: Vamsi Vytla Date: Sat, 6 Mar 2021 14:31:24 -0800 Subject: [PATCH 6/6] Remove ussysmon.py as it is consolidated inside xadc.py --- litex/soc/cores/ussysmon.py | 147 ------------------------------------ 1 file changed, 147 deletions(-) delete mode 100644 litex/soc/cores/ussysmon.py diff --git a/litex/soc/cores/ussysmon.py b/litex/soc/cores/ussysmon.py deleted file mode 100644 index 0616ce836..000000000 --- a/litex/soc/cores/ussysmon.py +++ /dev/null @@ -1,147 +0,0 @@ - -from migen import * - -from litex.soc.interconnect.csr import * - -# SYSMONE1 --------------------------------------------------------------------------------------------- - -analog_layout = [("vauxp", 16), ("vauxn", 16), ("vp", 1), ("vn", 1)] - -class USSYSMON(Module, AutoCSR): - def __init__(self, analog_pads=None): - # Temperature - self.temperature = CSRStatus(10, description="""Raw Temperature value from SYSMONE1.\n - Temperature (°C) = ``Value`` x 503.975 / 1024 - 273.15.""") - - # Voltages - self.vccint = CSRStatus(10, description="""Raw VCCINT value from SYSMONE1.\n - VCCINT (V) = ``Value`` x 3 / 1024.""") - self.vccaux = CSRStatus(10, description="""Raw VCCAUX value from SYSMONE1.\n - VCCAUX (V) = ``Value`` x 3 / 1024.""") - self.vccbram = CSRStatus(10, description="""Raw VCCBRAM value from SYSMONE1.\n - VCCBRAM (V) = ``Value`` x 3 / 1024.""") - self.vccpsintlp = CSRStatus(10, description="""Raw VCCPSINTLP value from SYSMONE1.\n - VCCPSINTLP (V) = ``Value`` x 3 / 1024.""") - self.vccpsintfp = CSRStatus(10, description="""Raw VCCPSINTFP value from SYSMONE1.\n - VCCPSINTFP (V) = ``Value`` x 3 / 1024.""") - self.vccpsaux = CSRStatus(10, description="""Raw VCCPSAUX value from SYSMONE1.\n - VCCPSAUX (V) = ``Value`` x 3 / 1024.""") - - # End of Convertion/Sequence - self.eoc = CSRStatus(description="End of Conversion Status, ``1``: Conversion Done.") - self.eos = CSRStatus(description="End of Sequence Status, ``1``: Sequence Done.") - - # Alarms - self.alarm = Signal(16) - self.ot = Signal() - - # # # - - busy = Signal() - channel = Signal(8) - eoc = Signal() - eos = Signal() - - # SYSMONE1 instance ---------------------------------------------------------------------------- - self.dwe = Signal() - self.den = Signal() - self.drdy = Signal() - self.dadr = Signal(8) - self.di = Signal(16) - self.do = Signal(16) - self.drp_en = Signal() - self.specials += Instance("SYSMONE1", - # From ug580 - 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_47=0x000f, p_INIT_4A=0x47e0, p_INIT_4B=0x0000, - p_INIT_4C=0x0000, p_INIT_4D=0x0000, - p_INIT_4E=0x0000, p_INIT_4F=0x0000, - p_INIT_50=0xb5ed, p_INIT_51=0x5999, - p_INIT_52=0xa147, p_INIT_53=0xdddd, - 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_VAUXP = 0 if analog_pads is None else analog_pads.vauxp, - 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_VN = 0 if analog_pads is None else analog_pads.vn, - 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.comb += [ - If(~self.drp_en, - self.den.eq(eoc), - self.dadr.eq(channel), - ) - ] - - # Channels update -------------------------------------------------------------------------- - channels = { - 0: self.temperature, - 1: self.vccint, - 2: self.vccaux, - 6: self.vccbram, - 0xd: self.vccpsintlp, - 0xe: self.vccpsintfp, - 0xf: self.vccpsaux, - } - self.sync += [ - If(self.drdy, - Case(channel, dict( - (k, v.status.eq((self.do >> 6) & 0x3ff)) - 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(8, reset_less=True) - self.drp_dat_w = CSRStorage(16, reset_less=True) - self.drp_dat_r = CSRStatus(16) - - # # # - - den_pipe = Signal() # add a register to ease timing closure of den - - self.comb += [ - self.di.eq(self.drp_dat_w.storage), - self.drp_dat_r.status.eq(self.do), - If(self.drp_en, - self.den.eq(den_pipe), - self.dadr.eq(self.drp_adr.storage), - ) - ] - self.sync += [ - self.dwe.eq(self.drp_write.re), - self.drp_en.eq(self.drp_enable.storage), - den_pipe.eq(self.drp_read.re | self.drp_write.re), - If(self.drp_read.re | self.drp_write.re, - self.drp_drdy.status.eq(0) - ).Elif(self.drdy, - self.drp_drdy.status.eq(1) - ) - ]