pass Ethernet config to LiteEth core generator
This commit is contained in:
parent
63e912fb63
commit
5e642101ef
|
|
@ -192,38 +192,45 @@ class EthernetInterface(Elaboratable):
|
|||
sock.sendto(bytes_out, (self.fpga_ip_addr, self.udp_port))
|
||||
|
||||
def generate_liteeth_core(self):
|
||||
"""
|
||||
Generate a LiteEth core by calling a slightly modified form of the LiteEth
|
||||
standalone core generator. This passes the contents of the 'ethernet' section
|
||||
of the Manta configuration file to LiteEth, after modifying it slightly to
|
||||
include the UDP ports and set a MAC address if the user didn't specify one.
|
||||
"""
|
||||
liteeth_config = self.config.copy()
|
||||
|
||||
# Randomly assign a MAC address if one is not specified in the configuration.
|
||||
# This will choose a MAC address in the Locally Administered, Administratively Assigned group.
|
||||
# For more information, see:
|
||||
# https://en.wikipedia.org/wiki/MAC_address#Ranges_of_group_and_locally_administered_addresses
|
||||
|
||||
if "mac_address" not in self.config:
|
||||
mac_address = list(f"{randint(0, (2**48) - 1):012x}")
|
||||
mac_address[1] = "2"
|
||||
mac_address = int("".join(mac_address), 16)
|
||||
if "mac_address" not in liteeth_config:
|
||||
addr = list(f"{randint(0, (2**48) - 1):012x}")
|
||||
addr[1] = "2"
|
||||
liteeth_config["mac_address"] = int("".join(addr), 16)
|
||||
|
||||
else:
|
||||
mac_address = self.config["mac_address"]
|
||||
# Force use of DHCP
|
||||
liteeth_config["dhcp"] = True
|
||||
|
||||
liteeth_config = {
|
||||
"phy": self.config["phy"],
|
||||
"vendor": self.config["vendor"],
|
||||
"toolchain": self.config["toolchain"],
|
||||
"refclk_freq": self.config["refclk_freq"],
|
||||
"clk_freq": self.config["clk_freq"],
|
||||
"mac_address": mac_address,
|
||||
"dhcp": True,
|
||||
"data_width": 32,
|
||||
"udp_ports": {
|
||||
"udp0": {
|
||||
"udp_port": self.udp_port,
|
||||
"data_width": 32,
|
||||
"tx_fifo_depth": 64,
|
||||
"rx_fifo_depth": 64,
|
||||
}
|
||||
},
|
||||
# Use UDP
|
||||
liteeth_config["core"] = "udp"
|
||||
|
||||
# Use 32-bit words. Might be redundant, as I think using DHCP forces
|
||||
# LiteEth to use 32-bit words
|
||||
liteeth_config["data_width"] = 32
|
||||
|
||||
# Add UDP port
|
||||
liteeth_config["udp_ports"] = {
|
||||
"udp0": {
|
||||
"udp_port": self.udp_port,
|
||||
"data_width": 32,
|
||||
"tx_fifo_depth": 64,
|
||||
"rx_fifo_depth": 64,
|
||||
}
|
||||
}
|
||||
|
||||
# Generate the core
|
||||
from .liteeth_gen import main
|
||||
|
||||
return main(liteeth_config)
|
||||
|
|
|
|||
|
|
@ -230,6 +230,8 @@ def get_udp_raw_port_ios(name, data_width):
|
|||
|
||||
|
||||
# PHY Core -----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
class PHYCore(SoCMini):
|
||||
SoCMini.csr_map = {
|
||||
"ctrl": 0,
|
||||
|
|
@ -322,8 +324,14 @@ class PHYCore(SoCMini):
|
|||
|
||||
qpll_settings = QPLLSettings(
|
||||
refclksel=0b001,
|
||||
fbdiv=4,
|
||||
fbdiv_45={125e6: 5, 156.25e6: 4}[refclk_freq],
|
||||
fbdiv={
|
||||
liteeth_phys.A7_1000BASEX: 4,
|
||||
liteeth_phys.A7_2500BASEX: 5,
|
||||
}[phy],
|
||||
fbdiv_45={
|
||||
125e6: 5,
|
||||
156.25e6: 4,
|
||||
}[refclk_freq],
|
||||
refclk_div=1,
|
||||
)
|
||||
qpll = QPLL(ethphy_pads.refclk, qpll_settings)
|
||||
|
|
@ -371,7 +379,73 @@ class PHYCore(SoCMini):
|
|||
)
|
||||
|
||||
|
||||
# MAC Core -----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
class MACCore(PHYCore):
|
||||
def __init__(self, platform, core_config):
|
||||
# Parameters -------------------------------------------------------------------------------
|
||||
nrxslots = core_config.get("nrxslots", 2)
|
||||
ntxslots = core_config.get("ntxslots", 2)
|
||||
bus_standard = core_config["core"]
|
||||
tx_cdc_depth = core_config.get("tx_cdc_depth", 32)
|
||||
tx_cdc_buffered = core_config.get("tx_cdc_buffered", False)
|
||||
rx_cdc_depth = core_config.get("rx_cdc_depth", 32)
|
||||
rx_cdc_buffered = core_config.get("rx_cdc_buffered", False)
|
||||
assert bus_standard in ["wishbone", "axi-lite"]
|
||||
|
||||
# PHY --------------------------------------------------------------------------------------
|
||||
PHYCore.__init__(self, platform, core_config)
|
||||
|
||||
# MAC --------------------------------------------------------------------------------------
|
||||
self.ethmac = ethmac = LiteEthMAC(
|
||||
phy=self.ethphy,
|
||||
dw=32,
|
||||
interface="wishbone",
|
||||
endianness=core_config["endianness"],
|
||||
nrxslots=nrxslots,
|
||||
ntxslots=ntxslots,
|
||||
full_memory_we=core_config.get("full_memory_we", False),
|
||||
tx_cdc_depth=tx_cdc_depth,
|
||||
tx_cdc_buffered=tx_cdc_buffered,
|
||||
rx_cdc_depth=rx_cdc_depth,
|
||||
rx_cdc_buffered=rx_cdc_buffered,
|
||||
)
|
||||
|
||||
if bus_standard == "wishbone":
|
||||
# Wishbone Interface -----------------------------------------------------------------------
|
||||
wb_bus = wishbone.Interface()
|
||||
platform.add_extension(wb_bus.get_ios("wishbone"))
|
||||
self.comb += wb_bus.connect_to_pads(
|
||||
self.platform.request("wishbone"), mode="slave"
|
||||
)
|
||||
self.bus.add_master(master=wb_bus)
|
||||
|
||||
if bus_standard == "axi-lite":
|
||||
# AXI-Lite Interface -----------------------------------------------------------------------
|
||||
axil_bus = axi.AXILiteInterface(address_width=32, data_width=32)
|
||||
platform.add_extension(axil_bus.get_ios("bus"))
|
||||
self.submodules += axi.Wishbone2AXILite(ethmac.bus, axil_bus)
|
||||
self.comb += axil_bus.connect_to_pads(
|
||||
self.platform.request("bus"), mode="slave"
|
||||
)
|
||||
self.bus.add_master(master=axil_bus)
|
||||
|
||||
ethmac_region_size = (nrxslots + ntxslots) * buffer_depth
|
||||
ethmac_region = SoCRegion(
|
||||
origin=self.mem_map.get("ethmac", None),
|
||||
size=ethmac_region_size,
|
||||
cached=False,
|
||||
)
|
||||
self.bus.add_slave(name="ethmac", slave=ethmac.bus, region=ethmac_region)
|
||||
|
||||
# Interrupt Interface ----------------------------------------------------------------------
|
||||
self.comb += self.platform.request("interrupt").eq(self.ethmac.ev.irq)
|
||||
|
||||
|
||||
# UDP Core -----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
class UDPCore(PHYCore):
|
||||
def add_streamer_port(self, platform, name, port_cfg):
|
||||
# Use default Data-Width of 8-bit when not specified.
|
||||
|
|
@ -571,6 +645,8 @@ class UDPCore(PHYCore):
|
|||
|
||||
|
||||
# Build --------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
def main(core_config):
|
||||
# Convert YAML elements to Python/LiteX --------------------------------------------------------
|
||||
for k, v in core_config.items():
|
||||
|
|
@ -598,7 +674,12 @@ def main(core_config):
|
|||
raise ValueError("Unsupported vendor: {}".format(core_config["vendor"]))
|
||||
platform.add_extension(_io)
|
||||
|
||||
soc = UDPCore(platform, core_config)
|
||||
if core_config["core"] in ["wishbone", "axi-lite"]:
|
||||
soc = MACCore(platform, core_config)
|
||||
elif core_config["core"] == "udp":
|
||||
soc = UDPCore(platform, core_config)
|
||||
else:
|
||||
raise ValueError("Unknown core: {}".format(core_config["core"]))
|
||||
|
||||
with TemporaryDirectory() as path:
|
||||
builder = Builder(soc, compile_gateware=False, output_dir=path)
|
||||
|
|
|
|||
Loading…
Reference in New Issue