当前位置: 首页 > news >正文

FPGA 37 ,FPGA千兆以太网设计实战:RGMII接口时序实现全解析( RGMII接口时序设计,RGMII~GMII,GMII~RGMII 接口转换 )

目录

前言
一、设计流程
1.1 需求理解
1.2 模块划分
1.3 测试验证
二、模块分工
2.1 RGMII→GMII(接收方向,rgmii_rx 模块)
2.2 GMII→RGMII(发送方向,rgmii_tx 模块)
三、代码实现
3.1 顶层模块 rgmii_to_gmii
3.2 接收模块 rgmii_rx
3.3 发送模块 rgmii_tx
3.4 测试平台模块 tb
四、逻辑分析
4.1 双向转换的关键逻辑实现
4.2 双向转换逻辑的逻辑验证
五、注意事项
5.1 时钟处理
5.2 数据转换
5.3 测试验证
六、本文总结
七、更多操作

前言

在现代网络通信系统中,为了减少引脚数量并提高传输速率,RGMII 被广泛应用。在 FPGA 开发中,RGMII 和 GMII 是常见的网络接口标准。RGMII 接口具有信号线少、传输效率高的特点,而 GMII 接口则相对更易于理解和处理。在实际应用中,如与传统设备兼容时,常常需要在这两种接口之间进行数据转换。这里将详细介绍 RGMII 到 GMII 接口转换的设计流程、代码实现以及注意事项。

RGMII(Reduced Gigabit Media Independent Interface):简化的千兆媒体独立接口

GMII(Gigabit Media Independent Interface):千兆介质专用接口

更多 GMII RGMII 解析,请看

FPGA 32 ,以太网TCP/IP四层模型:从MII到RGMII的深度解析https://blog.csdn.net/weixin_65793170/article/details/146006143?spm=1001.2014.3001.5501

一、设计流程

1.1 需求理解

在进行接口转换设计之前,需要明确 RGMII 和 GMII 接口的特点和差异。RGMII 接口采用双沿数据传输,而 GMII 接口采用单沿数据传输。因此,设计的核心是实现双沿数据和单沿数据之间的转换。

1.2 模块划分

根据功能需求,将整个设计划分为三个主要模块:

  1. 顶层模块 rgmii_to_gmii
  2. 接收模块 rgmii_rx 
  3. 发送模块 rgmii_tx

顶层模块负责连接各个子模块,接收模块将 RGMII 的双沿数据转换为 GMII 的单沿数据,发送模块将 GMII 的单沿数据转换为 RGMII 的双沿数据。

1.3 测试验证

设计完成后,需要编写测试平台对整个系统进行功能验证,确保接口转换的正确性。最后,通过tb(Test Bench)模块,对设计模块(如 rgmii_to_gmii)进行功能验证,确保接口转换的逻辑正确性。


二、模块分工

各模块核心作用:

模块转换方向核心功能
rgmii_to_gmii双向(RGMII↔GMII)顶层整合模块,实例化 rgmii_rx 和 rgmii_tx,实现 RGMII 与 GMII 接口的双向转换:
- 连接 RGMII 侧(PHY)与 GMII 侧(MAC)的时钟、数据、控制信号
- 传递接收方向(RGMII→GMII)和发送方向(GMII→RGMII)的数据流
- 统一管理时钟同步(如将 GMII 时钟映射为 RGMII 发送时钟)
rgmii_rxRGMII → GMII(接收)将 RGMII 的双沿数据(4 位,上下沿各 2 位)和控制信号转换为 GMII 的单沿数据(8 位,仅上升沿有效):
- 利用 IDDR 原语提取时钟双沿的信号
- 时钟处理(BUFIO/BUFG)确保 GMII 时钟质量
- 控制信号转换(双沿有效 → 单沿使能)
rgmii_txGMII → RGMII(发送)将 GMII 的单沿数据(8 位,仅上升沿有效)和控制信号转换为 RGMII 的双沿数据(4 位,上下沿各 2 位):
- 利用 ODDR 原语生成双沿数据和控制信号
- 时钟同步(直接复用 GMII 时钟作为 RGMII 发送时钟)
tb(Test Bench)无(测试验证)测试平台模块,不参与实际接口转换,仅用于仿真验证:
- 生成时钟激励(125MHz,50% 占空比)
- 驱动输入信号(RGMII 接收数据、GMII 发送数据)递增变化
- 验证输出信号是否符合双向转换逻辑(如双沿数据拼接 / 拆分的正确性)

双向转换的核心模块:

模块转换方向核心功能
rgmii_rxRGMII → GMII(接收)将 RGMII 的双沿数据(4 位,上下沿各 2 位)和控制信号转换为 GMII 的单沿数据(8 位,仅上升沿有效)。
rgmii_txGMII → RGMII(发送)将 GMII 的单沿数据(8 位,仅上升沿有效)和控制信号转换为 RGMII 的双沿数据(4 位,上下沿各 2 位)。

2.1 RGMII→GMII(接收方向,rgmii_rx 模块)

  • 输入(RGMII 侧)
    • 时钟 rgmii_rxc(PHY 提供,双沿同步)
    • 双沿数据 rgmii_rxd[3:0](上升沿传高 2 位 [3:2],下降沿传低 2 位 [1:0]
    • 控制信号 rgmii_rx_ctrl(RXDV 和 RXER 的异或,双沿有效)
  • 输出(GMII 侧)
    • 时钟 gmii_rxc(经时钟缓冲处理,供 GMII 使用)
    • 单沿数据 gmii_rxd[7:0]rgmii_rxd 双沿数据拼接:上升沿数据放低 4 位,下降沿数据放高 4 位?需结合代码逻辑,实际代码中IDDR的 Q1 对应上升沿,Q2 对应下降沿,拼接为[i][4+i],即 0-3 位为上升沿采样,4-7 位为下降沿采样)
    • 使能信号 gmii_rx_en(由双沿控制信号相与生成,确保数据有效时持续高电平)

2.2 GMII→RGMII(发送方向,rgmii_tx 模块)

  • 输入(GMII 侧)
    • 时钟 gmii_txc(FPGA 内部时钟,125MHz,单沿驱动)
    • 单沿数据 gmii_tx_data[7:0](仅上升沿有效,高 4 位和低 4 位分别对应 RGMII 双沿的上下沿)
    • 使能信号 gmii_tx_en(单沿有效,控制数据发送)
  • 输出(RGMII 侧)
    • 时钟 rgmii_txc(与gmii_txc同频,供 PHY 使用)
    • 双沿数据 rgmii_data[3:0]gmii_tx_data 高 4 位 [7:4] 对应上升沿,低 4 位 [3:0] 对应下降沿,通过ODDR双沿输出)
    • 控制信号 rgmii_tx_ctrl(由gmii_tx_en 双沿驱动,确保上下沿数据均有效)

125M的时钟,一个时钟8ns,4ns反转一次就可以。


三、代码实现

3.1 顶层模块 rgmii_to_gmii

`timescale 1ns / 1ps
module rgmii_to_gmii(//rgmii接口input  wire       rgmii_rxc     ,//由phy提供的时钟input  wire       rgmii_rx_ctrl ,//由en和error的异或值组成input  wire [3:0] rgmii_rxd     ,//由phy芯片提供的双沿数据output wire       rgmii_txc     ,//发送给phy芯片的时钟output wire       rgmii_tx_ctrl ,//由en、error的异或值组成output wire [3:0] rgmii_data    ,//双沿数据//gmii接口output wire       gmii_txc     ,//fpga的时钟,125Mhz,可以用phy提供的时钟,需要做约束处理input  wire       gmii_tx_en   ,//使能---高有效input  wire [7:0] gmii_tx_data ,//单沿数据output wire       gmii_rxc     ,//经过buf处理后的时钟output wire       gmii_rx_en   ,//使能信号output wire [7:0] gmii_rxd      //经过单双沿源语处理后的单沿数据);// 将gmii_txc赋值为gmii_rxcassign gmii_txc = gmii_rxc;// 实例化接收模块rgmii_rx rgmii_rx_u(. rgmii_rxc    (rgmii_rxc    ) ,//由phy提供的时钟. rgmii_rx_ctrl(rgmii_rx_ctrl) ,//由en和error的异或值组成. rgmii_rxd    (rgmii_rxd    ) ,//由phy芯片提供的双沿数据. gmii_rxc     (gmii_rxc     ) ,//经过buf处理后的时钟. gmii_rx_en   (gmii_rx_en   ) ,//使能信号. gmii_rxd     (gmii_rxd     )  //经过单双沿源语处理后的单沿数据);// 实例化发送模块rgmii_tx rgmii_tx_u(. gmii_txc     (gmii_txc     ),//fpga的时钟,125Mhz,可以用phy提供的时钟,需要做约束处理. gmii_tx_en   (gmii_tx_en   ),//使能---高有效. gmii_tx_data (gmii_tx_data ),//单沿数据. rgmii_txc    (rgmii_txc    ),//发送给phy芯片的时钟. rgmii_tx_ctrl(rgmii_tx_ctrl),//由en、error的异或值组成. rgmii_data   (rgmii_data   ) //双沿数据);
endmodule

逻辑实现流程

  • 首先将 gmii_txc 赋值为 gmii_rxc,确保两者时钟一致。
  • 实例化 rgmii_rx 模块,将 RGMII 接口的接收数据传递给该模块进行处理。
  • 实例化 rgmii_tx 模块,将 GMII 接口的发送数据传递给该模块进行处理。

此模块负责整合接收和发送功能。

3.2 接收模块 rgmii_rx

`timescale 1ns / 1ps
//gmii to rgmii----双沿转单沿数据
module rgmii_rx(input  wire       rgmii_rxc     ,//由phy提供的时钟input  wire       rgmii_rx_ctrl ,//由en和error的异或值组成input  wire [3:0] rgmii_rxd     ,//由phy芯片提供的双沿数据output wire       gmii_rxc      ,//经过buf处理后的时钟output wire       gmii_rx_en    ,//使能信号output wire [7:0] gmii_rxd       //经过单双沿源语处理后的单沿数据);wire [1:0] gmii_rx_ctrl;//寄存rgmii_rx_ctrl双沿的数据//----------时钟处理wire rgmii_rxc_bufio;//经过io时钟资源的输入时钟wire rgmii_rxc_bufg  ;//经过全局时钟网络资源的输入时钟// 将gmii_rxc赋值为经过全局时钟网络资源处理后的时钟assign gmii_rxc = rgmii_rxc_bufg;// 使用BUFIO原语处理输入时钟BUFIO BUFIO_inst (.O(rgmii_rxc_bufio), // 1-bit output: Clock output (connect to I/O clock loads)..I(rgmii_rxc)  // 1-bit input: Clock input (connect to an IBUF or BUFMR).);// 使用BUFG原语处理输入时钟BUFG BUFG_inst (.O(rgmii_rxc_bufg), // 1-bit output: Clock output.I(rgmii_rxc)  // 1-bit input: Clock input);//--------ctrl的双单沿转换// 将gmii_rx_en赋值为gmii_rx_ctrl的两个位相与的结果assign gmii_rx_en = gmii_rx_ctrl [0] & gmii_rx_ctrl[1];// 使用IDDR原语进行控制信号的双单沿转换IDDR #(.DDR_CLK_EDGE("SAME_EDGE_PIPELINED"), // "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_inst_rx_ctrl (.Q1(gmii_rx_ctrl[0]), // 1-bit output for positive edge of clock.Q2(gmii_rx_ctrl[1]), // 1-bit output for negative edge of clock.C(rgmii_rxc_bufio),   // 1-bit clock input.CE(1'b1), // 1-bit clock enable input.D(rgmii_rx_ctrl),   // 1-bit DDR data input.R(1'b0),   // 1-bit reset.S(1'b0)    // 1-bit set);//----------数据的双单沿转换genvar i;// 使用generate语句进行数据的双单沿转换generatefor (i = 0;i < 4 ;i = i + 1 ) begin:iddr_rxdIDDR #(.DDR_CLK_EDGE("SAME_EDGE_PIPELINED"), // "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_inst_rxd (.Q1(gmii_rxd[i]), // 1-bit output for positive edge of clock.Q2(gmii_rxd[4 + i]), // 1-bit output for negative edge of clock.C(rgmii_rxc_bufio),   // 1-bit clock input.CE(1'b1), // 1-bit clock enable input.D(rgmii_rxd[i]),   // 1-bit DDR data input.R(1'b0),   // 1-bit reset.S(1'b0)    // 1-bit set); endendgenerate
endmodule

逻辑实现流程

  • 时钟处理:使用 BUFIO 和 BUFG 原语对输入时钟 rgmii_rxc 进行处理,确保时钟信号的质量,并将处理后的时钟输出给 gmii_rxc
  • 控制信号转换:使用 IDDR 原语在时钟的上升沿和下降沿分别采集 rgmii_rx_ctrl 的值,将这两个值存储在 gmii_rx_ctrl 中,然后将 gmii_rx_ctrl 的两个位相与得到 gmii_rx_en
  • 数据转换:使用 generate 语句和 IDDR 原语将 rgmii_rxd 的双沿数据转换为 gmii_rxd 的单沿数据。

3.3 发送模块 rgmii_tx

`timescale 1ns / 1ps
//GMII to RGMII---单沿转双沿数据
module rgmii_tx(input  wire         gmii_txc     ,//fpga的时钟,125Mhz,可以用phy提供的时钟,需要做约束处理input  wire         gmii_tx_en   ,//使能---高有效input  wire [7:0]   gmii_tx_data ,//单沿数据output wire         rgmii_txc    ,//发送给phy芯片的时钟output wire         rgmii_tx_ctrl,//由en、error的异或值组成output wire [3:0]   rgmii_data    //双沿数据);// 将rgmii_txc赋值为gmii_txcassign rgmii_txc = gmii_txc;//--------ctrl的单双沿转换// 使用ODDR原语进行控制信号的单双沿转换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_ctrl (.Q(rgmii_tx_ctrl),   // 1-bit DDR output.C(gmii_txc),   // 1-bit clock input.CE(1'b1), // 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'b0),   // 1-bit reset.S(1'b0)    // 1-bit set);//--------数据的单双沿转换genvar i;//定义循环变量,只能在generate这个循环语句中使用// 使用generate语句进行数据的单双沿转换generatefor (i = 0;i < 4 ;i = i + 1 ) begin:gmii_txd //定义标签,作为generate循环语句中的实例名称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_data (.Q(rgmii_data[i]),   // 1-bit DDR output.C(gmii_txc),   // 1-bit clock input.CE(1'b1), // 1-bit clock enable input.D1(gmii_tx_data[i]), // 1-bit data input (positive edge).D2(gmii_tx_data[4 + i]), // 1-bit data input (negative edge).R(1'b0),   // 1-bit reset.S(1'b0)    // 1-bit set); endendgenerate
endmodule

逻辑实现流程

  • 将 rgmii_txc 赋值为 gmii_txc,确保发送时钟一致。
  • 控制信号转换:使用 ODDR 原语将单沿的 gmii_tx_en 转换为双沿的 rgmii_tx_ctrl
  • 数据转换:使用 generate 语句和 ODDR 原语将单沿的 gmii_tx_data 转换为双沿的 rgmii_data

3.4 测试平台模块 tb

`timescale 1ns / 1ps
module tb();// Parameters// Portsreg  rgmii_rxc = 0;reg  rgmii_rx_ctrl = 0;reg [3:0] rgmii_rxd;wire  rgmii_txc;wire  rgmii_tx_ctrl;wire [3:0] rgmii_data;wire  gmii_txc;reg  gmii_tx_en = 0;reg [7:0] gmii_tx_data;wire  gmii_rxc;wire  gmii_rx_en;wire [7:0] gmii_rxd;// 实例化顶层模块rgmii_to_gmii rgmii_to_gmii_dut (.rgmii_rxc (rgmii_rxc ),.rgmii_rx_ctrl (rgmii_rx_ctrl ),.rgmii_rxd (rgmii_rxd ),.rgmii_txc (rgmii_txc ),.rgmii_tx_ctrl (rgmii_tx_ctrl ),.rgmii_data (rgmii_data ),.gmii_txc (gmii_txc ),.gmii_tx_en (gmii_tx_en ),.gmii_tx_data (gmii_tx_data ),.gmii_rxc (gmii_rxc ),.gmii_rx_en (gmii_rx_en ),.gmii_rxd  ( gmii_rxd));initial begin// 初始化输入信号rgmii_rxc       = 0 ;rgmii_rx_ctrl   = 1 ;rgmii_rxd       = 0 ;gmii_tx_en      = 1 ;gmii_tx_data    = 0 ;end// 生成时钟信号always #4 rgmii_rxc = ~rgmii_rxc;// 当gmii_rx_en有效时,rgmii_rxd在时钟的上升沿和下降沿加1always@(posedge rgmii_rxc or negedge rgmii_rxc)beginif(gmii_rx_en)beginrgmii_rxd <= rgmii_rxd + 1;endend// 当gmii_rx_en有效时,gmii_tx_data在时钟的上升沿加1always@(posedge rgmii_rxc )beginif(gmii_rx_en)begingmii_tx_data  <= gmii_tx_data + 1;endendendmodule

逻辑实现流程

  • 初始化输入信号,包括时钟信号、控制信号和数据信号。
  • 生成时钟信号 rgmii_rxc,周期为 8ns。
  • 当 gmii_rx_en 有效时,rgmii_rxd 在时钟的上升沿和下降沿加 1。
  • 当 gmii_rx_en 有效时,gmii_tx_data 在时钟的上升沿加 1。


四、逻辑分析

4.1 双向转换的关键逻辑实现

① 双沿数据与单沿数据的映射关系

  • RGMII→GMII(接收方向)

    • 数据转换:每个 RGMII 时钟周期传输 4 位(上下沿各 2 位),通过 IDDR 原语在上升沿采样高 2 位(存入gmii_rxd[i]),下降沿采样低 2 位(存入gmii_rxd[4+i]),最终拼接为 8 位单沿数据(如 rgmii_rxd[3:2] → gmii_rxd[0:1]rgmii_rxd[1:0] → gmii_rxd[4:5]?需注意代码中i的索引,实际代码中i从 0 到 3,Q1对应gmii_rxd[i]Q2对应gmii_rxd[4+i],即 0-3 位为上升沿采样,4-7 位为下降沿采样)。
    • 控制信号rgmii_rx_ctrl 在上下沿分别采样,通过 IDDR 得到两位信号,相与后作为 GMII 的使能信号 gmii_rx_en(确保双沿数据均有效时才输出高电平)。
  • GMII→RGMII(发送方向)

    • 数据转换:GMII 的 8 位单沿数据需拆分为 RGMII 的 4 位双沿数据,其中 gmii_tx_data[3:0] 对应下降沿数据(存入rgmii_data[i]的下降沿输入D2),gmii_tx_data[7:4] 对应上升沿数据(存入rgmii_data[i]的上升沿输入D1),通过 ODDR 原语在时钟上下沿分别输出。
    • 控制信号gmii_tx_en 单沿信号通过 ODDR 转换为双沿信号 rgmii_tx_ctrl,确保 RGMII 侧上下沿数据均被使能。

② 时钟处理与同步

  • 接收方向(RGMII→GMII)
    • RGMII 时钟 rgmii_rxc 由 PHY 提供,通过 BUFIO 和 BUFG 原语优化时钟路径,确保 GMII 侧时钟 gmii_rxc 的低抖动和低延迟,满足 GMII 接口的时序要求。
  • 发送方向(GMII→RGMII)
    • FPGA 内部时钟 gmii_txc 直接作为 RGMII 时钟 rgmii_txc,需通过时序约束(如时钟频率、占空比)确保与 PHY 的兼容性(通常为 125MHz,50% 占空比)。

4.2 双向转换逻辑的逻辑验证

双向转换的验证逻辑,也就是tb 模块。测试平台通过以下方式验证双向转换的正确性:

  1. 时钟激励:生成 125MHz 时钟(周期 8ns),模拟 RGMII 和 GMII 的同步时钟。
  2. 数据递增
    • gmii_rx_en有效时,RGMII 接收数据 rgmii_rxd 在上下沿递增(模拟 PHY 发送的双沿数据),验证 GMII 输出 gmii_rxd 是否正确拼接为 8 位单沿数据(如rgmii_rxd=0x5(二进制0101)时,上升沿01对应gmii_rxd[1:0]=01,下降沿01对应gmii_rxd[5:4]=01,最终gmii_rxd=0x15?需根据实际索引确认)。
    • GMII 发送数据 gmii_tx_data 在上升沿递增,验证 RGMII 输出 rgmii_data 是否正确拆分为双沿数据(如gmii_tx_data=0xA(二进制1010)时,上升沿数据10对应rgmii_data[3:2]=10,下降沿数据10对应rgmii_data[1:0]=10,最终rgmii_data=0xA)。
  3. 控制信号联动:确保gmii_rx_enrgmii_tx_ctrl在数据有效时保持高电平,无数据时拉低,避免无效数据传输。


五、注意事项

5.1 时钟处理

在进行接口转换时,时钟的处理非常重要。使用 BUFIO 和 BUFG 原语可以确保时钟信号的质量,避免时钟抖动和延迟对数据传输的影响。

5.2 数据转换

在进行双沿数据和单沿数据转换时,需要注意数据的对齐和时序关系。使用 IDDR 和 ODDR 原语时,要正确设置参数,确保数据的正确转换。

5.3 测试验证

在设计完成后,一定要进行充分的测试验证。可以使用仿真工具对测试平台进行仿真,观察各个信号的波形,确保接口转换的正确性。同时,还可以进行硬件测试,将设计下载到 FPGA 开发板上进行实际测试。


六、本文总结

本文围绕 FPGA 中 RGMII 与 GMII 接口的转换设计,详细阐述了从需求分析到代码实现的完整流程,重点解决了双沿数据与单沿数据之间的转换问题。通过模块化设计,将功能划分为顶层模块、接收模块(RGMII 转 GMII)和发送模块(GMII 转 RGMII),并利用 FPGA 的 IDDR/ODDR 原语实现双沿数据的采样与生成,确保了接口时序的严格对齐。

在接收模块中,通过 BUFIO 和 BUFG 原语优化时钟路径,使用 IDDR 提取时钟双沿的控制信号和数据,最终拼接为 GMII 所需的 8 位单沿数据;发送模块则通过 ODDR 将 GMII 的单沿数据映射到 RGMII 的双沿信号,实现高效的数据传输。测试平台通过时钟激励和数据递增逻辑,验证了接口转换的功能正确性。

设计中需特别注意时钟质量优化、双沿数据的时序对齐以及跨时钟域处理(如需),确保满足 IEEE 标准和硬件时序约束。该方案为 FPGA 网络接口设计提供了可复用的模板,适用于千兆以太网等高速数据传输场景,具有较强的工程实践价值。通过合理的模块划分和原语应用,可有效简化开发流程,提升系统稳定性。实际部署建议结合Xilinx的UltraScale Architecture PCB Design Guide进行板级优化,并通过Tcl脚本实现自动化时序检查。


七、更多操作

完整FPGA系列,请看

FPGA系列,文章目录https://blog.csdn.net/weixin_65793170/article/details/144185217

相关文章:

FPGA 37 ,FPGA千兆以太网设计实战:RGMII接口时序实现全解析( RGMII接口时序设计,RGMII~GMII,GMII~RGMII 接口转换 )

目录 前言 一、设计流程 1.1 需求理解 1.2 模块划分 1.3 测试验证 二、模块分工 2.1 RGMII→GMII&#xff08;接收方向&#xff0c;rgmii_rx 模块&#xff09; 2.2 GMII→RGMII&#xff08;发送方向&#xff0c;rgmii_tx 模块&#xff09; 三、代码实现 3.1 顶层模块 …...

torch.cat和torch.stack的区别

torch.cat 和 torch.stack 是 PyTorch 中用于组合张量的两个常用函数&#xff0c;它们的核心区别在于输入张量的维度和输出张量的维度变化。以下是详细对比&#xff1a; 1. torch.cat (Concatenate) 作用&#xff1a;沿现有维度拼接多个张量&#xff0c;不创建新维度 输入要求…...

索引下推(Index Condition Pushdown, ICP)

概念 索引下推是一种数据库查询优化技术&#xff0c;通过在存储引擎层面应用部分WHERE条件来减少不必要的数据读取。它特别适用于复合索引的情况&#xff0c;因为它可以在索引扫描阶段就排除不符合全部条件的数据行&#xff0c;而不是将所有可能匹配的记录加载到服务器层再进行…...

C++基础精讲-06

文章目录 1. this指针1.1 this指针的概念1.2 this指针的使用 2. 特殊的数据成员2.1 常量数据成员2.2 引用数据成员2.3 静态数据成员2.4 对象成员 3. 特殊的成员函数3.1 静态成员函数3.2 const成员函数3.3 mutable关键字 1. this指针 1.1 this指针的概念 1.c规定&#xff0c;t…...

Django3 - 建站基础

学习开发网站必须了解网站的组成部分、网站类型、运行原理和开发流程。使用Django开发网站必须掌握Django的基本操作&#xff0c;比如创建项目、使用Django的操作指令以及开发过程中的调试方法。 一、网站的定义及组成 网站(Website)是指在因特网上根据一定的规则&#xff0c;…...

UE5蓝图设置界面尺寸大小

UE5蓝图设置界面尺寸大小 Create widget 创建UIadd to Viewport 添加视图get Game User Settings获取游戏用户设置set Screen Resolutions 设置屏幕尺寸大小1920*1080set Fullscreen Mode 设置全屏模式为&#xff1a;窗口化或者全屏Apply Settings 应用设置...

无数字字母RCE

无数字字母RCE&#xff0c;这是一个老生常谈的问题&#xff0c;就是不利用数字和字母构造出webshell&#xff0c;从而能够执行我们的命令。 <?php highlight_file(__FILE__); $code $_GET[code]; if(preg_match("/[A-Za-z0-9]/",$code)){die("hacker!&quo…...

AutoGen参数说明

UserProxyAgent用户 user_proxy = UserProxyAgent配置说明: # 构造参数 def __init__(self,name: str,is_termination_msg: Optional[Callable[[Dict], bool]] = None,max_consecutive_auto_reply: Optional[int] = None,human_input_mode: Literal["ALWAYS", &qu…...

6.2 GitHub API接口设计实战:突破限流+智能缓存实现10K+仓库同步

GitHub Sentinel 定期更新 API 接口设计 关键词:GitHub API 集成、异步爬虫开发、RESTful 接口设计、请求限流策略、数据增量更新 1. 接口架构设计原则 采用 分层隔离架构 实现数据采集与业务逻辑解耦: #mermaid-svg-WihvC78J0F5oGDbs {font-family:"trebuchet ms&quo…...

用java代码如何存取数据库的blob字段

一.业务 在业务中我们被要求将文件或图片等转成 byte[] 或 InputStream存到数据库的Blob类型的字段中. 二.Blob类型介绍 在 MySQL 中&#xff0c;Blob 数据类型用于存储二进制数据。MySQL 提供了四种不同的 Blob 类型&#xff1a; TINYBLOB: 最大存储长度为 255 个字节。BL…...

2025蓝桥杯C++研究生组真题-上海市省赛

2025蓝桥杯C研究生组真题 A&#xff1a;数位倍数&#xff08;5分&#xff09; 问题描述&#xff1a;请问在 1 至 202504&#xff08;含&#xff09;中&#xff0c;有多少个数的各个数位之和是 5 的整数倍。例如&#xff1a;5、19、8025 都是这样的数。 A是填空题&#xff0c…...

原子操作CAS(Compare-And-Swap)和锁

目录 原子操作 优缺点 锁 互斥锁&#xff08;Mutex&#xff09; 自旋锁&#xff08;Spin Lock&#xff09; 原子性 单核单CPU 多核多CPU 存储体系结构 缓存一致性 写传播&#xff08;Write Propagation&#xff09; 事务串行化&#xff08;Transaction Serialization&#…...

Aspose.Words导出word,服务器用内存流处理,不生成磁盘文件

框架集&#xff1a;.NET8 public async Task<IActionResult> ExportPDF(long? id) {var infoawait form_Dahui_ReportDao.GetAsync(id);if (info null){return Content("没找到数据");}//读取word模板string fileTemp Path.Combine(AppContext.BaseDirect…...

攻防世界——Web题ez_curl

目录 Express PHP和Node.js的解析差异 Python代码 这道题最终得不到flag&#xff0c;用了很多师傅的代码也不成功。但还是需要学习 下载的附件&#xff1a; const express require(express);const app express();const port 3000; const flag process.env.flag;app.ge…...

力扣面试150题--螺旋矩阵

Day 20 题目描述 思路 根据题目描述&#xff0c;我们需要顺时针输出矩阵元素&#xff0c;顺时针说明有四种输出状态&#xff0c;横向从左到右和从右到左&#xff0c;纵向从上到下和从下到上&#xff0c;唯一的难点在于&#xff0c;输出完成一层后&#xff0c;如何进入内层&am…...

智能指针之设计模式2

前面介绍了工厂模式控制了智能指针和资源对象的创建过程&#xff0c;现在介绍一下智能指针是如何利用代理模式来实现“类指针&#xff08;like-pointer&#xff09;”的功能&#xff0c;并控制资源对象的销毁过程的。 2、代理模式 代理模式是为其它对象提供一种代理以控制对这…...

【Redis】redis持久化

Redis 持久化 Redis&#xff1a;非关系型的内存数据库 持久化&#xff1a;将数据永久写入磁盘&#xff08;内存→磁盘&#xff09; Redis 默认开启了持久化&#xff0c;默认模式为 RDB 为什么需要持久化&#xff1f; Redis 是内存数据库&#xff0c;宕机或关机后数据会丢失。…...

AtCoder Beginner Contest 401 E题 题解

E - Reachable Sethttp://E - Reachable Set 题意概述 &#xff1a; 给定一个无向图&#xff0c; 对于每个 &#xff0c;解决以下问题&#xff1a; -选择最少的一些顶点&#xff0c;使得删除这些顶点及其关联的所有边后 点1只能到达以内的所有点 牵制芝士 &#xff1a;头文…...

Kubernetes控制平面组件:API Server Webhook 授权机制 详解

云原生学习路线导航页&#xff08;持续更新中&#xff09; kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计&#xff08;一&#xff09;Kubernetes架构原则和对象设计&#xff08;二&#xff09;Kubernetes架构原则和对象设计&#xff08;三&#xff09;Kubernetes控…...

【CodeMirror】系列(二)官网示例(六)自动补全、边栏

一、自动补全 codemirror/autocomplete 包提供了在编辑器中显示输入建议的功能。这个示例展示了如何启用该功能以及如何编写自己的补全来源。 自动补全是通过在编辑器的配置项中加入 autocompletion 扩展实现的。有些语言包支持内置的自动补全功能&#xff0c;比如HTML包。 默…...

CSS 表格样式学习笔记

CSS 提供了强大的工具来美化和定制 HTML 表格的外观。通过合理使用 CSS 属性&#xff0c;可以使表格更加美观、易读且功能强大。以下是对 CSS 表格样式的详细学习笔记。 一、表格边框 1. 单独边框 默认情况下&#xff0c;表格的 <table>、<th> 和 <td> 元…...

简单记录一下Android四大组件

1、Android Layout 1.1、LinearLayout 线性布局&#xff0c;子控件按照水平或垂直的方向依次排列&#xff0c;排列方向通过属性android:orientation控制&#xff0c;horizontal为水平排列&#xff0c;vertical为垂直排列。对于同一水平线上的控件&#xff0c;可以调整它的lay…...

在线地图支持天地图和腾讯地图,仪表板和数据大屏支持发布功能,DataEase开源BI工具v2.10.7 LTS版本发布

2025年4月11日&#xff0c;人人可用的开源BI工具DataEase正式发布v2.10.7 LTS版本。 这一版本的功能变动包括&#xff1a;数据源方面&#xff0c;Oracle数据源支持获取和查询物化视图&#xff1b;图表方面&#xff0c;在线地图支持天地图、腾讯地图&#xff1b;新增子弹图&…...

【图像处理基石】什么是通透感?

一、画面的通透感定义 画面的通透感指图像在色彩鲜明度、空间层次感、物体轮廓清晰度三方面的综合表现&#xff0c;具体表现为&#xff1a; 色彩鲜明&#xff1a;颜色纯净且饱和度适中&#xff0c;无灰暗或浑浊感&#xff1b;层次分明&#xff1a;明暗过渡自然&#xff0c;光…...

猫咪如厕检测与分类识别系统系列【六】分类模型训练+混合检测分类+未知目标自动更新

前情提要 家里养了三只猫咪&#xff0c;其中一只布偶猫经常出入厕所。但因为平时忙于学业&#xff0c;没法时刻关注牠的行为。我知道猫咪的如厕频率和时长与健康状况密切相关&#xff0c;频繁如厕可能是泌尿问题&#xff0c;停留过久也可能是便秘或不适。为了更科学地了解牠的如…...

NoSQL入门指南:Redis与MongoDB的Java实战

一、为什么需要NoSQL&#xff1f; 在传统SQL数据库中&#xff0c;数据必须严格遵循预定义的表结构&#xff0c;就像把所有物品整齐摆放在固定尺寸的货架上。而NoSQL&#xff08;Not Only SQL&#xff09;数据库则像一个灵活的储物间&#xff0c;允许存储各种类型的数据&#x…...

游戏引擎学习第223天

回顾 今天我们正在进行过场动画序列的制作&#xff0c;因此我想深入探讨这个部分。昨天&#xff0c;我们暂时停止了过场动画的制作&#xff0c;距离最终结局还有一些内容没有完成。今天的目标是继续完成这些内容。 我们已经制作了一个过场动画的系列&#xff0c;并把它们集中…...

【redis进阶二】分布式系统之主从复制结构(1)

目录 一 为什么要有分布式系统&#xff1f; 二 分布式系统涉及到的非常关键的问题&#xff1a;单点问题 三 学习部署主从结构的redis (1)创建一个目录 (2)进入目录拷贝两份原有redis (3)使用vim修改几个选项 (4)启动两个从节点服务器 (5)建立复制&#xff0c;要想配…...

(自用)若依生成左树右表

第一步&#xff1a; 在数据库创建树表和单表&#xff1a; SQL命令&#xff1a; 商品表 CREATE TABLE products (product_id INT AUTO_INCREMENT PRIMARY KEY,product_name VARCHAR(255) , price DECIMAL(10, 2) , stock INT NOT NULL, category_id INT NOT NULL); 商品分类…...

VectorBT量化入门系列:第六章 VectorBT实战案例:机器学习预测策略

VectorBT量化入门系列&#xff1a;第六章 VectorBT实战案例&#xff1a;机器学习预测策略 本教程专为中高级开发者设计&#xff0c;系统讲解VectorBT技术在量化交易中的应用。通过结合Tushare数据源和TA-Lib技术指标&#xff0c;深度探索策略开发、回测优化与风险评估的核心方法…...

5G网络下客户端数据业务掉线频繁

MCPTT&#xff08;Mission Critical Push-to-Talk&#xff09;客户端的日志&#xff0c;和界面在待机状态下&#xff08;即没有做通话等业务操作&#xff09;&#xff0c;会频繁提示“离线”。 主要先看有没有丢网&#xff0c;UL BLER有没有问题。确认没有问题。看到业务信道释…...

CPU(中央处理器)

一、CPU的定义与核心作用 CPU 是计算机的核心部件&#xff0c;负责 解释并执行指令、协调各硬件资源 以及 完成数据处理&#xff0c;其性能直接影响计算机的整体效率。 核心功能&#xff1a; 从内存中读取指令并译码。执行算术逻辑运算。控制数据在寄存器、内存和I/O设备间的…...

Java从入门到“放弃”(精通)之旅——程序逻辑控制④

Java从入门到“放弃”&#xff08;精通&#xff09;之旅&#x1f680;&#xff1a;程序逻辑的完美理解 一、开篇&#xff1a;程序员的"人生选择" 曾经的我&#xff0c;生活就像一段顺序执行的代码&#xff1a; System.out.println("早上8:00起床"); Syste…...

[Dify] 基于明道云实现金融业务中的Confirmation生成功能

在金融业务的日常流程中,交易记录的处理不仅涉及数据录入、流程审批,更重要的是其最终输出形式——交易确认函(Confirmation)。本文将介绍如何通过明道云的打印模板功能,快速、准确地生成符合业务需求的交易Confirmation,提升工作效率与合规性。 为什么需要Confirmation?…...

Qt安卓设备上怎么安装两个不同的Qt应用?

在安卓设备上安装两个不同的Qt应用时&#xff0c;需要确保这两个应用在安卓系统中被视为独立的应用程序。以下是详细的步骤和注意事项&#xff0c;帮助你实现这一目标&#xff1a; 一、修改应用的包名 安卓系统通过应用的包名&#xff08;package属性&#xff09;来区分不同的…...

Prompt工程提示词(1-6章)

White graces&#xff1a;个人主页 &#x1f439;今日诗词:怅望千秋一洒泪&#xff0c;萧条异代不同时&#x1f439; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微小博主&#x1f64f; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微小博主&#x1f64f; 目录 &#x1f680; 第…...

0基础 | 硬件滤波 C、RC、LC、π型

一、滤波概念 &#xff08;一&#xff09;滤波定义 滤波是将信号中特定波段频率滤除的操作&#xff0c;是抑制和防止干扰的重要措施。通过滤波器实现对特定频率成分的筛选&#xff0c;确保目标信号的纯净度&#xff0c;提升系统稳定性。 &#xff08;二&#xff09;滤波器分…...

C++ 编程指南34 - C++ 中 ABI 不兼容的典型情形

一:概述 ABI(Application Binary Interface)是二进制层面的接口规范。如果一个库的 ABI 发生了变化,那么基于旧 ABI 编译的代码可能在运行时与新库不兼容(即使接口名字都一样也不行)。那么在C++中编程中,哪些情形会导致ABI不兼容呢?下面逐一列举一下。 二:C++ 中 ABI…...

【动态规划】深入动态规划:背包问题

文章目录 前言01背包例题一、01背包二、分割等和子集三、目标和四、最后一块石头的重量|| 完全背包例题一、完全背包二、 零钱兑换三、零钱兑换||四、完全平方数 前言 什么是背包问题&#xff0c;怎么解决算法中的背包问题呢&#xff1f; 背包问题 (Knapsack problem) 是⼀种组…...

NVIDIA AI Aerial

NVIDIA AI Aerial 适用于无线研发的 NVIDIA AI Aerial 基础模组Aerial CUDA 加速 RANAerial Omniverse 数字孪生Aerial AI 无线电框架 用例构建商业 5G 网络加速 5G生成式 AI 和 5G 数据中心 加速 6G 研究基于云的工具 优势100% 软件定义通过部署在数字孪生中进行测试6G 标准化…...

计算机视觉6——相机基础

一、数字相机基本工作原理 &#xff08;一&#xff09;像素概念 数字相机生成二维图像&#xff0c;图像最小单元是像素。 每个像素对应三维世界中某个特定方向&#xff0c;像素值衡量某一时刻来自该方向的光照强度/颜色 &#xff0c;即相机度量每个像素的光照情况并保存到对…...

入门到精通,C语言十大经典程序

以下是十个经典的C语言程序示例&#xff0c;这些程序涵盖了从基础到稍复杂的应用场景&#xff0c;适合初学者和有一定基础的开发者学习和参考。 1. Hello, World! 这是每个初学者学习编程时的第一个程序&#xff0c;用于验证开发环境是否正确配置。 #include <stdio.h>…...

【毕设】Python构建基于TMDB电影推荐系统

个性化电影推荐系统 这是一个基于FastAPI开发的现代化电影推荐系统&#xff0c;结合了协同过滤和深度学习技术&#xff0c;为用户提供个性化的电影推荐服务。 主要功能 &#x1f3af; 个性化电影推荐&#x1f50d; 电影搜索与浏览⭐ 电影评分系统&#x1f49d; 收藏夹功能&a…...

嵌入式常见概念的介绍

目录 一、MCU、MPU、ARM &#xff08;一&#xff09;MCU&#xff08;微控制器&#xff09; &#xff08;二&#xff09;MPU&#xff08;微处理器&#xff09; &#xff08;三&#xff09;ARM&#xff08;架构&#xff09; 二、DSP &#xff08;一&#xff09;数字信号处理…...

富兴号:拨云见日,打造普洱品质典范

在高端普洱茶市场的混沌格局中&#xff0c;价格与品质的天平严重失衡&#xff0c;消费者往往深陷 “高价却难觅好茶” 的困境。而新兴品牌富兴号强势崛起&#xff0c;奋力冲破这一迷局&#xff0c;致力于重塑 “号级茶” 的卓越品质&#xff0c;为茶叶赋予珍贵的品鉴与收藏价值…...

【WORD】批量将doc转为docx

具体步骤进行&#xff1a; 打开Word文档&#xff0c;按下AltF11快捷键&#xff0c;打开VBA编辑器。在VBA编辑器中&#xff0c;左侧的“项目资源管理器”窗口会显示当前打开的Word文档相关项目。找到您要添加代码的文档项目&#xff08;通常以文档名称命名&#xff09;&#xf…...

Linux内存管理架构(1)

0.内存空间架构 1.用户空间 在 Linux 系统中&#xff0c;应用程序通过 malloc() 申请内存&#xff0c;并通过 free() 释放内存时&#xff0c;底层的内存管理是由 glibc&#xff08;GNU C Library&#xff09;中的内存分配器实现的。glibc 的内存分配器负责与操作系统的内核交互…...

Ubuntu 各个常见长期支持历史版本与代号

文章目录 1. Ubuntu 历史版本与代号2. 查看当前系统版本 在 Ubuntu 操作系统里&#xff0c;每个版本都有一个别具特色的名字。该名字由一个形容词与一个动物名称构成&#xff0c;且形容词和动物名称的首字母是一样的。例如 “Warty Warthog&#xff08;长疣的疣猪&#xff09;”…...

信息安全管理与评估2021年国赛正式卷答案截图以及十套国赛卷

2021年全国职业院校技能大赛高职组 “信息安全管理与评估”赛项 任务书1 赛项时间 共计X小时。 赛项信息 赛项内容 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 第一阶段 平台搭建与安全设备配置防护 任务1 网络平台搭建 任务2 网络安全设备配置与防护 第二…...

在线上定位1G日志文件中的异常信息时,我这样做合适吗

1G级线上日志文件 的异常定位系统性方案 一、快速定位流程 import datetime import randomdef generate_springboot_log(file_name, file_size_gb):# 模拟Spring Boot日志内容log_levels ["INFO", "DEBUG", "WARNING", "ERROR"]cla…...