首页 > 其他分享 >实战篇-FPGA实现RGMII数据接收

实战篇-FPGA实现RGMII数据接收

时间:2024-07-26 17:29:12浏览次数:19  
标签:实战篇 FPGA rx b0 RGMII output input bit rgmii

        RGMII时序

        前面讲到关于关于ARP的理论知识,该章节主要通过FPGA接收以太网数据,并作数据分析。

        首先关于以太网RGMII接收时序如下图所示:

        

                                                        图1 RGMII接收时序图

        如上图所示,RGMII采用双沿采样,4根数据线,时钟采用125MHz。这里提一下关于GMII时钟同样是125MHz,8根数据线,采用单沿采样。

        如上图所示,接收的信号需要将数据端整体偏移,保证数据在时钟沿的中间,这样保证采样时数据处于稳定状态。移动后的数据如下图所示:

                                                                图2 数据偏移后的数据

        偏移数据采和双沿采集会用到FPGA里的IDELAYE2原语和IDDR原语,下面就FPGA原语做简单介绍。

        FPGA驱动

        FPGA解析双沿信号一般使用IDDR转换成单沿信号,根据ug471_7Series_SelectIO文档说明,IDDR分别由三种工作模式,分别为OPPOSITE_EDGE mode、SAME_EDGE mode、SAME_EDGE_PIPELINED mode。时序图如下图所示:

                                                图3 OPPOSITE_EDGE mode模式

                                                        图4 SAME_EDGE mode模式

                                          图5 SAME_EDGE_PIPELINED mode模式

        本设计以太网采用第一种模式,如下图所示为rgmii接收端FPGA代码驱动:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2024/07/22 16:11:10
// Design Name: 
// Module Name: rgmii_2_gmii_rx
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module rgmii_2_gmii_rx(
	input              idelay_clk  ,
    input              rgmii_rxc   , //RGMII接收时钟
    (* MARK_DEBUG="true" *)input              rgmii_rx_ctl, //RGMII接收数据控制信号
    (* MARK_DEBUG="true" *)input       [3:0]  rgmii_rxd   , //RGMII接收数据
	
    output             gmii_rx_clk , //GMII接收时钟
    (* MARK_DEBUG="true" *)output             gmii_rx_dv  , //GMII接收数据有效信号
    (* MARK_DEBUG="true" *)output      [7:0]  gmii_rxd    	 //GMII接收数据
	
	
	
    );

	
wire[3:0] rgmii_rxd_delay;
wire rgmii_rx_ctl_delay;	
wire rgmii_clk;
wire rgmii_rxc_io;

wire[3:0] rx_data_rise;
wire[3:0] rx_data_neg;

wire rgmii_rx_ctl_delay_rise;
wire rgmii_rx_ctl_delay_neg;

assign gmii_rx_clk = rgmii_clk;
assign gmii_rx_dv = rgmii_rx_ctl_delay_rise & rgmii_rx_ctl_delay_neg;
assign gmii_rxd = {rx_data_neg,rx_data_rise};



IDDR 2 BUFIO	BUFIO 在采集源同步 IO 数据时,提供非常小的延时
WORK 2 BUFG

//全局时钟缓存
BUFG BUFG_inst (
  .I            (rgmii_rxc),     // 1-bit input: Clock input
  .O            (rgmii_clk) // 1-bit output: Clock output
);

//全局时钟IO缓存
BUFIO BUFIO_inst (
  .I            (rgmii_rxc),      // 1-bit input: Clock input
  .O            (rgmii_rxc_io) // 1-bit output: Clock output
);




		
	
IDELAYCTRL	IDELAYCTRL_inst (
      .RDY(),       // 1-bit output: Ready output
      .REFCLK(idelay_clk), // 1-bit input: Reference clock input
      .RST(1'b0)        // 1-bit input: Active high reset input
   );	
	

genvar i;
generate 
	for	(i = 0; i < 4; i = i + 1)begin
		IDELAYE2 #(
		.CINVCTRL_SEL("FALSE"),          // Enable dynamic clock inversion (FALSE, TRUE)
		.DELAY_SRC("IDATAIN"),           // Delay input (IDATAIN, DATAIN)
		.HIGH_PERFORMANCE_MODE("FALSE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE")
		.IDELAY_TYPE("FIXED"),           // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
		.IDELAY_VALUE(15),                // Input delay tap setting (0-31)
		.PIPE_SEL("FALSE"),              // Select pipelined mode, FALSE, TRUE
		.REFCLK_FREQUENCY(200.0),        // IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0).
		.SIGNAL_PATTERN("DATA")          // DATA, CLOCK input signal
	)
	IDELAYE2_inst0 (
		.CNTVALUEOUT(), // 5-bit output: Counter value output
		.DATAOUT(rgmii_rxd_delay[i]),         // 1-bit output: Delayed data output
		.C(1'b0),                     // 1-bit input: Clock input
		.CE(1'b0),                   // 1-bit input: Active high enable increment/decrement input
		.CINVCTRL(1'b0),       // 1-bit input: Dynamic clock inversion input
		.CNTVALUEIN(1'b0),   // 5-bit input: Counter value input
		.DATAIN(),           // 1-bit input: Internal delay data input
		.IDATAIN(rgmii_rxd[i]),         // 1-bit input: Data input from the I/O
		.INC(1'b0),                 // 1-bit input: Increment / Decrement tap delay input
		.LD(1'b0),                   // 1-bit input: Load IDELAY_VALUE input
		.LDPIPEEN(1'b0),       // 1-bit input: Enable PIPELINE register to load data input
		.REGRST(1'b0)            // 1-bit input: Active-high reset tap-delay input
	);
	end
endgenerate
	
	
	
	IDELAYE2 #(
		.CINVCTRL_SEL("FALSE"),          // Enable dynamic clock inversion (FALSE, TRUE)
		.DELAY_SRC("IDATAIN"),           // Delay input (IDATAIN, DATAIN)
		.HIGH_PERFORMANCE_MODE("FALSE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE")
		.IDELAY_TYPE("FIXED"),           // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
		.IDELAY_VALUE(15),                // Input delay tap setting (0-31)
		.PIPE_SEL("FALSE"),              // Select pipelined mode, FALSE, TRUE
		.REFCLK_FREQUENCY(200.0),        // IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0).
		.SIGNAL_PATTERN("DATA")          // DATA, CLOCK input signal
	)
	IDELAYE2_inst1 (
		.CNTVALUEOUT(), // 5-bit output: Counter value output
		.DATAOUT(rgmii_rx_ctl_delay),         // 1-bit output: Delayed data output
		.C(1'b0),                     // 1-bit input: Clock input
		.CE(1'b0),                   // 1-bit input: Active high enable increment/decrement input
		.CINVCTRL(1'b0),       // 1-bit input: Dynamic clock inversion input
		.CNTVALUEIN(1'b0),   // 5-bit input: Counter value input
		.DATAIN(),           // 1-bit input: Internal delay data input
		.IDATAIN(rgmii_rx_ctl),         // 1-bit input: Data input from the I/O
		.INC(1'b0),                 // 1-bit input: Increment / Decrement tap delay input
		.LD(1'b0),                   // 1-bit input: Load IDELAY_VALUE input
		.LDPIPEEN(1'b0),       // 1-bit input: Enable PIPELINE register to load data input
		.REGRST(1'b0)            // 1-bit input: Active-high reset tap-delay input
	);	
	
	

//IDDR

genvar j;
generate 
	for	(j = 0; j < 4; j = j + 1)begin
		IDDR #(
			.DDR_CLK_EDGE("OPPOSITE_EDGE"), // "OPPOSITE_EDGE", "SAME_EDGE" 
                                      //    or "SAME_EDGE_PIPELINED" 
			.INIT_Q1(1'b0), // Initial value of Q1: 1'b0 or 1'b1
			.INIT_Q2(1'b0), // Initial value of Q2: 1'b0 or 1'b1
			.SRTYPE("SYNC") // Set/Reset type: "SYNC" or "ASYNC" 
		)IDDR_inst0 (
			.Q1(rx_data_rise[j]), // 1-bit output for positive edge of clock
			.Q2(rx_data_neg[j]), // 1-bit output for negative edge of clock
			.C(rgmii_rxc_io),   // 1-bit clock input
			.CE(1'b1), // 1-bit clock enable input
			.D(rgmii_rxd[j]),   // 1-bit DDR data input
			.R(1'b0),   // 1-bit reset
			.S(1'b0)    // 1-bit set
		);
	
	end
endgenerate	
	
	
IDDR #(
	.DDR_CLK_EDGE("OPPOSITE_EDGE"), // "OPPOSITE_EDGE", "SAME_EDGE" 
                              //    or "SAME_EDGE_PIPELINED" 
	.INIT_Q1(1'b0), // Initial value of Q1: 1'b0 or 1'b1
	.INIT_Q2(1'b0), // Initial value of Q2: 1'b0 or 1'b1
	.SRTYPE("SYNC") // Set/Reset type: "SYNC" or "ASYNC" 
)IDDR_inst1 (
	.Q1(rgmii_rx_ctl_delay_rise), // 1-bit output for positive edge of clock
	.Q2(rgmii_rx_ctl_delay_neg), // 1-bit output for negative edge of clock
	.C(rgmii_rxc_io),   // 1-bit clock input
	.CE(1'b1), // 1-bit clock enable input
	.D(rgmii_rx_ctl_delay),   // 1-bit DDR data input
	.R(1'b0),   // 1-bit reset
	.S(1'b0)    // 1-bit set
);	
	
	
	
endmodule




仿真代码如下:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2024/07/22 16:39:53
// Design Name: 
// Module Name: eth_tb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module eth_tb(

    );
	
reg sys_clk;
reg sys_rst_n;
reg eth_clk;
reg eth_rxc;
reg eth_rx_ctl;
reg[3:0] eth_rxd;
reg[7:0] cnt;


always #5 sys_clk = ~sys_clk;
always #4 eth_rxc = ~eth_rxc;
always #2 eth_clk = ~eth_clk;


initial begin
	sys_clk = 'd0;
	eth_rxc = 'd0;
	eth_clk = 'd1;
	
	sys_rst_n = 'd0;
	#2002
	sys_rst_n = 'd1;
	
end	
	
	
always @(posedge eth_clk or negedge sys_rst_n) begin
    if(sys_rst_n == 'd0) begin	
		eth_rx_ctl = 'd0;
		eth_rxd <= 'd0;
		cnt <= 'd0;
	end
	else if(cnt <= 'd11)begin
		eth_rxd <= eth_rxd + 'd1;
		eth_rx_ctl <= 'd1;
		cnt <= cnt + 'd1;		
	end
	else if(cnt <= 'd200)begin
		eth_rxd <= 'd0;
		eth_rx_ctl <= 'd0;
		cnt <= cnt + 'd1;		
	end
	else begin
		cnt <= 'd0;		
	end
end

	
	
top	top_inst(
	.sys_clk(sys_clk),
	.sys_rst_n(sys_rst_n),  
	.eth_rxc(eth_rxc),
	.eth_rx_ctl(eth_rx_ctl),
	.eth_rxd(eth_rxd),
	.eth_txc(eth_txc),
	.eth_tx_ctl(),
	.eth_txd(),
	.eth_rst_n()
    );	
	
	
	
	
	
	
	
endmodule

  如下图所示为为仿真数据

                                                        图6 RGMII接收信号仿真

        紫色的信号是原始信号,黄色是经过IDDR转化后的数据,理论上应该是输出0x21、0x43、0x65、0x87......但实际上通过ILA抓波形数据会反过来,所以这里高低位反了了一遍,目前原因不明。

        通过CMD命令发送“ping”指令,PC端会向板卡发送ARP数据包,如下图所示为FPGA经过ILA抓的实际波形

图7 ILA抓ARP包1

                                                                图8 ILA抓ARP包2

        如上图所示为ARP包,包解析如下:

        55_55_55_55_55_55_55:前导码;

        d5:帧起始界定符,固定值;

        ff_ff_ff_ff_ff_ff:目的MAC,代表广播;

        d4_93_90_24_23_9a:源端MAC地址,这里通过CMD命令查询MAC地址命令为“ipconfig/ all”,x显示如下:

                                                        图9 电脑MAC地址

        源端MAC地址和LIA抓到的值一致。

        08_06:代表ARP包;

        00_01:硬件类型值1;

        08_00:协议类型0800;

        06_04:硬件地址长度和协议地址长度,ARP固定值;

        00_01:代表ARP请求包;

        d4_93_90_24_23_9a:源端MAC地址;

        00_00_00_00:源IP地址,这里为何为0,wireshark抓包是有源IP信息的。

        00_00_00_00_00_00:目的MAC地址,这里为何不是全F?,经过查询,该处对于未知目的MAC,写入的值是全0,Wishare抓取到的目的MAC地址也是全0。

        c0_a8_89_0b:目的IP地址;

        00_......_00:18个00,数据填充位;

        8a_82_da_16:CRC校验位

        根据ARP数据包解析,这里有两个地方和前一章节写的有冲突,分别是源端IP地址为全0,目的MAC地址也为全0。

       

       RGMII接收FPGA驱动代码编写完毕,如有疑问可留言。

        

        

标签:实战篇,FPGA,rx,b0,RGMII,output,input,bit,rgmii
From: https://blog.csdn.net/weixin_51418325/article/details/140637482

相关文章

  • FPGA实验8:PWM信号发生器的设计
    一、实验目的与要求1、熟悉QuartusⅡ软件的基本使用方法;2、熟悉EDA实验开发系统的基本使用方法;3、学习VHDL程序中数据对象、数据类型、顺序语句和并行语句的综合使用。二、实验原理设计并调试好一个脉宽数控调制信号发生器,此信号发生器是由两个完全相同的可自加载加法计......
  • [米联客-安路飞龙DR1-FPSOC] FPGA基础篇连载-05 FPGA流水灯实验
    软件版本:Anlogic-TD5.9.1-DR1_ES1.1操作系统:WIN1064bit硬件平台:适用安路(Anlogic)FPGA实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板板卡获取平台:https://milianke.tmall.com/登录"米联客"FPGA社区http://www.uisrc.com视频课程、答疑解惑!1概述流水灯以及Helloworld实验是......
  • [米联客-安路飞龙DR1-FPSOC] FPGA基础篇连载- [米联客-安路飞龙DR1-FPSOC] FPGA基础篇
    软件版本:Anlogic-TD5.9.1-DR1_ES1.1操作系统:WIN1064bit硬件平台:适用安路(Anlogic)FPGA实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板板卡获取平台:https://milianke.tmall.com/登录"米联客"FPGA社区http://www.uisrc.com视频课程、答疑解惑! 1概述前面实验中我们完成了基......
  • [米联客-安路飞龙DR1-FPSOC] FPGA基础篇连载-03安路TD结合modelsim仿真
    软件版本:Anlogic-TD5.9.1-DR1_ES1.1操作系统:WIN1064bit硬件平台:适用安路(Anlogic)FPGA实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板板卡获取平台:https://milianke.tmall.com/登录"米联客"FPGA社区http://www.uisrc.com视频课程、答疑解惑!1概述FPGA开发中对设计的代码功能......
  • XILINX FPGA Debug 工具ILA和VIO
    原因在需要观测、调试FPGA内部逻辑时,2个工具ILA和VIO是非常有用的工具,ILA是内部逻辑分析仪,用于分析信号抓取波形,VIO是虚拟IO,用于手动修改FPGA内部变量,可以大大方便调试。https://docs.amd.com/r/en-US/ug908-vivado-programming-debuggingILA集成逻辑分析器(ILA)是一项强大的工......
  • 《程序猿学会 Vue · 基础与实战篇》
    ......
  • 实战篇——支付逻辑漏洞portswigger靶场实战
    实战篇——支付逻辑漏洞portswigger靶场实战portswigger是burpsuite的官方在线靶场,内置了大量常见Web漏洞的场景,本章以Businesslogicvulnerabilities一章为例,浅析支付逻辑漏洞。Excessivetrustinclient-sidecontrols点击Addtocart,抓包:将price改成1,发送:成功篡改价......
  • 基于FPGA的秒表计时系统设计--第一版--郝旭帅电子设计团队
    欢迎各位朋友关注“郝旭帅电子设计团队”,本篇为各位朋友介绍基于FPGA的秒表计时系统设计--第一版--郝旭帅电子设计团队。 功能说明:  1.利用六个数码管显示。 2.以10ms为精度显示 3.以秒为单位进行显示 4.记录最大为999.99 5.第一个数码管在运行时不显示......
  • [米联客-安路飞龙DR1-FPSOC] FPGA基础篇连载-02使用安路TD开发工具创建FPGA工程
    软件版本:Anlogic-TD5.9.1-DR1_ES1.1操作系统:WIN1064bit硬件平台:适用安路(Anlogic)FPGA实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板板卡获取平台:https://milianke.tmall.com/登录"米联客"FPGA社区http://www.uisrc.com视频课程、答疑解惑!1概述本实验以FPGA芯片DR1M9......
  • FPGA DNA 获取
    FPGADNADNA是FPGA芯片的唯一标识,FPGA都有一个独特的ID,也就是DeviceDNA,这个ID相当于我们的身份证,在FPGA芯片生产的时候就已经固定在芯片的eFuse寄存器中,具有不可修改的属性。在xilinx7series和7series以前,ID都是57bit的,但是在Xilinx的Ultraslace架构......