From 111a7d3021d35ea9be7306312fd2ded069237351 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Fran=C3=A7ois=20Nguyen?= Date: Tue, 29 Jun 2021 18:39:59 +0200 Subject: [PATCH] cores.litedram: move memory map population to _populate_ctrl_map(). --- lambdasoc/cores/litedram.py | 60 ++++++++++++++------------- lambdasoc/test/test_cores_litedram.py | 3 +- 2 files changed, 34 insertions(+), 29 deletions(-) diff --git a/lambdasoc/cores/litedram.py b/lambdasoc/cores/litedram.py index c5a7c60..31a3a35 100644 --- a/lambdasoc/cores/litedram.py +++ b/lambdasoc/cores/litedram.py @@ -7,7 +7,7 @@ import textwrap from nmigen import * from nmigen import tracer -from nmigen.build.run import BuildPlan +from nmigen.build.run import BuildPlan, BuildProducts from nmigen.utils import log2_int from nmigen_soc import wishbone @@ -457,10 +457,39 @@ class Core(Elaboratable): before :meth:`Core.build` is called with `do_build=True`). """ if self._ctrl_bus is None: - raise AttributeError("Core.build(do_build=True) must be called before accessing " + raise AttributeError("Control bus memory map has not been populated. " + "Core.build(do_build=True) must be called before accessing " "Core.ctrl_bus") return self._ctrl_bus + def _populate_ctrl_map(self, build_products): + if not isinstance(build_products, BuildProducts): + raise TypeError("Build products must be an instance of BuildProducts, not {!r}" + .format(build_products)) + + # LiteDRAM's Wishbone to CSR bridge has a granularity of 8 bits. + ctrl_map = MemoryMap(addr_width=1, data_width=8) + + csr_csv = build_products.get(f"{self.name}_csr.csv", mode="t") + for row in csv.reader(csr_csv.split("\n"), delimiter=","): + if not row or row[0][0] == "#": continue + res_type, res_name, addr, size, attrs = row + if res_type == "csr_register": + ctrl_map.add_resource( + res_name, + addr = int(addr, 16), + size = int(size, 10) * self.config.csr_data_width // ctrl_map.data_width, + extend = True, + ) + + self._ctrl_bus = wishbone.Interface( + addr_width = ctrl_map.addr_width + - log2_int(self.config.csr_data_width // ctrl_map.data_width), + data_width = self.config.csr_data_width, + granularity = ctrl_map.data_width, + ) + self._ctrl_bus.memory_map = ctrl_map + def build(self, builder, *, do_build=True, build_dir="build/litedram", sim=False, name_force=False): """Build the LiteDRAM core. @@ -493,32 +522,7 @@ class Core(Elaboratable): return plan products = plan.execute_local(build_dir) - - # LiteDRAM's Wishbone to CSR bridge uses an 8-bit granularity. - ctrl_map = MemoryMap(addr_width=1, data_width=8) - - with products.extract(f"{self.name}_csr.csv") as csr_csv_filename: - with open(csr_csv_filename, "r") as csr_csv: - for row in csv.reader(csr_csv, delimiter=","): - if row[0][0] == "#": continue - res_type, res_name, addr, size, attrs = row - if res_type == "csr_register": - ctrl_map.add_resource( - res_name, - addr = int(addr, 16), - size = int(size, 10) * self.config.csr_data_width - // ctrl_map.data_width, - extend = True, - ) - - self._ctrl_bus = wishbone.Interface( - addr_width = ctrl_map.addr_width - - log2_int(self.config.csr_data_width // ctrl_map.data_width), - data_width = self.config.csr_data_width, - granularity = ctrl_map.data_width, - ) - self._ctrl_bus.memory_map = ctrl_map - + self._populate_ctrl_map(products) return products def elaborate(self, platform): diff --git a/lambdasoc/test/test_cores_litedram.py b/lambdasoc/test/test_cores_litedram.py index aabf6f8..d58957c 100644 --- a/lambdasoc/test/test_cores_litedram.py +++ b/lambdasoc/test/test_cores_litedram.py @@ -433,7 +433,8 @@ class CoreTestCase(unittest.TestCase): def test_ctrl_bus_not_ready(self): core = litedram.Core(self._cfg) with self.assertRaisesRegex(AttributeError, - r"Core.build\(do_build=True\) must be called before accessing Core\.ctrl_bus"): + r"Control bus memory map has not been populated. Core.build\(do_build=True\) must " + r"be called before accessing Core\.ctrl_bus"): core.ctrl_bus def test_wrong_config(self): -- 2.30.2