FPGA实现以太网通信可以这么简单(以太网视频传输)_fpga网口通信
一、fpga实现以太网通信有以下几种方案
fpga想同外部的主机通过以太网进行通信,一般采用以下方案:
1、外部CPU桥接方案。即网口通过主机cpu再同fpga通信,网络协议运行在CPU上。缺点是以太网通信速度由CPU处理速度决定,当cpu处理速度跟不上时,容易导至缓存溢出。因此带宽利用率低。
2、网络协议硬核桥接芯片方案。例如W5500芯片等。但是这种方案网络带宽利用率还是不高。同时设计灵活度低,适合与低速单片机配合使用。
3、fpga RTL逻辑实现方案。这样就能充分发挥FPGA流水线并行处理速度,也不会出现因数据处理不及时而导致缓存溢出,造成丢包。因此理论上可接近线速带宽利用率,实测可达95%以上。
二、以太网视频传输方案设计
播放视频参数如下:
- 视频帧率:24帧/秒;
- 分辨率:1280*720;
- 数据格式为RGB16,每个像素占2字节;
传输速度:24帧/秒 × 2字节/像素 × 1280×720像素 = 42.2MB/S ,这速度小于1G以太网的带宽882MB/S(1G以太网实际速度带宽测试),因此普偏使用的1G以太网进行传输。
采用RTL逻辑实现的第三种方案,确保传输可靠性。方案整体架构如下:
时序控制流程
- UDP IP核接收视频流数据包
- 数据经过协议解析后写入DDR3缓存
- DMA控制器按帧周期读取视频数据
- HDMI发送器从DMA获取数据并进行编码
- 显示器接收TMDS信号完成图像显示
三、UDP协议FPGA IP Core
幻智星科技开发的UDP协议IP Core运行在FPGA逻辑层,主要功能特性如下:
- 支持千兆以太网物理层接口
- 实现UDP协议栈硬件加速
- 内置数据校验和错误重传机制(确保udp数据包不丢包)
IP Core 详细介绍请点击链接: DMA/Bridge Subsystem for Ethernet Interface
接口说明:
- I2C接口外接EEprom芯片,目的是为了在量产时,能动态设置MAC地址和IP地址;
- axi_lite接口是低速总线,一般访问外部模块内部配置寄存器,IO口等;
- axi_full接口是高速总线,一般外接可以突发传输的缓存模块,例如ddr3、ddr4、blockRAM等缓存。
- sys_clk 输入时钟选择,同网口速度有关,1G网口时为125M;
- m_axilite_clk , m_axi_clk可以选用各自的合适的时种频率。在本项目中使用100M时钟。
同ip核配套提供的动态链接库接口函数:
// Company: 幻智星科技// Engineer: 俞工// email: yupc123@qq.comtypedef void (*FuncPtr_Irq)();typedef void *MHANDLE;extern \"C\" int mstar_ethbridge_open(const char* strip);extern \"C\" void mstar_ethbridge_close();extern \"C\" int axilite_read(MHANDLE phdev,uint32_t address, uint8_t* pbuf, size_t buflen);extern \"C\" int axilite_write(MHANDLE phdev,uint32_t address, uint8_t* pbuf, size_t buflen);extern \"C\" int axifull_read(MHANDLE phdev,uint64_t address, uint8_t* pbuf, size_t buflen);extern \"C\" int axifull_write(MHANDLE phdev,uint64_t address, uint8_t* pbuf, size_t buflen);extern \"C\" int register_irqfun(MHANDLE phdev, int irq_number, FuncPtr_Irq funinterupt);extern \"C\" MHANDLE get_device_ip(const char * strip);extern \"C\" MHANDLE get_device(size_t index);extern \"C\" MHANDLE get_device_mac(const char* strmac);extern \"C\" size_t get_udpclient_size();extern \"C\" int get_device_strip(MHANDLE phdev, char* strip, size_t strlen);extern \"C\" int get_device_strmac(MHANDLE phdev, char* strmac, size_t strlen);
在Xilinx Artix-7 系列fpga 上逻辑资源使用情况如下图:
测试报告链接:基于fpga的1000M以太网UDP双向传输测试(三) 发送速度达到882Mbps
实测收发速度如下图:
四、Frame DMA 读控制逻辑
直接内存访问控制器(DMA)实现高效数据传输,支持突发传输模式、数据预取机制和图像缓存双缓冲管理等特性,并在在场信号标志使能下自动起动DMA传输。下图为模块示意图:
接口说明:
- S_AXILITE:为从axi_lite总线接口,同udp协议IP核的低速总线axi_lite接口相连。
- M_AXI:为主axi_full 总线接口,同DDR3控制器相连,是读取视频帧的dma通道。
- read_req/read_req_ack:是一对读申请握手信号,frame_rdma 收到此信号扣,起动读dma传输。
- video_read_dat/video_read_en:是读取的视频数据流。
- video_left_offset/video_top_offset:表示视频图像左上角在显示屏上的坐标。可动态设置。
- video_width/video_height:表示视频图像的宽和高。可动态设置。
五、hdmi接口逻辑
hdmi接口逻辑的功能就是把视频图像数据(RGB格式)通过hdmi接口发送出去。下图为模块示意图:
接口说明:
- video_clk:本项目选用频率为62.5M的时钟,刷新率为60帧/S;
- video_serclk:是video_clk的5倍频率,即:312.5M;
六、视频传输项目电路图
vivado 工程的模块整体连接图如下图:
图比较大,看起来不清楚,给几张局部放大图。
各模块地址分配情况:
七、QT编写的测试APP
QT APP界面图:
frame_rdma部份初始化代码:
// Company: 幻智星科技// Engineer: 俞工// email: yupc123@qq.com#include \"MstarEthBridge.h\"#define DMA_DDR_BASEADDR 0L#define DMA_DDR_BUFFSIZE 0x8000000 //128M#define MSTAR_DISPDMA_CONRGE_BASEADDRESS 0x0100#define MSTAR_DISPDMA_CONRGE_ID 0x10001#define ADDR_FRAME_ID 0#define ADDR_FRAME_CON (ADDR_FRAME_ID+4)#define ADDR_FRAME_STPOINT (ADDR_FRAME_CON+4)#define ADDR_FRAME_IMAGESIZE (ADDR_FRAME_STPOINT+4)#define ADDR_FRAME_DMASIZE (ADDR_FRAME_IMAGESIZE+4)#define ADDR_FRAME_BUFFERADDR (ADDR_FRAME_DMASIZE+4)#define FRAME_WIDTH_MAX 1280#define FRAME_HIGHT_MAX 720#define DMA_ADDRESS_BURST_MAX (4096) //dma one read/write length max, the buffer size#define DMA_FRAMBUF_NUMMAX 3#pragma pack(push, 4)struct dispframe_st { uint32_t id; uint32_t control; //eeprom 地址 uint16_toffset_top;//读写数据buf寄存器 uint16_t offset_left; uint16_t frame_hight; uint16_t frame_width; uint32_t frame_size; uint32_t frame_num;};#pragma pack(pop)class MstarDispFrame : public QThread{ Q_OBJECTpublic: MstarDispFrame(QObject *parent = nullptr, uint32_t devid=MSTAR_DISPDMA_CONRGE_ID, uint32_t dev_baseaddress=MSTAR_DISPDMA_CONRGE_BASEADDRESS, size_t baseaddr=DMA_DDR_BASEADDR,size_t bufsize=DMA_DDR_BUFFSIZE, uint16_t disp_width=FRAME_WIDTH_MAX, uint16_t disp_hight=FRAME_HIGHT_MAX); ~MstarDispFrame() {m_stop=true; }; bool dispframeInit(MHANDLE devhandle); void set_dmabuffer_baseaddr(size_t baseaddr,size_t bufsize); //设置缓存 int set_frame_offset(uint16_t offset_left, uint16_t offset_top);//显示位置 int set_frame_size(uint16_t frame_width, uint16_t frame_hight); void set_disp_size(uint16_t disp_width, uint16_t disp_hight); //显示屏大小 void push(QImage &img); void ethsend(QImage &img); void init_videotimer(); void frame_cnt_inc(); void fun_sendth(); void video_pause(); void video_play();protected: void run();private: MHANDLE m_handle; uint32_t m_baseaddr; uint32_t m_id; dispframe_st m_reginfor; size_t m_dmabuf_baseaddr; size_t m_dmabufsize; uint16_t m_disp_width; uint16_t m_disp_hight; size_t m_framebuf_size; size_t m_framebuf_num; size_t m_framebuf_nummax; QImage m_logo; QQueue m_image_qu; size_t m_framecnt;//帧计数器 QElapsedTimer m_videotimer; qint64 m_pretimercnt=0; QElapsedTimer m_ethsendtimer; qint64 m_ethsendcnt=0; qint64 m_imgsendtime=0; bool m_stop=false; float get_framerate(); float get_ethspeed(); //QFuture m_future; void dma_rst();};
调用动太链接库发送视频的代码:
// Company: 幻智星科技// Engineer: 俞工// email: yupc123@qq.comvoid MstarDispFrame::ethsend(QImage &img){ if(m_handle==nullptr) return; frame_cnt_inc(); float temp=get_framerate(); float webspeed=get_ethspeed();//(temp*img_t.sizeInBytes()/1024/1024); QString str_framerate=QString::asprintf(\"视频帧率:%.1f帧/秒 网口速率:%.2f MB/秒 发送队列:%d 单帧时间%dms\",temp,webspeed,m_image_qu.size(),m_imgsendtime); QPainter painter(&img); painter.drawImage(5,5,m_logo); painter.setFont(QFont(\"Arial\",20)); painter.setPen(Qt::red); painter.drawText(15+m_logo.width(),m_logo.height(),\"幻智星科技\"); painter.drawText(240,75,str_framerate); painter.setFont(QFont(\"Arial\",30)); painter.setPen(Qt::green); painter.drawText(360,190,\"UDP协议FPGA IP核\"); painter.drawText(359,191,\"UDP协议FPGA IP核\"); painter.setPen(Qt::white); painter.drawText(358,192,\"UDP协议FPGA IP核\"); painter.setPen(Qt::green); painter.setFont(QFont(\"Arial\",20)); painter.drawText(260,230,\"DMA/Bridge Subsystem for Ethernet Interface 是把以太网UDP/IP协议用\"); painter.drawText(200,260,\"纯逻辑实现的 FPGA IP Core,已在数据采集,喷印设备及工业视觉等场景中应用。\"); painter.drawText(260,290,\"1、纯RTL逻辑实现:适用不同速度的以太网接口;\"); painter.drawText(260,320,\"2、支持AXI4接口:支持AXI_lite、AXI_full、AXI_stream 等;\"); painter.drawText(260,350,\"3、高读/写带宽:1000M以太网接口读写实测速度达882Mbps;\"); painter.drawText(260,380,\"4、快速上手,技术支持,方便适配国产FPGA;\"); painter.setFont(QFont(\"Arial\",30)); QFont font= painter.font(); font.setBold(true); painter.setFont(font); painter.setPen(Qt::red); painter.drawText(200,450,\"优点:不易丢包,更低成本,加速研发,稳定易用!\"); painter.setPen(Qt::green); font.setBold(false); painter.setFont(font); painter.setFont(QFont(\"Arial\",20)); painter.drawText(450,500,\"电话 俞先生:13867435883 蒋先生:13452942803\"); painter.end(); if(set_frame_size(img.width(),img.height())=m_framebuf_nummax) m_framebuf_num=0;}
八、项目运行效果视频
UDP协议FPGA IP Core 视频传输稳定性测试
再上传几张照片 可以看清楚测试结果: