soc_core: optimize mem_decoder
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 22 Jul 2019 06:53:18 +0000 (08:53 +0200)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 22 Jul 2019 06:53:54 +0000 (08:53 +0200)
Non-optimized version was tested on 7-series and was additional resource usage
was not noticeable. This does not seems to be the case on iCE40 (see #220), so
hand optimize it. On 256MB aligned addresses, it should be equivalent to the
old decoder used by previously in LiteX.

The only requirement is that to have address aligned on size, which was already
the case. An assertion will trigger it this condition is not respected.

litex/soc/integration/soc_core.py

index 12295e0884e9f1858640a531fb2b3aafb92b9556..8f16bfb288bf7c92b84f65a9676388281c81d069 100644 (file)
@@ -98,7 +98,10 @@ def get_mem_data(filename_or_regions, endianness="big", mem_size=None):
 
 def mem_decoder(address, size=0x10000000):
     address &= ~0x80000000
-    return lambda a: (a[:-1] >= address//4) & (a[:-1] < (address + size)//4)
+    assert (address & (size - 1)) == 0
+    address >>= 2 # bytes to words aligned
+    size    >>= 2 # bytes to words aligned
+    return lambda a: (a[log2_int(size):-1] == (address >> log2_int(size)))
 
 def csr_map_update(csr_map, csr_peripherals):
     csr_map.update(dict((n, v)