Compare commits
6 commits
a28816b2e6
...
c44e94da5d
Author | SHA1 | Date | |
---|---|---|---|
c44e94da5d | |||
a13569c2eb | |||
5f589aca37 | |||
5fb8d3a176 | |||
f026fcfe5c | |||
77c602c8fd |
6 changed files with 162 additions and 52 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
||||||
/work/
|
/work/
|
||||||
*.o
|
*.o
|
||||||
|
__pycache__
|
||||||
|
|
6
firmware/Cargo.toml
Normal file
6
firmware/Cargo.toml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[package]
|
||||||
|
name = "firmware"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
3
firmware/src/main.rs
Normal file
3
firmware/src/main.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fn main() {
|
||||||
|
println!("Hello, world!");
|
||||||
|
}
|
|
@ -27,7 +27,7 @@ from liteeth.common import *
|
||||||
|
|
||||||
from liteeth import phy as liteeth_phys
|
from liteeth import phy as liteeth_phys
|
||||||
from liteeth.mac import LiteEthMAC
|
from liteeth.mac import LiteEthMAC
|
||||||
from liteeth.core import LiteEthUDPIPCore
|
from liteeth_cores import LiteEthUDPIPCore
|
||||||
from liteeth.core.udp import LiteEthUDP
|
from liteeth.core.udp import LiteEthUDP
|
||||||
|
|
||||||
# IOs ----------------------------------------------------------------------------------------------
|
# IOs ----------------------------------------------------------------------------------------------
|
||||||
|
@ -43,6 +43,9 @@ _io = [
|
||||||
# IP/MAC Address.
|
# IP/MAC Address.
|
||||||
("ip_address", 0, Pins(32)),
|
("ip_address", 0, Pins(32)),
|
||||||
|
|
||||||
|
# Interrupt
|
||||||
|
("interrupt", 0, Pins(1)),
|
||||||
|
|
||||||
# MII PHY Pads
|
# MII PHY Pads
|
||||||
("mii_eth_clocks", 0,
|
("mii_eth_clocks", 0,
|
||||||
Subsignal("tx", Pins(1)),
|
Subsignal("tx", Pins(1)),
|
||||||
|
@ -180,40 +183,26 @@ class UDPCore(PHYCore):
|
||||||
clk_freq=CLK_FREQ,
|
clk_freq=CLK_FREQ,
|
||||||
dw=8,
|
dw=8,
|
||||||
with_sys_datapath=False,
|
with_sys_datapath=False,
|
||||||
|
hybrid=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
# DHCP port
|
# CPU port
|
||||||
data_width = 32
|
nrxslots = self.core.mac.rx_slots.constant
|
||||||
|
ntxslots = self.core.mac.tx_slots.constant
|
||||||
|
|
||||||
platform.add_extension(get_udp_streamer_port_ios(
|
wb_bus = wishbone.Interface()
|
||||||
"dhcp",
|
platform.add_extension(wb_bus.get_ios("wishbone"))
|
||||||
data_width=data_width,
|
self.comb += wb_bus.connect_to_pads(self.platform.request("wishbone"), mode="slave")
|
||||||
))
|
self.add_wb_master(wb_bus)
|
||||||
dhcp_ios = platform.request("dhcp")
|
|
||||||
|
|
||||||
dhcp_streamer = LiteEthUDPStreamer(
|
ethmac_region_size = (nrxslots + ntxslots)*buffer_depth
|
||||||
self.core.udp,
|
ethmac_region = SoCRegion(
|
||||||
ip_address=dhcp_ios.ip_address,
|
origin=self.mem_map.get("ethmac", None),
|
||||||
udp_port=67,
|
size=ethmac_region_size,
|
||||||
data_width=data_width,
|
cached=False
|
||||||
tx_fifo_depth=64,
|
|
||||||
rx_fifo_depth=64
|
|
||||||
)
|
)
|
||||||
self.submodules += dhcp_streamer
|
self.bus.add_slave(name="ethmac", slave=self.core.mac.bus, region=ethmac_region)
|
||||||
|
self.comb += self.platform.request("interrupt").eq(self.core.mac.ev.irq)
|
||||||
self.comb += [
|
|
||||||
# Connect UDP Sink IOs to UDP Steamer.
|
|
||||||
dhcp_streamer.sink.valid.eq(dhcp_ios.sink_valid),
|
|
||||||
dhcp_streamer.sink.last.eq(dhcp_ios.sink_last),
|
|
||||||
dhcp_ios.sink_ready.eq(dhcp_streamer.sink.ready),
|
|
||||||
dhcp_streamer.sink.data.eq(dhcp_ios.sink_data),
|
|
||||||
|
|
||||||
# Connect UDP Streamer to UDP Source IOs.
|
|
||||||
dhcp_ios.source_valid.eq(dhcp_streamer.source.valid),
|
|
||||||
dhcp_ios.source_last.eq(dhcp_streamer.source.last),
|
|
||||||
dhcp_streamer.source.ready.eq(dhcp_ios.source_ready),
|
|
||||||
dhcp_ios.source_data.eq(dhcp_streamer.source.data),
|
|
||||||
]
|
|
||||||
|
|
||||||
# Pixel port
|
# Pixel port
|
||||||
data_width = 32
|
data_width = 32
|
||||||
|
|
96
liteeth_cores.py
Normal file
96
liteeth_cores.py
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
#
|
||||||
|
# This file is part of LiteEth.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2015-2020 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
from liteeth.common import *
|
||||||
|
from liteeth.mac import LiteEthMAC
|
||||||
|
from liteeth.core.arp import LiteEthARP
|
||||||
|
from liteeth.core.ip import LiteEthIP
|
||||||
|
from liteeth.core.udp import LiteEthUDP
|
||||||
|
from liteeth.core.icmp import LiteEthICMP
|
||||||
|
|
||||||
|
# IP Core ------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class LiteEthIPCore(Module, AutoCSR):
|
||||||
|
def __init__(self, phy, mac_address, ip_address, clk_freq, dw=8,
|
||||||
|
hybrid = False,
|
||||||
|
with_icmp = True,
|
||||||
|
with_ip_broadcast = True,
|
||||||
|
with_sys_datapath = False):
|
||||||
|
# Parameters.
|
||||||
|
# -----------
|
||||||
|
ip_address = convert_ip(ip_address)
|
||||||
|
|
||||||
|
# MAC.
|
||||||
|
# ----
|
||||||
|
self.submodules.mac = LiteEthMAC(
|
||||||
|
phy = phy,
|
||||||
|
dw = dw,
|
||||||
|
interface = "hybrid" if hybrid else "crossbar",
|
||||||
|
with_preamble_crc = True,
|
||||||
|
with_sys_datapath = with_sys_datapath,
|
||||||
|
)
|
||||||
|
|
||||||
|
# ARP.
|
||||||
|
# ----
|
||||||
|
self.submodules.arp = LiteEthARP(
|
||||||
|
mac = self.mac,
|
||||||
|
mac_address = mac_address,
|
||||||
|
ip_address = ip_address,
|
||||||
|
clk_freq = clk_freq,
|
||||||
|
dw = dw,
|
||||||
|
)
|
||||||
|
|
||||||
|
# IP.
|
||||||
|
# ---
|
||||||
|
self.submodules.ip = LiteEthIP(
|
||||||
|
mac = self.mac,
|
||||||
|
mac_address = mac_address,
|
||||||
|
ip_address = ip_address,
|
||||||
|
arp_table = self.arp.table,
|
||||||
|
with_broadcast = with_ip_broadcast,
|
||||||
|
dw = dw,
|
||||||
|
)
|
||||||
|
# ICMP (Optional).
|
||||||
|
# ----------------
|
||||||
|
if with_icmp:
|
||||||
|
self.submodules.icmp = LiteEthICMP(
|
||||||
|
ip = self.ip,
|
||||||
|
ip_address = ip_address,
|
||||||
|
dw = dw,
|
||||||
|
)
|
||||||
|
|
||||||
|
# UDP IP Core --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class LiteEthUDPIPCore(LiteEthIPCore):
|
||||||
|
def __init__(self, phy, mac_address, ip_address, clk_freq, dw=8,
|
||||||
|
hybrid=False,
|
||||||
|
with_icmp = True,
|
||||||
|
with_ip_broadcast = True,
|
||||||
|
with_sys_datapath = False):
|
||||||
|
# Parameters.
|
||||||
|
# -----------
|
||||||
|
ip_address = convert_ip(ip_address)
|
||||||
|
|
||||||
|
# Core: MAC + ARP + IP + (ICMP).
|
||||||
|
# ------------------------------
|
||||||
|
LiteEthIPCore.__init__(self,
|
||||||
|
phy = phy,
|
||||||
|
mac_address = mac_address,
|
||||||
|
ip_address = ip_address,
|
||||||
|
clk_freq = clk_freq,
|
||||||
|
hybrid = hybrid,
|
||||||
|
with_icmp = with_icmp,
|
||||||
|
dw = dw,
|
||||||
|
with_ip_broadcast = with_ip_broadcast,
|
||||||
|
with_sys_datapath = with_sys_datapath,
|
||||||
|
)
|
||||||
|
# UDP.
|
||||||
|
# ----
|
||||||
|
self.submodules.udp = LiteEthUDP(
|
||||||
|
ip = self.ip,
|
||||||
|
ip_address = ip_address,
|
||||||
|
dw = dw,
|
||||||
|
)
|
|
@ -36,7 +36,7 @@ entity arty_a7 is
|
||||||
-- when necessary
|
-- when necessary
|
||||||
pmod_a : out std_logic_vector(7 downto 0);
|
pmod_a : out std_logic_vector(7 downto 0);
|
||||||
pmod_b : out std_logic_vector(7 downto 0);
|
pmod_b : out std_logic_vector(7 downto 0);
|
||||||
pmod_c : in std_logic_vector(7 downto 0);
|
pmod_c : out std_logic_vector(7 downto 0);
|
||||||
pmod_d : out std_logic_vector(7 downto 0);
|
pmod_d : out std_logic_vector(7 downto 0);
|
||||||
|
|
||||||
clock_100mhz : in std_logic;
|
clock_100mhz : in std_logic;
|
||||||
|
@ -87,18 +87,19 @@ architecture a of arty_a7 is
|
||||||
|
|
||||||
ip_address : in std_logic_vector(31 downto 0);
|
ip_address : in std_logic_vector(31 downto 0);
|
||||||
|
|
||||||
--== DHCP PORT ==--
|
--== WISHBONE PORT ==--
|
||||||
dhcp_ip_address : in std_logic_vector(31 downto 0);
|
wishbone_adr : in std_logic_vector(29 downto 0);
|
||||||
|
wishbone_dat_w : in std_logic_vector(31 downto 0);
|
||||||
dhcp_sink_valid : in std_logic;
|
wishbone_dat_r : out std_logic_vector(31 downto 0);
|
||||||
dhcp_sink_last : in std_logic;
|
wishbone_sel : in std_logic_vector(3 downto 0);
|
||||||
dhcp_sink_ready : out std_logic;
|
wishbone_cyc : in std_logic;
|
||||||
dhcp_sink_data : in std_logic_vector(31 downto 0);
|
wishbone_stb : in std_logic;
|
||||||
|
wishbone_ack : out std_logic;
|
||||||
dhcp_source_valid : out std_logic;
|
wishbone_we : in std_logic;
|
||||||
dhcp_source_last : out std_logic;
|
wishbone_cti : in std_logic_vector(2 downto 0);
|
||||||
dhcp_source_ready : in std_logic;
|
wishbone_bte : in std_logic_vector(1 downto 0);
|
||||||
dhcp_source_data : out std_logic_vector(31 downto 0);
|
wishbone_err : out std_logic;
|
||||||
|
interrupt : out std_logic;
|
||||||
|
|
||||||
--== PIXEL DATA PORT ==--
|
--== PIXEL DATA PORT ==--
|
||||||
pixel_bind_port : in std_logic_vector(15 downto 0);
|
pixel_bind_port : in std_logic_vector(15 downto 0);
|
||||||
|
@ -247,12 +248,15 @@ begin
|
||||||
|
|
||||||
ip_address => x"0a141e28", -- 10.20.30.40
|
ip_address => x"0a141e28", -- 10.20.30.40
|
||||||
|
|
||||||
dhcp_ip_address => x"0a141e29", -- 10.20.30.41
|
--== WISHBONE PORT ==--
|
||||||
dhcp_sink_valid => '0',
|
wishbone_adr => (others => '1'),
|
||||||
dhcp_sink_last => '1',
|
wishbone_dat_w => (others => '1'),
|
||||||
dhcp_sink_data => x"cafebebe",
|
wishbone_sel => (others => '1'),
|
||||||
|
wishbone_cyc => '1',
|
||||||
dhcp_source_ready => '1',
|
wishbone_stb => '1',
|
||||||
|
wishbone_we => '1',
|
||||||
|
wishbone_cti => (others => '1'),
|
||||||
|
wishbone_bte => (others => '1'),
|
||||||
|
|
||||||
--== PIXEL DATA PORT ==--
|
--== PIXEL DATA PORT ==--
|
||||||
pixel_bind_port => x"effd", -- port 61437 - "PIXEL"
|
pixel_bind_port => x"effd", -- port 61437 - "PIXEL"
|
||||||
|
@ -320,9 +324,20 @@ begin
|
||||||
|
|
||||||
sys_reset <= not pll_locked or not n_reset;
|
sys_reset <= not pll_locked or not n_reset;
|
||||||
|
|
||||||
pmod_a <= drivers(7 downto 0);
|
pmod_a <= "00" & drivers(5 downto 0);
|
||||||
pmod_b <= drivers(15 downto 8);
|
pmod_b <= "00" & drivers(11 downto 6);
|
||||||
pmod_d <= drivers(23 downto 16);
|
|
||||||
|
pmod_c(7) <= '0';
|
||||||
|
pmod_c(6) <= '0';
|
||||||
|
pmod_c(5) <= drivers(17);
|
||||||
|
pmod_c(4) <= drivers(16);
|
||||||
|
pmod_c(3) <= drivers(15);
|
||||||
|
pmod_c(2) <= drivers(14);
|
||||||
|
-- workaround for https://github.com/gatecat/nextpnr-xilinx/issues/42#issuecomment-1183525828
|
||||||
|
pmod_c(1) <= drivers(12);
|
||||||
|
pmod_c(0) <= drivers(13);
|
||||||
|
|
||||||
|
pmod_d <= "00" & drivers(23 downto 18);
|
||||||
|
|
||||||
sender: process(sys_clk)
|
sender: process(sys_clk)
|
||||||
begin
|
begin
|
||||||
|
|
Loading…
Reference in a new issue