ethernet: add HWITL ethernet test
This commit is contained in:
parent
2761507803
commit
363bef8d87
|
|
@ -20,9 +20,9 @@ class EthernetIOCoreExample(Elaboratable):
|
|||
vendor="xilinx",
|
||||
toolchain="vivado",
|
||||
refclk_freq=50e6,
|
||||
clk_freq = 50e6,
|
||||
fpga_ip_addr = "10.0.0.2",
|
||||
host_ip_addr = "10.0.0.1",
|
||||
clk_freq=50e6,
|
||||
fpga_ip_addr="10.0.0.2",
|
||||
host_ip_addr="10.0.0.1",
|
||||
udp_port=2000,
|
||||
)
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ class EthernetIOCoreExample(Elaboratable):
|
|||
("i", "clk", ClockSignal()),
|
||||
("o", "ethclk", ethclk.clk),
|
||||
)
|
||||
platform.add_file("divider.sv", open("divider.sv"))
|
||||
platform.add_file("divider.sv", open("../common/divider.sv"))
|
||||
|
||||
# Add Manta as a submodule
|
||||
m.submodules.manta = DomainRenamer("ethclk")(self.manta)
|
||||
|
|
@ -55,46 +55,46 @@ class EthernetIOCoreExample(Elaboratable):
|
|||
m.d.comb += led.o.eq(self.leds[i])
|
||||
m.submodules += led
|
||||
|
||||
# Wire Ethernet pins to the Manta instance
|
||||
|
||||
# This is only required for Amaranth < 0.5.2
|
||||
eth_pin_names = ["mdio", "mdc", "reset", "rxd", "rxerr", "txd", "txen", "crs_dv", "int", "clk"]
|
||||
eth_pin_names = [
|
||||
"mdio",
|
||||
"mdc",
|
||||
"reset",
|
||||
"rxd",
|
||||
"rxerr",
|
||||
"txd",
|
||||
"txen",
|
||||
"crs_dv",
|
||||
"int",
|
||||
"clk",
|
||||
]
|
||||
eth_pin_dirs = {name: "-" for name in eth_pin_names}
|
||||
eth_pins = platform.request("eth", dir=eth_pin_dirs)
|
||||
|
||||
# For Amaranth > 0.5.2, this simpler syntax may be used:
|
||||
# eth_pins = platform.request("eth")
|
||||
|
||||
# self.manta.interface.set_phy_io(
|
||||
# rmii_clocks_ref_clk = eth_pins.clk,
|
||||
# rmii_rst_n = eth_pins.reset,
|
||||
# rmii_rx_data = eth_pins.rxd,
|
||||
# rmii_crs_dv = eth_pins.crs_dv,
|
||||
# rmii_tx_en = eth_pins.txen,
|
||||
# rmii_tx_data = eth_pins.txd,
|
||||
# rmii_mdc = eth_pins.mdc,
|
||||
# rmii_mdio = eth_pins.mdio,
|
||||
# )
|
||||
|
||||
# Run the PHY's ethclk from the 50MHz divider
|
||||
m.submodules.eth_clk_io_buf = eth_clk_io_buf = io.Buffer("o", eth_pins.clk)
|
||||
m.d.comb += eth_clk_io_buf.o.eq(ethclk.clk)
|
||||
|
||||
self.manta.interface._phy_io = [
|
||||
("i", "rmii_clocks_ref_clk", ethclk.clk),
|
||||
("o", "rmii_rst_n", eth_pins.reset.io),
|
||||
("i", "rmii_rx_data", eth_pins.rxd.io),
|
||||
("i", "rmii_crs_dv", eth_pins.crs_dv.io),
|
||||
("o", "rmii_tx_en", eth_pins.txen.io),
|
||||
("o", "rmii_tx_data", eth_pins.txd.io),
|
||||
("o", "rmii_mdc", eth_pins.mdc.io),
|
||||
("io", "rmii_mdio", eth_pins.mdio.io),
|
||||
]
|
||||
# Wire Ethernet pins to the Manta instance
|
||||
self.manta.interface.set_phy_io(
|
||||
rmii_clocks_ref_clk=ethclk.clk,
|
||||
rmii_rst_n=eth_pins.reset.io,
|
||||
rmii_rx_data=eth_pins.rxd.io,
|
||||
rmii_crs_dv=eth_pins.crs_dv.io,
|
||||
rmii_tx_en=eth_pins.txen.io,
|
||||
rmii_tx_data=eth_pins.txd.io,
|
||||
rmii_mdc=eth_pins.mdc.io,
|
||||
rmii_mdio=eth_pins.mdio.io,
|
||||
)
|
||||
|
||||
return m
|
||||
|
||||
def test(self):
|
||||
# Build and program the FPGA
|
||||
# self.platform.build(self, do_program=True)
|
||||
self.platform.build(self, do_program=True)
|
||||
|
||||
# Iterate through all the LEDs, blinking them off and on
|
||||
i = 0
|
||||
|
|
@ -104,11 +104,15 @@ class EthernetIOCoreExample(Elaboratable):
|
|||
sleep(0.1)
|
||||
|
||||
|
||||
# Amaranth has a built-in build system, and well as a set of platform
|
||||
# definitions for a huge number of FPGA boards. The class defined above is
|
||||
# very generic, as it specifies a design independent of any particular FGPA
|
||||
# board. This means that by changing which platform you pass UARTIOCoreExample
|
||||
# below, you can port this example to any FPGA board!
|
||||
# Although Amaranth provides an environment that is almost entirely independent
|
||||
# of FPGA vendor or family, it does not provide any facilites for clock
|
||||
# generation. As a result, this example design includes an external Verilog
|
||||
# snippet containing a clock generator created by Vivado's Clock Wizard.
|
||||
# This uses a MMCM clock generation primitive to make a 50MHz clock from the
|
||||
# onboard 100MHz oscillator, in order to drive the Ethernet PHY. This primitive
|
||||
# is only available on Xilinx Series-7 parts, so this example will only work on
|
||||
# Series-7 parts clocked at 100MHz that have RMII PHYs connected...which is
|
||||
# pretty much just the Nexys4DDR and the Arty A7 :)
|
||||
|
||||
if __name__ == "__main__":
|
||||
from amaranth_boards.nexys4ddr import Nexys4DDRPlatform
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
!divider.sv
|
||||
|
|
@ -51,7 +51,7 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// User entered comments
|
||||
//----------------------------------------------------------------------------
|
||||
// popopopopopopopopopopop
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Output Output Phase Duty Cycle Pk-to-Pk Phase
|
||||
|
|
@ -4,6 +4,7 @@ from random import getrandbits
|
|||
from amaranth import *
|
||||
from amaranth.hdl import IOPort
|
||||
|
||||
from manta.ethernet.phy_io_defs import phy_io_mapping
|
||||
from manta.ethernet.sink_bridge import UDPSinkBridge
|
||||
from manta.ethernet.source_bridge import UDPSourceBridge
|
||||
from manta.utils import *
|
||||
|
|
@ -76,7 +77,8 @@ class EthernetInterface(Elaboratable):
|
|||
self.bus_i = Signal(InternalBus())
|
||||
self.bus_o = Signal(InternalBus())
|
||||
|
||||
self._phy_io = self._define_phy_io()
|
||||
# Define PHY IO, assuming that we're in a Verilog-based workflow.
|
||||
self._define_phy_io(self._phy)
|
||||
|
||||
clk_freq_rounded = round(self._clk_freq)
|
||||
self._dhcp_start = Signal()
|
||||
|
|
@ -158,95 +160,24 @@ class EthernetInterface(Elaboratable):
|
|||
octets = [bin(int(o))[2:].zfill(8) for o in ip_addr.split(".")]
|
||||
return int("".join(octets), 2)
|
||||
|
||||
def _define_phy_io(self):
|
||||
if self._phy in ["LiteEthPHYMII"]:
|
||||
return [
|
||||
("i", "mii_clocks_tx", mii_clocks_tx := IOPort(1)),
|
||||
("i", "mii_clocks_rx", mii_clocks_rx := IOPort(1)),
|
||||
("o", "mii_rst_n", mii_rst_n := IOPort(1)),
|
||||
("io", "mii_mdio", mii_mdio := IOPort(1)),
|
||||
("o", "mii_mdc", mii_mdc := IOPort(1)),
|
||||
("i", "mii_rx_dv", mii_rx_dv := IOPort(1)),
|
||||
("i", "mii_rx_er", mii_rx_er := Signal()),
|
||||
("i", "mii_rx_data", mii_rx_data := IOPort(4)),
|
||||
("o", "mii_tx_en", mii_tx_en := IOPort(1)),
|
||||
("o", "mii_tx_data", mii_tx_data := IOPort(4)),
|
||||
("i", "mii_col", mii_col := IOPort(1)),
|
||||
("i", "mii_crs", mii_crs := IOPort(1)),
|
||||
]
|
||||
def _define_phy_io(self, phy):
|
||||
phy_io = phy_io_mapping[phy]
|
||||
|
||||
elif self._phy in ["LiteEthPHYRMII"]:
|
||||
return [
|
||||
("i", "rmii_clocks_ref_clk", rmii_clocks_ref_clk := IOPort(1)),
|
||||
("o", "rmii_rst_n", rmii_rst_n := IOPort(1)),
|
||||
("i", "rmii_rx_data", rmii_rx_data := IOPort(2)),
|
||||
("i", "rmii_crs_dv", rmii_crs_dv := IOPort(1)),
|
||||
("o", "rmii_tx_en", rmii_tx_en := IOPort(1)),
|
||||
("o", "rmii_tx_data", rmii_tx_data := IOPort(2)),
|
||||
("o", "rmii_mdc", rmii_mdc := IOPort(1)),
|
||||
("io", "rmii_mdio", rmii_mdio := IOPort(1)),
|
||||
]
|
||||
self._phy_io = [
|
||||
(p.dir, p.name, IOPort(width=p.width, name=p.name)) for p in phy_io
|
||||
]
|
||||
|
||||
elif self._phy in [
|
||||
"LiteEthPHYGMII",
|
||||
"LiteEthPHYGMIIMII",
|
||||
]:
|
||||
return [
|
||||
("i", "gmii_clocks_tx", gmii_clocks_tx := IOPort(1)),
|
||||
("o", "gmii_clocks_gtx", gmii_clocks_gtx := IOPort(1)),
|
||||
("i", "gmii_clocks_rx", gmii_clocks_rx := IOPort(1)),
|
||||
("o", "gmii_rst_n", gmii_rst_n := IOPort(1)),
|
||||
("i", "gmii_int_n", gmii_int_n := IOPort(1)),
|
||||
("io", "gmii_mdio", gmii_mdio := IOPort(1)),
|
||||
("o", "gmii_mdc", gmii_mdc := IOPort(1)),
|
||||
("i", "gmii_rx_dv", gmii_rx_dv := IOPort(1)),
|
||||
("i", "gmii_rx_er", gmii_rx_er := IOPort(1)),
|
||||
("i", "gmii_rx_data", gmii_rx_data := IOPort(8)),
|
||||
("o", "gmii_tx_en", gmii_tx_en := IOPort(1)),
|
||||
("o", "gmii_tx_er", gmii_tx_er := IOPort(1)),
|
||||
("o", "gmii_tx_data", gmii_tx_data := IOPort(8)),
|
||||
("i", "gmii_col", gmii_col := IOPort(1)),
|
||||
("i", "gmii_crs", gmii_crs := IOPort(1)),
|
||||
]
|
||||
def set_phy_io(self, **kwargs):
|
||||
# Given the user's IO, create a list of tuples that can be passed to Instance
|
||||
# Only to be used in Amaranth-Native workflows!
|
||||
|
||||
elif self._phy in [
|
||||
"LiteEthS7PHYRGMII",
|
||||
"LiteEthECP5PHYRGMII",
|
||||
]:
|
||||
return [
|
||||
("o", "rgmii_clocks_tx", rgmii_clocks_tx := IOPort(1)),
|
||||
("i", "rgmii_clocks_rx", rgmii_clocks_rx := IOPort(1)),
|
||||
("o", "rgmii_rst_n", rgmii_rst_n := IOPort(1)),
|
||||
("i", "rgmii_int_n", rgmii_int_n := IOPort(1)),
|
||||
("io", "rgmii_mdio", rgmii_mdio := IOPort(1)),
|
||||
("o", "rgmii_mdc", rgmii_mdc := IOPort(1)),
|
||||
("i", "rgmii_rx_ctl", rgmii_rx_ctl := IOPort(1)),
|
||||
("i", "rgmii_rx_data", rgmii_rx_data := IOPort(4)),
|
||||
("o", "rgmii_tx_ctl", rgmii_tx_ctl := IOPort(1)),
|
||||
("o", "rgmii_tx_data", rgmii_tx_data := IOPort(4)),
|
||||
]
|
||||
all_phy_io = phy_io_mapping.values()
|
||||
all_io_definitions = [io for phy_io in all_phy_io for io in phy_io]
|
||||
find_io_def = lambda name: next(
|
||||
(iod for iod in all_io_definitions if iod.name == name), None
|
||||
)
|
||||
|
||||
elif self._phy in [
|
||||
"A7_1000BASEX",
|
||||
"A7_2500BASEX",
|
||||
"K7_1000BASEX",
|
||||
"K7_2500BASEX",
|
||||
"KU_1000BASEX",
|
||||
"KU_2500BASEX",
|
||||
"USP_GTH_1000BASEX",
|
||||
"USP_GTH_2500BASEX",
|
||||
"USP_GTY_1000BASEX",
|
||||
"USP_GTY_2500BASEX",
|
||||
]:
|
||||
return [
|
||||
("i", "sgmii_refclk", sgmii_refclk := IOPort(1)),
|
||||
("i", "sgmii_rst", sgmii_rst := IOPort(1)),
|
||||
("o", "sgmii_txp", sgmii_txp := IOPort(1)),
|
||||
("o", "sgmii_txn", sgmii_txn := IOPort(1)),
|
||||
("i", "sgmii_rxp", sgmii_rxp := IOPort(1)),
|
||||
("i", "sgmii_rxn", sgmii_rxn := IOPort(1)),
|
||||
("o", "sgmii_link_up", sgmii_link_up := IOPort(1)),
|
||||
]
|
||||
self._phy_io = [(find_io_def(k).dir, k, v) for k, v in kwargs.items()]
|
||||
|
||||
def elaborate(self, platform):
|
||||
m = Module()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,101 @@
|
|||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@dataclass
|
||||
class IODefinition:
|
||||
dir: str
|
||||
name: str
|
||||
width: int
|
||||
|
||||
|
||||
mii_phy_io = [
|
||||
IODefinition("i", "mii_clocks_tx", 1),
|
||||
IODefinition("i", "mii_clocks_rx", 1),
|
||||
IODefinition("o", "mii_rst_n", 1),
|
||||
IODefinition("io", "mii_mdio", 1),
|
||||
IODefinition("o", "mii_mdc", 1),
|
||||
IODefinition("i", "mii_rx_dv", 1),
|
||||
IODefinition("i", "mii_rx_er", 1),
|
||||
IODefinition("i", "mii_rx_data", 4),
|
||||
IODefinition("o", "mii_tx_en", 1),
|
||||
IODefinition("o", "mii_tx_data", 4),
|
||||
IODefinition("i", "mii_col", 1),
|
||||
IODefinition("i", "mii_crs", 1),
|
||||
]
|
||||
|
||||
rmii_phy_io = [
|
||||
IODefinition("i", "rmii_clocks_ref_clk", 1),
|
||||
IODefinition("o", "rmii_rst_n", 1),
|
||||
IODefinition("i", "rmii_rx_data", 2),
|
||||
IODefinition("i", "rmii_crs_dv", 1),
|
||||
IODefinition("o", "rmii_tx_en", 1),
|
||||
IODefinition("o", "rmii_tx_data", 2),
|
||||
IODefinition("o", "rmii_mdc", 1),
|
||||
IODefinition("io", "rmii_mdio", 1),
|
||||
]
|
||||
|
||||
gmii_phy_io = [
|
||||
IODefinition("i", "gmii_clocks_tx", 1),
|
||||
IODefinition("o", "gmii_clocks_gtx", 1),
|
||||
IODefinition("i", "gmii_clocks_rx", 1),
|
||||
IODefinition("o", "gmii_rst_n", 1),
|
||||
IODefinition("i", "gmii_int_n", 1),
|
||||
IODefinition("io", "gmii_mdio", 1),
|
||||
IODefinition("o", "gmii_mdc", 1),
|
||||
IODefinition("i", "gmii_rx_dv", 1),
|
||||
IODefinition("i", "gmii_rx_er", 1),
|
||||
IODefinition("i", "gmii_rx_data", 8),
|
||||
IODefinition("o", "gmii_tx_en", 1),
|
||||
IODefinition("o", "gmii_tx_er", 1),
|
||||
IODefinition("o", "gmii_tx_data", 8),
|
||||
IODefinition("i", "gmii_col", 1),
|
||||
IODefinition("i", "gmii_crs", 1),
|
||||
]
|
||||
|
||||
rgmii_phy_io = [
|
||||
IODefinition("o", "rgmii_clocks_tx", 1),
|
||||
IODefinition("i", "rgmii_clocks_rx", 1),
|
||||
IODefinition("o", "rgmii_rst_n", 1),
|
||||
IODefinition("i", "rgmii_int_n", 1),
|
||||
IODefinition("io", "rgmii_mdio", 1),
|
||||
IODefinition("o", "rgmii_mdc", 1),
|
||||
IODefinition("i", "rgmii_rx_ctl", 1),
|
||||
IODefinition("i", "rgmii_rx_data", 4),
|
||||
IODefinition("o", "rgmii_tx_ctl", 1),
|
||||
IODefinition("o", "rgmii_tx_data", 4),
|
||||
]
|
||||
|
||||
sgmii_phy_io = [
|
||||
IODefinition("i", "sgmii_refclk", 1),
|
||||
IODefinition("i", "sgmii_rst", 1),
|
||||
IODefinition("o", "sgmii_txp", 1),
|
||||
IODefinition("o", "sgmii_txn", 1),
|
||||
IODefinition("i", "sgmii_rxp", 1),
|
||||
IODefinition("i", "sgmii_rxn", 1),
|
||||
IODefinition("o", "sgmii_link_up", 1),
|
||||
]
|
||||
|
||||
|
||||
phy_io_mapping = {
|
||||
# MII
|
||||
"LiteEthPHYMII": mii_phy_io,
|
||||
# RMII
|
||||
"LiteEthPHYRMII": rmii_phy_io,
|
||||
# GMII
|
||||
"LiteEthPHYGMII": gmii_phy_io,
|
||||
"LiteEthPHYGMIIMII": gmii_phy_io,
|
||||
# RGMII
|
||||
"LiteEthS7PHYRGMII": rgmii_phy_io,
|
||||
"LiteEthECP5PHYRGMII": rgmii_phy_io,
|
||||
# SGMII
|
||||
"A7_1000BASEX": sgmii_phy_io,
|
||||
"A7_2500BASEX": sgmii_phy_io,
|
||||
"K7_1000BASEX": sgmii_phy_io,
|
||||
"K7_2500BASEX": sgmii_phy_io,
|
||||
"KU_1000BASEX": sgmii_phy_io,
|
||||
"KU_2500BASEX": sgmii_phy_io,
|
||||
"USP_GTH_1000BASEX": sgmii_phy_io,
|
||||
"USP_GTH_2500BASEX": sgmii_phy_io,
|
||||
"USP_GTY_1000BASEX": sgmii_phy_io,
|
||||
"USP_GTY_2500BASEX": sgmii_phy_io,
|
||||
}
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
import pytest
|
||||
import time
|
||||
from random import getrandbits
|
||||
from amaranth import *
|
||||
from amaranth.lib import io
|
||||
from amaranth_boards.nexys4ddr import Nexys4DDRPlatform
|
||||
|
||||
from manta import *
|
||||
from manta.utils import *
|
||||
|
||||
class EthernetMemoryCoreTest(Elaboratable):
|
||||
def __init__(self, platform):
|
||||
self.platform = platform
|
||||
self.width = 28
|
||||
self.depth = 612
|
||||
|
||||
# Create Manta instance
|
||||
self.manta = Manta()
|
||||
|
||||
# Configure it to communicate over Ethernet
|
||||
self.manta.interface = EthernetInterface(
|
||||
phy="LiteEthPHYRMII",
|
||||
device="xc7a",
|
||||
vendor="xilinx",
|
||||
toolchain="vivado",
|
||||
refclk_freq=50e6,
|
||||
clk_freq=50e6,
|
||||
fpga_ip_addr="10.0.0.2",
|
||||
host_ip_addr="10.0.0.1",
|
||||
udp_port=2000,
|
||||
)
|
||||
|
||||
self.manta.cores.mem = MemoryCore("bidirectional", self.width, self.depth)
|
||||
|
||||
def elaborate(self, platform):
|
||||
m = Module()
|
||||
|
||||
# Create 50MHz clock domain
|
||||
m.domains.ethclk = ethclk = ClockDomain()
|
||||
m.submodules.divider = Instance(
|
||||
"divider",
|
||||
("i", "clk", ClockSignal()),
|
||||
("o", "ethclk", ethclk.clk),
|
||||
)
|
||||
platform.add_file("../examples/common/divider.sv", open("divider.sv"))
|
||||
|
||||
# Add Manta as a submodule
|
||||
m.submodules.manta = DomainRenamer("ethclk")(self.manta)
|
||||
|
||||
# This is only required for Amaranth < 0.5.2
|
||||
eth_pin_names = [
|
||||
"mdio",
|
||||
"mdc",
|
||||
"reset",
|
||||
"rxd",
|
||||
"rxerr",
|
||||
"txd",
|
||||
"txen",
|
||||
"crs_dv",
|
||||
"int",
|
||||
"clk",
|
||||
]
|
||||
eth_pin_dirs = {name: "-" for name in eth_pin_names}
|
||||
eth_pins = platform.request("eth", dir=eth_pin_dirs)
|
||||
|
||||
# For Amaranth > 0.5.2, this simpler syntax may be used:
|
||||
# eth_pins = platform.request("eth")
|
||||
|
||||
# Run the PHY's ethclk from the 50MHz divider
|
||||
m.submodules.eth_clk_io_buf = eth_clk_io_buf = io.Buffer("o", eth_pins.clk)
|
||||
m.d.comb += eth_clk_io_buf.o.eq(ethclk.clk)
|
||||
|
||||
# Wire Ethernet pins to the Manta instance
|
||||
self.manta.interface.set_phy_io(
|
||||
rmii_clocks_ref_clk=ethclk.clk,
|
||||
rmii_rst_n=eth_pins.reset.io,
|
||||
rmii_rx_data=eth_pins.rxd.io,
|
||||
rmii_crs_dv=eth_pins.crs_dv.io,
|
||||
rmii_tx_en=eth_pins.txen.io,
|
||||
rmii_tx_data=eth_pins.txd.io,
|
||||
rmii_mdc=eth_pins.mdc.io,
|
||||
rmii_mdio=eth_pins.mdio.io,
|
||||
)
|
||||
|
||||
return m
|
||||
|
||||
def verify(self):
|
||||
self.platform.build(self, do_program=True)
|
||||
|
||||
# Wait for the FPGA to acquire IP address
|
||||
time.sleep(5)
|
||||
|
||||
for addr in jumble(range(self.depth)):
|
||||
data = getrandbits(self.width)
|
||||
self.manta.cores.mem.write(addr, data)
|
||||
|
||||
# Verify the same number is returned when reading
|
||||
readback = self.manta.cores.mem.read(addr)
|
||||
if readback != data:
|
||||
raise ValueError(
|
||||
f"Memory read from {hex(addr)} returned {hex(readback)} instead of {hex(data)}"
|
||||
)
|
||||
|
||||
|
||||
|
||||
@pytest.mark.skipif(not xilinx_tools_installed(), reason="no toolchain installed")
|
||||
def test_mem_core_xilinx():
|
||||
EthernetMemoryCoreTest(Nexys4DDRPlatform()).verify()
|
||||
|
|
@ -33,10 +33,10 @@ from amaranth_boards.icestick import ICEStickPlatform
|
|||
from amaranth_boards.nexys4ddr import Nexys4DDRPlatform
|
||||
|
||||
# Import Examples
|
||||
from examples.amaranth.ethernet_io_core import EthernetIOCoreExample
|
||||
from examples.amaranth.uart_io_core import UARTIOCoreExample
|
||||
from examples.amaranth.uart_logic_analyzer import UARTLogicAnalyzerExample
|
||||
from examples.amaranth.uart_memory_core import UARTMemoryCoreExample
|
||||
from examples.amaranth.ethernet_io_core import EthernetIOCoreExample
|
||||
|
||||
# Manually specify a list of examples/platforms to test.
|
||||
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ class MemoryCoreLoopbackTest(Elaboratable):
|
|||
|
||||
if self.mode in ["bidirectional", "host_to_fpga"]:
|
||||
for addr in jumble(range(self.depth)):
|
||||
# Write a random balue to a random bus address
|
||||
# Write a random value to a random bus address
|
||||
data = getrandbits(self.width)
|
||||
self.manta.cores.mem.write(addr, data)
|
||||
|
||||
|
|
@ -87,7 +87,7 @@ class MemoryCoreLoopbackTest(Elaboratable):
|
|||
readback = self.read_user_side(addr)
|
||||
if readback != data:
|
||||
raise ValueError(
|
||||
f"Memory read from {hex(addr)} returned {hex(data)} instead of {hex(readback)}."
|
||||
f"Memory read from {hex(addr)} returned {hex(readback)} instead of {hex(data)}."
|
||||
)
|
||||
|
||||
if self.mode in ["bidirectional", "fpga_to_host"]:
|
||||
|
|
@ -100,7 +100,7 @@ class MemoryCoreLoopbackTest(Elaboratable):
|
|||
readback = self.manta.cores.mem.read(addr)
|
||||
if readback != data:
|
||||
raise ValueError(
|
||||
f"Memory read from {hex(addr)} returned {hex(data)} instead of {hex(readback)}."
|
||||
f"Memory read from {hex(addr)} returned {hex(readback)} instead of {hex(data)}."
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue