Skip to content

Commit

Permalink
soc/add_master: Add region support to allow remapping.
Browse files Browse the repository at this point in the history
Allow connecting a master to a specific region of the SoC and limiting access to it.
  • Loading branch information
enjoy-digital committed Feb 13, 2024
1 parent 36767c6 commit bd7921c
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 2 deletions.
33 changes: 31 additions & 2 deletions litex/soc/integration/soc.py
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,34 @@ def bus_standard_convert(interface, direction):

return adapted_interface

def add_master(self, name=None, master=None):
# Add Remapper ---------------------------------------------------------------------------------
def add_remapper(self, name, interface, origin, size):
interface_cls = type(interface)
remapper_cls = {
wishbone.Interface : wishbone.Remapper,
axi.AXILiteInterface : axi.AXILiteRemapper,
axi.AXIInterface : axi.AXIRemapper,
}[interface_cls]

adapted_interface = interface_cls(
data_width = interface.data_width,
address_width = interface.address_width,
addressing = interface.addressing,
)

self.submodules += remapper_cls(interface, adapted_interface, origin, size)

fmt = "{name} Bus {remapped} to {origin} (Size: {size})."
self.logger.info(fmt.format(
name = colorer(name),
remapped = colorer("remapped", color="cyan"),
origin = colorer(f"0x{origin:08x}"),
size = colorer(f"0x{size:08x}"),
))

return adapted_interface

def add_master(self, name=None, master=None, region=None):
if name is None:
name = "master{:d}".format(len(self.masters))
if name in self.masters.keys():
Expand All @@ -456,6 +483,8 @@ def add_master(self, name=None, master=None):
colorer("already declared", color="red")))
self.logger.error(self)
raise SoCError()
if region:
master = self.add_remapper(name, master, region.origin, region.size)
master = self.add_adapter(name, master, "m2s")
self.masters[name] = master
self.logger.info("{} {} as Bus Master.".format(
Expand All @@ -466,7 +495,7 @@ def add_controller(self, name=None, controller=None):
self.add_master(self, name=name, master=controller)

def add_slave(self, name=None, slave=None, region=None):
no_name = name is None
no_name = name is None
no_region = region is None
if no_name and no_region:
self.logger.error("Please {} {} or/and {} of Bus Slave.".format(
Expand Down
14 changes: 14 additions & 0 deletions litex/soc/interconnect/axi/axi_full.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

"""AXI4-Full/Lite support for LiteX"""

from math import log2

from migen import *
from migen.genlib import roundrobin

Expand Down Expand Up @@ -138,6 +140,18 @@ def connect(self, slave, **kwargs):
def layout_flat(self):
return list(axi_layout_flat(self))

# AXI Remapper -------------------------------------------------------------------------------------

class AXIRemapper(LiteXModule):
def __init__(self, master, slave, origin, size):
# Mask.
mask = 2**int(log2(size)) - 1

# Address Mask and Shift.
self.comb += master.connect(slave)
self.comb += slave.aw.addr.eq(origin | master.aw.addr & mask)
self.comb += slave.ar.addr.eq(origin | master.ar.addr & mask)

# AXI Bursts to Beats ------------------------------------------------------------------------------

class AXIBurst2Beat(LiteXModule):
Expand Down
15 changes: 15 additions & 0 deletions litex/soc/interconnect/axi/axi_lite.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

"""AXI4-Full/Lite support for LiteX"""

from math import log2

from migen import *
from migen.genlib import roundrobin

Expand Down Expand Up @@ -128,6 +130,19 @@ def read(self, addr):
yield self.r.ready.eq(0)
return (data, resp)


# AXI-Lite Remapper --------------------------------------------------------------------------------

class AXILiteRemapper(LiteXModule):
def __init__(self, master, slave, origin, size):
# Mask.
mask = 2**int(log2(size)) - 1

# Address Mask and Shift.
self.comb += master.connect(slave)
self.comb += slave.aw.addr.eq(origin | master.aw.addr & mask)
self.comb += slave.ar.addr.eq(origin | master.ar.addr & mask)

# AXI-Lite to Simple Bus ---------------------------------------------------------------------------

def axi_lite_to_simple(axi_lite, port_adr, port_dat_r, port_dat_w=None, port_we=None):
Expand Down
18 changes: 18 additions & 0 deletions litex/soc/interconnect/wishbone.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,24 @@ def connect_to_pads(self, pads, mode="master"):
r.append(sig.eq(pad))
return r

# Wishbone Remapper --------------------------------------------------------------------------------

class Remapper(LiteXModule):
def __init__(self, master, slave, origin, size):
# Parameters.
addressing = master.addressing
assert master.addressing == slave.addressing

# Mask.
log2_size = int(log2(size))
if addressing == "word":
log2_size -= int(log2(len(master.dat_w)//8))
mask = 2**log2_size - 1

# Address Mask and Shift.
self.comb += master.connect(slave, omit={"adr"})
self.comb += slave.adr.eq(origin | (master.adr & mask))

# Wishbone Timeout ---------------------------------------------------------------------------------

class Timeout(LiteXModule):
Expand Down

0 comments on commit bd7921c

Please sign in to comment.