interconnect/csr_bus/SRAM: allow 64-bit alignment (on 64-bit CPUs)
Similarly to how CSRBank subregisters are aligned to the CPU word
width (see commit f4770219f
), ensure SRAM word_bits are also aligned
to the CPU word width.
Additionally, fix the MMPTR() macro to access CSR subregisters as
CPU word (unsigned long) sized slices.
This fixes the functionality of the 'ident' bios command on 64-bit
CPUs (e.g., Rocket).
Signed-off-by: Gabriel Somlo <gsomlo@gmail.com>
This commit is contained in:
parent
690de79d8b
commit
d087e2e0af
|
@ -86,7 +86,7 @@ class SRAM(Module):
|
||||||
mem = Memory(data_width, mem_or_size//(data_width//8), init=init)
|
mem = Memory(data_width, mem_or_size//(data_width//8), init=init)
|
||||||
mem_size = int(mem.width*mem.depth/8)
|
mem_size = int(mem.width*mem.depth/8)
|
||||||
if mem_size > 512:
|
if mem_size > 512:
|
||||||
print("WARNING: memory > 512 bytes in CSR region requires paged access".format(mem_size))
|
print("WARNING: memory > 512 bytes in CSR region requires paged access (mem_size = {} bytes)".format(mem_size))
|
||||||
csrw_per_memw = (mem.width + data_width - 1)//data_width
|
csrw_per_memw = (mem.width + data_width - 1)//data_width
|
||||||
word_bits = log2_int(csrw_per_memw)
|
word_bits = log2_int(csrw_per_memw)
|
||||||
page_bits = log2_int((mem.depth*csrw_per_memw + 511)//512, False)
|
page_bits = log2_int((mem.depth*csrw_per_memw + 511)//512, False)
|
||||||
|
@ -109,11 +109,15 @@ class SRAM(Module):
|
||||||
sel_r = Signal()
|
sel_r = Signal()
|
||||||
self.sync += sel_r.eq(sel)
|
self.sync += sel_r.eq(sel)
|
||||||
self.comb += sel.eq(self.bus.adr[9:] == address)
|
self.comb += sel.eq(self.bus.adr[9:] == address)
|
||||||
|
if bus.alignment == 64:
|
||||||
|
self.comb += If(self.bus.adr[0], sel.eq(0))
|
||||||
|
|
||||||
|
adr_shift = log2_int(bus.alignment//32)
|
||||||
|
|
||||||
if word_bits:
|
if word_bits:
|
||||||
word_index = Signal(word_bits)
|
word_index = Signal(word_bits)
|
||||||
word_expanded = Signal(csrw_per_memw*data_width)
|
word_expanded = Signal(csrw_per_memw*data_width)
|
||||||
self.sync += word_index.eq(self.bus.adr[:word_bits])
|
self.sync += word_index.eq(self.bus.adr[adr_shift:adr_shift+word_bits])
|
||||||
self.comb += [
|
self.comb += [
|
||||||
word_expanded.eq(port.dat_r),
|
word_expanded.eq(port.dat_r),
|
||||||
If(sel_r,
|
If(sel_r,
|
||||||
|
@ -124,11 +128,11 @@ class SRAM(Module):
|
||||||
wregs = []
|
wregs = []
|
||||||
for i in range(csrw_per_memw-1):
|
for i in range(csrw_per_memw-1):
|
||||||
wreg = Signal(data_width)
|
wreg = Signal(data_width)
|
||||||
self.sync += If(sel & self.bus.we & (self.bus.adr[:word_bits] == i), wreg.eq(self.bus.dat_w))
|
self.sync += If(sel & self.bus.we & (self.bus.adr[adr_shift:adr_shift+word_bits] == i), wreg.eq(self.bus.dat_w))
|
||||||
wregs.append(wreg)
|
wregs.append(wreg)
|
||||||
memword_chunks = [self.bus.dat_w] + list(reversed(wregs))
|
memword_chunks = [self.bus.dat_w] + list(reversed(wregs))
|
||||||
self.comb += [
|
self.comb += [
|
||||||
port.we.eq(sel & self.bus.we & (self.bus.adr[:word_bits] == csrw_per_memw - 1)),
|
port.we.eq(sel & self.bus.we & (self.bus.adr[adr_shift:adr_shift+word_bits] == csrw_per_memw - 1)),
|
||||||
port.dat_w.eq(Cat(*memword_chunks))
|
port.dat_w.eq(Cat(*memword_chunks))
|
||||||
]
|
]
|
||||||
else:
|
else:
|
||||||
|
@ -140,10 +144,10 @@ class SRAM(Module):
|
||||||
]
|
]
|
||||||
|
|
||||||
if self._page is None:
|
if self._page is None:
|
||||||
self.comb += port.adr.eq(self.bus.adr[word_bits:word_bits+len(port.adr)])
|
self.comb += port.adr.eq(self.bus.adr[adr_shift+word_bits:adr_shift+word_bits+len(port.adr)])
|
||||||
else:
|
else:
|
||||||
pv = self._page.storage
|
pv = self._page.storage
|
||||||
self.comb += port.adr.eq(Cat(self.bus.adr[word_bits:word_bits+len(port.adr)-len(pv)], pv))
|
self.comb += port.adr.eq(Cat(self.bus.adr[adr_shift+word_bits:adr_shift+word_bits+len(port.adr)-len(pv)], pv))
|
||||||
|
|
||||||
def get_csrs(self):
|
def get_csrs(self):
|
||||||
if self._page is None:
|
if self._page is None:
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#ifdef __ASSEMBLER__
|
#ifdef __ASSEMBLER__
|
||||||
#define MMPTR(x) x
|
#define MMPTR(x) x
|
||||||
#else /* ! __ASSEMBLER__ */
|
#else /* ! __ASSEMBLER__ */
|
||||||
#define MMPTR(x) (*((volatile unsigned int *)(x)))
|
#define MMPTR(x) (*((volatile unsigned long *)(x)))
|
||||||
|
|
||||||
static inline void csr_writeb(uint8_t value, unsigned long addr)
|
static inline void csr_writeb(uint8_t value, unsigned long addr)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue