memory_core: use 32-bit instead of 16-bit data words
This commit is contained in:
parent
a1c7d194e8
commit
7fca0bf5f0
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
Loading…
Reference in New Issue