引言
前文链接:
基于FPGA的UDP 通信(一)
基于FPGA的UDP 通信(二)
基于FPGA的UDP 通信(三)
基于FPGA的UDP 通信(四)
基于FPGA的UDP 通信(五)
本文基于FPGA和MATLAB对千兆以太网通信模块UDP数据发送(FPGA发送)进行联合调试。
设计条件
FPGA芯片:xc7a35tfgg484-2
网络芯片(PHY):RTL8211(支持1000M/100M/10M)
MAC与PHY接口:GMII
接口类型:RJ-45
Vivado版本:2018.3
Matlab版本:R2022a
电脑:小新Pro16 2022 酷睿版 笔记本
转接口:绿联USB转千兆以太网 转接器
联调思路
模式0:纯接收模式
模式1:纯发送模式
模式2:回环测试
MATLAB发送数据至FPGA,FPGA收到后将数据发至MATLAB测试数据的完整性和准确性。
模式3:测速模式
FPGA一直向电脑发送UDP数据,查看实际通信速率。
模式切换由FPGA开发板的开关控制。
设计源码
数据生成模块
// | ===================================================---------------------------===================================================
// | --------------------------------------------------- UDP 发送数据产生模块 ---------------------------------------------------
// | ===================================================---------------------------===================================================
// | 创建时间 : 2022-01-13
// | 完成时间 : 2022-01-13
// | 作 者 :Xu Y. B.(CSDN 用户名:在路上,正出发)
// | 功能说明 :
// | -1- 长生UDP发送模块需要的规律数据
// | -2- 可用于通信速率测试(连续发送:帧间隔为 0 )
// | -3- 最大帧间隔支持 1024 个时钟周期
// | -4- 规律数从零开始
// |
// | ================================= 模块修改历史纪录 =================================
// | 修改日期:
// | 修改作者:
// | 修改注解:
`timescale 1ns / 1ps
module UDP_TX_DATA_GEN_MDL(
// | ==================================== 模块输入输出端口声明 ====================================
// 时钟、复位
input I_CLK_125M,
input I_SYS_RSTN,
// 测试使能
input I_TEST_EN,
// 发送 握手信号
output reg O_TX_EN,//脉冲信号
input I_TX_DONE,
// 数据
output reg [7:0] O_TX_DATA,
input I_DATA_REQ,
// 数据帧间隔
input [9:0] I_FRAME_GAP,
output reg O_GEN_FINISH
);
// | ==================================== 模块内部参数声明 ====================================
// 状态编码
localparam LP_ST_IDLE = 5'b0_0001;
localparam LP_ST_TX_EN = 5'b0_0010;
localparam LP_ST_GEN_DATA = 5'b0_0100;
localparam LP_ST_WAIT_DONE = 5'b0_1000;
localparam LP_ST_IFG = 5'b1_0000;
// | ==================================== 模块内部信号声明 ====================================
// 状态信号
reg [4:0] R_STATE;
reg [9:0] R_IFG_CNT;
reg R_DATA_REQ;
// | ==================================== 模块内部逻辑设计 ====================================
always @ (posedge I_CLK_125M)
begin
if(~I_SYS_RSTN)
begin
R_DATA_REQ <= 1'b0;
end
else
begin
R_DATA_REQ <= I_DATA_REQ;
end
end
always @ (posedge I_CLK_125M)
begin
if(~I_SYS_RSTN)
begin
R_STATE <= LP_ST_IDLE;
O_TX_EN <= 1'b0;
O_TX_DATA <= 8'd0;
O_GEN_FINISH <= 1'b0;
R_IFG_CNT <= 10'd0;
end
else
begin
case(R_STATE)
LP_ST_IDLE:
begin
O_TX_EN <= 1'b0;
O_TX_DATA <= 8'd0;
O_GEN_FINISH <= 1'b0;
R_IFG_CNT <= 10'd0;
if(I_TEST_EN)
begin
R_STATE <= LP_ST_TX_EN;
end
else
begin
R_STATE <= LP_ST_IDLE;
end
end
LP_ST_TX_EN:
begin
O_TX_EN <= 1'b1;
O_TX_DATA <= 8'd0;
O_GEN_FINISH <= 1'b0;
R_IFG_CNT <= 10'd0;
R_STATE <= LP_ST_GEN_DATA;
end
LP_ST_GEN_DATA:
begin
O_TX_EN <= 1'b0;
if(~I_DATA_REQ & R_DATA_REQ)
begin
R_STATE <= LP_ST_WAIT_DONE;
end
else
begin
R_STATE <= LP_ST_GEN_DATA;
end
if(I_DATA_REQ)
begin
O_TX_DATA <= O_TX_DATA + 1;
end
else
begin
O_TX_DATA <= 8'd0;
end
end
LP_ST_WAIT_DONE:
begin
if(I_TX_DONE)
begin
R_STATE <= LP_ST_IFG;
end
else
begin
R_STATE <= LP_ST_WAIT_DONE;
end
end
LP_ST_IFG:
begin
if(I_FRAME_GAP != 10'd0)
begin
if(R_IFG_CNT == (I_FRAME_GAP-1))
begin
R_IFG_CNT <= 10'd0;
O_GEN_FINISH <= 1'b1;
if(I_TEST_EN)
begin
R_STATE <= LP_ST_TX_EN;
end
else
begin
R_STATE <= LP_ST_IDLE;
end
end
else
begin
R_IFG_CNT <= R_IFG_CNT + 1;
end
end
else
begin
R_IFG_CNT <= 10'd0;
O_GEN_FINISH <= 1'b1;
if(I_TEST_EN)
begin
R_STATE <= LP_ST_TX_EN;
end
else
begin
R_STATE <= LP_ST_IDLE;
end
end
end
default:
begin
R_STATE <= LP_ST_IDLE;
end
endcase
end
end
endmodule
测试模式控制模块
// | ===================================================---------------------------===================================================
// | --------------------------------------------------- UDP 测试模式控制 ---------------------------------------------------
// | ===================================================---------------------------===================================================
// | 创建时间 : 2022-01-16
// | 完成时间 : 2022-01-16
// | 作 者 :Xu Y. B.(CSDN 用户名:在路上,正出发)
// | 功能说明 :
// | -1- 模式说明
// | 00:纯接收模式
// | 01:纯发送模式
// | 02:回环模式
// | 03:测速模式
// | -2-
// | -3-
// | -4-
// | -5-
// |
// | ================================= 模块修改历史纪录 =================================
// | 修改日期:
// | 修改作者:
// | 修改注解:
`timescale 1ns / 1ps
module UDP_TEST_MODE_CTRL(
// | ==================================== 模块输入输出端口声明 ====================================
// 系统复位
input I_SYS_RSTN,
// 模式控制
input [1:0] I_UDP_TEST_MODE,
input I_TX_ONCE,
// 接收
input I_RX_CLK,
input I_RX_VAL,
input [7:0] I_RX_DATA,
// 发送
input I_TX_CLK,
output O_TX_EN,
input I_TX_DONE,
output reg [15:0] O_TX_DATA_LEN,
input I_DATA_REQ,
output [7:0] O_TX_DATA,
input [9:0] I_FRAME_GAP
);
// | ==================================== 模块内部参数声明 ====================================
localparam LP_MODE_RX_ONLY = 2'b00;
localparam LP_MODE_TX_ONLY = 2'b01;
localparam LP_MODE_LOOP_BACK = 2'b10;
localparam LP_MODE_TEST_SPEED = 2'b11;
// | ==================================== 模块内部信号声明 ====================================
wire W_RX_RSTN;//系统复位 同步至 RX时钟域
// FIFO
wire W_FIFO_EMPTY;
wire W_WR_RST_BUSY;
wire W_RD_RST_BUSY;
wire [7:0] W_FIFO_RD_DATA;
// 数据产生模块
reg R_GEN_TEST_EN;
wire [7:0] W_GEN_TX_DATA;
wire W_GEN_TX_EN;
wire W_GEN_FINISH;
reg [1:0] R_TX_ONCE;
// 数据接收
reg [15:0] R_ETH_RCV_CNT;
reg [1:0] R_TX_DONE;
reg [1:0] R_RX_VAL;
// | ==================================== 模块内部逻辑设计 ====================================
always @ (posedge I_TX_CLK)
begin
if(~I_SYS_RSTN)
begin
R_TX_ONCE <= 2'b00;
end
else
begin
R_TX_ONCE <= {R_TX_ONCE[0],I_TX_ONCE};
end
end
always @ (posedge I_RX_CLK)
begin
if(~W_RX_RSTN)
begin
R_TX_DONE <= 2'b00;
end
else
begin
R_TX_DONE <= {R_TX_DONE[0],I_TX_DONE};
end
end
always @ (posedge I_RX_CLK)
begin
if(~W_RX_RSTN)
begin
R_ETH_RCV_CNT <= 16'd0;
end
else if(R_TX_DONE[1])
begin
R_ETH_RCV_CNT <= 16'd0;
end
else if(I_RX_VAL)
begin
R_ETH_RCV_CNT <= R_ETH_RCV_CNT + 1;
end
end
always @ (posedge I_TX_CLK)
begin
if(~W_RX_RSTN)
begin
R_RX_VAL <= 2'b00;
end
else
begin
R_RX_VAL <= {R_RX_VAL[0],I_RX_VAL};
end
end
always @ (posedge I_TX_CLK)
begin
if(~I_SYS_RSTN)
begin
R_GEN_TEST_EN <= 1'b0;
O_TX_DATA_LEN <= 16'd0;
end
else
begin
case(I_UDP_TEST_MODE)
LP_MODE_RX_ONLY:
begin
if(I_TX_DONE)
begin
R_GEN_TEST_EN <= 1'b0;
O_TX_DATA_LEN <= 16'd0;
end
end
LP_MODE_TX_ONLY:
begin
R_GEN_TEST_EN <= R_TX_ONCE[0] ^ R_TX_ONCE[1];
if(I_TX_DONE | O_TX_EN)
begin
O_TX_DATA_LEN <= 16'd50;
end
end
LP_MODE_LOOP_BACK:
begin
R_GEN_TEST_EN <= ~R_RX_VAL[0] & R_RX_VAL[1];
if(I_TX_DONE | O_TX_EN)
begin
O_TX_DATA_LEN <= R_ETH_RCV_CNT;
end
end
LP_MODE_TEST_SPEED:
begin
R_GEN_TEST_EN <= 1'b1;
if(I_TX_DONE | O_TX_EN)
begin
O_TX_DATA_LEN <= 16'd1470;
end
end
default:
begin
R_GEN_TEST_EN <= 1'b0;
O_TX_DATA_LEN <= 16'd0;
end
endcase
end
end
assign O_TX_DATA = ((I_UDP_TEST_MODE == LP_MODE_TEST_SPEED) || (I_UDP_TEST_MODE == LP_MODE_TX_ONLY)) ? W_GEN_TX_DATA : W_FIFO_RD_DATA;
// | ==================================== 模块内部模块例化 ====================================
RESET_SYNC_MDL #(
.P_INPUT_RESET_ACTIVE_LEVEL (1'b0),
.P_OUTPUT_RESET_ACTIVE_LEVEL(1'b0),
.P_SYNC_DEPTH (32'd2)
) INST_RESET_SYNC_MDL (
.I_SYNC_CLK (I_RX_CLK),
.I_RESET (I_SYS_RSTN),
.O_RESET (W_RX_RSTN)
);
UDP_TX_DATA_GEN_MDL INST_UDP_TX_DATA_GEN_MDL
(
.I_CLK_125M (I_TX_CLK),
.I_SYS_RSTN (I_SYS_RSTN),
.I_TEST_EN (R_GEN_TEST_EN),
.O_TX_EN (O_TX_EN),
.I_TX_DONE (I_TX_DONE),
.O_TX_DATA (W_GEN_TX_DATA),
.I_DATA_REQ (I_DATA_REQ),
.I_FRAME_GAP (I_FRAME_GAP),
.O_GEN_FINISH (W_GEN_FINISH)
);
ASYNC_FIFO_64X8 INST_ASYNC_FIFO_64X8 (
.rst(~I_SYS_RSTN), // input wire rst
.wr_clk(I_RX_CLK), // input wire wr_clk
.rd_clk(I_TX_CLK), // input wire rd_clk
.din(I_RX_DATA), // input wire [7 : 0] din
.wr_en(I_RX_VAL), // input wire wr_en
.rd_en(~W_FIFO_EMPTY & I_DATA_REQ), // input wire rd_en
.dout(W_FIFO_RD_DATA), // output wire [7 : 0] dout
.full(), // output wire full
.empty(W_FIFO_EMPTY), // output wire empty
.wr_rst_busy(W_WR_RST_BUSY), // output wire wr_rst_busy
.rd_rst_busy(W_RD_RST_BUSY) // output wire rd_rst_busy
);
endmodule
UDP收发顶层封装
// | ===================================================---------------------------===================================================
// | --------------------------------------------------- UDP 通信模块 ---------------------------------------------------
// | ===================================================---------------------------===================================================
// | 创建时间 : 2022-01-15
// | 完成时间 : 2022-01-15
// | 作 者 :Xu Y. B.(CSDN 用户名:在路上,正出发)
// | 功能说明 :
// | -1-
// | -2-
// | -3-
// | -4-
// |
// | ================================= 模块修改历史纪录 =================================
// | 修改日期:
// | 修改作者:
// | 修改注解:
`timescale 1ns / 1ps
module TOP_UDP_TR_MDL#(
// | ==================================== 模块可配置参数声明 ====================================
parameter P_FPGA_MAC_ADDR = 48'h00_00_00_00_00_00, // FPGA侧 MAC地址
parameter P_FPGA_IP_ADDR = {8'd0,8'd0,8'd0,8'd0}, // FPGA侧 IP地址
parameter P_FPGA_UDP_PORT = 16'd0, // FPGA侧 UDP端口号
parameter P_DST_MAC_ADDR = 48'h00_00_00_00_00_00, // 目的侧 MAC地址
parameter P_DST_IP_ADDR = {8'd0,8'd0,8'd0,8'd0}, // 目的侧 IP地址
parameter P_DST_UDP_PORT = 16'd0 // 目的侧 UDP端口号
)(
// | ==================================== 模块输入输出端口声明 ====================================
// ==== 系统复位
input I_SYS_RSTN,
// ==== PHY复位
output O_PHY_RSTB,
// UDP 发送
// 时钟、复位
input I_CLK_125M,
// 发送 握手信号
input I_TX_EN,//脉冲信号
output O_TX_DONE,
// 数据长度
input [15:0] I_TX_DATA_LEN, //一直有效至下一次传输开始,
// 最小数据为 1 最大为 1472(最大值前提是 IP首部长度 20)
// ==== 数据
input [7:0] I_TX_DATA,
output O_DATA_REQ,
// GMII接口
output O_GMII_TX_CLK,
output [7:0] O_GMII_TXD, //插入I/O缓冲,提高驱动
output O_GMII_TX_EN, //插入I/O缓冲
// ==== UDP 接收
// PHY芯片接口
input I_PHY_RX_CLK,
input I_PHY_RXDV,
input [7:0] I_PHY_RXD,
input I_PHY_RXER,
// 用户数据
output O_ETH_USR_DATA_VAL,
output [7:0] O_ETH_USR_DATA
);
// | ==================================== 模块内部逻辑设计 ====================================
assign O_PHY_RSTB = 1'b1;
// | ==================================== 模块内部模块例化 ====================================
// UDP 发
UDP_TX_MDL #(
.P_FPGA_MAC_ADDR(P_FPGA_MAC_ADDR),
.P_FPGA_IP_ADDR (P_FPGA_IP_ADDR),
.P_FPGA_UDP_PORT(P_FPGA_UDP_PORT),
.P_DST_MAC_ADDR (P_DST_MAC_ADDR),
.P_DST_IP_ADDR (P_DST_IP_ADDR),
.P_DST_UDP_PORT (P_DST_UDP_PORT)
) INST_UDP_TX_MDL (
.I_CLK_125M (I_CLK_125M),
.I_SYS_RSTN (I_SYS_RSTN),
.I_TX_EN (I_TX_EN),
.O_TX_DONE (O_TX_DONE),
.I_TX_DATA_LEN (I_TX_DATA_LEN),
.I_TX_DATA (I_TX_DATA),
.O_DATA_REQ (O_DATA_REQ),
.O_GMII_TX_CLK (O_GMII_TX_CLK),
.O_GMII_TXD (O_GMII_TXD),
.O_GMII_TX_EN (O_GMII_TX_EN)
);
// UDP 收
UDP_RX_MDL #(
.P_FPGA_MAC_ADDR (P_FPGA_MAC_ADDR),
.P_FPGA_IP_ADDR (P_FPGA_IP_ADDR)
) INST_UDP_RX_MDL (
.I_SYS_RSTN (I_SYS_RSTN),
.I_PHY_RX_CLK (I_PHY_RX_CLK),
.I_PHY_RXDV (I_PHY_RXDV),
.I_PHY_RXD (I_PHY_RXD),
.I_PHY_RXER (I_PHY_RXER),
.O_ETH_USR_DATA_VAL (O_ETH_USR_DATA_VAL),
.O_ETH_USR_DATA (O_ETH_USR_DATA)
);
endmodule
UDP数据环回设计
UDP收发时钟异步,因此为保证回环数据安全,使用异步FIFO进行跨时钟域数据传输。
异步FIFO配置
回环测试时,一次性写入数据不要超过64个。
测试顶层
顶层例化的部分代码:
// UDP 数据收发 `ifdef UDP_TEST TOP_UDP_TR_MDL #( .P_FPGA_MAC_ADDR (P_FPGA_MAC_ADDR), .P_FPGA_IP_ADDR (P_FPGA_IP_ADDR), .P_FPGA_UDP_PORT (P_FPGA_UDP_PORT), .P_DST_MAC_ADDR (P_DST_MAC_ADDR), .P_DST_IP_ADDR (P_DST_IP_ADDR), .P_DST_UDP_PORT (P_DST_UDP_PORT) ) INST_TOP_UDP_TR_MDL ( .I_SYS_RSTN (W_MMCM_LOCKED), .O_PHY_RSTB (O_PHY_RSTB), .I_CLK_125M (W_CLK_125M), .I_TX_EN (W_TX_EN), .O_TX_DONE (W_TX_DONE), .I_TX_DATA_LEN (W_TX_DATA_LEN), .I_TX_DATA (W_TX_DATA), .O_DATA_REQ (W_DATA_REQ), .O_GMII_TX_CLK (O_GMII_TX_CLK), .O_GMII_TXD (O_GMII_TXD), .O_GMII_TX_EN (O_GMII_TX_EN), .I_PHY_RX_CLK (I_PHY_RX_CLK), .I_PHY_RXDV (I_PHY_RXDV), .I_PHY_RXD (I_PHY_RXD), .I_PHY_RXER (I_PHY_RXER), .O_ETH_USR_DATA_VAL (W_ETH_USR_DATA_VAL), .O_ETH_USR_DATA (W_ETH_USR_DATA) ); UDP_TEST_MODE_CTRL INST_UDP_TEST_MODE_CTRL ( .I_SYS_RSTN (W_MMCM_LOCKED), .I_UDP_TEST_MODE (I_UDP_TEST_MODE), .I_TX_ONCE (I_TX_ONCE), .I_RX_CLK (I_PHY_RX_CLK), .I_RX_VAL (W_ETH_USR_DATA_VAL), .I_RX_DATA (W_ETH_USR_DATA), .I_TX_CLK (W_CLK_125M), .O_TX_EN (W_TX_EN), .I_TX_DONE (W_TX_DONE), .O_TX_DATA_LEN (W_TX_DATA_LEN), .I_DATA_REQ (W_DATA_REQ), .O_TX_DATA (W_TX_DATA), .I_FRAME_GAP (10'd0) ); assign O_TEST_LED[0] = I_UDP_TEST_MODE == 2'd0; assign O_TEST_LED[1] = I_UDP_TEST_MODE == 2'd1; assign O_TEST_LED[2] = I_UDP_TEST_MODE == 2'd2; assign O_TEST_LED[3] = I_UDP_TEST_MODE == 2'd3; `endif
功能仿真
将数据产生模块与数据发送模块作联合仿真,验证数据发送的功能。
UDP发送模块的源码在上篇博文。
TEST BENCH
// | ===================================================---------------------------===================================================
// | --------------------------------------------------- UDP 数据发送模块测试 ---------------------------------------------------
// | ===================================================---------------------------===================================================
// | 创建时间 : 2022-01-15
// | 完成时间 : 2022-01-15
// | 作 者 :Xu Y. B.(CSDN 用户名:在路上,正出发)
// | 功能说明 :
// | -1-
// | -2-
// |
// | ================================= 模块修改历史纪录 =================================
// | 修改日期:
// | 修改作者:
// | 修改注解:
`timescale 1ns / 1ps
module TB_UDP_TX_GEN();
// | ==================================== 模块可配置参数声明 ====================================
parameter P_FPGA_MAC_ADDR = 48'h00_0a_35_01_fe_c0; // FPGA侧 MAC地址
parameter P_FPGA_IP_ADDR = {8'd192,8'd168,8'd8,8'd3}; // FPGA侧 IP地址
parameter P_FPGA_UDP_PORT = 16'd6001; // FPGA侧 UDP端口号
parameter P_DST_MAC_ADDR = 48'hC8_5B_76_DD_0B_38; // 目的侧 MAC地址
parameter P_DST_IP_ADDR = {8'd192,8'd168,8'd8,8'd2}; // 目的侧 IP地址
parameter P_DST_UDP_PORT = 16'd6002; // 目的侧 UDP端口号
// | ==================================== 模块输入输出端口声明 ====================================
// 时钟、复位
reg I_CLK_125M;
reg I_SYS_RSTN;
// 发送 握手信号
wire I_TX_EN;//脉冲信号
wire O_TX_DONE;
// 数据长度
reg [15:0] I_TX_DATA_LEN; //一直有效至下一次传输开始,
// 最小数据为 1 最大为 1472(最大值前提是 IP首部长度 20)
// 数据
wire [7:0] I_TX_DATA;
wire O_DATA_REQ;
// GMII接口
wire O_GMII_TX_CLK;
(*IOB = "TRUE"*)
wire [7:0] O_GMII_TXD; //插入I/O缓冲,提高驱动
(*IOB = "TRUE"*)
wire O_GMII_TX_EN; //插入I/O缓冲
reg [9:0] I_FRAME_GAP;
reg I_TEST_EN;
wire O_GEN_FINISH;
// | ==================================== 产生测试激励 ====================================
initial I_CLK_125M = 1'b0;
always #4 I_CLK_125M = ~I_CLK_125M;
initial
begin
I_SYS_RSTN = 0;
I_TX_DATA_LEN = 16'd0;
I_FRAME_GAP = 10'd0;
I_TEST_EN = 1'b0;
#124;
I_SYS_RSTN = 1;
@(posedge I_CLK_125M)
I_TEST_EN <= 1'b1;
I_TX_DATA_LEN = 16'd200;
I_FRAME_GAP = 10'd100;
#109;
@(posedge I_CLK_125M)
I_TEST_EN <= 1'b0;
@(posedge O_GEN_FINISH);
#309;
@(posedge I_CLK_125M)
I_TEST_EN <= 1'b1;
I_TX_DATA_LEN = 16'd10;
I_FRAME_GAP = 10'd0;
@(posedge O_GEN_FINISH);
@(posedge O_GEN_FINISH);
@(posedge O_GEN_FINISH);
#109;
@(posedge I_CLK_125M)
I_TEST_EN <= 1'b0;
#1090;
$finish;
end
UDP_TX_MDL #(
.P_FPGA_MAC_ADDR (P_FPGA_MAC_ADDR),
.P_FPGA_IP_ADDR (P_FPGA_IP_ADDR),
.P_FPGA_UDP_PORT (P_FPGA_UDP_PORT),
.P_DST_MAC_ADDR (P_DST_MAC_ADDR),
.P_DST_IP_ADDR (P_DST_IP_ADDR),
.P_DST_UDP_PORT (P_DST_UDP_PORT)
) INST_UDP_TX_MDL (
.I_CLK_125M (I_CLK_125M),
.I_SYS_RSTN (I_SYS_RSTN),
.I_TX_EN (I_TX_EN),
.O_TX_DONE (O_TX_DONE),
.I_TX_DATA_LEN (I_TX_DATA_LEN),
.I_TX_DATA (I_TX_DATA),
.O_DATA_REQ (O_DATA_REQ),
.O_GMII_TX_CLK (O_GMII_TX_CLK),
.O_GMII_TXD (O_GMII_TXD),
.O_GMII_TX_EN (O_GMII_TX_EN)
);
UDP_TX_DATA_GEN_MDL INST_UDP_TX_DATA_GEN_MDL
(
.I_CLK_125M (I_CLK_125M),
.I_SYS_RSTN (I_SYS_RSTN),
.I_TEST_EN (I_TEST_EN),
.O_TX_EN (I_TX_EN),
.I_TX_DONE (O_TX_DONE),
.O_TX_DATA (I_TX_DATA),
.I_DATA_REQ (O_DATA_REQ),
.I_FRAME_GAP (I_FRAME_GAP),
.O_GEN_FINISH(O_GEN_FINISH)
);
endmodule
仿真结果
板级联调
MATLAB源码
clc;
clearvars;
% UDP 参数设置
LocalHost = "192.168.8.1";
LocalPort = 6002;
Timeout = 60;
% 创建UDP端口对象
U_UDP_PORT_OBJ = udpport("ByteOrder","little-endian","LocalHost",LocalHost,"LocalPort",LocalPort,"Timeout",Timeout);
% 写数据
DstHost = "192.168.8.2";
DstPort = 6001;
WR_DATA = 1:10;
write(U_UDP_PORT_OBJ,WR_DATA,"uint8",DstHost,DstPort);
% 等待数据
while(U_UDP_PORT_OBJ.NumBytesAvailable == 0)
U_UDP_PORT_OBJ.NumBytesAvailable
end
% 读数据
DATA_READ = read(U_UDP_PORT_OBJ,length(WR_DATA),"uint8")
% 清除缓存
flush(U_UDP_PORT_OBJ);
clear U_UDP_PORT_OBJ
FPGA侧以太网参数设置
其中目的 MAC地址需要通过以下方式获取:
1、cmd命令提示符内输入并执行(Enter键):
ipconfig -all
2、找到所连接的以太网名称,找到对应的 MAC地址 ,即为 FPGA发送端的目的MAC地址。
测速结果
模式3下,FPGA侧一直发送UDP数据,发送数据1470字节,帧间距设置0,测速结果:
演示视频
感兴趣可以看看,主要包含了四种测试模式的实际调试。
C站:基于FPGA的 千兆以太网收发 板级调试演示视频
B站:基于FPGA的 千兆以太网收发 板级调试演示视频