From b0dcd269bcb7e57cfadbec733acdf389276165b3 Mon Sep 17 00:00:00 2001 From: Fischer Moseley <42497969+fischermoseley@users.noreply.github.com> Date: Mon, 19 Feb 2024 11:42:28 -0800 Subject: [PATCH] add from_config to memory_core --- src/manta/logic_analyzer/__init__.py | 14 +++++--- src/manta/logic_analyzer/sample_mem.py | 16 --------- src/manta/manta.py | 2 +- src/manta/memory_core.py | 47 ++++++++++---------------- test/test_logic_analyzer_sim.py | 10 +++--- test/test_mem_core_sim.py | 3 +- 6 files changed, 33 insertions(+), 59 deletions(-) delete mode 100644 src/manta/logic_analyzer/sample_mem.py diff --git a/src/manta/logic_analyzer/__init__.py b/src/manta/logic_analyzer/__init__.py index 20a8ef8..1ffe387 100644 --- a/src/manta/logic_analyzer/__init__.py +++ b/src/manta/logic_analyzer/__init__.py @@ -1,8 +1,8 @@ from amaranth import * from manta.utils import * +from manta.memory_core import ReadOnlyMemoryCore from manta.logic_analyzer.trigger_block import LogicAnalyzerTriggerBlock from manta.logic_analyzer.fsm import LogicAnalyzerFSM, States, TriggerModes -from manta.logic_analyzer.sample_mem import LogicAnalyzerSampleMemory from manta.logic_analyzer.playback import LogicAnalyzerPlayback @@ -35,8 +35,12 @@ class LogicAnalyzerCore(Elaboratable): self._trig_blk = LogicAnalyzerTriggerBlock( self._probes, self._fsm.get_max_addr() + 1, interface ) - self._sample_mem = LogicAnalyzerSampleMemory( - self._config, self._trig_blk.get_max_addr() + 1, interface + + self._sample_mem = ReadOnlyMemoryCore( + width=sum(self._config["probes"].values()), + depth=self._config["sample_depth"], + base_addr=self._trig_blk.get_max_addr() + 1, + interface=interface, ) def _check_config(self): @@ -317,13 +321,13 @@ class LogicAnalyzerCapture: values_t = [list(x) for x in zip(*values)] import csv - with open(path, 'w') as f: + + with open(path, "w") as f: writer = csv.writer(f) writer.writerow(names) writer.writerows(values_t) - def export_vcd(self, path): """ Export the capture to a VCD file, containing the data of all probes in diff --git a/src/manta/logic_analyzer/sample_mem.py b/src/manta/logic_analyzer/sample_mem.py deleted file mode 100644 index 045fabb..0000000 --- a/src/manta/logic_analyzer/sample_mem.py +++ /dev/null @@ -1,16 +0,0 @@ -from amaranth import * -from manta.memory_core import ReadOnlyMemoryCore - - -class LogicAnalyzerSampleMemory(ReadOnlyMemoryCore): - """ - A module that wraps a ReadOnlyMemoryCore, using the config from a LogicAnalyzerCore - to determine the parameters with which to instantiate the core. - """ - - def __init__(self, config, base_addr, interface): - width = sum(config["probes"].values()) - depth = config["sample_depth"] - mem_config = {"width": width, "depth": depth} - - super().__init__(mem_config, base_addr, interface) diff --git a/src/manta/manta.py b/src/manta/manta.py index 9384957..5dca676 100644 --- a/src/manta/manta.py +++ b/src/manta/manta.py @@ -84,7 +84,7 @@ class Manta(Elaboratable): core = LogicAnalyzerCore(attrs, base_addr, self.interface) elif attrs["type"] == "memory_read_only": - core = ReadOnlyMemoryCore(attrs, base_addr, self.interface) + core = ReadOnlyMemoryCore.from_config(attrs, base_addr, self.interface) # make sure we're not out of address space if core.get_max_addr() > (2**16) - 1: diff --git a/src/manta/memory_core.py b/src/manta/memory_core.py index 6d92ee4..6bc3681 100644 --- a/src/manta/memory_core.py +++ b/src/manta/memory_core.py @@ -15,14 +15,12 @@ class ReadOnlyMemoryCore(Elaboratable): https://fischermoseley.github.io/manta/memory_core/ """ - def __init__(self, config, base_addr, interface): - self._config = config + def __init__(self, width, depth, base_addr, interface): + self._width = width + self._depth = depth self._base_addr = base_addr self._interface = interface - self._check_config(config) - self._depth = self._config["depth"] - self._width = self._config["width"] self._max_addr = self._base_addr + (self._depth * ceil(self._width / 16)) # Bus Connections @@ -36,7 +34,8 @@ class ReadOnlyMemoryCore(Elaboratable): self._define_mems() - def _check_config(self, config): + @classmethod + def from_config(cls, config, base_addr, interface): # Check for unrecognized options valid_options = ["type", "depth", "width"] for option in config: @@ -44,25 +43,29 @@ class ReadOnlyMemoryCore(Elaboratable): warn(f"Ignoring unrecognized option '{option}' in memory core.") # Check depth is provided and positive - if "depth" not in config: + depth = config.get("depth") + if not depth: raise ValueError("Depth of memory core must be specified.") - if not isinstance(config["depth"], int): + if not isinstance(depth, int): raise ValueError("Depth of memory core must be an integer.") - if config["depth"] <= 0: + if not depth > 0: raise ValueError("Depth of memory core must be positive. ") # Check width is provided and positive - if "width" not in config: + width = config.get("width") + if not width: raise ValueError("Width of memory core must be specified.") - if not isinstance(config["width"], int): + if not isinstance(width, int): raise ValueError("Width of memory core must be an integer.") - if config["width"] <= 0: + if not width > 0: raise ValueError("Width of memory core must be positive. ") + cls(width, depth, base_addr, interface) + def _pipeline_bus(self, m): self._bus_pipe = [Signal(InternalBus()) for _ in range(3)] m.d.sync += self._bus_pipe[0].eq(self.bus_i) @@ -160,7 +163,8 @@ class ReadOnlyMemoryCore(Elaboratable): def read_from_user_addr(self, addrs): """ - Read the memory stored at the provided address, as seen from the user side. + Read the memory stored at the provided address, as seen from the user + side. """ # Convert user address space to bus address space @@ -180,20 +184,3 @@ class ReadOnlyMemoryCore(Elaboratable): datas = self._interface.read(bus_addrs) data_chunks = split_into_chunks(datas, len(self._mems)) return [words_to_value(chunk) for chunk in data_chunks] - - # def write_to_user_addr(self, addrs, datas): - # """ - # Read from the address - # """ - - # bus_addrs = [] - # for addr in addrs: - # bus_addrs += [ - # addr + self._base_addr + i * self._depth for i in range(len(self._mems)) - # ] - - # bus_datas = [] - # for data in datas: - # bus_datas += value_to_words(data) - - # self._interface.write(bus_addrs, bus_datas) diff --git a/test/test_logic_analyzer_sim.py b/test/test_logic_analyzer_sim.py index 0346bd6..f5c7ea2 100644 --- a/test/test_logic_analyzer_sim.py +++ b/test/test_logic_analyzer_sim.py @@ -33,8 +33,8 @@ def print_data_at_addr(addr): def set_fsm_register(name, data): - addr = la.fsm.registers._memory_map[name]["addrs"][0] - strobe_addr = la.fsm.registers._base_addr + addr = la._fsm.registers._memory_map[name]["addrs"][0] + strobe_addr = la._fsm.registers._base_addr yield from write_register(la, strobe_addr, 0) yield from write_register(la, addr, data) @@ -43,8 +43,8 @@ def set_fsm_register(name, data): def set_trig_blk_register(name, data): - addr = la.trig_blk.registers._memory_map[name]["addrs"][0] - strobe_addr = la.trig_blk.registers._base_addr + addr = la._trig_blk.registers._memory_map[name]["addrs"][0] + strobe_addr = la._trig_blk.registers._base_addr yield from write_register(la, strobe_addr, 0) yield from write_register(la, addr, data) @@ -54,7 +54,7 @@ def set_trig_blk_register(name, data): def set_probe(name, value): probe = None - for p in la.probes: + for p in la._probes: if p.name == name: probe = p diff --git a/test/test_mem_core_sim.py b/test/test_mem_core_sim.py index 675991f..e793c4f 100644 --- a/test/test_mem_core_sim.py +++ b/test/test_mem_core_sim.py @@ -15,8 +15,7 @@ def fill_mem_from_user_port(mem_core, depth): def verify_mem_core(width, depth, base_addr): - config = {"type": "memory", "width": width, "depth": depth} - mem_core = ReadOnlyMemoryCore(config, base_addr, interface=None) + mem_core = ReadOnlyMemoryCore(width, depth, base_addr, interface=None) def testbench(): yield from fill_mem_from_user_port(mem_core, depth)