在 FPGA 开发中,集成高速网络通信与大容量数据存储是构建复杂系统的核心。本文将分享一个基于 Xilinx KCU105 或 KC705 开发板的工程实践,实现了 10/100/1000M 自适应的千兆以太网通信(基于 LWIP 协议栈)以及对 DDR4 内存的读写测试。如果你正在为类似的项目寻找参考代码或设计思路,希望本文能为你提供帮助。
一、千兆以太网(10/100/1000M)与 LWIP 通信
1. LWIP 简介
LWIP(Lightweight IP)是一个轻量级的开源 TCP/IP 协议栈,专为资源受限的嵌入式系统设计。在 FPGA 项目中集成 LWIP,可以高效地实现网络协议处理,而无需依赖外部处理器运行完整的操作系统,非常适合需要网络功能的 SoC 或纯 FPGA 设计。
2. 代码示例
以下是一段初始化网络接口的核心 C 代码示例:
#include "lwip/init.h"
#include "lwip/netif.h"
#include “lwip/tcpip.h”
// 定义全局网络接口结构体
struct netif gnetif;
void ethernetif_init(void) {
// 初始化LWIP协议栈
lwip_init();
// 添加网络接口,需配置IP地址、子网掩码、网关等参数
netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, &tcpip_input);
// 设置该接口为默认网络接口并启用
netif_set_default(&gnetif);
netif_set_up(&gnetif);
}
3. 代码分析
- 首先引入 LWIP 相关的头文件,它们分别负责协议栈初始化、网络接口管理和 TCP/IP 核心功能。
- 定义一个全局的
struct netif gnetif 变量,用于管理整个工程的网络接口状态。
- 在
ethernetif_init 函数中,调用 lwip_init() 完成协议栈的初始化工作。
- 使用
netif_add() 函数将物理网络接口(如以太网 MAC IP 核)添加到 LWIP 中,并配置基本的网络参数(示例中用 &ipaddr 等表示,实际需赋值)。
- 最后,通过
netif_set_default() 和 netif_set_up() 启用该接口,使其可以开始收发网络数据包。
二、DDR4 内存读写测试
1. DDR4 在 FPGA 中的应用
DDR4 SDRAM 提供了高带宽和大容量,在视频处理、高速数据采集等 FPGA 应用中常作为核心缓存。在 KCU105/KC705 平台上,可以通过 Xilinx 的 MIG (Memory Interface Generator) IP 核生成 DDR4 控制器,实现对内存的访问。
2. 代码示例(简化控制器 VHDL 描述)
下面是一个高度简化的 DDR4 控制器接口行为描述,用于说明读写的基本逻辑:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity ddr4_controller is
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
write_en : in STD_LOGIC;
read_en : in STD_LOGIC;
address : in STD_LOGIC_VECTOR (31 downto 0);
write_data : in STD_LOGIC_VECTOR (63 downto 0);
read_data : out STD_LOGIC_VECTOR (63 downto 0));
end ddr4_controller;
architecture Behavioral of ddr4_controller is
-- 此处仅为示意,用一个信号模拟一个存储单元
signal ddr4_mem : STD_LOGIC_VECTOR (63 downto 0) := (others => '0');
begin
-- 写进程
process(clk, rst)
begin
if rst = '1' then
ddr4_mem <= (others => ‘0’);
elsif rising_edge(clk) then
if write_en = ‘1’ then
ddr4_mem <= write_data;
end if;
end if;
end process;
-- 读进程
process(clk, rst)
begin
if rst = ‘1’ then
read_data <= (others => ‘0’);
elsif rising_edge(clk) then
if read_en = ‘1’ then
read_data <= ddr4_mem;
end if;
end if;
end process;
end Behavioral;
3. 代码分析
- 代码声明了必要的 IEEE 库,用于标准逻辑类型和算术运算。
ddr4_controller 实体定义了与用户逻辑交互的接口,包括时钟、复位、读写使能、地址和数据总线。
- 在结构体中,用一个
ddr4_mem 信号模拟内存单元。第一个进程处理复位和写操作:复位时清零,在写使能有效时将输入数据存入。
- 第二个进程处理复位和读操作:复位时清空输出,在读使能有效时将
ddr4_mem 的数据输出到 read_data 端口。
- 请注意:这是一个极度简化的模型,用于说明握手逻辑。真实的 DDR4 控制器涉及复杂的初始化、刷新、行列地址选通等时序,必须通过 MIG IP 核来实现。

上图为该工程在 Vivado 中的综合与实现报告截图,显示了资源利用率、时序收敛情况等信息。
三、系统整合与测试
将千兆以太网 LWIP 通信模块和 DDR4 内存控制器整合到一个完整的 FPGA 工程中,便可以构建这样一个数据通路:从网络接收到的数据包,经 LWIP 协议栈解析后,将有效载荷写入 DDR4 内存;反之,也可以从 DDR4 内存中读取数据,经由 LWIP 协议栈打包后通过以太网发送出去。

使用网络调试工具成功与 FPGA 板卡建立 TCP 连接并进行数据回环测试(发送 “hellow world”,接收相同内容)。
在实际工程中,关键在于处理好不同时钟域之间的数据同步(例如以太网 MAC 时钟、DDR4 控制器时钟和用户逻辑时钟),合理分配 FPGA 内部的 BRAM、DSP 等资源,并确保 AXI 等模块间接口协议的正确对接。

基于 MicroBlaze 软核处理器搭建的 SoC 系统架构图,展示了 LWIP、DDR4 控制器(AXI_DDR3_SDRAM)、UART、GPIO 等外设通过 AXI 互连矩阵连接在一起。
通过这样的项目实践,你不仅能掌握 LWIP 在 FPGA 上的移植与配置,还能深入理解高速 DDR4 内存接口的设计要点,从而充分发挥 FPGA 在高速数据处理和实时网络通信方面的潜力。如果在开发中遇到问题,欢迎到技术社区交流讨论,共同学习成长。