FPGA实现精简版UDP通信,占资源很少但很稳定,提供2套工程源码

news2024/12/29 8:59:19

目录

  • 1.高端、中等和精简版UDP通信的选择
  • 2.精简版UDP通信实现方案
  • 3.工程1介绍及资源占用率和性能表现
  • 4.工程2介绍及资源占用率和性能表现
  • 5.上板调试验证
  • 6.福利:工程代码的获取

1.高端、中等和精简版UDP通信的选择

FPGA实现UDP协议可难可易,具体根据项目需求而定,目前项目上的需求大概有如下几种:
1、使用Xilinx系列FPGA实现UDP通信,且传输的数据量大,速率快,带宽高,这类的UDP通信必然要用到Xilinx的三速网IP,用户接口的数据必然是AXIS流,此类UDP协议功能齐全,无疑是很好的方案,关于这类的UDP通信介绍以及工程源码请参考我之前写的文章点击查看:高端UDP通信,附带工程源码
此类UDP协议虽然很好,但占用FPGA资源较多,对于A7、Spatan6、Altera之类的低端FPGA来说资源消耗太大,不太可能被采用,再者,对于国产FPGA来说,没有三速网IP也无法实现;
2、不使用三速网IP,通信速率相对较低,实现过程几乎使用纯verilog代码实现的中等UDP通信方案,关于这类的UDP通信介绍以及工程源码请参考我之前写的文章点击查看:中等UDP通信,附带工程源码
此类方案没有了IP的限制,任何品牌的FPGA均可实现,但占用FPGA资源还是较多,低端FPGA依然很难实现;
3、精简版UDP通信方案
就是此文介绍的方案
优点:
纯verilog代码实现,没有任何IP;
代码量很少,所占逻辑资源很少;
通用性好,Xilinx、Altera、国产FPGA均可使用;
稳定性好,本人反复测试,很稳定;

2.精简版UDP通信实现方案

总体实现方案如下:
在这里插入图片描述
RGMII-GMII模块实现网络PHY数据与FPGA接口的数据转换,由PHY的4位DDR双边沿采样数据到FPGA接口8位单边沿采样数据的转换;模块接口顶层如下:

module gmii_to_rgmii(
    input              idelay_clk  , //IDELAY时钟
    //以太网GMII接口
    output             gmii_rx_clk , //GMII接收时钟
    output             gmii_rx_dv  , //GMII接收数据有效信号
    output      [7:0]  gmii_rxd    , //GMII接收数据
    output             gmii_tx_clk , //GMII发送时钟
    input              gmii_tx_en  , //GMII发送数据使能信号
    input       [7:0]  gmii_txd    , //GMII发送数据            
    //以太网RGMII接口   
    input              rgmii_rxc   , //RGMII接收时钟
    input              rgmii_rx_ctl, //RGMII接收数据控制信号
    input       [3:0]  rgmii_rxd   , //RGMII接收数据
    output             rgmii_txc   , //RGMII发送时钟    
    output             rgmii_tx_ctl, //RGMII发送数据控制信号
    output      [3:0]  rgmii_txd     //RGMII发送数据          
    );

ARP模块顾名思义就是实现了ARP协议,该模块在不同应用中可有可无,在于上位机通信时需要,在FPGA板间通信时则可以不需要,模块接口顶层如下:

module arp(
    input                rst_n      , //复位信号,低电平有效
    //GMII接口
    input                gmii_rx_clk, //GMII接收数据时钟
    input                gmii_rx_dv , //GMII输入数据有效信号
    input        [7:0]   gmii_rxd   , //GMII输入数据
    input                gmii_tx_clk, //GMII发送数据时钟
    output               gmii_tx_en , //GMII输出数据有效信号
    output       [7:0]   gmii_txd   , //GMII输出数据          

    //用户接口
    output               arp_rx_done, //ARP接收完成信号
    output               arp_rx_type, //ARP接收类型 0:请求  1:应答
    output       [47:0]  src_mac    , //接收到目的MAC地址
    output       [31:0]  src_ip     , //接收到目的IP地址    
    input                arp_tx_en  , //ARP发送使能信号
    input                arp_tx_type, //ARP发送类型 0:请求  1:应答
    input        [47:0]  des_mac    , //发送的目标MAC地址
    input        [31:0]  des_ip     , //发送的目标IP地址
    output               tx_done      //以太网发送完成信号    
    );

UDP模块顾名思义就是实现了UDP协议,该部分内部已经包含了IP协议的编解码,这部分时整个工程的核心,UDP协议其实真的很简单,接收部分就是根据协议进行数据解包,解出帧头部分并丢弃,解出有效数据并输出;发送部分就是根据协议进行数据组包,把发送数据加上帧头发出去就完事儿了,模块接口顶层如下:

module udp(
    input                rst_n       , //复位信号,低电平有效
    //GMII接口
    input                gmii_rx_clk , //GMII接收数据时钟
    input                gmii_rx_dv  , //GMII输入数据有效信号
    input        [7:0]   gmii_rxd    , //GMII输入数据
    input                gmii_tx_clk , //GMII发送数据时钟    
    output               gmii_tx_en  , //GMII输出数据有效信号
    output       [7:0]   gmii_txd    , //GMII输出数据 
    //用户接口
    output               rec_pkt_done, //以太网单包数据接收完成信号
    output               rec_en      , //以太网接收的数据使能信号
    output       [31:0]  rec_data    , //以太网接收的数据
    output       [15:0]  rec_byte_num, //以太网接收的有效字节数 单位:byte     
    input                tx_start_en , //以太网开始发送信号
    input        [31:0]  tx_data     , //以太网待发送数据  
    input        [15:0]  tx_byte_num , //以太网发送的有效字节数 单位:byte  
    input        [47:0]  des_mac     , //发送的目标MAC地址
    input        [31:0]  des_ip      , //发送的目标IP地址    
    output               tx_done     , //以太网发送完成信号
    output               tx_req        //读数据请求信号    
    );

工程介绍:
在这里插入图片描述
简而言之就是实现UDP自发自收,以验证UDP协议的正确性;

3.工程1介绍及资源占用率和性能表现

工程1介绍;
开发板:Kintex7开发板;
网络PHY:B50610
输出:RJ45网口
接收:电脑上位机;
B50610不需要配置,使用默认的配置,工作在延时模式,PHY的发送时钟rgmii_txc 与FPGA发送时钟gmii_tx_clk一致;
代码部分如下:

assign rgmii_txc = gmii_tx_clk;

工程顶层代码如下:


module eth_udp_loop(
    input              clk_50   , //系统时钟
    //PL以太网RGMII接口   
    input              phy1_rgmii_rx_clk   , //RGMII接收数据时钟
    input              phy1_rgmii_rx_ctl, //RGMII输入数据有效信号
    input       [3:0]  phy1_rgmii_rx_data   , //RGMII输入数据
    output             phy1_rgmii_tx_clk   , //RGMII发送数据时钟    
    output             phy1_rgmii_tx_ctl, //RGMII输出数据有效信号
    output      [3:0]  phy1_rgmii_tx_data   , //RGMII输出数据          
    output             phy_reset   //以太网芯片复位信号,低电平有效   
    );

//parameter define
parameter  BOARD_MAC = 48'h00_11_22_33_44_55;   //开发板MAC地址 
parameter  BOARD_IP  = {8'd192,8'd168,8'd10,8'd1};  //开发板IP地址
parameter  DES_MAC   = 48'hff_ff_ff_ff_ff_ff; 	//目的MAC地址    
parameter  DES_IP    = {8'd192,8'd168,8'd10,8'd2};	//目的IP地址 
parameter IDELAY_VALUE = 0;	//输入数据IO延时,此处为0,即不延时(如果为n,表示延时n*78ps) 
parameter  BOARD_POART =16'd1234;
parameter  DES_POART   =16'd1234;

//wire define
wire          clk_200m   ; //用于IO延时的时钟         
wire          gmii_rx_clk; //GMII接收时钟
wire          gmii_rx_dv ; //GMII接收数据有效信号
wire  [7:0]   gmii_rxd   ; //GMII接收数据
wire          gmii_tx_clk; //GMII发送时钟
wire          gmii_tx_en ; //GMII发送数据使能信号
wire  [7:0]   gmii_txd   ; //GMII发送数据     
wire          arp_gmii_tx_en; //ARP GMII输出数据有效信号 
wire  [7:0]   arp_gmii_txd  ; //ARP GMII输出数据
wire          arp_rx_done   ; //ARP接收完成信号
wire          arp_rx_type   ; //ARP接收类型 0:请求  1:应答
wire  [47:0]  src_mac       ; //接收到目的MAC地址
wire  [31:0]  src_ip        ; //接收到目的IP地址    
wire          arp_tx_en     ; //ARP发送使能信号
wire          arp_tx_type   ; //ARP发送类型 0:请求  1:应答
wire  [47:0]  des_mac       ; //发送的目标MAC地址
wire  [31:0]  des_ip        ; //发送的目标IP地址   
wire          arp_tx_done   ; //ARP发送完成信号
wire          udp_gmii_tx_en; //UDP GMII输出数据有效信号 
wire  [7:0]   udp_gmii_txd  ; //UDP GMII输出数据
wire          rec_pkt_done  ; //UDP单包数据接收完成信号
wire          rec_en        ; //UDP接收的数据使能信号
wire  [31:0]  rec_data      ; //UDP接收的数据
wire  [15:0]  rec_byte_num  ; //UDP接收的有效字节数 单位:byte 
wire  [15:0]  tx_byte_num   ; //UDP发送的有效字节数 单位:byte 
wire          udp_tx_done   ; //UDP发送完成信号
wire          tx_req        ; //UDP读数据请求信号
wire  [31:0]  tx_data       ; //UDP待发送数据
wire sys_rst_n;
//*****************************************************
//**                    main code
//*****************************************************
assign gmii_tx_clk = gmii_rx_clk ;
assign tx_start_en = rec_pkt_done;
assign tx_byte_num = rec_byte_num;
assign des_mac = src_mac;
assign des_ip = src_ip;
assign phy_reset = sys_rst_n;

clk_wiz_0 instance_name
   (
    // Clock out ports
    .clk_200m(clk_200m),     // output clk_200m
    .clk_125m(),     // output clk_125m
    .clk_125m_90(),     // output clk_125m_90
    // Status and control signals
    .locked(sys_rst_n),       // output locked
   // Clock in ports
    .clk_in1(clk_50));      // input clk_in1

//GMII接口转RGMII接口
gmii_to_rgmii 
    #(
     .IDELAY_VALUE (IDELAY_VALUE)
     )
    u_gmii_to_rgmii(
    .idelay_clk    (clk_200m    ),
    .gmii_rx_clk   (gmii_rx_clk ),
    .gmii_rx_dv    (gmii_rx_dv  ),
    .gmii_rxd      (gmii_rxd    ),
    .gmii_tx_clk   (gmii_tx_clk ),
    .gmii_tx_en    (gmii_tx_en  ),
    .gmii_txd      (gmii_txd    ),
    .rgmii_rxc     (phy1_rgmii_rx_clk     ),
    .rgmii_rx_ctl  (phy1_rgmii_rx_ctl  ),
    .rgmii_rxd     (phy1_rgmii_rx_data     ),
    .rgmii_txc     (phy1_rgmii_tx_clk     ),
    .rgmii_tx_ctl  (phy1_rgmii_tx_ctl  ),
    .rgmii_txd     (phy1_rgmii_tx_data     )
    );

//ARP通信
arp                                             
   #(
    .BOARD_MAC     (BOARD_MAC),      //参数例化
    .BOARD_IP      (BOARD_IP ),
    .DES_MAC       (DES_MAC  ),
    .DES_IP        (DES_IP   )
    )
   u_arp(
    .rst_n         (sys_rst_n  ),             
    .gmii_rx_clk   (gmii_rx_clk),
    .gmii_rx_dv    (gmii_rx_dv ),
    .gmii_rxd      (gmii_rxd   ),
    .gmii_tx_clk   (gmii_tx_clk),
    .gmii_tx_en    (arp_gmii_tx_en ),
    .gmii_txd      (arp_gmii_txd),              
    .arp_rx_done   (arp_rx_done),
    .arp_rx_type   (arp_rx_type),
    .src_mac       (src_mac    ),
    .src_ip        (src_ip     ),
    .arp_tx_en     (arp_tx_en  ),
    .arp_tx_type   (arp_tx_type),
    .des_mac       (des_mac    ),
    .des_ip        (des_ip     ),
    .tx_done       (arp_tx_done)
    );

//UDP通信
udp                                             
   #(
    .BOARD_MAC     (BOARD_MAC),      //参数例化
    .BOARD_IP      (BOARD_IP ),
    .DES_MAC       (DES_MAC  ),
    .DES_IP        (DES_IP   ),
	.BOARD_POART     (BOARD_POART),
	.DES_POART       (DES_POART  )	
    )
   u_udp(
    .rst_n         (sys_rst_n   ),  
    .gmii_rx_clk   (gmii_rx_clk ),           
    .gmii_rx_dv    (gmii_rx_dv  ),         
    .gmii_rxd      (gmii_rxd    ),                   
    .gmii_tx_clk   (gmii_tx_clk ), 
    .gmii_tx_en    (udp_gmii_tx_en),         
    .gmii_txd      (udp_gmii_txd),  
    .rec_pkt_done  (rec_pkt_done),    
    .rec_en        (rec_en      ),     
    .rec_data      (rec_data    ),         
    .rec_byte_num  (rec_byte_num),      
    .tx_start_en   (tx_start_en ),        
    .tx_data       (tx_data     ),         
    .tx_byte_num   (tx_byte_num ),  
    .des_mac       (des_mac     ),
    .des_ip        (des_ip      ),    
    .tx_done       (udp_tx_done ),        
    .tx_req        (tx_req      )           
    ); 

//同步FIFO
sync_fifo_2048x32b u_sync_fifo_2048x32b (
    .clk      (gmii_rx_clk),  // input wire clk
    .rst      (~sys_rst_n),  // input wire rst
    .din      (rec_data  ),  // input wire [31 : 0] din
    .wr_en    (rec_en    ),  // input wire wr_en
    .rd_en    (tx_req    ),  // input wire rd_en
    .dout     (tx_data   ),  // output wire [31 : 0] dout
    .full     (),            // output wire full
    .empty    ()             // output wire empty
    );    

//以太网控制模块
eth_ctrl u_eth_ctrl(
    .clk            (gmii_rx_clk),
    .rst_n          (sys_rst_n),
    .arp_rx_done    (arp_rx_done   ),
    .arp_rx_type    (arp_rx_type   ),
    .arp_tx_en      (arp_tx_en     ),
    .arp_tx_type    (arp_tx_type   ),
    .arp_tx_done    (arp_tx_done   ),
    .arp_gmii_tx_en (arp_gmii_tx_en),
    .arp_gmii_txd   (arp_gmii_txd  ),               
    .udp_gmii_tx_en (udp_gmii_tx_en),
    .udp_gmii_txd   (udp_gmii_txd  ),            
    .gmii_tx_en     (gmii_tx_en    ),
    .gmii_txd       (gmii_txd      )
    );
endmodule

K7上的资源消耗和性能表现如下:
在这里插入图片描述
由于工程中使用到了PLL和fifo,实际UDP部分所占资源更小;

4.工程2介绍及资源占用率和性能表现

工程2介绍;
开发板:Artix7开发板;
网络PHY:RTL8211
输出:RJ45网口
接收:电脑上位机;
RTL8211不需要配置,使用默认的配置,工作在延时模式,PHY的发送时钟rgmii_txc 与FPGA发送时钟gmii_tx_clk不一致;rgmii_txc与gmii_tx_clk相位偏差+90°;
代码部分如下:


module rgmii_tx(
    //GMII发送端口
    input              gmii_tx_clk , //GMII发送时钟
	input              gmii_tx_clk_90 ,
    input              gmii_tx_en  , //GMII输出数据有效信号
    input       [7:0]  gmii_txd    , //GMII输出数据        
    
    //RGMII发送端口
    output             rgmii_txc   , //RGMII发送数据时钟    
    output             rgmii_tx_ctl, //RGMII输出数据有效信号
    output      [3:0]  rgmii_txd     //RGMII输出数据     
    );

assign rgmii_txc = gmii_tx_clk_90;

//输出双沿采样寄存器 (rgmii_tx_ctl)
ODDR #(
    .DDR_CLK_EDGE  ("SAME_EDGE"),  // "OPPOSITE_EDGE" or "SAME_EDGE" 
    .INIT          (1'b0),         // Initial value of Q: 1'b0 or 1'b1
    .SRTYPE        ("SYNC")        // Set/Reset type: "SYNC" or "ASYNC" 
) ODDR_inst (
    .Q             (rgmii_tx_ctl), // 1-bit DDR output
    .C             (gmii_tx_clk),  // 1-bit clock input
    .CE            (1'b1),         // 1-bit clock enable input
    .D1            (gmii_tx_en),   // 1-bit data input (positive edge)
    .D2            (gmii_tx_en),   // 1-bit data input (negative edge)
    .R             (1'b0),         // 1-bit reset
    .S             (1'b0)          // 1-bit set
); 

genvar i;
generate for (i=0; i<4; i=i+1)
    begin : txdata_bus
        //输出双沿采样寄存器 (rgmii_txd)
        ODDR #(
            .DDR_CLK_EDGE  ("SAME_EDGE"),  // "OPPOSITE_EDGE" or "SAME_EDGE" 
            .INIT          (1'b0),         // Initial value of Q: 1'b0 or 1'b1
            .SRTYPE        ("SYNC")        // Set/Reset type: "SYNC" or "ASYNC" 
        ) ODDR_inst (
            .Q             (rgmii_txd[i]), // 1-bit DDR output
            .C             (gmii_tx_clk),  // 1-bit clock input
            .CE            (1'b1),         // 1-bit clock enable input
            .D1            (gmii_txd[i]),  // 1-bit data input (positive edge)
            .D2            (gmii_txd[4+i]),// 1-bit data input (negative edge)
            .R             (1'b0),         // 1-bit reset
            .S             (1'b0)          // 1-bit set
        );        
    end
endgenerate
endmodule

相应的工程顶层代码的时钟部分也有改变,如下:


module eth_udp_loop(
    input              clk_50   , //系统时钟
    //PL以太网RGMII接口   
    input              phy1_rgmii_rx_clk   , //RGMII接收数据时钟
    input              phy1_rgmii_rx_ctl, //RGMII输入数据有效信号
    input       [3:0]  phy1_rgmii_rx_data   , //RGMII输入数据
    output             phy1_rgmii_tx_clk   , //RGMII发送数据时钟    
    output             phy1_rgmii_tx_ctl, //RGMII输出数据有效信号
    output      [3:0]  phy1_rgmii_tx_data   , //RGMII输出数据          
    output             phy_reset   //以太网芯片复位信号,低电平有效   
    );

//parameter define
parameter  BOARD_MAC = 48'h00_11_22_33_44_55;   //开发板MAC地址 
parameter  BOARD_IP  = {8'd192,8'd168,8'd10,8'd1};  //开发板IP地址
parameter  DES_MAC   = 48'hff_ff_ff_ff_ff_ff; 	//目的MAC地址    
parameter  DES_IP    = {8'd192,8'd168,8'd10,8'd2};	//目的IP地址 
parameter IDELAY_VALUE = 0;	//输入数据IO延时,此处为0,即不延时(如果为n,表示延时n*78ps) 
parameter  BOARD_POART =16'd1234;
parameter  DES_POART   =16'd1234;

//wire define
wire          clk_200m   ; //用于IO延时的时钟              
wire          gmii_rx_clk; //GMII接收时钟
wire          gmii_rx_dv ; //GMII接收数据有效信号
wire  [7:0]   gmii_rxd   ; //GMII接收数据
wire          gmii_tx_clk; //GMII发送时钟
wire          gmii_tx_en ; //GMII发送数据使能信号
wire  [7:0]   gmii_txd   ; //GMII发送数据     
wire          arp_gmii_tx_en; //ARP GMII输出数据有效信号 
wire  [7:0]   arp_gmii_txd  ; //ARP GMII输出数据
wire          arp_rx_done   ; //ARP接收完成信号
wire          arp_rx_type   ; //ARP接收类型 0:请求  1:应答
wire  [47:0]  src_mac       ; //接收到目的MAC地址
wire  [31:0]  src_ip        ; //接收到目的IP地址    
wire          arp_tx_en     ; //ARP发送使能信号
wire          arp_tx_type   ; //ARP发送类型 0:请求  1:应答
wire  [47:0]  des_mac       ; //发送的目标MAC地址
wire  [31:0]  des_ip        ; //发送的目标IP地址   
wire          arp_tx_done   ; //ARP发送完成信号
wire          udp_gmii_tx_en; //UDP GMII输出数据有效信号 
wire  [7:0]   udp_gmii_txd  ; //UDP GMII输出数据
wire          rec_pkt_done  ; //UDP单包数据接收完成信号
wire          rec_en        ; //UDP接收的数据使能信号
wire  [31:0]  rec_data      ; //UDP接收的数据
wire  [15:0]  rec_byte_num  ; //UDP接收的有效字节数 单位:byte 
wire  [15:0]  tx_byte_num   ; //UDP发送的有效字节数 单位:byte 
wire          udp_tx_done   ; //UDP发送完成信号
wire          tx_req        ; //UDP读数据请求信号
wire  [31:0]  tx_data       ; //UDP待发送数据
wire sys_rst_n;
wire clk_125m;
wire clk_125m_90;

//*****************************************************
//**                    main code
//*****************************************************
assign gmii_tx_clk = clk_125m ;
assign tx_start_en = rec_pkt_done;
assign tx_byte_num = rec_byte_num;
assign des_mac = src_mac;
assign des_ip = src_ip;
assign phy_reset = sys_rst_n;

clk_wiz_0 instance_name
   (
    // Clock out ports
    .clk_200m(clk_200m),     // output clk_200m
    .clk_125m(clk_125m),     // output clk_125m
    .clk_125m_90(clk_125m_90),     // output clk_125m_90
    // Status and control signals
    .locked(sys_rst_n),       // output locked
   // Clock in ports
    .clk_in1(clk_50));      // input clk_in1

//GMII接口转RGMII接口
gmii_to_rgmii 
    #(
     .IDELAY_VALUE (IDELAY_VALUE)
     )
    u_gmii_to_rgmii(
    .idelay_clk    (clk_200m    ),
    .gmii_rx_clk   (gmii_rx_clk ),
    .gmii_rx_dv    (gmii_rx_dv  ),
    .gmii_rxd      (gmii_rxd    ),
    .gmii_tx_clk   (gmii_tx_clk ),
	.gmii_tx_clk_90(clk_125m_90),
    .gmii_tx_en    (gmii_tx_en  ),
    .gmii_txd      (gmii_txd    ),
    .rgmii_rxc     (phy1_rgmii_rx_clk     ),
    .rgmii_rx_ctl  (phy1_rgmii_rx_ctl  ),
    .rgmii_rxd     (phy1_rgmii_rx_data     ),
    .rgmii_txc     (phy1_rgmii_tx_clk     ),
    .rgmii_tx_ctl  (phy1_rgmii_tx_ctl  ),
    .rgmii_txd     (phy1_rgmii_tx_data     )
    );

//ARP通信
arp                                             
   #(
    .BOARD_MAC     (BOARD_MAC),      //参数例化
    .BOARD_IP      (BOARD_IP ),
    .DES_MAC       (DES_MAC  ),
    .DES_IP        (DES_IP   )
    )
   u_arp(
    .rst_n         (sys_rst_n  ),             
    .gmii_rx_clk   (gmii_rx_clk),
    .gmii_rx_dv    (gmii_rx_dv ),
    .gmii_rxd      (gmii_rxd   ),
    .gmii_tx_clk   (gmii_tx_clk),
    .gmii_tx_en    (arp_gmii_tx_en ),
    .gmii_txd      (arp_gmii_txd),              
    .arp_rx_done   (arp_rx_done),
    .arp_rx_type   (arp_rx_type),
    .src_mac       (src_mac    ),
    .src_ip        (src_ip     ),
    .arp_tx_en     (arp_tx_en  ),
    .arp_tx_type   (arp_tx_type),
    .des_mac       (des_mac    ),
    .des_ip        (des_ip     ),
    .tx_done       (arp_tx_done)
    );

//UDP通信
udp                                             
   #(
    .BOARD_MAC     (BOARD_MAC),      //参数例化
    .BOARD_IP      (BOARD_IP ),
    .DES_MAC       (DES_MAC  ),
    .DES_IP        (DES_IP   ),
	.BOARD_POART     (BOARD_POART),
	.DES_POART       (DES_POART  )	
    )
   u_udp(
    .rst_n         (sys_rst_n   ),  
    .gmii_rx_clk   (gmii_rx_clk ),           
    .gmii_rx_dv    (gmii_rx_dv  ),         
    .gmii_rxd      (gmii_rxd    ),                   
    .gmii_tx_clk   (gmii_tx_clk ), 
    .gmii_tx_en    (udp_gmii_tx_en),         
    .gmii_txd      (udp_gmii_txd),  
    .rec_pkt_done  (rec_pkt_done),    
    .rec_en        (rec_en      ),     
    .rec_data      (rec_data    ),         
    .rec_byte_num  (rec_byte_num),      
    .tx_start_en   (tx_start_en ),        
    .tx_data       (tx_data     ),         
    .tx_byte_num   (tx_byte_num ),  
    .des_mac       (des_mac     ),
    .des_ip        (des_ip      ),    
    .tx_done       (udp_tx_done ),        
    .tx_req        (tx_req      )           
    ); 

//同步FIFO
sync_fifo_2048x32b u_sync_fifo_2048x32b (
    .clk      (gmii_rx_clk),  // input wire clk
    .rst      (~sys_rst_n),  // input wire rst
    .din      (rec_data  ),  // input wire [31 : 0] din
    .wr_en    (rec_en    ),  // input wire wr_en
    .rd_en    (tx_req    ),  // input wire rd_en
    .dout     (tx_data   ),  // output wire [31 : 0] dout
    .full     (),            // output wire full
    .empty    ()             // output wire empty
    );    

//以太网控制模块
eth_ctrl u_eth_ctrl(
    .clk            (gmii_rx_clk),
    .rst_n          (sys_rst_n),
    .arp_rx_done    (arp_rx_done   ),
    .arp_rx_type    (arp_rx_type   ),
    .arp_tx_en      (arp_tx_en     ),
    .arp_tx_type    (arp_tx_type   ),
    .arp_tx_done    (arp_tx_done   ),
    .arp_gmii_tx_en (arp_gmii_tx_en),
    .arp_gmii_txd   (arp_gmii_txd  ),              
    .udp_gmii_tx_en (udp_gmii_tx_en),
    .udp_gmii_txd   (udp_gmii_txd  ),              
    .gmii_tx_en     (gmii_tx_en    ),
    .gmii_txd       (gmii_txd      )
    );
endmodule

A7上的资源消耗和性能表现如下:
在这里插入图片描述
由于工程中使用到了PLL和fifo,实际UDP部分所占资源更小;
代码架构如下:
在这里插入图片描述

5.上板调试验证

工程1验证:
开发板连接
在这里插入图片描述
工程2验证:
开发板连接
在这里插入图片描述
上位机收发显示如下:
在这里插入图片描述

6.福利:工程代码的获取

福利:工程代码的获取
代码太大,无法邮箱发送,以某度网盘链接方式发送,
资料如下:
在这里插入图片描述
获取方式:私。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/21917.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python 函数转命令行界面库 -- Argsense CLI

argsense 是一个 python 命令行界面库, 是 click, fire, typer 之外的又一个选项. argsense 最大的特点是极低的侵入性设计和近乎零成本的上手难度, 如果你熟悉 python 函数是如何传参的 (这是大部分 python 初学者已经掌握的知识), 那么你就可以很快上手 argsense. 特性一览 …

大数据(9e)图解Flink窗口

文章目录1、代码模板1.1、pom.xml1.2、log4j.properties1.3、Java模板2、按键分区&#xff08;Keyed&#xff09;、非按键分区&#xff08;Non-Keyed&#xff09;2.1、Keyed2.2、Non-Keyed3、窗口的分类3.1、基于时间的窗口3.2、基于事件个数的窗口4、窗口函数5、示例代码5.1、…

TIA博途_水处理项目中开启累计运行时间最短的泵_程序示例

TIA博途_水处理项目中开启累计运行时间最短的泵_程序示例 需求: 有N台水泵,每个水泵统计累计运行时间。当满足条件时,根据设定开泵的数量,启动累计运行时间最短的对应数量的泵。故障切换时,也切换到运行时间最短的泵。 具体方法可参考以下内容: 如下图所示,打开TIA博途后…

【毕业设计】62-基于单片机的防酒驾\酒精浓度检测系统设计研究(原理图、源代码、仿真工程、低重复率参考设计、PPT)

【毕业设计】62-基于单片机的防酒驾\酒精浓度检测系统设计研究&#xff08;原理图、源代码、仿真工程、低重复率参考设计、PPT&#xff09;[toc] 资料下载链接 资料下载链接 资料链接&#xff1a;https://www.cirmall.com/circuit/33758/ 包含此题目毕业设计全套资料&#xf…

国科大课程自动评价脚本JS

国科大课程一键评估 操作流程&#xff1a; 方法 打开F12点击console/控制台复制粘贴下面代码回车 for(var i 0; i<1000; i) { if($("input[nameitem_"i"]").length) $("input[nameitem_"i"]").get(Math.round(Math.random()*2)…

C++11--lambda表达式--包装器--bind--1119

1.lambda表达式 lambda表达式书写格式&#xff1a;[捕捉列表] (参数列表) mutable -> 返回值类型 { 比较的方法 } int func() {int a, b, c, d, e;a b c d e 1;// 全部传值捕捉auto f1 []() {cout << a << b << c << d << e << …

BLE学习(3):ATT和GATT详解

本文章将介绍在面向连接的蓝牙模式中&#xff0c;ATT(attribute protocol,属性协议)和GATT(generic attribute profile,通用属性配置文件)这两个重要的协议层&#xff0c;它与蓝牙的数据传输密切相关。 1 设备之间如何建立连接(Gap层) 若BLE设备之间要进行数据传输&#xff0…

Qt5 QML TreeView currentIndex当前选中项的一些问题

0.前言 Qt5 QML Controls1.4 中的 TreeView 存在诸多问题&#xff0c;比如节点连接的虚线不好实现&#xff0c;currentIndex 的设置和 changed 信号的触发等。我想主要的原因在于 TreeView 是派生自 BasicTableView&#xff0c;而 TableView 内部又是由 ListView 实现的。 正…

二、openCV+TensorFlow入门

目录一、openCV入门1 - 简单图片操作2 - 像素操作二、TensorFlow入门1 - TensorFlow常量变量2 - TensorFlow运算本质3 - TensorFlow四则运算4 - tensorflow矩阵基础5 - numpy矩阵6 - matplotlib绘图三、神经网络逼近股票收盘均价&#xff08;案例&#xff09;1 - 绘制15天股票K…

编译原理 x - 练习题

简答题逆波兰后缀表达式和三元式序列源程序翻译成中间代码DAG优化正则文法 构造正则表达式正规式 改 上下文无关文法表示DFA有限状态机图移进-规约消除左递归文法-最左推导-短语LL(1)文法LR(0) | SLR(1)文法简答题 编译过程可分为前端和后端&#xff0c;描述一下前端和后端分别…

【设计模式】装饰者模式:以造梦西游的例子讲解一下装饰者模式,这也是你的童年吗?

文章目录1 概述1.1 问题1.2 定义1.3 结构1.4 类图2 例子2.1 代码2.2 效果图3 优点及适用场景3.1 优点3.2 适用场景1 概述 1.1 问题 众所周知&#xff0c;造梦西游3有四个角色&#xff0c;也就是师徒四人&#xff0c;这师徒四人每个人都有自己专属的武器和装备。假定我们以及设…

推荐10个Vue 3.0开发的开源前端项目

Vue 是一款用于构建用户界面的 JavaScript 框,它基于标准 的HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,用以帮助开发者高效地开发用户界面。目前,Vue 3.0正式版也发布了两年的时间,越累越多的开发者也用上了Vue 3.0。 对比Vue2.x,Vue 3.0在…

并发bug之源(二)-有序性

什么是有序性&#xff1f; 简单来说&#xff0c;假设你写了下面的程序&#xff1a; java int a 1; int b 2; System.out.println(a); System.out.println(b);但经过编译器/CPU优化&#xff08;指令重排序&#xff0c;和编程语言无关&#xff09;后可能就变成了这样&#x…

【DDR3 控制器设计】(7)DDR3 的用户端口读写模块设计

写在前面 本系列为 DDR3 控制器设计总结&#xff0c;此系列包含 DDR3 控制器相关设计&#xff1a;认识 MIG、初始化、读写操作、FIFO 接口等。通过此系列的学习可以加深对 DDR3 读写时序的理解以及 FIFO 接口设计等&#xff0c;附上汇总博客直达链接。 【DDR3 控制器设计】系列…

CSS---复合选择器

目录 一&#xff1a;复合选择器的介绍 二、复合选择器的讲解 &#xff08;1&#xff09;后代选择器 &#xff08;2&#xff09;子元素选择器 &#xff08;3&#xff09;并集选择器 &#xff08;4&#xff09;链接伪类选择器 &#xff08;5&#xff09;focus伪类选择器 一&…

基于SpringBoot的线上买菜系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SpringBoot 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目…

【Spring系列】- Spring事务底层原理

Spring事务底层原理 &#x1f604;生命不息&#xff0c;写作不止 &#x1f525; 继续踏上学习之路&#xff0c;学之分享笔记 &#x1f44a; 总有一天我也能像各位大佬一样 &#x1f3c6; 一个有梦有戏的人 怒放吧德德 &#x1f31d;分享学习心得&#xff0c;欢迎指正&#xff0…

Vue-CLI的安装、使用及环境配置(超详细)

Vue CLI 是一个基于 Vue 进行快速项目开发的工具。它可以提供可交互式的项目脚手架和运行时的服务依赖&#xff0c;帮助你快速完成一个风格统一、拓展性强的现代化 web 单页面应用。 Vue-CLI 所需环境 Vue-CLI 是一个需要全局安装的NPM包&#xff0c;安装需要在 Node.js 环境下…

一、openCV+TensorFlow环境搭建

目录一、anaconda安装二、tensorflow安装三、Opencv安装四、pycharm新建项目使用Anaconda的环境五、验证环境安装六、tensorflow安装jupyter notebook一、anaconda安装 anaconda官网&#xff1a;https://www.anaconda.com/anaconda下载&#xff1a;https://repo.anaconda.com/…

【k8s】10.网络插件

文章目录一、etcd详解1、etcd的特点2、准备签发证书的环境二、网络插件原理1、flannel1.1 UDP模式&#xff08;性能差&#xff09;1.2 VXLAN模式&#xff08;性能较好&#xff09;1.3 host-gw模式&#xff08;性能最高&#xff09;2、calico插件3、总结一、etcd详解 etcd是Cor…