基于FPGA的轻量级WEB服务项目
项目开发标准文档
---
1. 项目概述
1.1 项目名称
基于 RISC-V 软核的 FPGA 嵌入式 Web 服务器设计与实现
1.2 项目简介
本项目要求在 FPGA 开发板上,基于 RISC-V 软核处理器,从零实现一个精简的 TCP/IP 协议栈和 HTTP Web 服务器。最终实现的效果是:PC 端浏览器通过网线直连 FPGA 开发板,访问板载网页,并通过网页上的输入框读写 FPGA 内部寄存器,从而实现对开发板的配置和状态进行访问。
1.3 项目定位
本项目是一个系统级工程实践项目,面向具备基础 FPGA 逻辑设计能力(已完成 UART/I2C/SPI 等基础外设实验)的本科生或研究生,项目周期为 8 周(2 个月)。
1.4 核心价值
• 串联 FPGA 硬件逻辑、RISC-V 嵌入式软件、TCP/IP 网络协议、Web 前端四层技术栈
• 掌握从二层以太网帧到七层 HTTP 应用的完整协议闭环
• 理解软核 CPU 与硬件加速器之间的软硬件协同设计方法
• 输出一个可DEMO、可验收、可扩展的完整嵌入式系统
---
2. 项目需求
2.1 功能需求
F1:以太网链路层
| 编号 | 需求描述 | 优先级 |
|------|---------|--------|
| F1.1 | 支持 RGMII 和SGMII 接口,正确接收和发送以太网帧 | P0 |
| F1.2 | 实现目的 MAC 地址过滤(单播匹配 + 广播接收) | P0 |
| F1.3 | 实现 EtherType 字段解析(ARP=0x0806, IP=0x0800) | P0 |
| F1.4 | 支持通过 MDIO 接口配置外部以太网 PHY 芯片 | P1 |
F2:ARP 协议
| 编号 | 需求描述 | 优先级 |
|------|---------|--------|
| F2.1 | 识别并响应 ARP Request(opcode=0x0001) | P0 |
| F2.2 | 正确构建 ARP Reply(opcode=0x0002),交换源/目标 MAC 和 IP | P0 |
| F2.3 | 仅响应对本机 IP 的 ARP 查询 | P0 |
F3:ICMP 协议
| 编号 | 需求描述 | 优先级 |
|------|---------|--------|
| F3.1 | 识别 ICMP Echo Request(Type=8) | P0 |
| F3.2 | 构建 ICMP Echo Reply(Type=0),保留 Identifier 和 Sequence | P0 |
| F3.3 | 正确计算 ICMP 校验和 | P0 |
F4:IP 层
| 编号 | 需求描述 | 优先级 |
|------|---------|--------|
| F4.1 | 解析 IPv4 头(版本、总长度、协议号、源/目标 IP) | P0 |
| F4.2 | 实现目标 IP 地址过滤 | P0 |
| F4.3 | 根据协议号分派(ICMP=0x01, TCP=0x06, UDP=0x11) | P0 |
| F4.4 | 回复时重建 IP 头并重算头校验和 | P0 |
F5:TCP 协议
| 编号 | 需求描述 | 优先级 |
|------|---------|--------|
| F5.1 | 实现 TCP 三次握手(SYN → SYN+ACK → ACK) | P0 |
| F5.2 | 实现 TCP 状态机,至少覆盖 CLOSED / SYN_RECEIVED / ESTABLISHED / FIN_WAIT / LAST_ACK | P0 |
| F5.3 | 支持多连接管理(最少 4 个并发连接) | P1 |
| F5.4 | 正确计算 TCP 校验和(含伪头部) | P0 |
| F5.5 | 支持 TCP 数据分段发送(MSS=1460) | P1 |
| F5.6 | 实现基本的四次挥手(FIN/ACK 处理) | P1 |
F6:HTTP 应用层
| 编号 | 需求描述 | 优先级 |
|------|---------|--------|
| F6.1 | 响应 HTTP GET 请求,返回内嵌的 HTML 控制页面 | P0 |
| F6.2 | 响应 HTTP POST 请求,解析 JSON 格式的地址/数据/模式 | P0 |
| F6.3 | 根据 POST 内容执行寄存器读或写操作 | P0 |
| F6.4 | 正确设置 Content-Length 字段 | P0 |
F7:Web 控制页面
| 编号 | 需求描述 | 优先级 |
|------|---------|--------|
| F7.1 | 提供地址输入框(十六进制格式) | P0 |
| F7.2 | 提供数据输入框(十六进制格式) | P0 |
| F7.3 | 提供读/写模式选择(Radio 按钮) | P0 |
| F7.4 | 使用 JavaScript fetch API 以 POST 方式提交 JSON 数据 | P0 |
| F7.5 | 操作完成后显示结果并自动返回主页 | P1 |
2.2 非功能需求
| 编号 | 需求描述 |
|------|---------|
| NF1 | C 固件代码运行在裸机环境,不依赖任何操作系统 |
| NF2 | 协议栈不依赖第三方网络库,手工实现所有协议层 |
| NF3 | 代码需在 RISC-V 工具链下编译通过(rv32ic 架构) |
| NF4 | 整个固件镜像限制在 16KB 以内 |
| NF5 | 仿真环境下所有协议层功能均可独立验证 |
| NF6 | 板级实测:ARP、Ping、HTTP GET/POST 四类交互全部通过 |
---
3. 实现目标(分层定义)
3.1 第一阶段目标:二层 + 三层闭环
• PC 能够通过 ARP 获取 FPGA 开发板的 MAC 地址
• PC 能够 Ping 通 FPGA 开发板
• Wireshark 抓包可验证 ARP Reply 和 ICMP Echo Reply 报文格式正确
3.2 第二阶段目标:TCP 连接建立
• 浏览器能够与 FPGA 开发板完成 TCP 三次握手
• Wireshark 可验证握手报文的 Seq/Ack 号正确递增
3.3 第三阶段目标:HTTP 页面交互
• 浏览器输入开发板 IP 地址后可看到 HTML 控制页面
• 页面包含地址输入、数据输入、读写选择和确认按钮
3.4 第四阶段目标:硬件控制闭环
• 在网页上输入寄存器地址和数据后点击确认
• POST read:能读回寄存器当前值并在页面上显示
• POST write:能写入目标寄存器,测试控制板上 LED 状态同步变化
---
4. 技术栈
4.1 硬件平台
| 类别 | 选型参考 | 说明 |
|------|---------|------|
| FPGA 开发板 | Xilinx 7 系列 / Altera Cyclone IV/V | 需具备千兆以太网接口 |
| 网络 PHY 芯片 | RTL8211 / 88E1111 等 | 支持 RGMII 或 GMII 接口 |
| 软核 CPU | RISC-V RV32IC | 开源指令集,有现成 GCC 工具链 |
| 调试接口 | JTAG + UART(可选) | 用于仿真波形观测和固件调试 |
4.2 HDL 设计语言与工具
| 类别 | 工具 | 说明 |
|------|------|------|
| 硬件描述语言 | SystemVerilog | 顶层集成与模块连接 |
| 仿真工具 | ModelSim / QuestaSim | 支持 SystemVerilog 仿真 |
| 综合工具 | Vivado / Quartus | 根据开发板选型确定 |
| 波形查看 | ModelSim Wave / GTKWave | 总线时序调试 |
4.3 嵌入式软件工具链
| 类别 | 工具 | 说明 |
|------|------|------|
| 编译器 | riscv-none-elf-gcc | RISC-V 裸机交叉编译 |
| 链接器 | riscv-none-elf-ld + linker.ld | 控制代码布局(复位向量等) |
| 二进制转换 | riscv-none-elf-objcopy | ELF → BIN |
| 指令 RAM 初始化脚本 | Python 脚本 | BIN → TCL |
| 架构选项 | -march=rv32ic -mabi=ilp32 | 压缩指令集 + 32 位整数 ABI |
4.4 调试与验证工具
| 类别 | 工具 | 说明 |
|------|------|------|
| 网络抓包 | Wireshark | 验证 ARP/Ping/TCP/HTTP 报文 |
| 浏览器 | Chrome / Edge | 访问开发板网页 |
| 串口终端 | PuTTY / TeraTerm | 查看 UART 调试输出(可选) |
| Python | Python 3.x | 辅助脚本:BIN 转换、TCL脚本 生成 |
---
5. 预备技能要求
开始本项目前,应确保具备以下技能:
5.1 FPGA 硬件设计基础(必备)
• 能读懂和编写 SystemVerilog/Verilog 模块
• 理解时钟域、复位、寄存器读写时序
• 有 Block RAM / FIFO 的例化经验
• 使用过 ModelSim 进行仿真
5.2 C 语言嵌入式编程基础(必备)
• 熟悉裸机 C 编程(无 OS 抽象)
• 理解内存映射 I/O(MMIO)的工作方式
• 掌握 volatile、attribute 等嵌入式常用语法
• 使用过交叉编译工具链
5.3 计算机网络基础(建议补齐)
• 理解 OSI 七层模型和 TCP/IP 四层模型的基本分层
• 理解以太网帧结构:目的 MAC(6) + 源 MAC(6) + EtherType(2) + Payload + FCS(4)
• 理解 ARP 的工作原理(IP→MAC 地址解析)
• 理解 IP 头各字段含义(总长度、校验和、TTL、协议号)
• 理解 ICMP Echo Request/Reply 的报文格式
• 理解 TCP 三次握手和四次挥手的状态转换过程
• 理解 HTTP GET/POST 的报文格式和 Content-Length 的含义
5.4 软核 CPU 基础(建议补齐)
• 理解 RISC-V 的基本执行模型(取指→译码→执行→写回)
• 理解 MMIO 的地址映射方式(CPU 通过地址访问外设寄存器)
• 理解轮询(Polling)主循环的工作模式
5.5 前端基础(够用即可)
• 了解 HTML 表单(form/input/button)的基本用法
• 了解 JavaScript fetch() API 的基本用法
• 了解 JSON 的基本格式
---
6. 项目系统架构
6.1 总体分层架构
┌──────────────────────────────────────────────────────────────┐ │ 网页应用层 │ │ HTML 控制页面 + JavaScript POST 交互 │ │ 浏览器输入地址/数据 → JSON → HTTP POST │ ├──────────────────────────────────────────────────────────────┤ │ RISC-V 固件协议层 │ │ ┌──────────┐ │ │ │ HTTP 处理 │ GET 返回页面 / POST 解析执行 │ │ ├──────────┤ │ │ │ TCP 协议 │ 三次握手 / 状态机 / 数据收发 / 四次挥手 │ │ ├──────────┤ │ │ │ IP 层 │ 地址过滤 / 协议分派 / 头部重建 │ │ ├──────────┤ │ │ │ ICMP 协议 │ Ping Echo Reply │ │ ├──────────┤ │ │ │ ARP 协议 │ ARP Request → ARP Reply │ │ ├──────────┤ │ │ │ 以太网帧 │ MAC 过滤 / EtherType 解析 / MAC 交换 │ │ └──────────┘ │ ├──────────────────────────────────────────────────────────────┤ │ FPGA 数据面层(RTL) │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ GMII/MAC │ │ cpu_ │ │ 寄存器 │ │ │ │ 数据通道 │→│ channel │→│ 映射模块 │ │ │ │ │ │ (FIFO) │ │ │ │ │ └──────────┘ └──────────┘ └──────────┘ │ ├──────────────────────────────────────────────────────────────┤ │ 网络物理与接口层 │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ RGMII/ │ │ 以太网 │ │ MDIO │ │ │ │ SGMII接口│ │ PHY 芯片 │ │ 管理接口 │ │ │ └──────────┘ └──────────┘ └──────────┘ │ └──────────────────────────────────────────────────────────────┘
6.2 RTL 模块架构(供参考)
RiscvWebServer (顶层) ├── PLL_50M ← 时钟生成(50M/125M/200M) ├── RiscV32_JTagCPU_Wrapper ← RISC-V 软核 CPU 实例 │ └── InstructRAM ← 指令 RAM(固件代码存放处) ├── reg_riscweb ← 寄存器映射模块(MMIO 译码) │ ├── CPU 总线请求译码(address → 寄存器选择) │ ├── 收包 FIFO 控制寄存器组 │ ├── 发包 FIFO 控制寄存器组 │ ├── LED 寄存器(地址 0x30) │ ├── 调试 RAM 接口(地址 0x7000+) │ └── MDIO 子总线接口(地址 0x1000+, 0x2000+) ├── sgmii2gmii ← SGMII → GMII 接口转换 ├── rgmii2gmii ← RGMII → GMII 接口转换(DDR→SDR) ├── gmii2mac ← GMII ↔ MAC 内部数据格式转换 │ ├── 前导码/SFD 去除与添加 │ ├── FCS 校验与生成 │ └── SOP/EOP 信号生成 ├── cpu_channel ← CPU 与 MAC 之间的包 FIFO 通道 │ ├── ram2pktfifo_int ← 接收:MAC 字节流 → 包 FIFO │ ├── package_fifo (rd) ← CPU 读包 FIFO(异步双时钟) │ ├── package_fifo (wr) ← CPU 发包 FIFO(异步双时钟) │ ├── pktfifo2ram_int_v2 ← 发送:包 FIFO → MAC 字节流 │ └── sop_eop_gen ← 发送 SOP/EOP 信号生成 ├── lcpu_mdio ← MDIO 控制器(PHY 寄存器读写) └── simple_dual_port_ram ← 调试 RAM(可选)
6.3 C 固件软件架构
main.c
└── reset_entry() ← RISC-V 复位向量(地址 0)
└── program_main()
└── designApp() [designApp.c]
├── heart_beat_mod2() ← LED 心跳(系统运行指示)
└── while(1):
├── LCPU_RD_EMPTY() ← 检查接收 FIFO
├── LCPU_RD_START_PACKET() ← 开始读包
├── LCPU_RD_PKT_LEN() ← 获取包长度
└── eth_proc() [eth.c]
├── EtherType=0x0806 → arp_reply() [arp.c]
└── EtherType=0x0800 → ip_proc() [ip.c]
├── Protocol=0x01 → icmp_reply() [icmp.c]
└── Protocol=0x06 → tcp_packet_handler() [tcp.c]
├── SYN → tcp_handle_syn() → send_syn_ack()
├── ACK(握手) → 进入 ESTABLISHED
├── ACK+Data → http_request_handler()
│ ├── GET → send_http_response(main_page)
│ └── POST → tcp_handle_post_request()
│ ├── 解析地址、数据、模式
│ ├── write_lcpu_register() 或 read_lcpu_register()
│ └── send_http_response(post_response)
└── FIN → send_ack() → close_connection()
6.4 数据通路(关键路径)
收包路径:
RJ45/1000BASE-X → PHY → RGMII/SGMII → rgmii2gmii/sgmii_ip → gmii2mac → cpu_channel(ram2pktfifo_int) → package_fifo(rd) → CPU 读取(LCPU_RD_DATA8)→ 协议栈解析
发包路径:
协议栈构造 → CPU 写入(LCPU_WR_BYTE)→ package_fifo(wr) → cpu_channel(pktfifo2ram) → gmii2mac → rgmii2gmii/sgmii_ip → RGMII/SGMII → PHY → RJ45/1000BASE-X
6.5 寄存器地址映射(部分关键寄存器)
| 地址偏移 | 寄存器 | 读写 | 说明 |
|---------|--------|------|------|
| 0x0001 | Eth_GRESET | RW | 以太网 PHY 硬件复位 |
| 0x0002 | second_event | RO | 秒脉冲事件标志 |
| 0x0010 | debug_RW_0 | RW | 调试控制字 0(含包过滤器) |
| 0x0030 | Led | RW | LED 控制寄存器(4bit) |
| 0x1000-0x1FFF | Eth0 MDIO | RW | MDIO 控制器 0 子总线 |
| 0x6000 | cpu_rd_empty | RO | 收包 FIFO 空标志 |
| 0x6001 | cpu_rd_rpkt_pop | RW | 收包 FIFO 弹出脉冲 |
| 0x6002 | cpu_rd_rpkt_len | RO | 当前包长度 |
| 0x6005 | cpu_rd_raddr | RW | 收包 FIFO 读地址 |
| 0x6006 | cpu_rd_rdata | RO | 收包 FIFO 读数据 |
| 0x6100 | cpu_wr_full | RO | 发包 FIFO 满标志 |
| 0x6102 | cpu_wr_waddr | RW | 发包 FIFO 写地址 |
| 0x6103 | cpu_wr_wdata | RW | 发包 FIFO 写数据 |
| 0x6104 | cpu_wr_wpkt_len | RW | 发包长度 |
| 0x6106 | cpu_wr_wpkt_push | RW | 发包推送脉冲 |
| 0x7000-0x7FFF | dbg_ram_0 | RW | 调试 RAM(可选) |
---
7. 项目开发计划(8 周)
第 1 周:环境搭建与知识准备
目标: 开发环境就绪,TCP/IP 协议及网络接口基础知识储备完成。
任务清单:
| 序号 | 任务 | 预计耗时 |
|------|------|---------|
| 1.1 | 确认 FPGA 开发板型号,整理板级资源(PHY 型号、引脚约束、时钟资源、GTX/GTP 收发器资源、光模块型号) | 0.5 天 |
| 1.2 | 安装 RISC-V GCC 工具链并验证 riscv-none-elf-gcc -march=rv32ic 编译通过 | 0.5 天 |
| 1.3 | 学习以太网帧格式、ARP、IPv4、ICMP、TCP、HTTP 基础协议知识 | 1.5 天 |
| 1.4 | 学习 RGMII 接口时序(DDR 双边沿采样、txc/rxc 时钟关系、TXD[3:0]/TX_CTL/TXC 引脚定义) | 0.5 天 |
| 1.5 | 学习 SGMII 与 1000BASE-X 基础知识(8B/10B 编码、GTX/GTP 串行收发器、CDR 时钟恢复、SFP 光模块接口、差分信号 txp/txn/rxp/rxn) | 1 天 |
| 1.6 | 使用 Wireshark 抓取一次完整的"浏览器访问网页"过程,逐层理解报文 | 1 天 |
阶段性产出:
• 协议知识学习笔记(含抓包截图与分析)
• RGMII 与 SGMII/1000BASE-X 接口对比表
• 开发环境搭建记录(截图 + 命令行输出)
• 板级资源清单(含 GTX/GTP 收发器通道分配)
---
第 2 周:RGMII 接口硬件通路搭建与数据通路验证
目标: RTL 侧完成从 RGMII → GMII → MAC → CPU 包 FIFO 的完整铜缆数据通路,仿真验证收发正确。
任务清单:
| 序号 | 任务 | 预计耗时 |
|------|------|---------|
| 2.1 | 编写/集成 rgmii2gmii 模块(RGMII DDR 双边沿采样 → GMII SDR 转换,含 IDELAY 延迟调节) | 1 天 |
| 2.2 | 编写/集成 gmii2mac 模块(前导码/SFD 去除与添加、FCS 校验与生成、SOP/EOP 信号生成) | 1 天 |
| 2.3 | 编写 cpu_channel 模块:MAC → 包 FIFO → CPU 读端口 | 1 天 |
| 2.4 | 编写 cpu_channel 模块:CPU 写端口 → 包 FIFO → MAC | 1 天 |
| 2.5 | 编写 Testbench,在 RGMII RX 侧发送测试以太网帧,验证 CPU 读 FIFO 可获取正确数据字节 | 0.5 天 |
| 2.6 | 验证 CPU 写 FIFO → MAC → RGMII TX 通路,确认输出波形符合 RGMII DDR 时序 | 0.5 天 |
阶段性产出:
• rgmii2gmii、gmii2mac、cpu_channel 模块 RTL 代码
• RGMII 数据通路仿真波形截图(RX 和 TX 方向各一份)
• RGMII 数据通路验证报告(收发字节数、FCS 校验结果、延时测量)
注意事项:
• RGMII RX 是 DDR 时序,需要在 rgmii_rxc 的上升沿和下降沿各采样 4bit 数据
• RGMII TX 的 txc 相对于 txd/tx_ctl 有 90° 相移,需按 PHY 芯片手册确认时序参数
• 跨时钟域(125MHz MAC 域 ↔ 50MHz CPU 域)需使用异步 FIFO
• 包 FIFO 需支持"先写完整包再弹出"的模式
---
第 3 周:1000BASE-X / SGMII 接口硬件通路搭建与数据通路验证
目标: RTL 侧完成 SGMII/1000BASE-X → GMII 的串行光口数据通路,仿真验证收发正确;同时完成寄存器映射模块和 C 固件框架。
任务清单:
| 序号 | 任务 | 预计耗时 |
|------|------|---------|
| 3.1 | 编写/集成 sgmii2gmii 或 SGMII IP 核(GTX/GTP 收发器例化、8B/10B 编解码、逗号检测与字对齐、CDR 时钟恢复、SGMII 自协商状态机) | 1.5 天 |
| 3.2 | 编写 Testbench,模拟 SGMII 串行差分信号发送测试帧,验证经 sgmii2gmii 后的 GMII 并行数据正确 | 1 天 |
| 3.3 | 与第 2 周的 GMII→MAC→FIFO 通路对接,验证 1000BASE-X 光口全链路收包和发包正确 | 0.5 天 |
| 3.4 | 编写顶层 RiscvWebServer 模块,例化 RGMII 和 SGMII 两套接口转换模块,通过参数/宏选择当前活跃接口 | 0.5 天 |
| 3.5 | 编写 reg_riscweb 模块:CPU 总线地址译码 + 各寄存器读/写逻辑 + LED 控制寄存器(地址 0x30) | 1 天 |
| 3.6 | 编写 lcpu_general.h 和 linker.ld,搭建基本 C 固件框架(复位向量 + 主循环 + LED 心跳) | 0.5 天 |
阶段性产出:
• sgmii2gmii 或 SGMII IP 核集成代码
• 1000BASE-X 数据通路仿真波形截图(SerDes 差分信号 → GMII 并行数据 → CPU FIFO)
• RGMII 与 1000BASE-X 双接口数据通路验证对比报告
• reg_riscweb.v 与 lcpu_general.h 配套代码
• LED 心跳在仿真中正常运行
注意事项:
• SGMII 使用 8B/10B 编码,线速率 1.25Gbps(数据速率 1Gbps),需要 FPGA 的 GTX/GTP 高速收发器支持
• SGMII 自协商需要 PHY 侧配合,仿真阶段可先旁路自协商状态机,直接验证数据通路
• 1000BASE-X 的 /C1/(K28.5)和 /C2/(K28.5 + D16.2)控制码用于链路同步
• 建议在仿真中先使用 GMII 回环或简化 SerDes BFM 来验证逻辑,降低 GTX/GTP 仿真模型的复杂度
• 顶层模块的条件编译应支持三种模式:纯 RGMII、纯 SGMII、双接口自动检测
---
第 4 周:ARP + ICMP + C 固件链路打通(二层 + 三层最小闭环)
目标: ARP Reply 和 Ping Reply 在仿真中验证通过,编译→仿真链路可一键执行。
任务清单:
| 序号 | 任务 | 预计耗时 |
|------|------|---------|
| 4.1 | 编写 eth.c:解析 EtherType,验证目的 MAC,交换源/目标 MAC | 1 天 |
| 4.2 | 编写 arp.c:解析 ARP Request,验证目标 IP,构造 ARP Reply | 1 天 |
| 4.3 | 编写 ip.c:解析 IP 头,验证目的 IP,读取协议号并分派,回复时重建 IP 头并重算头校验和 | 1 天 |
| 4.4 | 编写 icmp.c:将 ICMP Type 8→0,重算校验和,构造 Echo Reply | 1 天 |
| 4.5 | 编写 comlib.c:实现 16 位补码校验和计算函数 | 0.5 天 |
| 4.6 | 搭建编译脚本:GCC 编译 → objcopy 生成 BIN → Python 转 Verilog hex → 导入仿真,完成一键执行 | 0.5 天 |
阶段性产出:
• eth.c + arp.c + ip.c + icmp.c + comlib.c + designApp.c 源代码
• 仿真验证:发送 ARP Request → 收到 ARP Reply(MAC/IP 正确,分别验证 RGMII 和 1000BASE-X 通路)
• 仿真验证:发送 ICMP Echo Request → 收到 Echo Reply(Payload 一致,跨接口验证)
• Wireshark 抓包截图(两种接口各一份)
• 编译→仿真一键脚本
注意事项:
• ARP Reply 的以太网帧需要填充到 64 字节(含 FCS)
• ICMP 校验和覆盖 ICMP 头 + Payload,而 IP 头校验和仅覆盖 IP 头
• 本机 IP 和 MAC 在 lcpu_general.h 中定义为宏常量
• 建议在本阶段末尾分别用 RGMII TB 和 SGMII TB 各跑一遍完整测试,确保协议层与接口层解耦正确
---
第 5 周:TCP 三次握手
目标: 完成 TCP 状态机和三次握手,仿真验证通过。
任务清单:
| 序号 | 任务 | 预计耗时 |
|------|------|---------|
| 5.1 | 设计 TCP 连接管理数据结构(并行数组:状态/序号/确认号/端口/IP),最多支持 16 个并发连接 | 0.5 天 |
| 5.2 | 实现连接管理函数(find_free_connection、find_connection、close_connection) | 1 天 |
| 5.3 | 实现 TCP 状态机主循环(tcp_packet_handler),覆盖 CLOSED / SYN_RECEIVED / ESTABLISHED / FIN_WAIT / LAST_ACK 等核心状态 | 1.5 天 |
| 5.4 | 实现 SYN 处理(tcp_handle_syn → send_syn_ack),正确设置 ISN 和确认号 | 1 天 |
| 5.5 | 实现 ACK 处理与状态转换(SYN_RECEIVED → ESTABLISHED),处理握手阶段携带数据的情况 | 1 天 |
阶段性产出:
• tcp.c 源代码(含完整状态机骨架)
• 仿真验证:发送 TCP SYN → 收到 SYN+ACK(Seq/Ack 正确)
• 仿真验证:再发送 ACK → 进入 ESTABLISHED 状态
• Wireshark 三次握手截图(RGMII 和 1000BASE-X 各一份)
注意事项:
• 初始序列号(ISN)建议使用固定值简化调试(如 0x12345678)
• TCP 校验和必须包含伪头部(源 IP + 目标 IP + 协议号 + TCP 长度)
• 此阶段先不考虑多连接,单连接跑通后再扩展
• 注意 TCP 状态机中 RST 标志的处理——收到 RST 应立即关闭连接
---
第 6 周:HTTP GET + POST + 网页控制
目标: 浏览器能访问页面,POST 能控制 LED。
任务清单:
| 序号 | 任务 | 预计耗时 |
|------|------|---------|
| 6.1 | 设计 HTML 控制页面(地址框 + 数据框 + 读/写 Radio + 确认按钮),先使用英文版本 | 0.5 天 |
| 6.2 | 将 HTML 页面作为字符串常量嵌入 http.c,设计 POST 响应页面(操作结果 + 3 秒自动跳转回主页) | 0.5 天 |
| 6.3 | 实现 HTTP GET 请求识别与页面返回(http_request_handler),正确设置 Connection: keep-alive | 1 天 |
| 6.4 | 实现 POST JSON 数据解析(提取地址、数据、模式字段),支持读/写两种模式 | 1 天 |
| 6.5 | 实现寄存器读/写调用(read_lcpu_register / write_lcpu_register) | 0.5 天 |
| 6.6 | 计算并设置正确的 Content-Length(注意仅计算 Body 部分,不含响应头),编写计算过程说明 | 0.5 天 |
| 6.7 | 仿真端到端验证:ARP→Ping→TCP→GET→POST→LED 全链路(RGMII 和 1000BASE-X 各跑一遍) | 1 天 |
阶段性产出:
• http.c 源代码(含主页和 POST 响应页)
• 仿真中全链路测试通过
• Content-Length 计算过程文档
• 双接口全链路测试报告
注意事项:
• Content-Length 仅计算 HTTP Body 部分,不包含 HTTP 头
• POST body 中地址和数据字段为 8 字符 HEX 格式(如 "80007000")
• 网页中的中文字符可能导致 TCP 校验和出错(UTF-8 多字节编码),建议此阶段先用英文页面
• 响应页面设置 meta http-equiv="refresh" content="3" 自动跳转回主页
• 全链路测试应覆盖:正常场景(read/write)和异常场景(非法 HEX 字符、空字段等)
---
第 7 周:板级联调与系统验证(RGMII + 1000BASE-X 双接口)
目标: 所有功能在真实 FPGA 开发板上分别通过 RGMII 铜缆和 1000BASE-X 光口验证通过,撰写双接口对比测试报告。
任务清单:
| 序号 | 任务 | 预计耗时 |
|------|------|---------|
| 7.1 | RGMII 模式板级验证: 配置 PHY 芯片(通过 MDIO 写 PHY 寄存器,确保铜缆链路建立);烧录 FPGA bitstream + 固件 | 0.5 天 |
| 7.2 | RGMII 模式:PC 网线直连开发板,测试 ARP(arp -a)和 Ping(ping 169.254.15.88),Wireshark 抓包 | 0.5 天 |
| 7.3 | RGMII 模式:浏览器访问 http://169.254.15.88,验证主页正常显示;测试 POST write/read → LED 控制 | 0.5 天 |
| 7.4 | 1000BASE-X 模式板级验证: 配置 FPGA GTX/GTP 收发器参数(线速率 1.25Gbps、参考时钟、预加重);插入 SFP 光模块并连接光纤 | 0.5 天 |
| 7.5 | 1000BASE-X 模式:通过光口测试 ARP 和 Ping,验证光链路连通性;Wireshark 抓包对比铜缆和光口的 RTT 差异 | 0.5 天 |
| 7.6 | 1000BASE-X 模式:浏览器访问、POST write/read → LED 控制功能测试 | 0.5 天 |
| 7.7 | 双接口切换测试:通过寄存器(如 debug_RW_0)或顶层参数动态切换 RGMII/SGMII 模式,验证切换后链路可正常恢复 | 1 天 |
| 7.8 | 长时间运行稳定性测试(RGMII 和 1000BASE-X 各连续 Ping + 反复刷新网页 10 分钟) | 0.5 天 |
| 7.9 | 撰写双接口对比测试报告(包括:链路建立时间、Ping RTT、HTTP 响应时间、误码情况、功耗对比) | 0.5 天 |
阶段性产出:
• RGMII 模式板级测试记录表(ARP/Ping/GET/POST×2 逐项打勾)
• 1000BASE-X/SGMII 模式板级测试记录表
• 双接口对比测试报告(RTT、响应时间、稳定性、功耗)
• Wireshark 抓包文件(保存为 .pcapng,两种接口各一套)
• LED 控制演示视频或照片
常见问题排查:
| 现象 | 可能原因 | 排查方向 |
|------|---------|---------|
| RGMII 链路不通 | PHY 未配置 | 检查 MDIO 是否正确写 PHY 寄存器;确认 PHY 复位释放 |
| RGMII RX 数据错位 | DDR 采样相位偏差 | 调整 IDELAY 值;检查 rgmii_rxc 与数据的相位关系 |
| 1000BASE-X 链路 Down | GTX/GTP 未锁定 | 检查 rx_pll_lock 和 rx_data_valid 信号;确认参考时钟频率 |
| 1000BASE-X 收包错乱 | 字对齐(Word Alignment)失败 | 检查逗号检测逻辑;确认 8B/10B 解码的 /K28.5/ 检测正确 |
| SFP 光模块无光 | 光模块未使能 | 确认 sfp_tx_disable 信号为低;检查光模块供电 |
| ARP 无响应 | MAC 地址过滤失败 | 检查 eth.c 中 MAC 校验逻辑 |
| Ping 无响应 | IP 地址不匹配 | 确认本机 IP 宏定义与 PC 端 IP 在同一网段 |
| 网页打不开 | TCP 握手失败 | 检查 Seq/Ack 号计算是否正确 |
| 页面不断刷新 | Content-Length 错误 | 重新计算 Body 部分字节数 |
| POST 无反应 | JSON 解析失败 | 检查 POST 数据的引号匹配 |
| 接口切换后不通 | 状态机未复位 | 检查切换时是否正确复位 MAC 和 PHY/SGMII 状态机 |
---
第 8 周:文档整理与项目收尾
目标: 形成完整的项目交付物,包含 RGMII 和 1000BASE-X 双接口的全部设计、验证和测试文档。
任务清单:
| 序号 | 任务 | 预计耗时 |
|------|------|---------|
| 8.1 | 撰写项目总体设计文档(含双接口架构图、模块说明、数据流、RGMII/SGMII 接口对比分析) | 1 天 |
| 8.2 | 撰写模块职责说明文档(每个 .c/.v 文件的功能、接口、关键逻辑,特别说明 rgmii2gmii 和 sgmii2gmii 的差异与共用接口) | 1 天 |
| 8.3 | 撰写编译与仿真操作说明(环境配置 → 命令行 → 预期输出,区分 RGMII TB 和 SGMII TB 的运行方式) | 0.5 天 |
| 8.4 | 整理板级测试记录与 Wireshark 抓包分析(RGMII 和 1000BASE-X 双接口各一套) | 0.5 天 |
| 8.5 | 整理代码仓库(清理中间文件、添加 .gitignore、README,标注 RGMII/SGMII 条件编译宏的使用说明) | 0.5 天 |
| 8.6 | 整理问题清单与后续优化建议(含双接口开发中遇到的典型问题和解决过程) | 0.5 天 |
| 8.7 | 准备答辩材料(PPT 提纲 + 演示流程,包含 RGMII 和光口双接口的现场演示计划) | 1 天 |
阶段性产出:
• 完整项目文档(PDF)
• 代码版本归档
• 演示材料与答辩提纲
• 双接口设计与验证专题文档
---
8. 各阶段验收标准
阶段 1:环境准备验收
• [ ] RISC-V GCC 工具链可编译输出 .elf 和 .bin 文件
• [ ] 仿真环境可运行,波形可正常查看
• [ ] 能画出以太网帧结构和 TCP 三次握手时序图
• [ ] 能说明 RGMII、SGMII 和 1000BASE-X 三者的信号定义、编码方式和应用场景差异
阶段 2:RGMII 硬件通路验收
• [ ] 仿真中 RGMII RX 发送测试帧,CPU 读 FIFO 能获取到正确的数据字节
• [ ] CPU 写 FIFO → MAC → RGMII TX 通路可观测到正确输出,波形符合 RGMII DDR 时序
• [ ] 跨时钟域 FIFO 无数据丢失
阶段 3:1000BASE-X 硬件通路验收
• [ ] 仿真中 SGMII SerDes BFM 发送测试帧,经 8B/10B 解码后 GMII 并行数据正确
• [ ] 1000BASE-X 全链路(SerDes → GMII → MAC → FIFO → CPU → 协议处理 → 回包)可跑通
• [ ] 顶层模块可通过参数/宏在 RGMII 和 SGMII 模式间正确切换
• [ ] CPU 能正确读写 LED 寄存器
• [ ] LED 心跳指示正常运行
阶段 4:ARP+Ping 验收
• [ ] PC arp -a 可显示开发板 MAC 地址
• [ ] PC ping 开发板 IP 有正常 Reply
• [ ] Wireshark 抓包确认 ARP Reply 和 ICMP Reply 字段正确
• [ ] RGMII 和 1000BASE-X 两种接口下 ARP 和 Ping 均通过
阶段 5:TCP 验收
• [ ] Wireshark 观察到完整的三次握手过程(SYN→SYN+ACK→ACK)
• [ ] Seq/Ack 号递增正确
• [ ] 端口 80 连接正常建立
• [ ] 两种接口下 TCP 握手均通过
阶段 6:HTTP 验收
• [ ] 浏览器访问开发板 IP 可看到完整的 HTML 页面
• [ ] 页面输入十六进制地址和数据,POST write 可成功执行
• [ ] POST read 可返回正确的寄存器值
• [ ] LED 可通过网页控制
• [ ] 两种接口下 HTTP 功能均通过
阶段 7:板级双接口验收
• [ ] RGMII 铜缆接口所有功能在真实板卡上可运行
• [ ] 1000BASE-X/SGMII 光口所有功能在真实板卡上可运行
• [ ] 双接口切换功能正常,切换后链路可自动恢复
• [ ] RGMII 和 1000BASE-X 各自连续运行 10 分钟无异常
• [ ] 双接口对比测试报告完整(RTT、响应时间、稳定性、功耗)
• [ ] 多连接场景下连接管理正确
阶段 8:文档验收
• [ ] 后续开发者可根据文档复现整个项目(含双接口搭建步骤)
• [ ] 仿真步骤可重复执行(RGMII TB 和 SGMII TB 分别可运行)
• [ ] 所有模块的接口和职责有清晰说明
• [ ] RGMII 和 SGMII/1000BASE-X 的工程差异有专题说明
---
9. 推荐交付物清单
| 序号 | 交付物 | 形式 |
|------|--------|------|
| 1 | 项目总体设计文档(含双接口架构) | PDF |
| 2 | 模块职责说明文档 | PDF |
| 3 | 编译与仿真操作说明 | PDF |
| 4 | 完整 RTL 源码(SystemVerilog,含 rgmii2gmii 和 sgmii2gmii 模块) | 代码仓库 |
| 5 | 完整 C 固件源码 | 代码仓库 |
| 6 | 仿真 Testbench + 脚本(RGMII TB + SGMII TB 各一套) | 代码仓库 |
| 7 | 编译/转换脚本(Python/BAT) | 代码仓库 |
| 8 | RGMII 模式板级测试记录 | 表格 + 截图 |
| 9 | 1000BASE-X/SGMII 模式板级测试记录 | 表格 + 截图 |
| 10 | 双接口对比测试报告(RTT、响应时间、稳定性、功耗) | PDF |
| 11 | Wireshark 抓包记录(两种接口各一套,含分析) | pcapng + 截图 |
| 12 | 网页控制 LED 演示记录(两种接口各一份) | 视频或 GIF |
| 13 | 问题清单与优化建议 | 清单 |
| 14 | 答辩 PPT | PPT/PDF |
---
10. 风险与应对策略
10.1 技术风险
| 风险 | 影响 | 概率 | 应对策略 |
|------|------|------|---------|
| RGMII 接口时序调试困难 | 铜缆通路不通 | 高 | 可先使用 GMII 模式(如果 PHY 支持);使用 ILA/SignalTap 抓内部信号;调整 IDELAY 值 |
| GTX/GTP 串行收发器配置复杂 | 光口通路不通 | 高 | 优先使用 FPGA 厂商提供的 SerDes 示例工程;参考开发板的推荐收发器参数;仿真阶段用简化 BFM 验证逻辑 |
| 1000BASE-X 字对齐失败 | 光口收包错乱 | 中 | 检查 8B/10B 逗号检测逻辑;确认 /K28.5/ 控制码检测位置;调整接收缓冲的 bit-slip 参数 |
| SFP 光模块兼容性问题 | 光链路 Down | 中 | 确认 SFP 模块支持的速率模式(1000BASE-X);检查 tx_disable 信号和模块供电;准备备用光模块 |
| SGMII 自协商失败 | MAC-PHY 间配置不一致 | 中 | 仿真阶段先旁路自协商;板级调试时确认 PHY 侧 SGMII 模式已使能 |
| TCP 状态机边界条件遗漏 | 连接异常断开 | 中 | 使用 Wireshark 分析 TCP 流;先实现简化状态机再逐步完善 |
| Content-Length 计算错误 | 页面不断刷新 | 中 | 使用 Wireshark 抓包对比;使用在线工具计算 Body 字节数 |
| RGMII PHY 芯片配置失败 | 铜缆链路 Down | 中 | 查阅 PHY Data Sheet 确认寄存器地址和默认值;检查 MDIO 读写时序 |
| 跨时钟域 FIFO 数据丢失 | 包数据不完整 | 低 | 确认 FIFO 的读写时钟频率比;添加包长度校验 |
| C 固件体积超过 16KB | 编译失败 | 低 | 使用 -Os 优化;检查字符串常量大小;必要时扩大 ROM |
| 双接口切换时状态机卡死 | 切换后任一接口不通 | 低 | 设计接口切换时强制复位 MAC 和对应 PHY/SGMII 状态机;添加切换超时保护 |
10.2 管理风险
| 风险 | 影响 | 概率 | 应对策略 |
|------|------|------|---------|
| 网络协议知识储备不足 | 前两周进度迟缓 | 中 | 第 1 周集中学习,使用 Wireshark 实际抓包加深理解 |
| 高速串行接口调试耗时超出预期 | 第 3 周延期 | 中 | 提前准备 SerDes 示例工程;仿真阶段充分验证再上板;必要时先确保 RGMII 调通再攻关 SGMII |
| 在 TCP/HTTP 层花费过多时间 | 后期赶工 | 中 | 严格按照"ARP→Ping→TCP→HTTP"的顺序推进,每层验证通过再进入下一层 |
| 板级调试困难 | 仿真通过但板卡不工作 | 中 | 仿真时尽量使用真实时序和 SerDes BFM;板级调试使用 ILA/SignalTap 从底层往上排查 |
---
11. 后续可扩展方向
完成本项目的核心功能后,可继续扩展以下方向:
1. 外设扩展: 增加 GPIO、PWM、UART、温度传感器等更多板级外设的网页控制
2. 页面增强: 将网页字符串从固件中分离,存储在外部 SPI Flash 中,支持更大的页面
3. 多页面路由: 实现多个 URL 路径(/status、/config、/debug),支持更丰富的交互
4. UDP 协议: 增加 UDP 支持(如 DHCP 自动获取 IP 地址、DNS 域名解析)
5. TCP 增强: 实现滑动窗口、超时重传、拥塞控制等完整的 TCP 特性
6. 安全性: 增加基本的 HTTP Basic Auth 认证
7. WebSocket: 实现 WebSocket 协议,支持服务器主动推送数据到浏览器(实时状态监控)
8. 双网口: 利用 RTL 中预留的 Eth1 接口,实现 RGMII 铜口 + 1000BASE-X 光口同时工作,构建双接口冗余或桥接方案
9. 10G 光口升级: 将 1000BASE-X 升级为 10GBASE-R,搭配 10G SFP+ 光模块和 GTY 收发器实现万兆速率
10. 网络诊断增强: 在网页上增加实时速率监控、PHY 状态显示、光模块 DDM(数字诊断监控)信息展示
---
12. 附录
12.1 参考协议标准
| 协议 | RFC/标准 | 说明 |
|------|---------|------|
| Ethernet | IEEE 802.3 | 以太网基础标准 |
| 1000BASE-X | IEEE 802.3 Clause 36 | 千兆光口 PCS/PMA 层 |
| SGMII | Cisco SGMII Specification | 串行千兆介质无关接口 |
| ARP | RFC 826 | 地址解析协议 |
| IPv4 | RFC 791 | 互联网协议第四版 |
| ICMP | RFC 792 | 互联网控制消息协议 |
| TCP | RFC 793 | 传输控制协议 |
| HTTP/1.1 | RFC 2616, RFC 7230-7235 | 超文本传输协议 |
| JSON | RFC 8259 | JavaScript 对象表示法 |
| 8B/10B | IBM Journal 1983, Widmer & Franaszek | 8B/10B 编解码标准 |
12.2 推荐学习资源
• 《TCP/IP Illustrated, Volume 1》— W. Richard Stevens(协议经典)
• 《Computer Networks》— Andrew S. Tanenbaum
• IEEE 802.3 Clause 36(1000BASE-X PCS/PMA 规范)
• Xilinx UG482 / UG578(7 系列 GTX/GTP 收发器用户指南)
• Altera PHY IP Core User Guide(SGMII/1000BASE-X IP 使用手册)
• Wireshark 官方用户指南
• RISC-V Unprivileged ISA Specification
• 开发板对应的 PHY 芯片 Data Sheet(RTL8211 / 88E1111 等)
12.3 关键术语速查表
| 术语 | 全称 | 说明 |
|------|------|------|
| RGMII | Reduced Gigabit Media Independent Interface | 千兆简化介质无关接口(DDR 时序,4bit 数据位宽) |
| GMII | Gigabit Media Independent Interface | 千兆介质无关接口(SDR 时序,8bit 数据位宽) |
| SGMII | Serial Gigabit Media Independent Interface | 串行千兆介质无关接口(1.25Gbps 差分串行) |
| 1000BASE-X | 1000 Mbps Baseband - eXtended | 千兆光纤以太网标准(含 1000BASE-SX/LX) |
| MDIO | Management Data Input/Output | PHY 管理数据接口(IEEE 802.3 Clause 22) |
| MAC | Media Access Control | 介质访问控制层 |
| PHY | Physical Layer | 物理层芯片 |
| PCS | Physical Coding Sublayer | 物理编码子层(8B/10B 编解码、自协商) |
| PMA | Physical Medium Attachment | 物理介质连接子层(串行化/解串行化) |
| GTX/GTP | Gigabit Transceiver | Xilinx 7 系列高速串行收发器(GTX=12.5Gbps, GTP=6.6Gbps) |
| SerDes | Serializer/Deserializer | 串行化/解串行化器 |
| CDR | Clock and Data Recovery | 时钟数据恢复(从串行信号中恢复时钟) |
| SFP | Small Form-factor Pluggable | 小型可插拔光模块 |
| DDR | Double Data Rate | 双边沿数据传输(RGMII 使用) |
| SDR | Single Data Rate | 单边沿数据传输(GMII 使用) |
| 8B/10B | 8-Bit / 10-Bit Encoding | 8B/10B 编码(将 8bit 数据编为 10bit 传输,保证 DC 平衡) |
| K28.5 | Comma Character | 8B/10B 特殊控制字符(0xBC),用于字对齐和链路同步 |
| FIFO | First In First Out | 先进先出缓冲 |
| MMIO | Memory-Mapped I/O | 内存映射输入输出 |
| ISN | Initial Sequence Number | TCP 初始序列号 |
| MSS | Maximum Segment Size | TCP 最大分段大小 |
| FCS | Frame Check Sequence | 帧校验序列(以太网 CRC32) |
| SOP/EOP | Start/End of Packet | 包起始/结束标志 |
| IDELAY | Input Delay | Xilinx FPGA 的可编程输入延迟单元(RGMII 时序校准用) |