diff --git a/src/manta/memory_core.py b/src/manta/memory_core.py index 5c143cb..93799ea 100644 --- a/src/manta/memory_core.py +++ b/src/manta/memory_core.py @@ -37,7 +37,7 @@ class MemoryCore(MantaCore): self._width = width self._depth = depth - self._n_mems = ceil(self._width / 16) + self._n_mems = ceil(self._width / 32) # Bus Connections self.bus_i = Signal(InternalBus()) @@ -75,11 +75,11 @@ class MemoryCore(MantaCore): ] # Define memories - n_full = self._width // 16 - n_partial = self._width % 16 + n_full = self._width // 32 + n_partial = self._width % 32 self._mems = [ - Memory(shape=16, depth=self._depth, init=[0] * self._depth) for _ in range(n_full) + Memory(shape=32, depth=self._depth, init=[0] * self._depth) for _ in range(n_full) ] if n_partial > 0: self._mems += [Memory(shape=n_partial, depth=self._depth, init=[0] * self._depth)] @@ -214,7 +214,7 @@ class MemoryCore(MantaCore): for i, mem in enumerate(self._mems): write_port = mem.write_port() m.d.comb += write_port.addr.eq(self.user_addr) - m.d.comb += write_port.data.eq(self.user_data_in[16 * i : 16 * (i + 1)]) + m.d.comb += write_port.data.eq(self.user_data_in[32 * i : 32 * (i + 1)]) m.d.comb += write_port.en.eq(self.user_write_enable) # Handle read ports @@ -265,6 +265,25 @@ class MemoryCore(MantaCore): return bus_addrs + def read_block(self, base_addr, length): + # base_addr is in user's address space, not the bus address space + + assert base_addr <= self._depth + assert base_addr + length <= self._depth + + words_by_mem = [ + self.interface.read_block( + self.base_addr + base_addr + (i * self._depth), length + ) + for i in range(self._n_mems) + ] + + # transpose + words_by_addr = list(zip(*words_by_mem)) + assert len(words_by_addr) == length + assert len(words_by_addr[0]) == self._n_mems + return [words_to_value(words) for words in words_by_addr] + def read(self, addrs): """ Read the data stored in the Memory Core at one or many address. diff --git a/src/manta/utils.py b/src/manta/utils.py index 62a7712..a1359b8 100644 --- a/src/manta/utils.py +++ b/src/manta/utils.py @@ -118,8 +118,9 @@ class EthernetMessageHeader(Struct): length: 7 = 0 zero_padding: 9 = 0 - MAX_READ_LENGTH = 126 - MAX_WRITE_LENGTH = 126 + # TODO: determine if observed 63 word limit is a bug or just a limitation of LiteEth + MAX_READ_LENGTH = 63 + MAX_WRITE_LENGTH = 63 @classmethod def from_params(cls, msg_type, seq_num, length=0): @@ -190,15 +191,19 @@ def parse_sequences(numbers): return sequences -def words_to_value(data): +def words_to_value(data, width=32): """ - Takes a list of integers, interprets them as 16-bit integers, and + Takes a list of integers, interprets them as n-bit integers, and concatenates them together in little-endian order. """ - [check_value_fits_in_bits(d, 16) for d in data] + for d in data: + check_value_fits_in_bits(d, width) - return int("".join([f"{i:016b}" for i in data[::-1]]), 2) + result = 0 + for word in reversed(data): + result = (result << width) | word + return result def value_to_words(data, n_words):