注:此版本没有添加ARP PING 等,未完待续。
注:项目采用Verilog开发,基于Vivado编译器。
注:本版本没有计算校验
与上一篇相同开发环境,采用三段式状态机。
同样,接收后将数据写入FIFO,相比于数据发送更为简单,只需在写入数据时同步拉高FIFO使能就可以。
对外接口如下:

 input                       clk_i, //RX_clkinput                        rst_n,/*eth interface*/input                        Rxer_i,  input                          Rxdv_i,     input       [ 7:0]          Rxd_o,     /*control interface*/input       [ 3:0]          Eth_Command,/*fifo interface*/output reg    [ 7:0]          Fifo_Data_i,output reg                  Fifo_Wr_en

其中Rxdv_i为关键信号数据输入有效,只有当此信号为高,才证明这个数据是正确的。
Rxer_i 这个信号暂时没有用,具体在板上验证时做修改。
本模块状态划分如下:

localparam  idle         =  8'b1111_1110; //fe
localparam  Rec_MAC_addr    =  8'b1111_1101; //fd
localparam  Rec_IP_addr     =  8'b1111_1011; //fb
localparam  Rec_ARP         =  8'b1111_0111; //f7
localparam  Rec_Data        =  8'b1110_1111; //ef
localparam  Rec_Over        =  8'b1101_1111; //df
localparam  Rec_Zero        =  8'b1011_1111; //bf

状态1、空闲状态:当使能开启时,等待外部输入正确引导码启动
状态2、接收MAC地址,同时判断是否正确
状态3、同上接收正确IP地址
状态4、保留,上次还没有做ARP的发送
状态5、开始接收数据,从上面信息中提取数据数量,来判断需要读取多少数据
状态6、接收完成,写入本次数据的帧尾(包计数、数据量),用于判断是否丢包或丢数据
状态7、将各寄存器清零。如果不清,会在起始状态时寄存器内就有正确数据。
切换状态条件:

     idle:           nstate <= ( (Eth_Command[3] == 1'b1) && (Identifiy_Data[63:0] == `Leading_code))? Rec_MAC_addr : idle;Rec_MAC_addr: beginif( State_turn   == 1'b1 ) beginif(MAC_Data[ 63:16]  == `Destination_MAC && MAC_Data[111:64]  == `Source_MAC) beginif(MAC_Data[ 15: 0]  == `IP_TYPE) beginnstate <=  Rec_IP_addr;endelse if(MAC_Data[ 15: 0]  == `IP_TYPE_ARP) beginnstate <=  Rec_ARP;endelse beginnstate <= idle;endendelse beginnstate <= idle;endend          else beginnstate <= Rec_MAC_addr;end        endRec_IP_addr:   beginif( State_turn   == 1'b1 )beginif(Header_Data[ 47:32] == `Destination_Port && Header_Data[ 63:48] == `Source_Port       && Header_Data[ 95:64] == `Destination_IP    && Header_Data[127:96] == `Source_IP ) beginnstate <= Rec_Data;endelse beginnstate <= idle;endendelse beginnstate <= Rec_IP_addr;endendRec_Data: nstate <= (State_turn == 1'b1) ? Rec_Over : Rec_Data;Rec_Over: nstate <= (State_turn == 1'b1) ? Rec_Zero : Rec_Over;Rec_Zero: nstate <= idle;

当外部命令开启使能,就开始接收数据,接收到争取引导码后,跳入下一状态
Start_turn :与上一篇判断条件一样,接收正确数量的数据后,判断各地址是否正确,正确进入下一状态,不正确跳回idle。
数据管理代码

         idle: beginif(Rxdv_i)beginIdentifiy_Data[63:0] <= {Identifiy_Data[55:0],Rxd_o[7:0]};endelse beginIdentifiy_Data[63:0] <= Identifiy_Data[63:0];endendRec_MAC_addr: beginif(Rxdv_i)beginMAC_Data[111:0] <= {MAC_Data[104:0],Rxd_o[7:0]};endelse beginMAC_Data[111:0] <= MAC_Data[111:0];endendRec_IP_addr:  beginif(Rxdv_i)beginHeader_Data[223:0] <= {Header_Data[216:0],Rxd_o[7:0]};endelse beginHeader_Data[223:0] <= Header_Data[223:0];endendRec_Data,Rec_Over: beginIdentifiy_Data[ 63:0] <= Identifiy_Data[ 63:0];MAC_Data   [111:0] <= MAC_Data      [111:0];Header_Data   [223:0] <= Header_Data   [223:0];  endRec_Zero:beginIdentifiy_Data[ 63:0] <= { 8{8'h00}};MAC_Data   [111:0] <= {14{8'h00}};Header_Data   [223:0] <= {28{8'h00}};            end

Rxdv_i拉高,就收取数据,做移位操作,写入寄存器,接收到正确数量后,进行判断实现状态跳转。
FIFO写入代码

         Rec_Data: beginif(Rxdv_i)beginFifo_Data_i[7:0]<= Rxd_o[7:0];Fifo_Wr_en      <= 1'b1;endelse beginFifo_Data_i[7:0]<= Fifo_Data_i[7:0];Fifo_Wr_en        <= 1'b0;endend

能正确跳入这个状态后,就开始按照提取出的Data_length个数,开始写就行了。
接收整体代码不多,没加校验,具体等实际用的时候看情况需不需要。
本工程是用于记录以太网数据,并写入存储器内。
还在等板子中…先看看仿真叭,代码:

initial beginclk_o  = 1'b1;    forever begin#10ns clk_o = ~clk_o; //10Mhzend//#10200 RX_START = 1'b0;
end
initial beginrst_n = 1'b0;Data_length = 16'd1500;#1000ns rst_n = 1'b1;endalways @(posedge clk_o or negedge rst_n)
beginif(!rst_n) beginFifo_Data_i <= 8'hFF;endelse if (Fifo_Rd_en)beginFifo_Data_i <= Fifo_Data_i + 1'b1;endelse beginFifo_Data_i <= Fifo_Data_i;end
end
always @(posedge clk_o or negedge rst_n)
beginif(!rst_n) beginEth_Command = 4'h0;#500nsEth_Command = 4'h0;endelse beginif(Eth_Write_Busy) beginEth_Command = 4'h0;end  else begin#1000nsEth_Command = 4'hA;endend
end
endmodule

顶层连接关系:ETH_Send是上篇文章的代码

test test_u(.clk_o                   (clk_i),.rst_n                  (rst_n),.Eth_Command            (Eth_Command),.Data_length          (Data_length),.Eth_Write_Busy       (Eth_Write_Busy),.Fifo_Data_i           (Fifo_Data_o),.Fifo_Rd_en               (Fifo_Rd_en));ETH_Send ETH_Send_u(.clk_i                    (clk_i),.rst_n                  (rst_n),.Txen_o                 (Txen_o),                     .Txer_o                   (Txer_o),                     .Txd_o                    (Txd_o),     .Eth_Command           (Eth_Command),.Data_length          (Data_length),.Eth_Write_Busy       (Eth_Write_Busy),.Fifo_Data_o           (Fifo_Data_o),.Fifo_Rd_en               (Fifo_Rd_en));ETH_Receive ETH_Receive_u(.clk_i                  (clk_i),.rst_n                  (rst_n),.Rxer_i                 (1'b0),                     .Rxdv_i                    (Txen_o),                     .Rxd_o                    (Txd_o),     .Eth_Command           (Eth_Command),.Fifo_Data_i          (Fifo_Data_i),.Fifo_Wr_en               (Fifo_Wr_en));


问题不大,下面看看细节

正确提取引导码、MAC、IP、并提取出数据长度、包计数。
同时把发送读fifo的首个数据写入fifo中。
本项目还有个问题:读出数据后,会在下一个时钟发送出去,这样会时钟存在一个数据在线上,所以会首先发送出一个数据是上次读出来。这样就会在第一帧数据内多一个无效数,对后面没有任何影响,保证连续不丢。对我的应用没有影响…也就懒得改了。
暂时的想法是将读fifo的vaild信号与Txen_o强关联。具体上板验证时,再调叭。
对于接收,因为发送端fifo的问题,在接收过程中就是写入实际收到的数据。

可以看到把1500数据写入后写入我的帧尾 FF_FF+包计数+数据长度+FF_FF,然后将用于判断的寄存器清零。
简单收发已经实现,下一步准备添加其他模式。

Verilog 实现千兆网UDP协议 基于88E1111--数据接收相关推荐

  1. Verilog 实现千兆网UDP协议 基于88E1111--数据发送

    Verilog 实现千兆网UDP协议 基于88E1111–数据发送 注:此版本没有添加ARP PING 等,未完待续. 注:项目采用Verilog开发,基于Vivado编译器. UDP(User Da ...

  2. Verilog 实现千兆网UDP协议 基于88E1111--板级验证--增加ARP

    增加ARP后,Board通过电脑端的APR请求获取PC端MAC地址及IP,所以宏定义内不定义Destination_MAC.Destination_IP.提取到顶层文件用以寄存器存储. `define ...

  3. 一个udp用户数据报的数据字段为8192_基于FPGA的千兆网UDP通信分析

    千兆网UDP通信 以太网帧格式 图8‑12 以太网帧格式 表8‑5 以太网帧格式说明 UDP协议分析 为什么UDP协议在FPGA实现时很受欢迎,最主要一个原因就是简单,简答到什么地步呢?UDP协议只是 ...

  4. 基于zynq的千兆网udp项目_基于FPGA的千兆网UDP通信分析

    千兆网UDP通信 以太网帧格式 图8‑12 以太网帧格式 表8‑5 以太网帧格式说明 UDP协议分析 为什么UDP协议在FPGA实现时很受欢迎,最主要一个原因就是简单,简答到什么地步呢?UDP协议只是 ...

  5. 基于zynq的千兆网udp项目_米联客 ZYNQ/SOC 精品教程 S05-CH05 PS 千兆 UDP 加速

    软件版本:VIVADO2017.4 操作系统:WIN10 64bit 硬件平台:适用米联客 ZYNQ系列开发板 米联客(MSXBO)论坛:www.osrc.cn答疑解惑专栏开通,欢迎大家给我提问!! ...

  6. FPGA基于SFP光口实现1G千兆网UDP通信 1G/2.5G Ethernet PCS/PMA or SGMII替代网络PHY芯片 提供工程源码和技术支持

    目录 1.前言 2.我这里已有的UDP方案 3.详细设计方案 4.vivado工程详解 5.上板调试验证并演示 6.福利:工程代码的获取 1.前言 目前网上的fpga实现udp基本生态如下: 1:ve ...

  7. 基于zynq的千兆网udp项目_一种基于ZYNQ的四路万兆以太网安全交换机的制作方法...

    本实用新型涉及网络安全.网络通信技术领域,尤其是一种基于ZYNQ的四路万兆以太网安全交换机,适用于大中型企业的交换网络. 背景技术: 随着互联网的高速发展,传统的以太网交换机在功能和性能上已不能满足要 ...

  8. 基于zynq的千兆网udp项目_随时随地感受“沉浸式千兆体验”!海南互联网络迈入“三千兆”时代...

    海口网6月18日消息(记者刘杰)18日,海南电信在海口友谊阳光城举办"电信三千兆 智享新生活"发布会."电信三千兆"的发布标志着海南互联网络建设进入一个全新的发 ...

  9. 基于zynq的千兆网udp项目_基于Zynq平台的EtherCAT主站方案实现

    作者:陈秋苑 谢晓锋 陈海焕 广州虹科电子科技有限公司 摘 要:EtherCAT 是开放的实时以太网通讯协议,由德国倍福自动化有限公司研发.EtherCAT 具有高性能.低成本.容易使用等特点,目前在 ...

最新文章

  1. rocketmq(三 java操作rocket API, rocketmq 幂等性)
  2. 5G NGC — PCF Npcf_PolicyAuthorization Service
  3. 公众号微信支付ios和android,【微信支付】
  4. 宿主机windows Xp部署virtualBox虚拟机并在其上安装linux Centos(Red Hat)操作系统
  5. 为了压榨CNN模型,这几年大家都干了什么
  6. occam‘s razor
  7. json数据交互---SpringMVC学习笔记(十二)
  8. 关于Android手机CPU不同架构的问题
  9. JS对全角与半角的验证,相互转化以及介绍
  10. python3基础学习(XML文件解析)
  11. Mutation Testing(变异测试)
  12. .net中对象序列化技术
  13. 深度学习图像分割:U-Net 体系结构
  14. 等保测评机构推荐证书撤销,纳入国家认证体系
  15. GitHub又放大招,Python版本的植物大战僵尸还能作弊玩!
  16. 【Unity】动作游戏开发实战详细分析-26-组合攻击
  17. 120 行代码实现纯 Web 剪辑视频
  18. 5种最热门编程语言的优缺点
  19. 如何改变pycharm的背景颜色
  20. 软件著作权申请——使用了MIT-licence开源框架

热门文章

  1. 写博客没高质量配图?python爬虫教你绕过限制一键搜索下载图虫创意图片!
  2. 2021-2027年全球与中国矫正隐形眼镜行业市场前瞻与投资战略规划分析报告
  3. ROS ,how to subscriber hark_msgs----hark-ros
  4. 何万青:直呼其名——我与中国计算机学会十年命运交织
  5. Win11自带微软浏览器无法翻译
  6. Loadrunner执行https报错Action.c(7): Error -27778: SSL protocol error when attempting to connect with hos
  7. 管理人员巡店用表-生鲜部经理及主管每日检查事项
  8. Use Ant implementing Continous Integration.
  9. dsp版win10和普通版区别_Win10和 Windows10版本区别是什么?
  10. ruby读dbf文件