目录
1.协议栈层次结构
系统遵循TCP/IP协议栈的分层模型,FPGA主要实现数据链路层(以太网MAC)、网络层(IP)和传输层(UDP)的核心功能,架构如图1所示:

各层核心功能:
MAC层:实现以太网帧的封装与解析,包括前导码、帧起始符(SFD)、目的MAC地址、源MAC地址、类型字段、数据域和CRC校验;
IP层:处理IP数据包的路由选择(简化为本地子网校验)、IP地址过滤和头部校验和计算;
UDP层:实现端口号匹配、UDP长度计算和校验和验证,提供无连接的数据报服务。
2.核心模块原理与数学建模
2.1 以太网MAC层:帧结构与CRC校验
MAC层是FPGA与物理层(PHY)的接口,负责将IP数据包封装为以太网帧格式(IEEE802.3标准),并通过GMII/RGMII接口与PHY芯片通信。标准以太网帧结构(不包含前导码)的字段定义与长度(字节)如下:
| 字段 | 目的 MAC | 源 MAC | 类型 / 长度 | 数据域 | CRC 校验 |
|---|---|---|---|---|---|
| 长度(字节) | 6 | 6 | 2 | 46~1500 | 4 |

MAC层采用CRC32校验算法检测帧传输错误,生成多项式为:

2.2 IP层:地址解析与校验和计算
IP层负责数据包的路由和转发,FPGA实现时简化为本地子网内的通信,核心功能包括IP地址过滤、版本校验和头部校验和计算。IPv4 数据包头部(最小20字节)的关键字段定义:
| 字段 | 长度(比特) | 含义 | 约束条件 |
|---|---|---|---|
| 版本(Version) | 4 | IP 协议版本 | 必须为 4(01002) |
| 头部长度(IHL) | 4 | 头部字节数 / 4 | 最小值 5(01012,20 字节) |
| 总长度 | 16 | 包总长(字节) | 20≤Ltotal≤65535 |
| 源 IP 地址 | 32 | 发送端 IP | 32 位二进制表示(如192.168.1.1) |
| 目的 IP 地址 | 32 | 接收端 IP | 同上 |
| 头部校验和 | 16 | 头部错误检测 | 反码求和结果 |
2.3UDP层:端口匹配与数据封装
UDP协议提供无连接的数据传输服务,FPGA实现的核心功能包括端口号过滤、UDP长度计算和校验和验证。UDP 数据报结构(8字节固定头部+数据域):
| 字段 | 长度(比特) | 含义 | 数学约束 |
|---|---|---|---|
| 源端口 | 16 | 发送端端口号 | 0≤Port≤65535 |
| 目的端口 | 16 | 接收端端口号 | 同上 |
| 长度 | 16 | UDP 总长度(字节) | 8≤LUDP≤65507 |
| 校验和 | 16 | 错误检测(可选) | 反码求和(含伪首部) |
3.FPGA实现与数学映射
verilog程序如下:
................................................................
else begin //发送其它的数据包(第一个字节到倒数第二个字节)
tx_data_counter<=tx_data_counter+1'b1;
if(i==0) begin
dataout[7:0]<=datain_reg[31:24]; //发送高8位(31:24)数据
i<=i+1'b1;
ram_rd_addr<=ram_rd_addr+1'b1; //RAM地址加1, 提前让RAM输出数据
end
else if(i==1) begin
dataout[7:0]<=datain_reg[23:16]; //发送次高8位(23:16)数据
i<=i+1'b1;
end
else if(i==2) begin
dataout[7:0]<=datain_reg[15:8]; //发送次低8位(15:8)数据
i<=i+1'b1;
end
else if(i==3) begin
dataout[7:0]<=datain_reg[7:0]; //发送低8位(7:0)数据
datain_reg<=datain; //准备数据
i<=0;
end
end
end
default:tx_state<=idle;
endcase
end
alt_25 alt_25_u(enetclk,MDC);
assign ENET1_MDC=MDC;
assign GTX_CLK=0;
//产生发送的控制使能信号和地址信息
TXcontrol TXcontrol_u(
.TX_CLK (TX_CLK),//网口时钟
.SW4 (dataout[3:0]),
.flag (flag),//发送接收周期性标志信号
.addr (ADDR),//地址
.TX_EN (TX_EN),//控制网口的EN信号
.TX_ER (TX_ER),//控制网口的ER信号
.TX_DATA(TX_DATA)
);
always@(posedge MDC)// 命令
begin
if(flag==1'b1)
begin
case(cnt1)
0:begin
RST_N <= 1'b0;
men_MDIO <= men_MDIO+1;
if(men_MDIO&32'hffffffff==32'hffffffff)
begin
RST_N <= 1'b1;
cnt1 <= 1'b1;
end else
cnt1 <= 5'd0;
end
1:begin
men_MDIO <= TIME_SEQ1;//产生MDIO控制时序
cnt1 <= 5'd2;
end
2:begin
cnt2 <= cnt2 + 7'd1;
if(cnt2 < 7'd96)
begin
mdio <= men_MDIO[95];
wr_rd <= 1'b1;
men_MDIO <= men_MDIO<<1;
cnt1 <= 5'd2;
end else
begin
cnt1 <= 5'd5;
cnt2 <= 7'd0;
end
end
5:begin
men_MDIO <= TIME_SEQ2;
cnt1 <= 5'd6;
end
6:begin
cnt2 <= cnt2 + 7'd1;
if(cnt2<96)
begin
mdio <= men_MDIO[95];
wr_rd <= 1'b1;
men_MDIO <= men_MDIO<<1;
cnt1 <= 5'd6;
end else
begin
cnt1 <= 5'd9;
cnt2 <= 7'd0;
end
end
9:begin
men_MDIO <= TIME_SEQ3;
cnt1 <= 5'd10;
end
10:begin
cnt2 <= cnt2 + 7'd1;
if(cnt2 < 7'd96)
begin
mdio <= men_MDIO[95];
wr_rd <= 1'b1;
men_MDIO <= men_MDIO<<1;
cnt1 <= 5'd10;
end else
begin
cnt1 <= 5'd13;
cnt2 <= 7'd0;
end
end
13:begin
men_MDIO <= TIME_SEQ4;
cnt1 <= 5'd14;
end
14:begin
cnt2<=cnt2+1;
if(cnt2<96)
begin
mdio <= men_MDIO[95];
wr_rd <= 1'b1;
men_MDIO <= men_MDIO<<1;
cnt1 <= 5'd14;
end else
begin
cnt1 <= 5'd17;
cnt2 <= 7'd0;
end
end
17:begin
men_MDIO <= TIME_SEQ5;
cnt1 <= 5'd18;
end
18:begin
cnt2<=cnt2+7'd1;
if(cnt2 < 7'd96)
begin
mdio <= men_MDIO[95];
wr_rd <= 1;
men_MDIO <= men_MDIO<<1;
cnt1 <= 5'd18;
end else
begin
cnt1 <= 5'd19;
cnt2 <= 7'd0;
end
end
19:begin
men_MDIO <= TIME_SEQ6;
cnt1 <= 5'd20;
end
20:begin
cnt2<=cnt2+7'd1;
if(cnt2<7'd96)
begin
mdio <= men_MDIO[95];
wr_rd <= 1'b1;
men_MDIO <= men_MDIO<<1;
cnt1 <= 5'd20;
end else
begin
cnt1 <= 5'd21;
cnt2 <= 7'd0;
end
end
21:begin
cnt2<=cnt2+7'd1;
if(cnt2<7'd32)
begin
mdio <= 1'b1;
wr_rd <= 1'b1;
cnt1 <= 5'd21;
end else
begin
flag <= 1'b0;
wr_rd <= 1'b0;
end
end
endcase
end
else begin
case(UDP_states)
0:begin
men_MDIO <=TIME_SEQ7;
UDP_states <= 1;
wr_rd <= 1;
cnt2 <= 0;
end
1:begin
cnt2 <= cnt2 + 1;
if(cnt2<48)
begin
mdio <= men_MDIO[95];
men_MDIO <= men_MDIO<<1;
UDP_states <= 1;
end else
begin
wr_rd <=0;
UDP_states <=2;
end
end
2: UDP_states<=5'd3;
3: UDP_states<=5'd4;
4: UDP_states<=5'd5;
5: UDP_states<=5'd6;
6: UDP_states<=5'd7;
7: UDP_states<=5'd8;
8: UDP_states<=5'd9;
9: UDP_states<=5'd10;
10:UDP_states<=5'd11;
11:UDP_states<=5'd12;
12:UDP_states<=5'd13;
13:UDP_states<=5'd14;
14:UDP_states<=5'd15;
15:UDP_states<=5'd16;
16:UDP_states<=5'd17;
17:begin
cnt2 <= 7'd1;
UDP_states<= 5'd18;
end
18:begin
cnt2 <= cnt2+7'd1;
wr_rd <= 1'b1;
mdio <= 1'b1;
if(cnt2==7'h3f)
cnt2 <= 7'd0;
UDP_states <= 5'd0;
end
endcase
end
end
assign MDIO=wr_rd?mdio:1'bz;
assign mdio_in=MDIO;
endmodule
其中Tx端有三个信号:
Txd_RGM,
Tx_ctrl,
Tx_clk,
其中Tx_clk是由FPGA提供的125MHz的时钟,
Tx_RGM是发送的数据,
Tx_ctrl在Tx_clk时钟上升沿发送的是Tx_en,在下降沿发送的是Tx_en和Tx_er的异或值。
Rx端也有三个信号:Rxd_RGM,Rx_ctrl,Rx_clk,其中Rx_clk是由88E1111提供的125MHz的时钟,Rx_RGM表示接收到的数据,Rx_ctrl在Rx_clk的上升沿收到的是Rx_en,在下降沿收到的是Rx_en和Rx_er的异或值。

8069

被折叠的 条评论
为什么被折叠?



