From ecd9eee5a4dafa5f60578705f11fdd1d2d4fa979 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 21 Aug 2024 15:35:21 +0200 Subject: [PATCH] soc/core/hyperbus: Report Clk Ratio on Status register and use it in software to configure latency. --- litex/soc/cores/hyperbus.py | 44 ++++++++++++++++----------- litex/soc/software/libbase/hyperram.c | 7 +++-- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/litex/soc/cores/hyperbus.py b/litex/soc/cores/hyperbus.py index ea6241e6d..16dc8affe 100644 --- a/litex/soc/cores/hyperbus.py +++ b/litex/soc/cores/hyperbus.py @@ -48,21 +48,6 @@ class HyperRAM(LiteXModule): self.pads = pads self.bus = bus = wishbone.Interface(data_width=32, address_width=32, addressing="word") - # Config/Reg Interface. - # --------------------- - self.conf_rst = Signal() - self.conf_latency = Signal(8, reset=latency) - self.stat_latency_mode = Signal(reset={"fixed": 0, "variable": 1}[latency_mode]) - self.reg_write = Signal() - self.reg_read = Signal() - self.reg_addr = Signal(2) - self.reg_write_done = Signal() - self.reg_read_done = Signal() - self.reg_write_data = Signal(16) - self.reg_read_data = Signal(16) - if with_csr: - self.add_csr(default_latency=latency) - # # # # Parameters. @@ -80,6 +65,21 @@ class HyperRAM(LiteXModule): }[clk_ratio] self.sync_io = sync_io = getattr(self.sync, cd_io) + # Config/Reg Interface. + # --------------------- + self.conf_rst = Signal() + self.conf_latency = Signal(8, reset=latency) + self.stat_latency_mode = Signal(reset={"fixed": 0, "variable": 1}[latency_mode]) + self.reg_write = Signal() + self.reg_read = Signal() + self.reg_addr = Signal(2) + self.reg_write_done = Signal() + self.reg_read_done = Signal() + self.reg_write_data = Signal(16) + self.reg_read_data = Signal(16) + if with_csr: + self.add_csr(default_latency=latency) + # Internal Signals. # ----------------- clk = Signal() @@ -411,9 +411,19 @@ class HyperRAM(LiteXModule): CSRField("latency_mode", offset=0, size=1, values=[ ("``0b0``", "Fixed Latency."), ("``0b1``", "Variable Latency."), - ]) + ]), + CSRField("clk_ratio", offset=1, size=4, values=[ + ("``4``", "HyperRAM Clk = Sys Clk/4."), + ("``2``", "HyperRAM Clk = Sys Clk/2."), + ]), ]) - self.comb += self.status.fields.latency_mode.eq(self.stat_latency_mode) + self.comb += [ + self.status.fields.latency_mode.eq(self.stat_latency_mode), + self.status.fields.clk_ratio.eq({ + "sys" : 4, + "sys2x": 2, + }[self.cd_io]), + ] # Reg Interface. # -------------- diff --git a/litex/soc/software/libbase/hyperram.c b/litex/soc/software/libbase/hyperram.c index 30d075643..9dccd581c 100644 --- a/litex/soc/software/libbase/hyperram.c +++ b/litex/soc/software/libbase/hyperram.c @@ -57,12 +57,15 @@ static uint16_t hyperram_get_chip_latency_setting(uint32_t clk_freq) { static void hyperram_configure_latency(void) { uint16_t config_reg_0 = 0x8f2f; + uint8_t core_clk_ratio; uint16_t core_latency_setting; uint16_t chip_latency_setting; /* Compute Latency settings */ - core_latency_setting = hyperram_get_core_latency_setting(CONFIG_CLOCK_FREQUENCY/2); - chip_latency_setting = hyperram_get_chip_latency_setting(CONFIG_CLOCK_FREQUENCY/2); + core_clk_ratio = (hyperram_status_read() >> CSR_HYPERRAM_STATUS_CLK_RATIO_OFFSET & 0xf); + printf("HyperRAM Clk Ratio %d:1.\n", core_clk_ratio); + core_latency_setting = hyperram_get_core_latency_setting(CONFIG_CLOCK_FREQUENCY/core_clk_ratio); + chip_latency_setting = hyperram_get_chip_latency_setting(CONFIG_CLOCK_FREQUENCY/core_clk_ratio); /* Write Latency to HyperRAM Core */ printf("HyperRAM Core Latency: %d CK (X1).\n", core_latency_setting);