soc/add_master: Add region support to allow remapping.
Allow connecting a master to a specific region of the SoC and limiting access to it.
This commit is contained in:
parent
36767c66b4
commit
bd7921cda8
|
@ -447,7 +447,34 @@ class SoCBusHandler(LiteXModule):
|
|||
|
||||
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():
|
||||
|
@ -456,6 +483,8 @@ class SoCBusHandler(LiteXModule):
|
|||
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(
|
||||
|
@ -466,7 +495,7 @@ class SoCBusHandler(LiteXModule):
|
|||
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(
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
"""AXI4-Full/Lite support for LiteX"""
|
||||
|
||||
from math import log2
|
||||
|
||||
from migen import *
|
||||
from migen.genlib import roundrobin
|
||||
|
||||
|
@ -138,6 +140,18 @@ class AXIInterface:
|
|||
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):
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
"""AXI4-Full/Lite support for LiteX"""
|
||||
|
||||
from math import log2
|
||||
|
||||
from migen import *
|
||||
from migen.genlib import roundrobin
|
||||
|
||||
|
@ -128,6 +130,19 @@ class AXILiteInterface:
|
|||
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):
|
||||
|
|
|
@ -126,6 +126,24 @@ class Interface(Record):
|
|||
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):
|
||||
|
|
Loading…
Reference in New Issue