add from_config to memory_core
This commit is contained in:
parent
7ee51158d2
commit
b0dcd269bc
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue