interconnect/csr_bus/SRAM: allow 64-bit alignment (on 64-bit CPUs)
authorGabriel Somlo <gsomlo@gmail.com>
Fri, 3 Jan 2020 21:27:44 +0000 (16:27 -0500)
committerGabriel Somlo <gsomlo@gmail.com>
Fri, 3 Jan 2020 21:36:42 +0000 (16:36 -0500)
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>
litex/soc/interconnect/csr_bus.py
litex/soc/software/include/hw/common.h

index 1b7ccaf71a718b25a90041f6771a6c9aa693f09e..215ac66641fb07c048cec9cbab20ae380c5d4988 100644 (file)
@@ -86,7 +86,7 @@ class SRAM(Module):
             mem = Memory(data_width, mem_or_size//(data_width//8), init=init)
         mem_size = int(mem.width*mem.depth/8)
         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
         word_bits = log2_int(csrw_per_memw)
         page_bits = log2_int((mem.depth*csrw_per_memw + 511)//512, False)
@@ -109,11 +109,15 @@ class SRAM(Module):
         sel_r = Signal()
         self.sync += sel_r.eq(sel)
         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:
             word_index = Signal(word_bits)
             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 += [
                 word_expanded.eq(port.dat_r),
                 If(sel_r,
@@ -124,11 +128,11 @@ class SRAM(Module):
                 wregs = []
                 for i in range(csrw_per_memw-1):
                     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)
                 memword_chunks = [self.bus.dat_w] + list(reversed(wregs))
                 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))
                 ]
         else:
@@ -140,10 +144,10 @@ class SRAM(Module):
                 ]
 
         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:
             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):
         if self._page is None:
index 8ebdc4df7453526133724c7c87c776b07493d309..ba5cc61144aa416db389879a2bcd1a0fecb6a4e2 100644 (file)
@@ -14,7 +14,7 @@
 #ifdef __ASSEMBLER__
 #define MMPTR(x) x
 #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)
 {