62.以太网数据回环实验(5)

news2024/12/23 18:35:48

        (1)UDP顶层模块代码:

module udp
(
    input   wire                gmii_txc        ,
    input   wire                gmii_rxc        ,
    input   wire                reset_n         ,
    input   wire                gmii_rx_dv      ,
    input   wire    [7:0]       gmii_rxd        ,
    input   wire                tx_start_en     ,
    input   wire    [31:0]      tx_data         ,
    input   wire    [15:0]      tx_byte_num     ,
      
    output  wire    [31:0]      rec_data        ,
    output  wire                rec_en          ,
    output  wire                rec_pkt_done    ,
    output  wire                rec_byte_num    ,
    output  wire    [7:0]       gmii_txd        ,
    output  wire                gmii_tx_en      ,
    output  wire                tx_done         ,
    output  wire                tx_req  
    
);

//开发板MAC地址(48位)
parameter BOARO_MAC     =   48'hff_ff_ff_ff_ff_ff   ;
//开发板IP地址(32位)
parameter BOARO_IP      =   {8'd0,8'd0,8'd0,8'd0}   ;
//目的MAC地址(48位)
parameter DES_MAC       =   48'hff_ff_ff_ff_ff_ff   ;
//目的IP地址(32位)
parameter DES_IP        =   {8'd0,8'd0,8'd0,8'd0}   ;

wire    [31:0]      crc_data    ;
wire    [31:0]      crc_next    ;
wire                crc_en      ;
wire                crc_clr     ;

defparam udp_rx_inst.BOARO_MAC = BOARO_MAC;
defparam udp_rx_inst.BOARO_IP  = BOARO_IP;
defparam udp_tx_inst.BOARO_MAC = BOARO_MAC;
defparam udp_tx_inst.BOARO_IP  = BOARO_IP;
defparam udp_tx_inst.DES_MAC   = DES_MAC;
defparam udp_tx_inst.DES_IP    = DES_IP;

udp_rx  udp_rx_inst(

    .gmii_rxc            (gmii_rxc       ),
    .reset_n             (reset_n        ),
    .gmii_rx_dv          (gmii_rx_dv     ),   
    .gmii_rxd            (gmii_rxd       ),   
    .rec_data            (rec_data       ),   
    .rec_en              (rec_en         ),   
    .rec_pkt_done        (rec_pkt_done   ),   
    .rec_byte_num        (rec_byte_num   )    

);

udp_tx  udp_tx_inst
(
    .gmii_txc    (gmii_txc          ),
    .reset_n     (reset_n           ),
    .tx_start_en (tx_start_en       ),       
    .tx_data     (tx_data           ),       
    .tx_byte_num (tx_byte_num       ),       
    .crc_data    (crc_data          ),       
    .crc_next    (crc_next[31:24]   ),       

    .gmii_txd    (gmii_txd          ),       
    .gmii_tx_en  (gmii_tx_en        ),       
    .tx_done     (tx_done           ),       
    .tx_req      (tx_req            ),       
    .crc_en      (crc_en            ),       
    .crc_clr     (crc_clr           )        
);

crc32_d8 crc32_d8_inst
(
    .gmii_txc      (gmii_txc        ),  
    .reset_n       (reset_n         ),  
    .data          (gmii_txd        ),  
    .crc_en        (crc_en          ),  
    .crc_clr       (crc_clr         ),  
    .crc_data      (crc_data        ),  
    .crc_next      (crc_next        )   
);

endmodule

        (2)RTL视图:

        (3)转换模块调用源语过程:

        (4)gmii转rgmii代码:

module rgmii_tx
(
    input   wire            gmii_txc    ,
    input   wire    [7:0]   gmii_txd    ,
    input   wire            gmii_tx_en  ,

    output  wire            rgmii_txc   ,
    output  wire    [3:0]   rgmii_txd   ,
    output  wire            rgmii_tx_ctl
);

assign rgmii_txc = gmii_txc ;

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_tx_inst (
      .Q    (rgmii_tx_ctl       ),   // 1-bit DDR output
      .C    (gmii_txc           ),   // 1-bit clock input
      .CE   (1'd1               ), // 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'd0               ),   // 1-bit reset
      .S    (1'd0               )    // 1-bit set
);

genvar i;

generate for(i=0;i<4;i=i+1)

begin:  tx_data_bus

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_tx_inst_ctl (
      .Q    (rgmii_txd[i]       ),   // 1-bit DDR output
      .C    (gmii_txc           ),   // 1-bit clock input
      .CE   (1'd1               ), // 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'd0               ),   // 1-bit reset
      .S    (1'd0               )    // 1-bit set
);

end
endgenerate

endmodule
module rgmii_rx
(
    input   wire    [3:0]   rgmii_rxd       ,
    input   wire            rgmii_rxc       ,
    input   wire            rgmii_rx_ctl    ,
        
    output  wire            gmii_rxc        ,
    output  wire    [7:0]   gmii_rxd        ,
    output  wire            gmii_rx_ctl
);

wire    [1:0]   gmii_rx_ctl_t   ;

assign gmii_rx_ctl = gmii_rx_ctl_t[0] & gmii_rx_ctl_t[1]  ;

assign gmii_rxc  = rgmii_rxc    ;

IDDR #(
      .DDR_CLK_EDGE("SAME_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_rx_inst (
      .Q1       (gmii_rx_ctl_t[0]   ), // 1-bit output for positive edge of clock
      .Q2       (gmii_rx_ctl_t[1]   ), // 1-bit output for negative edge of clock
      .C        (gmii_rxc           ),   // 1-bit clock input
      .CE       (1'd1               ), // 1-bit clock enable input
      .D        (rgmii_rx_ctl       ),   // 1-bit DDR data input
      .R        (1'd0               ),   // 1-bit reset
      .S        (1'd0               )    // 1-bit set
);

genvar i;

generate for(i=0;i<4;i=i+1)

begin:  rx_data_bus
IDDR #(
      .DDR_CLK_EDGE("SAME_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_rx_inst_ctl (
      .Q1       (gmii_rxd[4+i]      ), // 1-bit output for positive edge of clock
      .Q2       (gmii_rxd[i]        ), // 1-bit output for negative edge of clock
      .C        (gmii_rxc           ),   // 1-bit clock input
      .CE       (1'd1               ), // 1-bit clock enable input
      .D        (rgmii_rxd[i]       ),   // 1-bit DDR data input
      .R        (1'd0               ),   // 1-bit reset
      .S        (1'd0               )    // 1-bit set
);
end
endgenerate

endmodule
module gmii_to_rgmii
(
    input   wire    [7:0]   gmii_txd    ,
    input   wire            gmii_tx_en  ,
    input   wire    [3:0]   rgmii_rxd   ,
    input   wire            rgmii_rx_ctl,
    input   wire            rgmii_rxc   ,
    
    output  wire            gmii_txc    ,
    output  wire            gmii_rxc    ,
    output  wire    [7:0]   gmii_rxd    ,
    output  wire            gmii_rx_ctl ,
    output  wire    [3:0]   rgmii_txd   ,
    output  wire            rgmii_tx_ctl,
    output  wire            rgmii_txc   
);

assign gmii_txc =  gmii_rxc;

rgmii_rx rgmii_rx_inst
(
    .rgmii_rxd       (rgmii_rxd     ),
    .rgmii_rxc       (rgmii_rxc     ),
    .rgmii_rx_ctl    (rgmii_rx_ctl  ),

    .gmii_rxc        (gmii_rxc      ),
    .gmii_rxd        (gmii_rxd      ),
    .gmii_rx_ctl     (gmii_rx_ctl   )
);

rgmii_tx rgmii_tx_inst
(
    .gmii_txc       (gmii_txc       ),
    .gmii_txd       (gmii_txd       ),
    .gmii_tx_en     (gmii_tx_en     ),
    
    .rgmii_txc      (rgmii_txc      ),
    .rgmii_txd      (rgmii_txd      ),
    .rgmii_tx_ctl   (rgmii_tx_ctl   )
);

endmodule

        (5)顶层模块:

module eth_udp_loop
(
    input   wire                clk         ,
    input   wire                reset_n     ,
    input   wire                eth_rxc     ,
    input   wire    [3:0]       eth_rxd     ,
    input   wire                eth_rx_ctl  ,

    output  wire                eth_txc     ,
    output  wire    [3:0]       eth_txd     ,
    output  wire                eth_tx_ctl  ,
    output  wire                eth_reset_n    
);

wire                    clk_phase       ;
wire    [7:0]           gmii_txd        ; 
wire                    gmii_tx_en      ;
wire                    gmii_txc        ;
wire                    gmii_rxc        ;
wire    [7:0]           gmii_rxd        ;
wire                    gmii_rx_ctl     ;
wire                    rec_pkt_done    ;
wire    [31:0]          tx_data         ;
wire    [15:0]          rec_byte_num    ;
wire    [31:0]          rec_data        ;
wire                    rec_en          ;
wire                    tx_done         ;
wire                    tx_req          ;

assign eth_reset_n = 1'd1;

clk_phase clk_phase_inst
(
    .clkout (clk_phase  ),      // output clkout
    .reset  (~reset_n   ),      // input reset
    .locked (           ),      // output locked
    .clkin  (eth_rxc    )       // input clkin
);  

fifo fifo_inst (
    .clk        (gmii_rxc   ),      // input wire clk
    .srst       (~reset_n   ),      // input wire srst
    .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
);
   
    
gmii_to_rgmii   gmii_to_rgmii_inst
(
    .gmii_txd    (gmii_txd      ),
    .gmii_tx_en  (gmii_tx_en    ),
    .rgmii_rxd   (eth_rxd       ),
    .rgmii_rx_ctl(eth_rx_ctl    ),
    .rgmii_rxc   (clk_phase     ),

    .gmii_txc    (gmii_txc      ),
    .gmii_rxc    (gmii_rxc      ),
    .gmii_rxd    (gmii_rxd      ),
    .gmii_rx_ctl (gmii_rx_ctl   ),
    .rgmii_txd   (eth_txd       ),
    .rgmii_tx_ctl(eth_tx_ctl    ),
    .rgmii_txc   (eth_txc       )
);      

defparam udp_inst.BOARO_MAC = 48'h12_34_56_78_9a_bc   ;
defparam udp_inst.BOARO_IP  = {8'd192,8'd168,8'd0,8'd234};
defparam udp_inst.DES_MAC   = 48'hff_ff_ff_ff_ff_ff;
defparam udp_inst.DES_IP    = {8'd192,8'd168,8'd0,8'd145};

udp udp_inst
(
    .gmii_txc        (gmii_txc      ),
    .gmii_rxc        (gmii_rxc      ),
    .reset_n         (reset_n       ),
    .gmii_rx_dv      (gmii_rx_ctl   ),
    .gmii_rxd        (gmii_rxd      ),
    .tx_start_en     (rec_pkt_done  ),
    .tx_data         (tx_data       ),
    .tx_byte_num     (rec_byte_num  ),

    .rec_data        (rec_data      ),
    .rec_en          (rec_en        ),
    .rec_pkt_done    (rec_pkt_done  ),
    .rec_byte_num    (rec_byte_num  ),
    .gmii_txd        (gmii_txd      ),
    .gmii_tx_en      (gmii_tx_en    ),
    .tx_done         (tx_done       ),
    .tx_req          (tx_req        )   
    
);         


endmodule

        (6)仿真代码及波形:

`timescale 1ns / 1ps

module tb_eth_udp_loop;

reg             clk             ;   //50MHz
reg             eth_rxc         ;   //125MHz
reg             eth_rxc_x2      ;   //250MHz
reg             reset_n         ;
reg             start_flag      ;   //数据输入开始标志信号
reg             eth_rx_ctl      ;
reg     [11:0]  cnt_data        ;   //数据包字节计数器
reg     [655:0] data_mem        ;   //82 * 8 =656 

wire    [3:0]   eth_rxd         ;
wire            eth_reset_n     ;
wire    [3:0]   eth_txd         ;
wire            eth_tx_ctl      ;
wire            eth_txc         ;

initial clk = 1'd1;
always#10 clk = ~clk;

initial eth_rxc = 1'd1;
always#4 eth_rxc = ~eth_rxc;

initial eth_rxc_x2 = 1'd1;
always#2 eth_rxc_x2 = ~eth_rxc_x2;

initial begin
    reset_n <= 1'd0;
    start_flag <= 1'd0;
    #200;
    reset_n <= 1'd1;
    #100;
    start_flag <= 1'd1;
    #50;
    start_flag <= 1'd0;
    #6000;
    $stop;
end

//data_mem
always@(negedge eth_rxc_x2 or negedge reset_n)
    if(reset_n == 1'b0)
        data_mem    <=  'hFE_DC_BA_98_76_54_32_10_FE_DC_BA_98_76_54_32_10_FE_DC_BA_98_76_54_32_10_FE_DC_BA_98_76_54_32_10_00_00_28_00_D2_04_D2_04_EA_00_A8_C0_91_00_A8_C0_00_00_11_80_00_00_00_5F_3C_00_00_45_00_08_2D_DB_4A_5E_D5_E0_BC_9A_78_56_34_12_D5_55_55_55_55_55_55_55;
    else    if(eth_rx_ctl == 1'b1)
        data_mem    <=  data_mem >> 4;
    else
        data_mem    <=  data_mem;

always@(posedge eth_rxc_x2 or negedge reset_n)
    if(!reset_n)
        cnt_data <= 12'd0;
    else if(eth_rx_ctl)
        cnt_data <= cnt_data + 12'd1;
    else 
        cnt_data <= cnt_data;
        
always@(posedge eth_rxc_x2 or negedge reset_n)
    if(!reset_n)
        eth_rx_ctl <= 1'd0;
    else if(cnt_data == 12'd163)      //86个字母减去4个验证字节,x2 = 164 164-1=163
        eth_rx_ctl <= 1'd0;
    else if(start_flag)
        eth_rx_ctl <= 1'd1;
    else 
        eth_rx_ctl <= eth_rx_ctl;

assign  eth_rxd =  eth_rx_ctl ? data_mem[3:0]: 4'd0;

eth_udp_loop    eth_udp_loop_inst
(
    .clk         (clk       ),
    .reset_n     (reset_n   ),
    .eth_rxc     (eth_rxc   ),
    .eth_rxd     (eth_rxd   ),
    .eth_rx_ctl  (eth_rx_ctl),

    .eth_txc     (eth_txc),
    .eth_txd     (eth_txd   ),
    .eth_tx_ctl  (eth_tx_ctl),
    .eth_reset_n (eth_reset_n)   
);

endmodule

(7)实验现象:

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

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

相关文章

使用FastJson2将对象转成JSON字符串时,小数转换出错

maven坐标 <dependency> <groupId>com.alibaba.fastjson2</groupId> <artifactId>fastjson2</artifactId> <version>2.0.40</version> </dependency> 问题现象&#xff1a; 问题原因&#xff1a; IOUtils.write…

RabbitMQ 高级特性——消息确认

文章目录 前言消息确认机制SpringBoot 实现消息确认NONEAUTOMANUAL 前言 前面我们学习了 SpringBoot 整合 RabbitMQ&#xff0c;并且使用 RabbitMQ 实现了几种工作模式&#xff0c;接下来我们将学习关于 RabbitMQ 的高级特性——消息确认机制&#xff0c;持久化和发送方确认。…

99.WEB渗透测试-信息收集-网络空间搜索引擎shodan(1)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;98.WEB渗透测试-信息收集-Google语法&#xff08;12&#xff09; 信息收集方向-网络空间…

探索全球实时云渲染与XR技术的多平台兼容性:谁是行业引领者?

在扩展现实&#xff08;XR&#xff09;技术与实时云渲染技术的飞速发展中&#xff0c;多平台兼容性已经成为行业技术竞争的关键要素。能够在不同的平台和设备上高效运行的解决方案&#xff0c;不仅关系到开发效率和场景多样性&#xff0c;还直接影响到用户体验和市场占有率。Pa…

续航和性能好的随身WiFi怎么选?一篇文章告诉你哪个随身WiFi值得买,格行vs华为vs中兴vs飞猫vs闪鱼

各大购物平台的大促已经开始&#xff0c;还在纠结入手哪个随身WiFi的小伙伴&#xff0c;小编今天用一篇文章告诉你哪款随身WiFi值得买 一、格行&#xff1a;成立于2009年&#xff0c;有15年的行业经验&#xff0c;是随身WiFi、物联网行业的巨头&#xff0c;销量持续保持领先&am…

活用c4d官方开发文档查询代码

当你问AI助手比如豆包&#xff0c;如何用python禁止掉xpresso标签时候&#xff0c;它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

码上进阶_刷题模块测试_用例设计

码上进阶_刷题模块测试_用例设计 系统概述&#xff1a; 码上进阶是为程序员专门打造的交流平台&#xff0c;采用主流的微服务框架和C端技术栈作为技术基础。在这个平台上&#xff0c;程序员 可以通过刷题、练习和模拟面试来提升自己的面试能力。 功能测试&#xff1a; 登录…

机器人领域超重量奖项TRO傅京孙最佳论文奖汇总【上】

更多优质内容&#xff0c;请关注公众号&#xff1a;智驾机器人技术前线 简介 IEEE Transactions on Robotics King-Sun Fu Memorial Best Paper Award这个奖项是为了表彰每年在《IEEE Transactions on Robotics》上发表的最佳论文。 以下是该奖项的一些信息&#xff1a; 奖项…

2025通信硕士找工作纪实

通信算法工程师秋招基本情况 读博难 国内读博难&#xff1a;华五以上&#xff0c;信息与通信工程专业&#xff0c;基本无普博hc&#xff0c;都是直博。偶尔有一些招普博的老师&#xff0c;是许久不科研&#xff0c;或者来了都去做横向。唯一可能的普博机会&#xff0c;是找刚入…

1.1 半导体基础知识

文章目录 半导体的特点本征半导体本征激发 杂质半导体N型半导体&#xff08;电子型&#xff09;电离施主杂质&#xff1a;多子少子 P型半导体&#xff08;空穴型&#xff09;电离受主杂质&#xff1a;多子少子 杂质半导体的示意图 PN结1、 PN 结中载流子的运动&#xff08;1&am…

苏茵茵:以时尚之名,诠释品质生活

在女性追求个性化与自我表达的今天&#xff0c;时尚早已超越了简单的穿着打扮&#xff0c;它成为女性展现自我风格、彰显独特魅力的重要方式。从广泛的兴趣爱好到精心雕琢的个人风格&#xff0c;每一处细节都闪耀着女性对个性独特与自我表达的深切渴望。正是这股不可阻挡的潮流…

《深度学习》OpenCV 模版匹配多个对象、图片旋转 综合应用

目录 一、模板匹配 1、什么是模版匹配 2、原理 3、应用领域 4、案例实现 1&#xff09;模版图片和输入图片信息 2&#xff09;代码实现 运行结果&#xff1a; 二、图像旋转 1、使用numpy方法 运行结果&#xff1a; &#xff08;图片来源网络&#xff0c;如有侵权敬…

ORBSLAM2三维重建后上下颠倒

调整 Z 坐标的符号&#xff0c;将d改为-d 引用文献 https://blog.csdn.net/qq_42450767/article/details/114144439

【技术调研】三维(1)-ThreeJs-基础常识及第一个程序

前言 ​ 公司有网页三维以及客户端、vr三维相关项目机会,需要对相关技术进行调研,进行项目可行性评估和大致成本评估。基于此对三维一些内容进行调研。 什么是three.js ​ Three.js是一款基于原生WebGL封装通用Web 3D引擎。由于前文已经了解过webGL,知道通过webGL的API我…

人工智能技术导论——基于产生式规则的机器推理

在引出本章的内容之前先介绍一个概念 知识 知识的概念 知识&#xff08;Knowledge&#xff09;是人们在改造客观世界的实践中形成的对客观事物&#xff08;包括自然的和人造的&#xff09;及其规律的认识&#xff0c;包括对事物的现象、本质、状态、关系、联系和运动等的认识…

大数据技术体系架构

数据源 社交媒体平台 云平台 网站资源 物联网&#xff08;IOT&#xff09; 数据库 特点 分布式 数据源一般分布在不同的设备上&#xff0c;这些设备通常由网络连接在一起&#xff0c;网络空间的安全及其重要&#xff1b; 异构性 数据的来源广泛&#xff0c;比如社交媒…

Qt常用控件——QRadioButton和QCheckBox

文章目录 QRadioButtonQAbstractButton信号实现简单的点餐页面QCheckBox QRadioButton QRadioButton是单选按钮&#xff0c;可以让我们在多个选项当中选择一个 作为QAbstractButton和QWidget的子类&#xff0c;它们的属性和语法&#xff0c;对于QRadioButton同样适用 QAbstrac…

springboot+vue+mybatis计算机毕业设计医护系统的设计与实现+PPT+论文+讲解+售后

近些年来&#xff0c;随着科技的飞速发展&#xff0c;互联网的普及逐渐延伸到各行各业中&#xff0c;给人们生活带来了十分的便利&#xff0c;医护系统的设计与实现利用计算机网络实现信息化管理&#xff0c;使整个医护系统的发展和服务水平有显著提升。 本文拟采用Eclipse开发…

【尚跑】2024陕西淳化天然氧吧半程马拉松赛149顺利完赛

1、赛事背景 奔跑美丽淳化&#xff0c;畅游天然氧吧。9月8日上午&#xff0c;2024淳化天然氧吧半程马拉松赛在淳化县润镇东街鸣枪开跑&#xff0c;4000名马拉松爱好者相聚美丽淳化&#xff0c;赏荞麦花海、闻硕果飘香&#xff0c;共同开启这场挑战自我、超越极限的奔跑之旅 本次…

EasyRecovery破解版下载无需注册,easyrecovery数据恢复软件免费版激活码密钥

EasyRecovery易恢复是一款功能强大的数据恢复软件&#xff0c;为无数人群解决了数据丢失的烦恼&#xff0c;为工作生活带去了便捷。无数使用者在使用过后&#xff0c;都肯定了其强大的数据恢复功能。具体来说&#xff0c;EasyRecovery易恢复可以恢复多方面的数据&#xff0c;Ea…