基于FPGA的以太网接口数据采集器设计与实现
- 格式:pdf
- 大小:276.41 KB
- 文档页数:3
基于FPGA的多通道ADC采集及DAC回放设计苏宁馨【摘要】在电子通信以及自动化等应用领域中,系统终端信号多以模拟量的形式直观存在并使用,因此模拟量采集和回放电路的设计尤为重要。
由于各系统对采集数据的速度、精度和可靠性指标的要求不同,现提出一种基于FPGA的多通道ADC模拟量采集及DAC回放电路的设计。
重点介绍了以5CEFA2F23CB规格的FPGA作为核心处理器,以VerilogHDL语言实现的采集和回放电路的设计过程,并分别采用SignalTap逻辑分析仪和示波器对数据进行捕获、分析和验证。
系统运行稳定可靠,功能完整实现,效率和精度高,可扩展性强。
【期刊名称】《太原学院学报:自然科学版》【年(卷),期】2019(037)001【总页数】6页(P60-65)【关键词】FPGA;ADC模拟量采集;DAC回放;SignalTap逻辑分析仪【作者】苏宁馨【作者单位】[1]安徽新华学院,安徽合肥230088【正文语种】中文【中图分类】TP2740 引言电子通信行业的蓬勃发展,带动了自动化、航天航空、电子制造等产业的革新。
在各产业系统终端数据的观察中,信号多以模拟量的形式直观存在并应用。
围绕系统终端模拟量采集的工作,行业上和技术上也提出了很多种方法和尝试,近年来模拟量采集电路的设计多以数模转换集成电路的形式出现,在机载系统和航天航空领域也逐渐提出了基于PLC、STM32的方式方法和尝试[1]。
由于不同系统存在环境的差异性,对多通道模拟信号采集数据的速度、精度、系统的稳定性的衡量和要求都有所不同,这就使得对采集系统提出了更高的要求。
为满足数据采集存储的可靠指标以及不同环境下的采集要求,现提出一种基于FPGA的多通道ADC模拟量采集及DAC回放电路的设计。
该电路可通过软件算法提高采集精度,并保证系统硬件电路运行的稳定性和可靠性,应用领域也得到了很好的扩展[2]。
1 系统开发工具及总体设计基于FPGA的多通道ADC模拟量采集及DAC回放设计,系统硬件部分采用Altera 公司现下最为流行的一款FPGA(Cyclone Ⅴ系列的5CEFA2F23CB核心处理器);模拟量采集部分选择ADC084S021 作为主要元件;回放部分则采用 DAC084S085 作为模拟信号回放输出。
摘要随着机器视觉的广泛应用,以及工业4.0和“中国制造2025”的提出,在数字图像的采集、传输、处理等领域也提出了越来越高的要求。
传统的基于ISA接口、PCI接口、串行和并行等接口的图像采集卡已经不能满足人们对于高分辨率、实时性的图像采集的需求了。
一种基于FPGA和USB3.0高速接口,进行实时高速图像采集传输的研究越来越成为国内外在高速图像采集研究领域的一个新的热点。
针对高速传输和实时传输这两点要求,通过采用FPGA作为核心控制芯片与USB3.0高速接口协调工作的架构,实现高帧率、高分辨率、实时性的高速图像的采集和传输,并由上位机进行可视化操作和数据的保存。
整体系统采用先硬件后软件的设计方式进行设计,并对系统各模块进行了测试和仿真验证。
通过在FPGA 内部实现滤波和边缘检测等图像预处理操作,验证了FPGA独特的并行数据处理方式在信号及图像处理方面的巨大优势。
在系统硬件设计部分,采用OV5640传感器作为采集前端,选用Altera的Cyclone IV E系列FPGA作为系统控制芯片,由DDR2存储芯片进行数据缓存,采用Cypress公司的USB3.0集成型USB3.0芯片作为数据高速接口,完成了各模块的电路设计和采集卡PCB实物制作。
系统软件设计,主要分为FPGA逻辑程序部分、USB3.0固件程序部分和上位机应用软件部分。
通过在FPGA上搭建“软核”的方式,由Qsys系统完成OV5640的配置和初始化工作。
由GPIF II接口完成FPGA和FX3之间的数据通路。
通过编写状态机完成Slave FIFO的时序控制,在Eclipse中完成USB3.0固件程序的设计和开发。
上位机采用VS2013软件通过MFC方式设计,从而完成整体图像采集数据通路,并在上位机中显示和保存。
整体设计实现预期要求,各模块功能正常,USB3.0传输速度稳定在320MB/s,通过上位机保存至PC机硬盘的图像分辨率大小为1920*1080,与传感器寄存器设置一致,采集卡图像采集帧率为30fps,滤波及边缘检测预处理符合要求,采集系统具有实际应用价值和研究意义。
【FPGA学习】基于FPGA的简易⾳频采集系统本篇博客记录⼀个⼩项⽬的开发———基于FPGA的简易⾳频采集系统,项⽬来源是⼀个寒假的活动的题⽬,直接购买了设计好的板卡,项⽬的基本要求如下:扩展板上的麦克风将声⾳信号转变为模拟电信号利⽤核⼼板上的⽐较器构成Sigma Delta ADC对⾳频模拟信号进⾏采集量化后的信号在OLED显⽰屏上进⾏波形显⽰同时利⽤FPGA内部的乘法器对采集到的信号进⾏FFT变换,将变换后的频谱显⽰在OLED上能够计算并显⽰出信号的频率、幅度、谐波分量Lattice使⽤的板卡是Lattice的ICE40UP5K,这⾥⾸先记录⼀下在Lattice的软件中开发FPGA的简单流程这⼀款FPGA开发所⽤的软件是Lattice的Radiant,可以在Lattice的官⽹找到,并且获取Lincense,步骤按照官⽹⼀步步来即可,这⾥不做详述安装完后即可打开软件使⽤:打开后点击New Project新建⼀个⼯程:确认⼯程⽬录和名字:选择FPGA型号与封装:然后就创建好了⼀个⼯程:新建⼀个Verilog⽂件:编写完Verilog代码后,需要进⾏配置:⾸先设置顶层⽂件:其次设置输出⼆进制⽂件的类型:然后综合:没有错误后进⾏管脚约束:保存后可以对整个⼯程进⾏编译,⽣成⼆进制⽂件:参考:OLED驱动要显⽰波形和⼀些其他信息就需要⽤到屏幕,OLED⽆疑是⽤的⽐较⼴泛的显⽰器之⼀,在本项⽬中也需要OLED来显⽰信号波形与频谱,因此在这⾥简单的说明⼀下OLED的参考:Sigma-Delta ADC简介关于Sigma-Delta ADC的介绍可以参考⼀下ADI的官⽅⽂档MT-022和MT-023,这两个⽂档对于Sigma-Delta ADC的发展历史和应⽤都介绍的⽐较好,能帮助开发者捋清⼀些逻辑,不过想要完全弄清Sigma-Delta ADC的前世今⽣,我认为还是要看⼀下这两个⽂档的参考⽂献,可以按照⽂中的脉络看⼀下,能对基础知识有更深的了解,当然也可以参考⼀些学位论⽂,⾥⾯对于这个的介绍也⽐较多,本篇博客主要给出⼀些概念的简单介绍:基本概念PCM:脉冲编码调制⼀阶Σ-Δ调制器md,学校封校了,东西落在外⾯了,等解封在搞。
㊀2020年㊀第12期仪表技术与传感器Instrument㊀Technique㊀and㊀Sensor2020㊀No.12㊀收稿日期:2019-12-19基于FPGA的JESD204B-光纤传输接口转换器设计王红亮,和㊀爽(中北大学,电子测试技术国家重点实验室,仪器科学与动态测试教育部重点实验室,山西太原㊀030051)㊀㊀摘要:针对目前JESD204B接口转换器在高速数据采集传输系统中逐渐普及,但接口IP尚未开源且接口信号与数据分析存储设备无法对接的现状,设计了JESD204B-光纤传输接口转换器㊂转换器以FPGA为逻辑控制核心,自主设计了JESD204B信号的接口逻辑,并利用SFP光模块与Aurora协议完成光纤接口传输,通过DDR3SDRAM进行数据缓存交互㊂最后对JESD204B链路的建立与整体转换器系统的数据传输进行了测试,验证了所设计的JESD204B接口可成功与外部采集卡建立链路,整体数据能够实现10Gbps的传输速率,且数据传输稳定无误㊂关键词:JESD204B;光纤传输;Aurora协议;高速采集中图分类号:TN919㊀㊀㊀文献标识码:A㊀㊀㊀文章编号:1002-1841(2020)12-0110-04JESD204B⁃opticalFiberTransmissionInterfaceConverterBasedonFPGAWANGHong⁃liang,HEShuang(NorthUniversityofChina,NationalKeyLaboratoryforElectronicMeasurementTechnology,KeyLaboratoryofInstrumentationScience&DynamicMeasurement,MinistryofEducation,Taiyuan030051,China)Abstract:InviewofthecurrentpopularityofJESD204Binterfaceconvertersinhigh⁃speeddataacquisitionandtransmissionsystems,buttheinterfaceIPwasnotyetopensourceandtheinterfacesignalscouldnotbeconnectedwithdataanalysisandstor⁃ageequipment,theJESD204B-opticalfibertransmissioninterfaceconverterwasdesigned.TheconverterusedFPGAasthelogiccontrolcore,andtheinterfacelogicoftheJESD204Bsignalwasindependentlydesigned,andtheSFPopticalmoduleandtheAu⁃roraprotocolwasusedtocompletetheopticalfiberinterfacetransmission,anddatabufferinteractionwasperformedthroughDDR3SDRAM.Finally,theestablishmentoftheJESD204Blinkandthedatatransmissionoftheoverallconvertersystemweretested.ItwasverifiedthatthedesignedJESD204Binterfacecansuccessfullyestablishalinkwithanexternalacquisitioncard,andtheoveralldatacanachieveatransmissionrateof10Gbpswiththestableanderror⁃freedatatransmission.Keywords:JESD204B;opticalfibertransmission;Auroraprotocol;high⁃speedacquisition0㊀引言随着星载通信㊁雷达测试等领域的不断发展,高速数据采集技术的需求不断增加,传统并行接口已逐渐难以满足日益增长的数据传输速率[1-2]㊂2011年推出的JESD204B串行接口,大幅提升传输速率,并具有对应封装尺寸小㊁成本低,PCB布局布线简化等优势,已成为目前高速数据转换器的主流接口片[3-5]㊂但JESD204B接口主要针对转换器采集数据收发,不适用于较远距离的传输,无法与常见的高速数据分析存储设备进行互联㊂而JESD204B的相关IP产品也尚未开源,无法针对特定开发进行裁剪,且费用昂贵[6]㊂因此,开发远距离传输JESD204B信号的拓展系统具有重要意义㊂目前,光纤传输由于其带宽高㊁距离远㊁灵敏度高㊁体积小等优势[7],已广泛应用于高速数据分析存储设备㊂在此背景下,本文提出了一种JESD204B-光纤传输接口转换器,并自主设计了JESD204B接口逻辑,实现了高速数据转换器与存储分析设备之间的数据收发㊂1㊀总体设计方案本文在对JESD204B接口和光纤传输接口相关协议进行分析后,以FPGA作为硬件控制平台,设计了相应接口逻辑㊁硬件电路与外围测试环境㊂转换器系统整体方案设计如图1所示㊂系统主要划分为JESD204B接口单元㊁光纤接口单元㊁数据缓存单元以及时钟管理单元㊂AD采集板卡的JESD204B接口通过FMC(FPGAmezzaninecard)插槽与系统的JESD204B接口单元互连,JESD204B接口单元接收到的数据经过处理整合后,传输至数据缓存单元进行缓存;光纤接口单元基于Aurora传输协㊀㊀㊀㊀㊀第12期王红亮等:基于FPGA的JESD204B-光纤传输接口转换器设计111㊀㊀图1㊀系统整体设计结构议,负责将接收数据打包处理并由SFP光模块转换为光纤信号向外部设备传输;时钟管理单元负责向JESD204B接口内部逻辑和外部AD采集板卡,以及光纤接口内部逻辑提供所需时钟㊂2㊀硬件设计2.1㊀JESD204B接口单元设计系统与外部采集板卡互连采用FMC接口㊂FMC接口插拔方便,接口信号类型丰富,包含电源信号㊁JTAG信号㊁IIC信号㊁普通用户信号及吉比特信号等,有助于系统针对不同外部采集板卡实现不同的拓展功能,提高系统设计的灵活性[8]㊂其中,吉比特信号引脚信号完整性可保证高达10Gbps的信号通信,可满足目前常见采集板卡JESD204B接口的数据传输要求㊂外部采集板卡多采用SPI接口进行工作模式等配置㊂为保证采集板与系统之间SPI信号的电平匹配,设计选取4位双电源电平转换芯片SN74AVC4T774对配置信号进行处理,并在两端信号分别串接阻值为22Ω的电阻,以防止信号过冲对电路的影响,电路连接如图2所示㊂图2㊀SPI接口电平转换电路2.2㊀光纤接口单元设计光纤接口选用SFP光模块AFBR-703ASDZ来实现电信号与光信号的转换与传输㊂AFBR-703ASDZ支持10Gb以太网设备设计,最高线路速率达10.313Gbps,最大传输距离300m,可有效传输前端JESD204B接口单元的数据㊂光纤接口单元电路连接如图3所示㊂图3㊀光纤接口单元硬件连接图光模块的收发数据端口RD+㊁RD-㊁TD+㊁TD-内部采用交流耦合方式,与FPGA内部串行收发器相连,走线阻抗需满足差分阻抗100Ω,以保证高速传输的信号完整性㊂其利用输入的高速差分逻辑信号来调节内部发送端的激光驱动器电流㊂FPGA通过TxFAULT和RxLOS信号检测光模块发送与接收链路故障与否,通过TxDIS信号控制光信号关断㊂3㊀FPGA内部逻辑设计FPGA平台选用XilinxKintex系列的XC7K325T芯片,其高性能HPBank适配于DDR缓存接口,内部集成GTX串行收发器,最大线路速率支持12.5Gbps㊂FPGA作为系统的逻辑控制核心,完成JESD204B接口与光纤接口的桥接通信㊂系统上电后,各单元进入初始化阶段,FPGA首先对时钟管理芯片进行配置,确保各单元所需时钟准确无误㊂之后控制JESD204B接口逻辑向外发送同步信号,通知外部采集板卡启动链路同步,待链路建立完成后,控制数据缓存逻辑接收采集数据,同时光纤接口单元与外部设备链接完成后,开始从缓存中读取数据向外传输㊂3.1㊀JESD204B接口逻辑设计接口逻辑构建基于GTX串行收发器与后端通道逻辑组成的数据流逻辑结构,如图4所示㊂在状态控制逻辑的控制下,外部串行数据由GTX串行收发器完成接收,经由通道逻辑部分实现接口协议的相关时序与验证㊂其中,对于GTX串行收发器而言,其内部锁相环需要高精度参考时钟以保证初始化等流程正常运行,其后端的数据通路需要用户时钟作为数据流传输基准㊂通道逻辑作为GTX数据流的承接部分也需要核心时钟确保正确传输㊂为减少时钟输入资源,系统配置通道逻辑数据通路与GTX输出数据通路保持一致,㊀㊀㊀㊀㊀112㊀InstrumentTechniqueandSensorDec.2020㊀图4㊀JESD204B接口逻辑结构从而保证参考时钟与数据流时钟为同一频率,均由串行收发器的MGTREFCLK差分引脚输入的时钟提供㊂时钟分配逻辑结构如图5所示,输入时钟由GTX专用缓冲转换器IBUFDS_GT转换为单端时钟后,一路直接输出至GTX的REFCLK端口,另一路通过全局时钟缓冲BUFG增大扇出能力,然后分别输出至GTX的RX⁃USRCLK端口与通道逻辑的核心时钟[9]㊂图5㊀时钟分配逻辑结构数据流根据JESD204B协议完成同步与传输,流程如图6所示[10]㊂首先拉低同步信号SYNC,通知外部采集板卡开始建立链路并发送/K/码㊂同时拉高GTX的复位信号并选择顺序复位,对GTX进行初始化,以保证内部锁相环与逻辑功能器件状态稳定㊂待复位完成后,对用于串行数据对齐的特殊字符Comma进行检测㊂检测到Comma字符后,对应检测信号拉高,启动串行数据与时钟的对齐,并将对齐后的数据解串解码㊂解串解码后的并行数据,需要进行/K/码检测,当连续无误地检测到4个/K/码后,拉高信号SYNC,协议的码组同步阶段结束㊂初始通道同步阶段开始,外部采集板卡会发送4个包含链路参数的多帧序列,如果序列验证无误,则进入数据传输阶段,链路建立成功;如果验证有误,则回到码组同步阶段,重新初始化GTX以及对齐串行数据㊂3.2㊀光纤接口逻辑设计光纤接口逻辑仍依托于FPGA的底层GTX串行收发器,同时采用Aurora协议进行传输㊂Aurora是一个轻量级链路层协议,在XilinxFPGA中可免费使用,图6㊀协议同步交互流程拓展性强且占用资源成本低,方便用户针对开发需求进行定制,图7是AuroraIP的内部逻辑结构㊂图7㊀AuroraIP内部逻辑结构针对系统的高速数据流设计需求,设计具体采用Aurora64B/66B协议,其相较传统8B/10B编码方式的传输开销更低,线路速率更高,最高可达10.3125Gbps[11]㊂用户数据接口采用通用化总线接口中的AXI4-Stream接口,AXI4-Stream接口面向高速数据流传输,无需考虑地址映射,允许无限制数据突发传输㊂整个接口通过全局逻辑完成通道绑定以及进行通道初始化,由通道逻辑实例化驱动GTX串行收发器,处理数据流的解码和编码,并执行错误检验㊂3.3㊀数据缓存逻辑设计数据缓存单元采用基于XilinxMIGIP的乒乓读写操作控制方案,利用对不同存储区域的读写切换有效降低预充电命令与激活命令之间的时间间隔,并且使用超长突发操作减少发送列寻址和读写命令所造成的时间延时[12],显著地提高数据传输效率㊂本设计中乒乓操作流程如图8所示,将DDR3分为A㊁B两个Bank,当初始化完成之后,缓存逻辑以写满DDR3中的ABank作为开始标志;往BBank写数据至写满后,并自ABank读出数据至读空,组成一个图8㊀DDR3读写乒乓操作流程乒乓操作;同理,自BBank读出数据至读空后,并往A㊀㊀㊀㊀㊀第12期王红亮等:基于FPGA的JESD204B-光纤传输接口转换器设计113㊀㊀Bank写数据至写满,组成另一个乒乓操作,2个操作循环往复;数据传输结束时,缓存逻辑将ABank中数据读出,作为DDR3中数据缓存结束的唯一标志㊂另外,由于只是一块DDR3及一个MIGIP来实现乒乓操作,其中命令地址线是共用的,因此该设计利用分时复用的方法来达到读写数据线和地址线的调用㊂4㊀测试验证为测试系统JESD204B接口单元功能完整性,外部采集板卡选用具有JESD204B接口的ADS54J60EVM采集板,其采样分辨率为16位,采样率设为500Msps,传输编码方式为8B/10B,则测试链路的线路速率为10Gbps㊂由信号源向采集板卡提供2.5MHz的模拟正弦波信号输入,Vivado软件与ILA核抓取FPGA内部逻辑信号,功能测试结果如图9所示㊂可以看出,在GTX复位完成及Comma码检测对齐正确后,通道恢复出正确的K码,并按顺序完成码组同步,初始通道同步,用户数据传输各阶段,采集到稳定平滑的正弦波信号,JESD204B链路建立成功㊂图9㊀JESD204B单元板级逻辑验证时序图其次,测试系统整体链接传输功能㊂为方便数据观测,将采集板卡配置为测试模式,发送连续递增数据序列,并将光纤接口单元与外部高速存储测试记录仪互连㊂序列发送周期为1000个采样点,双通道数据链路发送,FPGA内部数据抓取结果如图10所示,高速存储记录仪记录数据结果如图11所示㊂结果显示,采集板数据可通过系统稳定无误的传输至高速存储记录仪㊂图10㊀递增序列板级逻辑数据抓取结果5㊀结束语本文设计了一种JESD204B-光纤传输接口转换器,实现了JESD204B接口与光纤接口的桥接传输,拓展JESD204B信号的通用性与传输距离,使之能与高速数据分析存储设备对接㊂通过测试,链路传输速率可达10Gbps,且数据传输稳定无误,符合设计要求㊂本文为高速数据采集传输领域的提供了一种解决方图11㊀高速存储记录仪数据记录结果案,对与JESD204B接口自主化的进一步研究具有参考意义㊂参考文献:[1]㊀董伟涛,伊小素,曾华菘,等.基于FPGA的SpaceFibre-USB3.0接口卡设计[J].仪表技术与传感器,2019(8):27-31.[2]㊀田瑞,刘马良.JESD204B协议的高速串行转换器接口[J].西安电子科技大学学报,2017,44(4):69-74.[3]㊀胥京宇.JESD204:更先进的高速转换器至FPGA接口标准[J].世界电子元器件,2013(6):68-69.[4]㊀SPIRIDONS,YANH,EBERHARTH.Alinearityimprovementtechniqueforovercomingsignal⁃dependentinducedswitchingtimemismatchinDAC-Basedtransmitters[C].EuropeanSolid⁃StateCircuitsConference(ESSCIRC),2015:347-347.[5]㊀王红亮,曹京胜.基于JESD204B协议的数据采集接口设计与实现[J].电测与仪表,2018,55(7):87-91.[6]㊀冯克迁.JESD204B协议在Xilinx系列FPGA上的设计与实现[D].成都:电子科技大学,2019.[7]㊀刘祯,王世明,方子穆.光纤通信技术与光纤传输系统的研究[J].中国新通信,2019,21(3):1.[8]㊀罗义军,陈松.基于PCIe接口的高速数据采集系统[J].仪表技术与传感器,2019(5):91-95.[9]㊀Xilinx.LogiCOREIPJESD204v7.2ProductGuide[DB/OL].http://www.xilinx.com,2017.[10]㊀JEDEC.JESD204B.SerialInterfaceforDataConverters[S].3103North10thStreetSuite240SouthArlington:JEDEC,JANUARY2012.[11]㊀Xilinx.LogiCOREIPAurora64B/66Bv12.0ProductGuide[DB/OL].http://www.xilinx.com,2019.[12]㊀项力领,刘智,杨阳,等.单片SDRAM的数据读写乒乓操作设计[J].长春理工大学学报(自然科学版),2013,36(5):140-143.作者简介:王红亮(1978 ),副教授,博士,主要研究方向为测试系统集成㊁目标检测与识别㊁应用软件开发㊁超声成像等㊂E⁃mail:whl_nuc@163.com和爽(1995 ),硕士研究生,主要研究方向为高速数字总线接口技术㊂E⁃mail:1306024217@st.nuc.edu.cn。
FPGA——以太⽹MAC层数据发送协议实现及验证⼀、设计思路FPGA实现MAC层(数据链路层)的功能并连接到RTL8211物理层(PHY)芯⽚实现以太⽹数据的发送使⽤GMII接⼝时钟是125MHz,⼀次发8bit数据 8bit * 125M = 1000Mbit 所以叫做千兆以太⽹RTL8211时序来⼀个时钟上升沿就发⼀个字节的数据数据链路层(MAC帧协议)发送过程前同步码 0x55,发七次帧开始符 0xD5⽬的MAC地址(6字节)源MAC地址(6字节)类型:0x800 使⽤IP上层协议,代表下⾯发送的数据是IP数据报数据IP报⽂⾸部IP版本 0x4 IPv4⾸部长度服务类型总长度分段标识保留位DFMF段偏移⽣存周期TTL上层协议 0x11 UDP报⽂校验和源IP地址⽬的IP地址可选字段(0字节不需要)IP报⽂数据(UDP报⽂)UDP报⽂⾸部16位源端⼝号16位⽬的端⼝号16位UDP长度16位UDP校验和(可以直接置0)UDP报⽂数据CRC校验IP报⽂校验和将IP报⽂⾸部,从前到后拼成⼀个⼀个的2字节的数据相加(其中报⽂校验和置0)然后将所加的32bit数据的⾼16位于低16位相加,直到⾼16bit为0 将16bit取反,则为校验和虽然⽣成了函数,但是具体使⽤函数还是要做更改的注意:CRC校验是从发送⽬的MAC地址开始校验的IP⾸部长度单位是/32bit(4字节) 如果没有可选⾃动,⾸部长度就是 5(⾏)IP总长度总长度 = IP⾸部长度 + IP报⽂数据长度单位是/字节MAC帧协议的数据和填充数据和填充那个位置,⾄少要46个字节,如果要发送的UDP报⽂数据加起来没有46字节的话,就要在后⾯填0x00直到有46个字节为⽌ IP报⽂头部(20字节)+ UDP报⽂(8字节)+ 发送的数据 >= 46 发送的数据 >= 18字节FPGA状态机实现每⼀个状态都配套⼀个计数器⼆、以太⽹GMIII发送代码实现module eth_udp_tx_gmii(clk ,rst_n ,tx_en ,tx_done ,dst_mac ,src_mac ,dst_ip ,gmii_clk ,data_len ,data_vld ,gmii_en ,gmii_tx ,data_in);localparam MAC_W = 48;localparam IP_W = 32;localparam PORT_W = 16;localparam DATA_LEN_W = 16;localparam GMII_W = 8;localparam PREAMBLE = 8'h55; //前导码localparam SFD = 8'hD5; //帧开始符localparam ETH_TYPE = 16'h0800;//上层协议类型,IP协议localparam IP_VER = 4'h4; //IPV4localparam IP_HDR_LEN = 4'h5; //⾸部长度有5个32bit localparam IP_TOS = 8'h00; //服务类型,未⽤localparam IP_HED_LEN = 20; //IP头部长度localparam UDP_HED_LEN = 8; //UDP头部长度localparam IP_ID = 16'h0000;//分段标识localparam IP_RSV = 1'b0; //保留localparam IP_DF = 1'b0; //是否分段localparam IP_MF = 1'b0; //是否有后续分段localparam IP_FRAG_OFFSET = 13'h0; //段偏移(以8字节为单位)localparam IP_TTL = 8'h40; //⽣存周期,能经过40个路由器localparam IP_PROTOCOL = 8'h11; //上层协议(UDP)localparam MIN_DATA = 46; //UDP数据最⼩长度localparam DATA_W = 8;//状态机参数localparam IDLE = 7'b0000001;localparam TX_ETH_HED = 7'b0000010;localparam TX_IP_HED = 7'b0000100;localparam TX_UDP_HED = 7'b0001000;localparam TX_UDP_DATA = 7'b0010000;localparam TX_FILL_DATA = 7'b0100000;localparam TX_CRC = 7'b1000000;localparam STATE_W = 7;//计数器参数localparam ETH_HED_W = 5;localparam ETH_HED_N = 22;localparam IP_HED_W = 5;localparam IP_HED_N = 20;localparam UDP_HED_N = 8;localparam UDP_HED_W = 4;localparam CNT_DATA_W = 11;localparam FILL_W = 6;localparam CNT_CRC_W = 3;localparam CNT_CRC_N = 4;//模块参数localparam CHEC_W = 16;localparam CRC_OUT_W = 32;input clk;input rst_n;input tx_en; //发送使能input [MAC_W-1:0] dst_mac; //⽬的Mac地址input [MAC_W-1:0] src_mac; //源Mac地址input [IP_W-1:0] dst_ip; //⽬的ip地址input [IP_W-1:0] src_ip; //源ip地址input [PORT_W-1:0] dst_port; //⽬的端⼝input [PORT_W-1:0] src_port; //源端⼝input [DATA_LEN_W-1:0] data_len; //发送数据长度input [DATA_W-1:0] data_in; //输⼊数据output gmii_clk; //以太⽹接⼝时钟output gmii_en; //以太⽹使能output [GMII_W-1:0] gmii_tx; //以太⽹数据output tx_done; //发送完成output data_vld; //数据有效标志信号wire gmii_clk; //以太⽹接⼝时钟reg gmii_en; //以太⽹使能reg [GMII_W-1:0] gmii_tx; //以太⽹数据reg tx_done; //发送完成reg data_vld; //数据有效标志信号reg [STATE_W-1:0] state_c;reg [STATE_W-1:0] state_n;wire idle2tx_eth_hed;wire tx_eth_hed2tx_ip_hed;wire tx_ip_hed2tx_udp_hed;wire tx_udp_hed2tx_udp_data;wire tx_udp_data2tx_fill_data;wire tx_udp_data2tx_crc;wire tx_fill_data2tx_crc;wire tx_crc2idle;//计数器变量reg [ETH_HED_W-1:0] cnt_eth_hed;wire add_cnt_eht_hed;wire end_cnt_eth_hed;reg [IP_HED_W-1:0] cnt_ip_hed;wire add_cnt_ip_hed;wire end_cnt_ip_hed;reg [UDP_HED_W-1:0] cnt_udp_hed;wire add_cnt_udp_hed;wire end_cnt_udp_hed;reg [CNT_DATA_W-1:0] cnt_data;wire add_cnt_data;wire end_cnt_data;reg [FILL_W-1:0] cnt_fill;wire add_cnt_fill;wire end_cnt_fill;reg [CNT_CRC_W-1:0] cnt_crc;wire add_cnt_crc;wire end_cnt_crc;//中间变量reg tx_flag;reg [MAC_W-1:0] dst_mac_tmp; //⽬的Mac地址reg [MAC_W-1:0] src_mac_tmp; //源Mac地址reg [IP_W-1:0] dst_ip_tmp; //⽬的ip地址reg [IP_W-1:0] src_ip_tmp; //源ip地址reg [PORT_W-1:0] dst_port_tmp; //⽬的端⼝reg [PORT_W-1:0] src_port_tmp; //源端⼝reg [DATA_LEN_W-1:0] data_len_tmp; //发送数据长度reg [DATA_LEN_W-1:0] ip_total_len; //IP总长度reg [DATA_LEN_W-1:0] udp_total_len; //UDP总长度wire [16-1:0] udp_check_sum; //UDP校验和reg [DATA_W-1:0] data_out; //以太⽹数据reg tx_nocrc_flag;//模块变量wire [CHEC_W-1:0] check_sum; //IP报头校验和reg sum_en;reg crc_init;reg crc_en;wire [CRC_OUT_W-1:0] crc_out;always @(posedge clk or negedge rst_n)beginif(!rst_n)state_c <= IDLE;elsestate_c <= state_n;endalways @(*)begincase(state_c)IDLE:beginif(idle2tx_eth_hed)state_n = TX_ETH_HED;elsestate_n = state_c;endTX_ETH_HED:beginif(tx_eth_hed2tx_ip_hed)state_n = TX_IP_HED;elsestate_n = state_c;endTX_IP_HED:beginif(tx_ip_hed2tx_udp_hed)state_n = state_c;endTX_UDP_HED:beginif(tx_udp_hed2tx_udp_data)state_n = TX_UDP_DATA;elsestate_n = state_c;endTX_UDP_DATA:beginif(tx_udp_data2tx_fill_data)state_n = TX_FILL_DATA;else if(tx_udp_data2tx_crc)state_n = TX_CRC;elsestate_n = state_c;endTX_FILL_DATA:beginif(tx_fill_data2tx_crc)state_n = TX_CRC;elsestate_n = state_c;endTX_CRC:beginif(tx_crc2idle)state_n = IDLE;elsestate_n = state_c;enddefault:state_n = IDLE;endcaseendassign idle2tx_eth_hed = state_c == IDLE && tx_en;assign tx_eth_hed2tx_ip_hed = state_c == TX_ETH_HED && end_cnt_eth_hed;assign tx_ip_hed2tx_udp_hed = state_c == TX_IP_HED && end_cnt_ip_hed;assign tx_udp_hed2tx_udp_data = state_c == TX_UDP_HED && end_cnt_udp_hed;assign tx_udp_data2tx_fill_data = state_c == TX_UDP_DATA && end_cnt_data && (data_len_tmp > 0 && data_len_tmp < (MIN_DATA - IP_HED_LEN - UDP_HED_LEN)); assign tx_udp_data2tx_crc = state_c == TX_UDP_DATA && end_cnt_data && data_len_tmp >= (MIN_DATA - IP_HED_LEN - UDP_HED_LEN);assign tx_fill_data2tx_crc = state_c == TX_FILL_DATA && end_cnt_fill;assign tx_crc2idle = state_c == TX_CRC && end_cnt_crc;always@(posedge clk or negedge rst_n)beginif(!rst_n)data_out <= 0;else if(state_c == TX_ETH_HED)begincase(cnt_eth_hed)0,1,2,3,4,5,6:data_out <= PREAMBLE;7 :data_out <= SFD;8 :data_out <= dst_mac_tmp[47:40];9 :data_out <= dst_mac_tmp[39:32];10:data_out <= dst_mac_tmp[31:24];11:data_out <= dst_mac_tmp[23:16];12:data_out <= dst_mac_tmp[15:8];13:data_out <= dst_mac_tmp[7:0];14:data_out <= src_mac_tmp[47:40];15:data_out <= src_mac_tmp[39:32];16:data_out <= src_mac_tmp[31:24];17:data_out <= src_mac_tmp[23:16];18:data_out <= src_mac_tmp[15:8];19:data_out <= src_mac_tmp[7:0];20:data_out <= ETH_TYPE[15:8];21:data_out <= ETH_TYPE[7:0];default:data_out <= 8'h00;endcaseendelse if(state_c == TX_IP_HED)begincase(cnt_ip_hed)0 :data_out <= {IP_VER,IP_HDR_LEN};1 :data_out <= IP_TOS;2 :data_out <= ip_total_len[15:8];3 :data_out <= ip_total_len[7:0];4 :data_out <= IP_ID[15:8];5 :data_out <= IP_ID[7:0];6 :data_out <= {IP_RSV,IP_DF,IP_MF,IP_FRAG_OFFSET[12:8]};7 :data_out <= IP_FRAG_OFFSET[7:0];8 :data_out <= IP_TTL;9 :data_out <= IP_PROTOCOL;10:data_out <= check_sum[15:8];11:data_out <= check_sum[7:0];12:data_out <= src_ip_tmp[31:24];13:data_out <= src_ip_tmp[23:16];14:data_out <= src_ip_tmp[15:8];15:data_out <= src_ip_tmp[7:0];17:data_out <= dst_ip_tmp[23:16];18:data_out <= dst_ip_tmp[15:8];19:data_out <= dst_ip_tmp[7:0];default:data_out <= 8'h00;endcaseendelse if(state_c == TX_UDP_HED)begincase(cnt_udp_hed)0:data_out <= src_port_tmp[15:8];1:data_out <= src_port_tmp[7:0];2:data_out <= dst_port_tmp[15:8];3:data_out <= dst_port_tmp[7:0];4:data_out <= udp_total_len[15:8];5:data_out <= udp_total_len[7:0];6:data_out <= udp_check_sum[15:8];7:data_out <= udp_check_sum[7:0];default:data_out <= 8'h00;endcaseendelse if(state_c == TX_UDP_DATA)begindata_out <= data_in;endelse if(state_c == TX_FILL_DATA)begindata_out <= 8'h00;endelse if(state_c == TX_CRC)begindata_out <= 0;endend//以太⽹头部计数器always @(posedge clk or negedge rst_n)beginif(!rst_n)cnt_eth_hed <= 0;else if(add_cnt_eht_hed)beginif(end_cnt_eth_hed)cnt_eth_hed <= 0;elsecnt_eth_hed <= cnt_eth_hed + 1'b1;endendassign add_cnt_eht_hed = state_c == TX_ETH_HED;assign end_cnt_eth_hed = add_cnt_eht_hed && cnt_eth_hed == ETH_HED_N - 1; //IP头计数器always @(posedge clk or negedge rst_n)beginif(!rst_n)cnt_ip_hed <= 0;else if(add_cnt_ip_hed)beginif(end_cnt_ip_hed)cnt_ip_hed <= 0;elsecnt_ip_hed <= cnt_ip_hed + 1;endendassign add_cnt_ip_hed = state_c == TX_IP_HED;assign end_cnt_ip_hed = add_cnt_ip_hed && cnt_ip_hed == IP_HED_N - 1;//udp头部计数器always @(posedge clk or negedge rst_n)beginif(!rst_n)begincnt_udp_hed <= 0;endelse if(add_cnt_udp_hed)beginif(end_cnt_udp_hed)cnt_udp_hed <= 0;elsecnt_udp_hed <= cnt_udp_hed + 1;endendassign add_cnt_udp_hed = state_c == TX_UDP_HED;assign end_cnt_udp_hed = add_cnt_udp_hed && cnt_udp_hed == UDP_HED_N - 1; //UDP数据计数器always @(posedge clk or negedge rst_n)beginif(!rst_n)begincnt_data <= 0;endelse if(add_cnt_data)beginif(end_cnt_data)cnt_data <= 0;elsecnt_data <= cnt_data + 1;endassign add_cnt_data = state_c == TX_UDP_DATA;assign end_cnt_data = add_cnt_data && cnt_data == data_len_tmp - 1;//填充计数器always @(posedge clk or negedge rst_n)beginif(!rst_n)begincnt_fill <= 0;endelse if(add_cnt_fill)beginif(end_cnt_fill)cnt_fill <= 0;elsecnt_fill <= cnt_fill + 1;endendassign add_cnt_fill = state_c == TX_FILL_DATA;assign end_cnt_fill = add_cnt_fill && cnt_fill == (MIN_DATA - IP_HED_LEN - UDP_HED_LEN - data_len_tmp) - 1; //CRC计数器always @(posedge clk or negedge rst_n)beginif(!rst_n)begincnt_crc <= 0;endelse if(add_cnt_crc)beginif(end_cnt_crc)cnt_crc <= 0;elsecnt_crc <= cnt_crc + 1;endendassign add_cnt_crc = state_c == TX_CRC && !tx_nocrc_flag;assign end_cnt_crc = add_cnt_crc && cnt_crc == CNT_CRC_N - 1;always @(posedge clk or negedge rst_n)beginif(!rst_n)tx_flag <= 0;else if(tx_en)tx_flag <= 1;end//装载写⼊数据always @(posedge clk or negedge rst_n)beginif(!rst_n)begindst_mac_tmp <= 0;src_mac_tmp <= 0;dst_ip_tmp <= 0;src_ip_tmp <= 0;dst_port_tmp <= 0;src_port_tmp <= 0;data_len_tmp <= 0;endelse if(tx_en && (!tx_flag))begindst_mac_tmp <= dst_mac;src_mac_tmp <= src_mac;dst_ip_tmp <= dst_ip;src_ip_tmp <= src_ip;dst_port_tmp <= dst_port;src_port_tmp <= src_port;data_len_tmp <= data_len;endend//IP总长度,20字节的IP⾸部+8字节UDP⾸部+UDP数据长度always @(posedge clk or negedge rst_n)beginif(!rst_n)ip_total_len <= 0;else if(state_c == TX_ETH_HED && (cnt_eth_hed == 0 && add_cnt_eht_hed))ip_total_len = IP_HED_LEN + UDP_HED_LEN + data_len_tmp;endalways @(posedge clk or negedge rst_n)beginif(!rst_n)udp_total_len <= 0;else if(state_c == TX_ETH_HED && (cnt_eth_hed == 0 && add_cnt_eht_hed))udp_total_len <= UDP_HED_LEN + data_len_tmp;endalways @(posedge clk or negedge rst_n)beginif(!rst_n)sum_en <= 0;else if(state_c == TX_ETH_HED && end_cnt_eth_hed)sum_en <= 1;endalways @(posedge clk or negedge rst_n)beginif(!rst_n)crc_init <= 0;else if(tx_en && (!tx_flag))crc_init <= 1;elsecrc_init <= 0;endalways @(posedge clk or negedge rst_n)beginif(!rst_n)crc_en <= 0;else if(state_c == TX_ETH_HED)beginif(cnt_eth_hed == 9 - 1 && add_cnt_eht_hed)crc_en <= 1;endelse if(state_c == TX_IP_HED || state_c == TX_UDP_HED || state_c == TX_UDP_DATA || state_c == TX_FILL_DATA)crc_en <= 1;elsecrc_en <= 0;endalways @(posedge clk or negedge rst_n)beginif(!rst_n)gmii_tx <= 0;else if(tx_nocrc_flag)gmii_tx <= data_out;else if(state_c == TX_CRC)begincase(cnt_crc)0:gmii_tx <= crc_out[7:0];1:gmii_tx <= crc_out[15:8];2:gmii_tx <= crc_out[23:16];3:gmii_tx <= crc_out[31:24];default:gmii_tx <= 8'h00;endcaseendelse if(tx_done)gmii_tx <= 0;endalways @(posedge clk or negedge rst_n)beginif(!rst_n)tx_nocrc_flag <= 0;else if(state_c == TX_ETH_HED || state_c == TX_IP_HED || state_c == TX_UDP_HED || state_c == TX_UDP_DATA || state_c == TX_FILL_DATA) tx_nocrc_flag <= 1;elsetx_nocrc_flag <= 0;endalways @(posedge clk or negedge rst_n)beginif(!rst_n)tx_done <= 0;else if(end_cnt_crc)tx_done <= 1;elsetx_done <= 0;endalways @(posedge clk or negedge rst_n)beginif(!rst_n)data_vld <= 0;else if(end_cnt_udp_hed)data_vld <= 1;else if(end_cnt_data)data_vld <= 0;endalways @(posedge clk or negedge rst_n)beginif(!rst_n)gmii_en <= 0;else if(cnt_eth_hed == 1 && add_cnt_eht_hed)gmii_en <= 1;else if(tx_done)gmii_en <= 0;endassign gmii_clk = clk;assign udp_check_sum = 0;.rst_n (rst_n),.sum_en (sum_en), //使能.ver (IP_VER), //ip版本.hdr_len (IP_HDR_LEN), //⾸部长度(单位,字节) .tos (IP_TOS), //服务类型.total_len (ip_total_len), //总长度.id (IP_ID), //分段标识.rsv (IP_RSV), //未⽤.df (IP_DF), //DF.mf (IP_MF), //MF.frag_offset (IP_FRAG_OFFSET), //段偏移.ttl (IP_TTL), //⽣存周期TTL(单位,秒).protocal (IP_PROTOCOL), //上层协议.check_sum (check_sum), //报头校验和.src_ip (src_ip_tmp), //源ip地址.dst_ip (dst_ip_tmp) //⽬的ip地址);crc32_d8 crc32_d8(.clk (clk),.rst_n (rst_n),.data (data_out),.crc_init (crc_init),.crc_en (crc_en),.crc_out (crc_out));endmodule三、IP校验和模块module ip_checksum(clk ,rst_n ,sum_en , //使能ver , //ip版本hdr_len , //⾸部长度(单位,字节)tos , //服务类型total_len , //总长度id , //分段标识rsv , //未⽤df , //DFmf , //MFfrag_offset , //段偏移ttl , //⽣存周期TTL(单位,秒)protocal , //上层协议check_sum , //报头校验和src_ip , //源ip地址dst_ip //⽬的ip地址);localparam VER_W = 4;localparam HDR_W = 4;localparam TOS_W = 8;localparam TOT_W = 16;localparam ID_W = 16;localparam FRAG_W = 13;localparam TTL_W = 8;localparam PTOC_W = 8;localparam CHEC_W = 16;localparam SR_W = 32;localparam DS_W = 32;localparam SUM_W = 32;localparam ACC_W = 17;input clk;input rst_n;input sum_en;input [VER_W-1:0] ver;input [HDR_W-1:0] hdr_len;input [TOS_W-1:0] tos;input [TOT_W-1:0] total_len;input [ID_W-1:0] id;input rsv;input df;input mf;input [FRAG_W-1:0] frag_offset;input [TTL_W-1:0] ttl;input [PTOC_W-1:0] protocal;input [SR_W-1:0] src_ip;input [DS_W-1:0] dst_ip;output [CHEC_W-1:0] check_sum;reg [CHEC_W-1:0] check_sum;//中间变量reg [SUM_W-1:0] sum;reg [ACC_W-1:0] acc_high_low;always @(posedge clk or negedge rst_n)beginif(!rst_n)sum <= 0;else if(sum_en)sum <= {ver,hdr_len,tos} + total_len + id + {rsv,df,mf,frag_offset} + {ttl,protocal} + src_ip[31:16] + src_ip[15:0] + dst_ip[31:16] + dst_ip[15:0]; endalways @(posedge clk or negedge rst_n)beginif(!rst_n)acc_high_low <= 0;elseacc_high_low <= sum[15:0] + sum[31:16];endalways @(posedge clk or negedge rst_n)beginif(!rst_n)check_sum <= 0;elsecheck_sum <= ~(acc_high_low[15:0] + acc_high_low[16]);endendmodule四、CRC校验模块////////////////////////////////////////////////////////////////////////////////// Copyright (C) 1999-2008 Easics NV.// This source file may be used and distributed without restriction// provided that this copyright statement is not removed from the file// and that any derivative work contains the original copyright notice// and the associated disclaimer.//// THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS// OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED// WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.//// Purpose : synthesizable CRC function// * polynomial: x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1// * data width: 8//// Info : tools@easics.be// ////////////////////////////////////////////////////////////////////////////////module crc32_d8(clk ,rst_n ,data ,crc_init ,crc_en ,crc_out);localparam DATA_W = 8;localparam OUT_W = 32;input clk;input rst_n;input [DATA_W-1:0] data;input crc_init;input crc_en;output [OUT_W-1:0] crc_out;wire [OUT_W-1:0] crc_out;//中间变量wire [DATA_W-1:0] data_in;reg [OUT_W-1:0] crc_out_inv;//⽣成data反转电路generategenvar i;for(i = 0;i < DATA_W;i = i + 1)beginassign data_in[i] = data[(DATA_W-1) - i];end//⽣成crc反转电路generategenvar j;for(j = 0;j < OUT_W;j = j + 1)beginassign crc_out[j] = ~crc_out_inv[(OUT_W-1) - j];endendgenerate//输出CRC,初始化CRC为FFFF_FFFF,使能输出CRCalways @(posedge clk or negedge rst_n)beginif(!rst_n)crc_out_inv <= 0;else if(crc_init)crc_out_inv <= 32'hffff_ffff;else if(crc_en)crc_out_inv <= nextCRC32_D8(data_in,crc_out_inv);end// polynomial: x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1 // data width: 8// convention: the first serial bit is D[7]function [31:0] nextCRC32_D8;input [7:0] Data;input [31:0] crc;reg [7:0] d;reg [31:0] c;reg [31:0] newcrc;begind = Data;c = crc;newcrc[0] = d[6] ^ d[0] ^ c[24] ^ c[30];newcrc[1] = d[7] ^ d[6] ^ d[1] ^ d[0] ^ c[24] ^ c[25] ^ c[30] ^ c[31];newcrc[2] = d[7] ^ d[6] ^ d[2] ^ d[1] ^ d[0] ^ c[24] ^ c[25] ^ c[26] ^ c[30] ^ c[31];newcrc[3] = d[7] ^ d[3] ^ d[2] ^ d[1] ^ c[25] ^ c[26] ^ c[27] ^ c[31];newcrc[4] = d[6] ^ d[4] ^ d[3] ^ d[2] ^ d[0] ^ c[24] ^ c[26] ^ c[27] ^ c[28] ^ c[30];newcrc[5] = d[7] ^ d[6] ^ d[5] ^ d[4] ^ d[3] ^ d[1] ^ d[0] ^ c[24] ^ c[25] ^ c[27] ^ c[28] ^ c[29] ^ c[30] ^ c[31]; newcrc[6] = d[7] ^ d[6] ^ d[5] ^ d[4] ^ d[2] ^ d[1] ^ c[25] ^ c[26] ^ c[28] ^ c[29] ^ c[30] ^ c[31];newcrc[7] = d[7] ^ d[5] ^ d[3] ^ d[2] ^ d[0] ^ c[24] ^ c[26] ^ c[27] ^ c[29] ^ c[31];newcrc[8] = d[4] ^ d[3] ^ d[1] ^ d[0] ^ c[0] ^ c[24] ^ c[25] ^ c[27] ^ c[28];newcrc[9] = d[5] ^ d[4] ^ d[2] ^ d[1] ^ c[1] ^ c[25] ^ c[26] ^ c[28] ^ c[29];newcrc[10] = d[5] ^ d[3] ^ d[2] ^ d[0] ^ c[2] ^ c[24] ^ c[26] ^ c[27] ^ c[29];newcrc[11] = d[4] ^ d[3] ^ d[1] ^ d[0] ^ c[3] ^ c[24] ^ c[25] ^ c[27] ^ c[28];newcrc[12] = d[6] ^ d[5] ^ d[4] ^ d[2] ^ d[1] ^ d[0] ^ c[4] ^ c[24] ^ c[25] ^ c[26] ^ c[28] ^ c[29] ^ c[30];newcrc[13] = d[7] ^ d[6] ^ d[5] ^ d[3] ^ d[2] ^ d[1] ^ c[5] ^ c[25] ^ c[26] ^ c[27] ^ c[29] ^ c[30] ^ c[31];newcrc[14] = d[7] ^ d[6] ^ d[4] ^ d[3] ^ d[2] ^ c[6] ^ c[26] ^ c[27] ^ c[28] ^ c[30] ^ c[31];newcrc[15] = d[7] ^ d[5] ^ d[4] ^ d[3] ^ c[7] ^ c[27] ^ c[28] ^ c[29] ^ c[31];newcrc[16] = d[5] ^ d[4] ^ d[0] ^ c[8] ^ c[24] ^ c[28] ^ c[29];newcrc[17] = d[6] ^ d[5] ^ d[1] ^ c[9] ^ c[25] ^ c[29] ^ c[30];newcrc[18] = d[7] ^ d[6] ^ d[2] ^ c[10] ^ c[26] ^ c[30] ^ c[31];newcrc[19] = d[7] ^ d[3] ^ c[11] ^ c[27] ^ c[31];newcrc[20] = d[4] ^ c[12] ^ c[28];newcrc[21] = d[5] ^ c[13] ^ c[29];newcrc[22] = d[0] ^ c[14] ^ c[24];newcrc[23] = d[6] ^ d[1] ^ d[0] ^ c[15] ^ c[24] ^ c[25] ^ c[30];newcrc[24] = d[7] ^ d[2] ^ d[1] ^ c[16] ^ c[25] ^ c[26] ^ c[31];newcrc[25] = d[3] ^ d[2] ^ c[17] ^ c[26] ^ c[27];newcrc[26] = d[6] ^ d[4] ^ d[3] ^ d[0] ^ c[18] ^ c[24] ^ c[27] ^ c[28] ^ c[30];newcrc[27] = d[7] ^ d[5] ^ d[4] ^ d[1] ^ c[19] ^ c[25] ^ c[28] ^ c[29] ^ c[31];newcrc[28] = d[6] ^ d[5] ^ d[2] ^ c[20] ^ c[26] ^ c[29] ^ c[30];newcrc[29] = d[7] ^ d[6] ^ d[3] ^ c[21] ^ c[27] ^ c[30] ^ c[31];newcrc[30] = d[7] ^ d[4] ^ c[22] ^ c[28] ^ c[31];newcrc[31] = d[5] ^ c[23] ^ c[29];nextCRC32_D8 = newcrc;endendfunctionendmodule五、仿真验证`timescale 1ns / 1nsmodule eth_tb();localparam MAC_W = 48;localparam IP_W = 32;localparam PORT_W = 16;localparam DATA_LEN_W = 16;localparam GMII_W = 8;localparam DATA_W = 8;parameter CYCLE = 20;reg clk;reg rst_n;reg tx_en; //发送使能reg [MAC_W-1:0] dst_mac; //⽬的Mac地址reg [MAC_W-1:0] src_mac; //源Mac地址reg [IP_W-1:0] dst_ip; //⽬的ip地址reg [IP_W-1:0] src_ip; //源ip地址reg [PORT_W-1:0] dst_port; //⽬的端⼝reg [PORT_W-1:0] src_port; //源端⼝reg [DATA_LEN_W-1:0] data_len; //发送数据长度reg [DATA_W-1:0] data_in; //输⼊数据wire gmii_clk; //以太⽹接⼝时钟wire gmii_en; //以太⽹使能wire [GMII_W-1:0] gmii_tx; //以太⽹数据wire tx_done; //发送完成wire data_vld; //数据有效标志信号eth_udp_tx_gmii eth_udp_tx_gmii(.clk (clk),.rst_n (rst_n),.tx_en (tx_en),.tx_done (tx_done),.dst_mac (dst_mac),.src_mac (src_mac),.dst_ip (dst_ip),.src_ip (src_ip),.dst_port (dst_port),.src_port (src_port),.gmii_clk (gmii_clk),.data_len (data_len),.data_vld (data_vld),.gmii_en (gmii_en),.gmii_tx (gmii_tx),.data_in (data_in));initial clk = 1;always #(CYCLE/2) clk = ~clk;initial beginrst_n = 1;#3;rst_n = 0;#(3*CYCLE)rst_n = 1;endinitial begindst_mac = 0;#(10*CYCLE)dst_mac = 48'hA1_6F_5B_12_01_F8;endinitial beginsrc_mac = 0;#(10*CYCLE)src_mac = 48'h00_0a_35_01_fe_c0;endinitial begindst_ip = 0;#(10*CYCLE)dst_ip = 32'hc0_a8_00_02;endinitial beginsrc_ip = 0;#(10*CYCLE)src_ip = 32'hc0_a8_00_03;endinitial begindst_port = 0;#(10*CYCLE)dst_port = 16'd8080;endinitial beginsrc_port = 0;#(10*CYCLE)src_port = 16'd1010;endinitial begindata_len = 0;#(10*CYCLE)data_len = 10;endreg [4-1:0] cnt_data_in;wire add_cnt_data_in;wire end_cnt_data_in;always @(posedge clk or negedge rst_n)beginif(!rst_n)begincnt_data_in <= 0;endelse if(add_cnt_data_in)beginif(end_cnt_data_in)cnt_data_in <= 0;elsecnt_data_in <= cnt_data_in + 1;endendassign add_cnt_data_in = data_vld;assign end_cnt_data_in = add_cnt_data_in && cnt_data_in == 11 - 1; always @(*)begincase (cnt_data_in)0 :data_in = "X";1 :data_in = "I";2 :data_in = "L";3 :data_in = "I";4 :data_in = "N";5 :data_in = "X";6 :data_in = " ";7 :data_in = "F";8 :data_in = "P";9 :data_in = "G";10:data_in = "A";default: data_in = 8'h00;endcaseendinitial begin@(posedge tx_done)#200;$stop;endinitial begin#1;tx_en = 0;#(15*CYCLE)tx_en = 1;#(CYCLE)tx_en = 0;endendmodule六、板级验证module eth_udp_tx_gmii_test(clk ,rst_n ,led ,eth_rst_n,gmii_clk ,gmii_en ,gmii_tx);//延迟0.5msparameter DELAY_N = 625_00000;input clk;input rst_n;output led;output eth_rst_n;output gmii_clk ;output gmii_en ;output [8-1:0] gmii_tx;wire led;wire eth_rst_n;wire gmii_clk ;wire gmii_en ;wire [8-1:0] gmii_tx;wire locked;wire clk125M;wire data_vld;reg [8-1:0] data_in;reg tx_en;//PLL稳定后,开始⼯作assign eth_rst_n = locked;assign led = locked;pll pll(.clk_out1(clk125M),.resetn(rst_n),.locked(locked),.clk_in1(clk));eth_udp_tx_gmii eth_udp_tx_gmii(.clk (clk125M),.rst_n (eth_rst_n),.tx_en (tx_en),.tx_done (tx_done),.dst_mac (48'h10_1E_1F_12_11_18),.src_mac (48'h00_0a_35_01_fe_c0),.dst_ip (32'hc0_a8_00_03),.src_ip (32'hc0_a8_00_02),.dst_port (16'd6000),.src_port (16'd5000),.gmii_clk (gmii_clk),.data_len (23),.data_vld (data_vld),.gmii_en (gmii_en),.gmii_tx (gmii_tx),.data_in (data_in));reg [26-1:0] cnt_delay;wire add_cnt_delay;wire end_cnt_delay;always @(posedge clk125M or negedge rst_n)beginif(!rst_n)begincnt_delay <= 0;endelse if(add_cnt_delay)beginif(end_cnt_delay)cnt_delay <= 0;elsecnt_delay <= cnt_delay + 1;endendassign add_cnt_delay = eth_rst_n;assign end_cnt_delay = add_cnt_delay && cnt_delay == DELAY_N - 1 ; always @(posedge clk125M or negedge rst_n)beginif(!rst_n)tx_en <= 0;else if(end_cnt_delay)tx_en <= 1;elsetx_en <= 0;endreg [5-1:0] cnt_data_in;wire add_cnt_data_in;wire end_cnt_data_in;always @(posedge clk125M or negedge rst_n)beginif(!rst_n)begincnt_data_in <= 0;endelse if(add_cnt_data_in)beginif(end_cnt_data_in)cnt_data_in <= 0;elsecnt_data_in <= cnt_data_in + 1;endendassign add_cnt_data_in = data_vld;assign end_cnt_data_in = add_cnt_data_in && cnt_data_in == 23 - 1;always @(*)begincase (cnt_data_in)16'd0 : data_in = "H";16'd1 : data_in = "e";16'd2 : data_in = "l";16'd3 : data_in = "l";16'd4 : data_in = "o";16'd5 : data_in = ",";16'd6 : data_in = " ";16'd7 : data_in = "w";16'd8 : data_in = "e";16'd9 : data_in = "l";16'd10 : data_in = "c";16'd11 : data_in = "o";16'd12 : data_in = "m";16'd13 : data_in = "e";16'd14 : data_in = " ";16'd15 : data_in = "t";16'd16 : data_in = "o";16'd17 : data_in = " ";16'd18 : data_in = "F";16'd19 : data_in = "P";16'd20 : data_in = "G";16'd21 : data_in = "A";16'd22 : data_in = "!";default:data_in = 8'h00;endcaseendendmodule七、问题记录在板级验证过程中,抓取的包出现异常原因是FPGA开发板连接的物理层芯⽚引脚没有使⽤,但是FPGA的未⽤引脚是⾼电平和低电平影响了芯⽚的正常⼯作解决⽅法是:添加⼀条约束,将未⽤引脚置为⾼阻态set_property BITSTREAM.CONFIG.UNUSEDPIN Pullnone [current_design](IOB = "TRUE") output gmii_en; //以太⽹使能 (IOB = "TRUE") output [GMII_W-1:0] gmii_tx; //以太⽹数据。
第42卷第3期激光杂志 Vol.42,No_3 2021 年3 月L A S E R J O U R N A L M a rc h,2021•光电技术与应用•基于F P G A的光谱仪数据采集系统袁洪平,曾立波,林志鹏武汉大学电子信息学院,武汉430072摘要:傅里叶红外光谱仪高效、可靠地获得光谱数据对于后续定性和定量分析物质有着重大的意义。
使 用F P G A的并行处理能力和可自定义外设构建灵活的片内系统,配合外部硬件电路设计,提出了一种基于FP- G A的可定制高效稳定地采集、存储和传输光谱数据的系统实现方法。
阐述了基于F P G A完全使用硬件实现干 涉信号采集和存储的方法,用以提高数据采集的可靠性。
通过最终的实验结果表明,系统可以长时间稳定的运 行,解决了使用ARM进行数据采集和传输出现数据丢失的问题。
关键词:光谱仪;F P G A;自定义外设;数据采集中图分类号:TN216 文献标识码:A d o i:10. 14016/j. cnki. jgzz. 2021. 03. 153Data acquisition system of spectrometer based on FPGAYUAN Hongping,ZENG Libo,LIN ZhipengSchool o f Electronics a n d In fo rm a tio n,W uhan U niversity,W uhan430072, C hinaAbstract:The efficient and reliable acquisition of spectral data by Fourier infrared spectrom eter is significant for the subsequent qualitative and quantitative analysis of substances. Using the parallel processing capability of FPGA and the characteristic of building flexible in-c h ip system with custom izable peripheral and com bining with the design of external hardware circ u it, a system im plem entation m ethod based on FPGA can be custom ized and efficiently and stably co llec t, store and transm it spectral data was proposed. The method of interference signal acquisition and storage based on FPGA was described to improve data acquisition reliability. The final experim ental results show that the system can run stably for a long time and solve data loss in ARM data acquisition and transm ission.Key words:spectrom eter;F PG A;custom izable p e rip h e ra ls;data acquisitioni引言傅里叶红外光谱仪(Fourier Transform Infrared Spectrometer,FTS)能够对物质进行定性和定量分析,因此被广泛地应用于医药化工、石油、煤炭、环保等领 域[|4]。
总第180期2009年第6期舰船电子工程
ShipElectronicEngineeringVol.29No.6
173
基于FPGA的以太网接口数据采集器设计与实现3赵智勇1) 邹文胜2)(海军驻宜昌地区军事代表室
1) 宜昌 443005
)
(海声科技有限公司
2) 宜昌 443005
)
摘 要 基于FPGA的以太网接口数据采集器为水下声信号的采集和记录及水下声环境的分析提供了一种新的解决方案。着重研究了基于FPGA的以太网接口三通道数据采集和存储记录系统的设计和实现方法。关键词 数据采集;FPGA;以太网;水声环境中图分类号 TN929.3
DesignandImplementationofDataAcquisitionbyEthernetBasedonFPGA
ZhaoZhiyong1) ZouWensheng2)(MilitaryRepresentativeOfficeofNavyStationedinYichangArea1),Yichang 443005)(HaiShengScienceandTechnologyLimitedCompany2),Yichang 443005)
Abstract
ThedataacquisitionmachinebasedonFPGAandEnthernetoffersanewsolutionfortheunderwatersound
signalacquisitionandrecording.Thesolutionalsoprovidestheunderwatersoundenvironmentanalysis.Itemphasizesthedesignandsolutionofthethree-channelsdataacquisitionandstoragesystembasedontheFPGAandEnthernetinterface.Keywords
dataacquisition,FPGA,enthernet,underwaterenvironment
ClassNumber TN929.3
1 引言近年来,随着水声技术和数字信号处理技术的发展,从水下声信号中提取更多有用信息并将其实时采集存储成为数字信号处理应用方向之一。再经过分析和研究水声信号,可充分了解水下声环境并制定有效的信号处理方案,这在水声产品研制前期尤为重要。在此过程中不仅要对模拟信号进行采集、量化(数据采集器),同时还要考虑数据记录接口的通用性。本文介绍了基于FPGA的以太网接口的数据采集器的分析和设计方法,为水下声信号的采集和实时记录及水下声环境的分析提供了一种新的解决方案。2 系统基本结构及设计思想数据采集器分为湿端和干端两部分。湿端由一只二维矢量传感器(内含前置放大器)和一只电罗经组成;干端由后置放大模块、数据转换模块、UDP协议栈模块、以太网接口模块、电源模块组成。干端通过以太网接口与PC机连接,主要功能是将来自矢量传感器的三通道模拟信号数字化,与电罗经的数据打包后通过以太网接口送给PC机,
PC机将数据保存在硬盘中,同时显示三通道的时域波形和频谱及电罗经的真方位;PC机可以控制三通道放大器的增益。数据采集器基本框图如图
3收稿日期:2009年2月17日,修回日期:2009年3月23日作者简介:赵智勇,男,工程师,研究方向:电子技术。邹文胜,男,工程师,研究方向:电子技术。174 赵智勇等:基于FPGA的以太网接口数据采集器设计与实现总第180期1所示。图1 数据采集器基本框图数据采集器其主要设计思想如下:1)选用低功耗、低噪声器件,使系统噪声级位于16bit的3~4bit;2)通道数为3,通道带宽为20Hz~5kHz,通道增益可控;3)使用串行输出A/D,16位分辨率,三通道同步采集;4)使用FPGA(可编程逻辑器件)与A/D接口;5)电罗经与采集器干端通过RS422口连接;6)使用内部含物理层(PHY)的媒体访问控制器(MAC)实现以太网接口;7)网络传输使用UDP协议,在FPGA中用硬件实现UDP协议栈。3 关键模块的设计3.1 采集控制器数据采集器选用一片FPGA作为控制器,在FPGA中实现数据转换控制、UDP协议栈、以太网接口等功能模块。数据转换控制模块完成模拟信号到数字信号的转换、A/D串行数据到并行数据的转换,接受PC机的增益控制命令,并通过D/A控制压控放大器的增益。数据采集器要实现三个通道模拟信号的同步采集并接收电罗经的方位数据,同时还需与媒体访问控制器交换数据,这就要求采集控制器能够提供足够多的输入和输出端口。而FPGA(现场可编程门阵列)的特点是:可使用的端口数量多、内部逻辑可按使用需要编程、非常少的外围支持器件。采用FPGA作为采集控制器可以使系统设计简单、可靠,并且有很强的灵活性[1~2]。系统中FPGA选用Altera公司CYCLONE系列中的EP1C6Q240作为采集控制器。CY2CLONE系列采用了新的可编程逻辑架构,具有低功耗等特点[3]。3.2 UDP协议栈UDP是一种简单的面向报文的传输层协议,不提供可靠性支持,它把应用程序交下来的报文添加首部后向下交付给IP层发送出去。虽然UDP
不保证可靠交付,但是它占用的资源较少,瞬时数据量波动较小,对网络带宽的利用能力较好。在数据传输需要保证实时性时可以通过设计应用层协议提高UDP的传输质量,如可用采用冗余法:在发送端的数据流中加入冗余信息,接收端利用这些冗余信息,可恢复丢失的数据包,在带宽允许的情况下,只要误差在可接受的范围,UDP方式可以满足实时数据传输的要求。因此本文选用UDP协议。在PC机中,协议栈是由软件实现,因为PC机的主频很高,所以协议栈的效率比较高,数据传输速率就比较高。在FPGA中可实现的软处理器主频较低,其软件协议栈的效率就很低,数据传输速率就较低。必须在FPGA中用硬件逻辑来实现协议栈才能使协议栈的效率满足要求。TCP/IP协议栈是一个四层协议系统,每一层负责不同的功能。发送数据时根据每一层的协议将数据封装本层协议中并送往下一层协议,最后将封装好的数据送往以太网控制器,以太网控制器按照规定的速率将数据发送出去,接收数据是一个解封装的过程。UDP协议封装和解封装的过程如图2所示[4]。
图2 UDP协议栈封装和解封装过程3.3 以太网接口以太网控制器(NIC)选用的是SMSC公司为嵌入式的快速以太网应用而设计的第三代NIC
LAN91C111,其内部含有一个用于双绞线传输的100Base2TX/10Base2T物理层PHY,还有一个用于与外部PHY连接的MII媒体独立接口[5]。
图3 LAN91C111的32位方式读写时序 LAN91C111支持8位、16位和32位的主机接口,为了提高数据交换的效率,FPGA与MAC2009年第6期舰船电子工程175
图4 LAN91C111的32位方式写时序仿真之间采用32位方式接口[6]。图3为32位方式读写时序,图4为写时序仿真。
4 数据记录和显示数据的存储、记录和显示在PC机上完成。PC
机按照BIN文件的格式将收到数据保存在硬盘上,同时将原始数据解包。实时显示电罗经的真方位和通道增益,实时显示三通道的时域波形。在操作界面上可以选择显示任一通道的频谱LOFAR
图。通过观察时域波形,可以判断通道的增益是否合适,并可通过操作界面对增益进行调整。数据的存储记录和显示程序使用BorlandC+
+Builder6开发完成。
5 结语本文详细地阐述了基于FPGA的多通道数据
采集系统的设计及FPGA和以太网控制器接口的方法。在设计过程中充分利用了FPGA开发平台QUARTUSⅡ的仿真功能对每个功能模块进行了正确性验证;在调试过程中利用WinPcap软件捕获网络数据包的功能使网络的调试工作变得简单,
确保了系统设计和实现的顺利完成,性能指标达到了预期要求。
参考文献[1]褚振勇,翁木云.FPGA设计及应用[M].西安:西安电子科技大学出版社,2002
[2]吴继华,王诚.AlteraFPGA/CPLD设计[M].北京:人民邮电出版社,2005
[3]曾繁泰,陈美金.VHDL程序设计[M].北京:清华大学出版社,2001
[4]范建华.TCP/IP详解[M].北京:机械工业出版社,2000[5]LAN91C11110/100Non2PCIEthernetSingleChipMAC+PHYDatasheet.2005[6]ADS8320ANALOG2TO2DIGITALCONVERTERDatashe2et.1999
(上接第148页)5 结语数字校园管理规划系统将为校园规划、管理提供了最直观的表现形式。系统采用三维成像、虚拟现实技术实现进行三维场景的漫游功能,将校园景观三维可视化,既可以为校园树立良好的形象,让用户足不出户就可了解校园环境和有关介绍信息,
体验身临其境的感受;还可以作为校园规划管理的有力工具,从而提高校园管理的现代化水平。与此同时,在将其与校园的有关信息相结合后,可以改掉过去呆板的二维界面,提供给用户一个三维可视化的、有声有色的信息介绍与查询环境。
参考文献[1]教英.虚拟现实基础及实用算法[M].北京:科学出版社,2002:3~4[2]罗亚波,陈定方.图像与建模相结合的虚拟现实关键技术[J].交通与计算机,2000(8):20[3]郭恒业.基于图像的虚拟环境建模技术[J].哈尔滨工业大学学报,2001(5):21[4]石巧珍,刘晓,蒋刚毅.交互式三维虚拟校园的设计[J].电脑与信息技术,2003(4):66[5]吴亮.基于插件技术的GIS应用框架的研究与实现[J].地球科学-中国地质大学学报,2006,50(5):44~46[6]叶嘉安.数字城市与地理信息系统[J].地理信息世界,2007,5(4):35~37[7]侯红松.浅谈地理信息系统的发展[J].大众科技,2007,15(4):46~47[8]史磊.依托计算机技术的地理信息系统(GIS)发展趋势[J].科技咨询导报,2007,4(29):80~81