赞
踩
先放结果:
Py测试代码:
import socket #网络通信 TCP,UDP DST_IP = '192.168.0.4' DST_PORT = 8888 DST_ADDR = (DST_IP, DST_PORT) SRC_IP = '192.168.0.35' SRC_PORT = 8888 SRC_ADDR = (SRC_IP, SRC_PORT) udp = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) udp.bind(SRC_ADDR) times = 1000 right_pack_time = 0 err_pack_time = 0 while True: # data=input("输入消息") for n in range(times): data = b'\x10\x02\x03\x04\x05\x06\x07\x08\x09\x0A\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xBB' \ b'\x20\x02\x03\x04\x05\x06\x07\x08\x09\x0A\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xCC' \ b'\x30\x02\x03\x04\x05\x06\x07\x08\x09\x0A\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xDD' \ b'\x40\x02\x03\x04\x05\x06\x07\x08\x09\x0A\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xEE' \ b'\x50\x02\x03\x04\x05\x06\x07\x08\x09\x0A\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xFF' udp.sendto(data, DST_ADDR) # 发消息 data2 = udp.recvfrom(1024) if data == data2 : right_pack_time += 1 print(f'数据返回正确 pakage times:{right_pack_time}') else: err_pack_time += 1 print(f'数据返回正确 pakage times:{err_pack_time}') break udp.close()
测试平台:
数据收发参考:Verilog 实现千兆网UDP协议 基于88E1111–数据发送
Verilog 实现千兆网UDP协议 基于88E1111–数据接收
Verilog 实现千兆网UDP协议 基于88E1111–板级验证–增加ARP
**代码架构:**实现通信代码为ETH_Control下的几个模块,也就是send 发送 receive 接收 Eth_reg 为MDIO读取phy寄存器状态。两个FIFO,ping_data_buf专为ping指令reply使用,ETH_send_buf 为数据发送缓冲,本代码体系需提前数据发送数据长度,当数据发送缓冲fifo内数据足够时,代码执行开始发送指定量数量的数据。整体构架如下图:
应用时只需关注ETH_control下子模块,cmd_process用于对数据包进行解析,实际使用时会对数据区增加编帧用于传输指令或数据等区分。完整ETH_control代码如下:
`timescale 1ns / 1ps // _____ _____ _____ _____ _ _ ___ _____ _____ /// ___| / _ \ | _ \ | ____| | | | | / | | _ \ | _ \ //| | | | | | | | | | | |__ | |_| | / /| | | |_| | | | | | //| | | | | | | | | | | __| | _ | / / | | | _ / | | | | //| |___ | |_| | | |_| | | |___ | | | | / / | | | | \ \ | |_| | //\_____| \_____/ |_____/ |_____| |_| |_| /_/ |_| |_| \_\ |_____/ // _____ ___ __ __ _____ ___ __ __ _ _ _____ //| _ \ / | \ \ / / | _ \ / | \ \ / / | | | | | _ \ //| | | | / /| | \ \/ / | | | | / /| | \ \/ / | | | | | |_| | //| | | | / / | | \ / | | | | / / | | \ / | | | | | ___/ //| |_| | / / | | / / | |_| | / / | | / / | |_| | | | //|_____/ /_/ |_| /_/ |_____/ /_/ |_| /_/ \_____/ |_| // // Company: Nler Studio // Engineer: Yueze Liu // // Create Date: 14:30:16 7/15/2021 // Design Name: ETH_Control // Module Name: ETH_Control // Description: ETH_Control documents // Revision: <Code_revision_information> // // When I wrote this, only God and I understood what I was doing // Now, God only konws // So don't ask me // module ETH_Control( input clk_50m, input locked, output reg [ 3:0] Eth_Command_o , output [ 7:0] Txd_o , output Txen_o, output Txer_o, input Tx_Clk_i, output Tx_Gclk_o, input Rx_Clk_i, input [ 7:0] Rxd_i, input Rxdv_i, input Rxer_i, output reg ETH_RESET_n, output ETH_INT_n, input ETH_COL_i, input ETH_CRS_i, /*control interface*/ input Open_Eth_Sent, input [15:0] Data_length_i, input Eth_Fifo_Clk_i, output [ 7:0] Eth_Fifo_Data_i, output Eth_Fifo_Wr_en, input [ 7:0] Eth_Fifo_en_o, input [ 7:0] Eth_Fifo_Data_o, output ETH_fifo_Afull_o, output [10:0] Eth_Send_wr_count, output [15:0] Rec_data_length, input clk_5m, input rst_n, output MDC_o, inout MDIO_io ); /**/ reg [ 3:0] Eth_Command; //[3]receive_DATA [2]send_ARP [1]send_ICMP [0]send_data wire ARP_addr_en; reg ARP_addr_Get; wire [79:0] ARP_addr_data; reg [31:0] Destination_IP; reg [47:0] Destination_MAC; wire [ 7:0] E2L_Fifo_Data_o; wire E2L_Fifo_Rd_en; reg [31:0] eth_rst_reg; wire [ 7:0] Ping_Fifo_Data_i; wire Ping_Fifo_Wr_en; wire [ 7:0] Ping_Fifo_Data_o; wire Ping_Fifo_Rd_en; wire Ping_Fifo_Rd_Valid; wire Ping_Reply_Over; wire Ping_active; wire [15:0] Ping_data_length; wire [15:0] Ping_Check_Sum; reg [15:0] Ping_Check_Sum_i; reg Ping_active_r; wire clk_50m; wire [10:0] Eth_Send_rd_count; wire [ 4:0] Phy_addr; wire [ 4:0] Reg_addr; wire [15:0] Reg_data_i; wire [15:0] Reg_data_o; wire [ 0:0] Op_sw; wire [ 0:0] Op_enable; /*debug*/ /* */ assign ETH_INT_n = 1'b1; assign Tx_Gclk_o = Rx_Clk_i; /* Ethernet Power-Up Reset Process */ always @(posedge clk_50m ) begin if(!locked) begin eth_rst_reg <= 32'h0000_0000; ETH_RESET_n <= 1'b0; end else begin if(eth_rst_reg == 32'h02ff_ffff) begin eth_rst_reg <= eth_rst_reg; ETH_RESET_n <= 1'b1; end else begin eth_rst_reg <= eth_rst_reg + 1'b1; ETH_RESET_n <= 1'b0; end end end /*Process Control */ always @(posedge Rx_Clk_i or negedge locked) begin if(!locked)begin Eth_Command[3] <= 1'b0; //receive_open Eth_Command[2] <= 1'b0; //send_ARP Eth_Command[1] <= 1'b0; //send_ICMP Eth_Command[0] <= 1'b0; //send_data end else begin Eth_Command_o <= Eth_Command; /* ele_add receive start */ if(ETH_RESET_n) begin Eth_Command[3] <= 1'b1; end else begin Eth_Command[3] <= 1'b0; end /* receive ARP trigger reply // binding PC MAC IP */ if (ARP_addr_en) begin ARP_addr_Get <= 1'b1; Destination_MAC <= ARP_addr_data[79:32]; Destination_IP <= ARP_addr_data[31: 0]; Eth_Command[2] <= 1'b1; end else begin ARP_addr_Get <= 1'b0; Eth_Command[2] <= 1'b0; end /* receive ICMP trigger reply ping package */ if (Ping_active || Ping_active_r) begin Eth_Command[1] <= 1'b1; if(Ping_Reply_Over) begin Ping_active_r <= 1'b0; end else begin Ping_active_r <= 1'b1; end end else begin Eth_Command[1] <= 1'b0; end /*lock Ping_Check_Sum*/ if (Ping_active) Ping_Check_Sum_i <= Ping_Check_Sum; else Ping_Check_Sum_i<= Ping_Check_Sum_i; /*START send_data*/ if(Open_Eth_Sent) begin if(Eth_Send_rd_count > Data_length_i - 4'd10)begin Eth_Command[0] <= 1'b1; end else begin Eth_Command[0] <= 1'b0; end end else begin Eth_Command[0] <= 1'b0; end end end ETH_Send ETH_Send_u( .clk_i (Rx_Clk_i ), .rst_n (ETH_RESET_n ), .Txen_o (Txen_o ), .Txer_o (Txer_o ), .Txd_o (Txd_o ), .Eth_Command (Eth_Command ), .Data_length_i (Data_length_i ), .Eth_Fifo_Data_o (E2L_Fifo_Data_o ), .Eth_Fifo_Rd_en (E2L_Fifo_Rd_en ), .Destination_IP (Destination_IP ), .Destination_MAC (Destination_MAC ), .Ping_data_length (Ping_data_length ), .Ping_Check_Sum (Ping_Check_Sum_i ), .Ping_Reply_Over (Ping_Reply_Over ), .Ping_Fifo_Data_o (Ping_Fifo_Data_o ), .Ping_Fifo_Rd_en (Ping_Fifo_Rd_en ) ); ETH_Receive ETH_Receive_u( .clk_i (Rx_Clk_i ), .rst_n (ETH_RESET_n ), .Rxer_i (Rxer_i ), .Rxdv_i (Rxdv_i ), .Rxd_o (Rxd_i ), .Eth_Command (Eth_Command ), .Destination_IP (Destination_IP ), .Destination_MAC (Destination_MAC ), .Eth_Fifo_Data_i (Eth_Fifo_Data_i ), .Eth_Fifo_Wr_en (Eth_Fifo_Wr_en ), .Ping_Fifo_Data_i (Ping_Fifo_Data_i ), .Ping_Fifo_Wr_en (Ping_Fifo_Wr_en ), .ARP_addr_en (ARP_addr_en ), .ARP_addr_Get (ARP_addr_Get ), .ARP_addr_data (ARP_addr_data ), .Ping_active (Ping_active ), .Ping_data_length (Ping_data_length ), .Ping_Check_Sum (Ping_Check_Sum ), .Rec_data_length (Rec_data_length ) ); Ping_data_buf Ping_data_buf_u ( .rst (!locked ), .wr_clk (Rx_Clk_i ), .rd_clk (Rx_Clk_i ), .din (Ping_Fifo_Data_i ), .wr_en (Ping_Fifo_Wr_en ), .rd_en (Ping_Fifo_Rd_en ), .dout (Ping_Fifo_Data_o ), .full ( ), .empty ( ), .valid (Ping_Fifo_Rd_Valid ) ); Eth_Send_buf Eth_Send_buf_u ( .rst (!locked ), // input wire rst .wr_clk (Eth_Fifo_Clk_i ), // input wire wr_clk .rd_clk (Rx_Clk_i ), // input wire rd_clk .din (Eth_Fifo_Data_o ), // input wire [7 : 0] din .wr_en (Eth_Fifo_en_o ), // input wire wr_en .rd_en (E2L_Fifo_Rd_en ), // input wire rd_en .dout (E2L_Fifo_Data_o ), // output wire [7 : 0] dout .full ( ), // output wire full .almost_full (ETH_fifo_Afull_o ), // output wire almost_full .empty ( ), // output wire empty .rd_data_count (Eth_Send_rd_count ), // output wire [10 : 0] rd_data_count .wr_data_count (Eth_Send_wr_count ) // output wire [10 : 0] wr_data_count ); assign MDIO_io = (Op_sw_r) ? MDIO_o:1'bz; Eth_Reg_Wr Eth_Reg_Wr_u( .clk_i (clk_5m ), .rst_n (locked ), .MDC_o (MDC_o ), .MDIO_i (MDIO_io ), .MDIO_o (MDIO_o ), .Phy_addr (Phy_addr ), .Reg_addr (Reg_addr ), .Reg_data_i (Reg_data_i ), .Reg_data_o (Reg_data_o ), .Op_sw (Op_sw ), .Op_enable (Op_enable ), .Op_sw_r (Op_sw_r ) ); vio_0 vio_u ( .clk (clk_5m ), .probe_in0 (Reg_data_o ), .probe_out0 (Reg_data_i ), .probe_out1 (Phy_addr ), .probe_out2 (Reg_addr ), .probe_out3 (Op_sw ), .probe_out4 (Op_enable ) ); endmodule
对外控制接口:
Open_Eth_Sent,开启发送
Data_length_i,发送数据长度
接收数据直接写入fifo,这次测试实现CALLBACK所以外部没有连接fifo
Eth_Fifo_Clk_i,
Eth_Fifo_Data_i,
Eth_Fifo_Wr_en,
发送数据缓冲fifo
Eth_Fifo_en_o,
Eth_Fifo_Data_o,
ETH_fifo_Afull_o,
Eth_Send_wr_count,
接收数据package长度,从首部中提取出来计算出实际数据长度
Rec_data_length,
Process Control 内实现模式切换,包含UDP通讯,ARP响应,ICMP内PING reply
实现callback只需顶层将接收与发送信号相连
assign Open_Eth_Sent = 1'b1;
assign Eth_Fifo_Data_o = Eth_Fifo_Data_i;
assign Eth_Fifo_en_o = Eth_Fifo_Wr_en;
assign Data_length_i = Rec_data_length ;
assign Eth_Wr_Fifo_Clk = Rx_Clk_i;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。