基于FPGA的UDP 通信(三)
创始人
2024-05-11 06:20:37
0


目录

引言

设计框图

UDP接收模块

设计源码

TEST BENCH

仿真结果


引言

前文链接:

基于FPGA的UDP 通信(一)

基于FPGA的UDP 通信(二)

本文基于FPGA设计千兆以太网通信模块:FPGA接收上位机数据。后续会介绍FPGA发送UDP数据的设计。

设计条件:

FPGA芯片:xc7a35tfgg484-2

网络芯片(PHY):RTL8211(支持1000M/100M/10M)

MAC与PHY接口:GMII

接口类型:RJ-45



设计框图

本文先实现接收支路的功能。所设计的模块主要用于 PHY芯片和FPGA之间的通信,从原理图可知,与之对应的引脚:

引脚含义(PHY芯片手册 RTL8211):

UDP接收模块

数据解析利用状态机来实现,按照上篇文章讲的以太网数据格式,按照接收步骤依次解析。具体思路体现在设计代码里,比较容易理解,此处就不再赘述,给出设计源码:

设计源码

// | ===================================================---------------------------===================================================
// | ---------------------------------------------------       UDP 数据接收模块        ---------------------------------------------------
// | ===================================================---------------------------===================================================
// | 创建时间 : 2022-01-11
// | 完成时间 : 2022-01-11
// | 作    者 :Xu Y. B.(CSDN 用户名:在路上,正出发)
// | 功能说明 :
// |            -1- 参数可配置
// |            -2- 包含MAC地址检验、IP地址检验;未包含UDP端口号检验
// |             -3- 不做接收侧的CRC校验
// |            -4- IP首部仅校验首部长度、目的地址字段
// |
// |
// | =================================         模块修改历史纪录       =================================
// | 修改日期:
// | 修改作者:
// | 修改注解:`timescale 1ns / 1ps
module UDP_RX_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地址
)(
// | ==================================== 模块输入输出端口声明 ====================================
// 系统复位 
input                                                             I_SYS_RSTN,
// PHY芯片接口
input                                                             I_PHY_RX_CLK,
input                                                             I_PHY_RXDV,
input                 [7:0]                                        I_PHY_RXD,
input                                                             I_PHY_RXER,
// 用户数据
output     reg                                                        O_ETH_USR_DATA_VAL,
output     reg            [7:0]                                        O_ETH_USR_DATA);
// | ====================================   模块内部参数声明   ====================================
// 状态编码
localparam             LP_ST_IDLE                     =                7'b000_0001;
localparam             LP_ST_PREAMBLE                 =                7'b000_0010;
localparam             LP_ST_ETH_HEAD                 =                7'b000_0100;
localparam             LP_ST_IP_HEAD                =                7'b000_1000;
localparam             LP_ST_UDP_HEAD                 =                7'b001_0000;
localparam             LP_ST_RCV_DATA                 =                7'b010_0000;
localparam             LP_ST_RCV_END                 =                7'b100_0000;
// 以太网类型 IP数据报
localparam             LP_ETH_TYPE                 =                 16'h0800;//以太网 IP数据报 类型
// 
localparam             LP_ETH_PREAMBLE             =                8'h55;
localparam             LP_ETH_SFD                     =                8'hd5;
// | ====================================   模块内部信号声明   ====================================
// 复位同步化
wire                                                             W_RX_MDL_RSTN;
// 状态信号
reg                 [6:0]                                        R_CS;
reg                 [6:0]                                        R_NS;
// 目的MAC地址
reg                 [47:0]                                        R_DST_MAC_ADDR;
// 目的IP地址
reg                 [31:0]                                        R_DST_IP_ADDR;
// 以太网协议类型
reg                 [15:0]                                        R_ETH_TYPE;
// IP头部字节数目
reg                 [5:0]                                        R_IP_HEAD_BYTE_NUM;
// UDP数据字节数目
reg                 [15:0]                                        R_UDP_DATA_BYTE_NUM;
// 标志信号
reg                                                             R_PREAMBLE_RCV_DONE;
reg                                                             R_PREAMBLE_RCV_ERR;
reg                                                             R_ETH_HEAD_RCV_DONE;
reg                                                             R_ETH_HEAD_RCV_ERR;
reg                                                             R_IP_HEAD_RCV_DONE;
reg                                                             R_IP_HEAD_RCV_ERR;
reg                                                             R_IP_RIGHT;
reg                                                             R_UDP_HEAD_RCV_DONE;
reg                                                             R_UDP_DATA_RCV_DONE;
// 计数器
reg                 [2:0]                                        R_PREAMBLE_CNT;
reg                 [3:0]                                        R_ETH_HEAD_CNT;
reg                 [5:0]                                        R_IP_HEAD_CNT;
reg                 [2:0]                                        R_UDP_HEAD_CNT;
reg                 [15:0]                                        R_UDP_DATA_CNT;// | ====================================   模块内部逻辑设计   ====================================
// 状态机
always @ (posedge I_PHY_RX_CLK)
beginif(~W_RX_MDL_RSTN)beginR_CS <= LP_ST_IDLE;endelse if(I_PHY_RXER)beginR_CS <= LP_ST_RCV_END;endelse if(I_PHY_RXDV)//避免 PHY出现异常 ,数据发送期间 ,有效信号中断beginR_CS <= R_NS;endelsebeginR_CS <= LP_ST_IDLE;end
endalways @ (*)
beginif(~W_RX_MDL_RSTN)beginendelsebegincase(R_CS)LP_ST_IDLE:beginif(I_PHY_RXDV && (I_PHY_RXD == 8'h55))beginR_NS = LP_ST_PREAMBLE;endelsebeginR_NS = LP_ST_IDLE;endend         LP_ST_PREAMBLE:beginif(R_PREAMBLE_RCV_DONE)beginR_NS = LP_ST_ETH_HEAD;endelse if(R_PREAMBLE_RCV_ERR)beginR_NS = LP_ST_RCV_END;endelsebeginR_NS = LP_ST_PREAMBLE;endendLP_ST_ETH_HEAD:beginif(R_ETH_HEAD_RCV_DONE)beginR_NS = LP_ST_IP_HEAD;endelse if(R_ETH_HEAD_RCV_ERR)beginR_NS = LP_ST_RCV_END;endelsebeginR_NS = LP_ST_ETH_HEAD;endendLP_ST_IP_HEAD:beginif(R_IP_HEAD_RCV_DONE & R_IP_RIGHT)beginR_NS = LP_ST_UDP_HEAD;endelse if(R_IP_HEAD_RCV_ERR)beginR_NS = LP_ST_RCV_END;endelsebeginR_NS = LP_ST_IP_HEAD;endendLP_ST_UDP_HEAD:beginif(R_UDP_HEAD_RCV_DONE)beginR_NS = LP_ST_RCV_DATA;endelsebeginR_NS = LP_ST_UDP_HEAD;endendLP_ST_RCV_DATA:beginif(R_UDP_DATA_RCV_DONE)beginR_NS = LP_ST_RCV_END;endelsebeginR_NS = LP_ST_RCV_DATA;endendLP_ST_RCV_END :beginif(~I_PHY_RXDV)beginR_NS = LP_ST_IDLE;endelsebeginR_NS = LP_ST_RCV_END;endenddefault:beginR_NS = LP_ST_IDLE;endendcaseend
end// 接收并检验前导码及SFD
always @ (posedge I_PHY_RX_CLK)
beginif(~W_RX_MDL_RSTN)beginR_PREAMBLE_RCV_DONE <= 1'b0;R_PREAMBLE_RCV_ERR  <= 1'b0;R_PREAMBLE_CNT      <= 3'd0;endelse if(|(R_CS & LP_ST_PREAMBLE))beginif(I_PHY_RXDV)beginif((R_PREAMBLE_CNT <= 3'd5) && (I_PHY_RXD != LP_ETH_PREAMBLE))//接收检验 前导码beginR_PREAMBLE_RCV_DONE <= 1'b0;R_PREAMBLE_RCV_ERR  <= 1'b1;R_PREAMBLE_CNT      <= 3'd0;endelse if(R_PREAMBLE_CNT == 3'd6)beginR_PREAMBLE_CNT <= 3'd0;if(I_PHY_RXD == LP_ETH_SFD) // 接收检验 SFDbeginR_PREAMBLE_RCV_DONE <= 1'b1;R_PREAMBLE_RCV_ERR  <= 1'b0;endelsebeginR_PREAMBLE_RCV_DONE <= 1'b0;R_PREAMBLE_RCV_ERR  <= 1'b1;endendelsebeginR_PREAMBLE_RCV_DONE <= 1'b0;R_PREAMBLE_RCV_ERR  <= 1'b0;R_PREAMBLE_CNT      <= R_PREAMBLE_CNT + 1;endendendelsebeginR_PREAMBLE_RCV_DONE <= 1'b0;R_PREAMBLE_RCV_ERR  <= 1'b0;        R_PREAMBLE_CNT      <= 3'd0;end
end// 接收并检验以太网帧头
always @ (posedge I_PHY_RX_CLK)
beginif(~W_RX_MDL_RSTN)beginR_ETH_HEAD_RCV_DONE <= 1'b0;R_ETH_HEAD_RCV_ERR  <= 1'b0;R_ETH_HEAD_CNT      <= 4'd0;R_DST_MAC_ADDR         <= 48'd0;R_ETH_TYPE          <= 16'd0;endelse if(|(R_NS & LP_ST_ETH_HEAD))beginif(I_PHY_RXDV)beginif(R_ETH_HEAD_CNT <= 4'd5)//接收 目的MAC地址beginR_ETH_HEAD_CNT <= R_ETH_HEAD_CNT + 1;R_DST_MAC_ADDR <= {R_DST_MAC_ADDR[0+:40],I_PHY_RXD};endelse if(R_ETH_HEAD_CNT == 4'd12)//接收以太网类型beginR_ETH_HEAD_CNT <= R_ETH_HEAD_CNT + 1;R_ETH_TYPE[15:8] <= I_PHY_RXD;endelse if(R_ETH_HEAD_CNT == 4'd13)//接收以太网类型beginR_ETH_HEAD_CNT <= 4'd0;R_ETH_TYPE[7:0] <= I_PHY_RXD;if((R_DST_MAC_ADDR == P_FPGA_MAC_ADDR) || (R_DST_MAC_ADDR == {48{1'b1}}))//判断MAC地址是否一致beginR_ETH_HEAD_RCV_DONE <= 1'b1;endelsebeginR_ETH_HEAD_RCV_ERR <= 1'b1;endendelsebeginR_ETH_HEAD_CNT <= R_ETH_HEAD_CNT + 1;endendendelsebeginR_ETH_HEAD_RCV_DONE <= 1'b0;R_ETH_HEAD_RCV_ERR  <= 1'b0;R_ETH_HEAD_CNT      <= 4'd0;end
end// 接收并检验IP首部
always @ (posedge I_PHY_RX_CLK)
beginif(~W_RX_MDL_RSTN)beginR_IP_HEAD_RCV_DONE <= 1'b0;R_IP_HEAD_RCV_ERR  <= 1'b0;R_IP_RIGHT            <= 1'b0;R_IP_HEAD_CNT      <= 6'd0;R_IP_HEAD_BYTE_NUM <= 6'd0;R_DST_IP_ADDR      <= 32'd0;endelse if(|(R_NS & LP_ST_IP_HEAD))beginif(I_PHY_RXDV)beginif(R_IP_HEAD_CNT == 6'd0)//接收并计算IP头部数据字节个数beginR_IP_HEAD_BYTE_NUM <= {I_PHY_RXD[3:0],2'd0};//*4R_IP_HEAD_CNT <= R_IP_HEAD_CNT + 1;endelse if((R_IP_HEAD_CNT >= 6'd16) && (R_IP_HEAD_CNT <= 6'd18))//接收高3字节IP地址beginR_DST_IP_ADDR <= {R_DST_IP_ADDR[23:0],I_PHY_RXD};R_IP_HEAD_CNT <= R_IP_HEAD_CNT + 1;endelse if(R_IP_HEAD_CNT == 6'd19)//接收第4字节IP地址beginR_DST_IP_ADDR <= {R_DST_IP_ADDR[23:0],I_PHY_RXD};if((R_DST_IP_ADDR[23:0] == P_FPGA_IP_ADDR[31:8]) && (I_PHY_RXD == P_FPGA_IP_ADDR[7:0]))//判断 IP地址是否一致beginR_IP_RIGHT <= 1'b1;R_IP_HEAD_RCV_ERR <= 1'b0;endelsebeginR_IP_RIGHT <= 1'b0;R_IP_HEAD_RCV_ERR <= 1'b1;endif(6'd20 == R_IP_HEAD_BYTE_NUM)//判断 IP首部是否接收完毕beginR_IP_HEAD_CNT <= 6'd0;R_IP_HEAD_RCV_DONE <= 1'b1;endelsebeginR_IP_HEAD_CNT <= R_IP_HEAD_CNT + 1;R_IP_HEAD_RCV_DONE <= 1'b0;endendelse if(R_IP_HEAD_CNT == (R_IP_HEAD_BYTE_NUM-1))//判断 IP首部是否接收完毕beginR_IP_HEAD_CNT <= 6'd0;R_IP_HEAD_RCV_DONE <= 1'b1;endelsebeginR_IP_HEAD_CNT <= R_IP_HEAD_CNT + 1'b1;endendendelsebeginR_IP_HEAD_RCV_DONE <= 1'b0;R_IP_HEAD_RCV_ERR  <= 1'b0;R_IP_HEAD_CNT      <= 5'd0;R_IP_RIGHT         <= 1'b0;R_IP_HEAD_BYTE_NUM <= 6'd0;end
end// 接收并检验UDP首部
always @ (posedge I_PHY_RX_CLK)
beginif(~W_RX_MDL_RSTN)beginR_UDP_HEAD_RCV_DONE <= 1'b0;R_UDP_HEAD_CNT      <= 3'd0;R_UDP_DATA_BYTE_NUM <= 16'd0;endelse if(|(R_NS & LP_ST_UDP_HEAD))beginif(I_PHY_RXDV)beginif(R_UDP_HEAD_CNT == 3'd4)// 接收UDP数据字节数 高字节beginR_UDP_DATA_BYTE_NUM[15:8] <= I_PHY_RXD;R_UDP_HEAD_CNT <= R_UDP_HEAD_CNT + 1;endelse if(R_UDP_HEAD_CNT == 3'd5)// 接收UDP数据字节数 低字节beginR_UDP_DATA_BYTE_NUM[7:0] <= I_PHY_RXD;R_UDP_HEAD_CNT <= R_UDP_HEAD_CNT + 1;endelse if(&R_UDP_HEAD_CNT)// UDP首部接收结束beginR_UDP_DATA_BYTE_NUM <= R_UDP_DATA_BYTE_NUM - 16'd8;R_UDP_HEAD_RCV_DONE <= 1'b1;R_UDP_HEAD_CNT <= 3'd0;endelsebeginR_UDP_HEAD_CNT <= R_UDP_HEAD_CNT + 1;endendendelsebeginR_UDP_HEAD_RCV_DONE <= 1'b0;R_UDP_HEAD_CNT      <= 3'd0;R_UDP_DATA_BYTE_NUM <= R_UDP_DATA_BYTE_NUM;end
end// 接收UDP用户数据
always @ (posedge I_PHY_RX_CLK)
beginif(~W_RX_MDL_RSTN)beginO_ETH_USR_DATA_VAL <= 1'b0;O_ETH_USR_DATA     <= 8'd0;R_UDP_DATA_RCV_DONE<= 1'b0;R_UDP_DATA_CNT     <= 16'd0;endelse if(|(R_NS & LP_ST_RCV_DATA))beginif(I_PHY_RXDV)beginif(R_UDP_DATA_CNT == (R_UDP_DATA_BYTE_NUM-1))beginO_ETH_USR_DATA_VAL <= 1'b1;O_ETH_USR_DATA     <= I_PHY_RXD;R_UDP_DATA_RCV_DONE<= 1'b1;R_UDP_DATA_CNT     <= 16'd0;endelsebeginO_ETH_USR_DATA_VAL <= 1'b1;O_ETH_USR_DATA     <= I_PHY_RXD;R_UDP_DATA_RCV_DONE<= 1'b0;R_UDP_DATA_CNT     <= R_UDP_DATA_CNT + 1;                endendendelsebeginO_ETH_USR_DATA_VAL <= 1'b0;O_ETH_USR_DATA     <= 8'd0;R_UDP_DATA_RCV_DONE<= 1'b0;R_UDP_DATA_CNT     <= 16'd0;        end
end
// | ====================================   模块内部模块例化   ====================================
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_PHY_RX_CLK),.I_RESET    (I_SYS_RSTN),.O_RESET    (W_RX_MDL_RSTN));endmodule

TEST BENCH

仿真了5种情形:
1、正确传输(2次);
2、传输过程中,接收错误信号拉高;
3、目的MAC地址出错;
4、目的IP地址出错;

// | ===================================================---------------------------===================================================
// | ---------------------------------------------------    UDP 数据接收模块仿真   ---------------------------------------------------
// | ===================================================---------------------------===================================================
// | 创建时间 : 2022-01-12
// | 完成时间 : 2022-01-12
// | 作    者 :Xu Y. B.(CSDN 用户名:在路上,正出发)
// | 功能说明 :
// |			-1- 正确传输(2次);
// |			-2- 传输过程中,接收错误信号拉高;
// | 			-3- 目的MAC地址出错;
// |			-4- 目的IP地址出错;
// |
// |
// | ================================= 		模块修改历史纪录 	  =================================
// | 修改日期:
// | 修改作者:
// | 修改注解:`timescale 1ns / 1psmodule TB_UDP_RX_MDL();
// | ====================================  模块可配置参数声明  ==================================== 
parameter 			P_FPGA_MAC_ADDR				=				48'h11_11_11_11_11_11;  	  // FPGA侧 MAC地址
parameter 			P_FPGA_IP_ADDR				=				{8'd192,8'd168,8'd137,8'd3};  // FPGA侧 IP地址// | ==================================== 模块输入输出端口声明 ====================================
// 系统复位 
reg 															I_SYS_RSTN;
// PHY芯片接口
reg 															I_PHY_RX_CLK;
reg 															I_PHY_RXDV;
reg 				[7:0]										I_PHY_RXD;
reg 															I_PHY_RXER;
// 用户数据
wire															O_ETH_USR_DATA_VAL;
wire				[7:0]										O_ETH_USR_DATA;// | ====================================     产生仿真激励     ====================================
initial I_PHY_RX_CLK  =  1'b0;
always #4 I_PHY_RX_CLK = ~I_PHY_RX_CLK;initial
beginI_SYS_RSTN = 1'b0;I_PHY_RXDV = 1'b0;I_PHY_RXD  = 8'd0;I_PHY_RXER = 1'b0;#134;I_SYS_RSTN = 1'b1;#123;repeat(2)begin// 前导码repeat(7)begin@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'h55;end// SFD@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'hd5;// MAC地址TASK_SEND_MAC_ADDR(P_FPGA_MAC_ADDR);TASK_SEND_MAC_ADDR(48'h01_11_10_11_11_11);// 协议类型@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'h08;@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'h00;// IP首部@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'b0100_0101;repeat(15)begin@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'd0;endTASK_SEND_IP_ADDR(P_FPGA_IP_ADDR);// UDP首部repeat(4)begin@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'd0;end@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'd0;	@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'd108;	repeat(2)begin@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'd0;end// UDP数据repeat(100)begin@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= I_PHY_RXD + 1;end// FCSrepeat(4)begin@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'd0;end@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b0;I_PHY_RXD  <= 8'd0;	#1250;end#100;repeat(1)begin// 前导码repeat(7)begin@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'h55;end// SFD@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'hd5;// MAC地址TASK_SEND_MAC_ADDR(P_FPGA_MAC_ADDR);TASK_SEND_MAC_ADDR(48'h01_11_10_11_11_11);// 协议类型@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'h08;I_PHY_RXER <= 1'b1;//接收错误@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'h00;// IP首部@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'b0100_0101;I_PHY_RXER <= 1'b0;repeat(15)begin@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'd0;endTASK_SEND_IP_ADDR(P_FPGA_IP_ADDR);// UDP首部repeat(4)begin@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'd0;end@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'd0;	@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'd108;	repeat(2)begin@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'd0;end// UDP数据repeat(100)begin@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= I_PHY_RXD + 1;end// FCSrepeat(4)begin@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'd0;end@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b0;I_PHY_RXD  <= 8'd0;	#1250;end#100;repeat(1)begin// 前导码repeat(7)begin@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'h55;end// SFD@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'hd5;// MAC地址TASK_SEND_MAC_ADDR(48'h01_31_10_11_11_11);//MAC地址出错TASK_SEND_MAC_ADDR(48'h01_11_10_11_11_11);// 协议类型@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'h08;@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'h00;// IP首部@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'b0100_0101;repeat(15)begin@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'd0;endTASK_SEND_IP_ADDR(P_FPGA_IP_ADDR);// UDP首部repeat(4)begin@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'd0;end@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'd0;	@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'd108;	repeat(2)begin@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'd0;end// UDP数据repeat(100)begin@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= I_PHY_RXD + 1;end// FCSrepeat(4)begin@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'd0;end@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b0;I_PHY_RXD  <= 8'd0;	#1250;end#100;repeat(1)begin// 前导码repeat(7)begin@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'h55;end// SFD@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'hd5;// MAC地址TASK_SEND_MAC_ADDR(P_FPGA_MAC_ADDR);TASK_SEND_MAC_ADDR(48'h01_11_10_11_11_11);// 协议类型@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'h08;@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'h00;// IP首部@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'b0100_0101;repeat(15)begin@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'd0;endTASK_SEND_IP_ADDR(P_FPGA_IP_ADDR + 32'd2);//IP地址出错// UDP首部repeat(4)begin@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'd0;end@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'd0;	@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'd108;	repeat(2)begin@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'd0;end// UDP数据repeat(100)begin@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= I_PHY_RXD + 1;end// FCSrepeat(4)begin@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= 8'd0;end@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b0;I_PHY_RXD  <= 8'd0;	#1250;end#100;$finish;
end
// | ====================================     被测模块例化     ====================================
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));
// | ====================================     仿真任务声明     ====================================
task TASK_SEND_MAC_ADDR;input [47:0] MAC_ADDR;begin@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= MAC_ADDR[47:40];@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= MAC_ADDR[39:32];@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= MAC_ADDR[31:24];@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= MAC_ADDR[23:16];@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= MAC_ADDR[15:8];@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= MAC_ADDR[7:0];end
endtasktask TASK_SEND_IP_ADDR;input [31:0] IP_ADDR;begin@(posedge I_PHY_RX_CLK)I_PHY_RXD  <= IP_ADDR[31:24];@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= IP_ADDR[23:16];@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= IP_ADDR[15:8];@(posedge I_PHY_RX_CLK)I_PHY_RXDV <= 1'b1;I_PHY_RXD  <= IP_ADDR[7:0];end
endtask
endmodule

仿真结果

此过程可自行仿真查看。


相关内容

热门资讯

常用商务英语口语   商务英语是以适应职场生活的语言要求为目的,内容涉及到商务活动的方方面面。下面是小编收集的常用商务...
六年级上册英语第一单元练习题   一、根据要求写单词。  1.dry(反义词)__________________  2.writ...
复活节英文怎么说 复活节英文怎么说?复活节的英语翻译是什么?复活节:Easter;"Easter,anniversar...
2008年北京奥运会主题曲 2008年北京奥运会(第29届夏季奥林匹克运动会),2008年8月8日到2008年8月24日在中华人...
英语道歉信 英语道歉信15篇  在日常生活中,道歉信的使用频率越来越高,通过道歉信,我们可以更好地解释事情发生的...
六年级英语专题训练(连词成句... 六年级英语专题训练(连词成句30题)  1. have,playhouse,many,I,toy,i...
上班迟到情况说明英语   每个人都或多或少的迟到过那么几次,因为各种原因,可能生病,可能因为交通堵车,可能是因为天气冷,有...
小学英语教学论文 小学英语教学论文范文  引导语:英语教育一直都是每个家长所器重的,那么有关小学英语教学论文要怎么写呢...
英语口语学习必看的方法技巧 英语口语学习必看的方法技巧如何才能说流利的英语? 说外语时,我们主要应做到四件事:理解、回答、提问、...
四级英语作文选:Birth ... 四级英语作文范文选:Birth controlSince the Chinese Governmen...
金融专业英语面试自我介绍 金融专业英语面试自我介绍3篇  金融专业的学生面试时,面试官要求用英语做自我介绍该怎么说。下面是小编...
我的李老师走了四年级英语日记... 我的李老师走了四年级英语日记带翻译  我上了五个学期的小学却换了六任老师,李老师是带我们班最长的语文...
小学三年级英语日记带翻译捡玉... 小学三年级英语日记带翻译捡玉米  今天,我和妈妈去外婆家,外婆家有刚剥的`玉米棒上带有玉米籽,好大的...
七年级英语优秀教学设计 七年级英语优秀教学设计  作为一位兢兢业业的人民教师,常常要写一份优秀的教学设计,教学设计是把教学原...
我的英语老师作文 我的英语老师作文(通用21篇)  在日常生活或是工作学习中,大家都有写作文的经历,对作文很是熟悉吧,...
英语老师教学经验总结 英语老师教学经验总结(通用19篇)  总结是指社会团体、企业单位和个人对某一阶段的学习、工作或其完成...
初一英语暑假作业答案 初一英语暑假作业答案  英语练习一(基础训练)第一题1.D2.H3.E4.F5.I6.A7.J8.C...
大学生的英语演讲稿 大学生的英语演讲稿范文(精选10篇)  使用正确的写作思路书写演讲稿会更加事半功倍。在现实社会中,越...
VOA美国之音英语学习网址 VOA美国之音英语学习推荐网址 美国之音网站已经成为语言学习最重要的资源站点,在互联网上还有若干网站...
商务英语期末试卷 Part I Term Translation (20%)Section A: Translate ...