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 模块划分
根据功能需求,将整个设计划分为三个主要模块:
- 顶层模块
rgmii_to_gmii
- 接收模块
rgmii_rx
- 发送模块
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_rx | RGMII → GMII(接收) | 将 RGMII 的双沿数据(4 位,上下沿各 2 位)和控制信号转换为 GMII 的单沿数据(8 位,仅上升沿有效): - 利用 IDDR 原语提取时钟双沿的信号- 时钟处理( BUFIO /BUFG )确保 GMII 时钟质量- 控制信号转换(双沿有效 → 单沿使能) |
rgmii_tx | GMII → RGMII(发送) | 将 GMII 的单沿数据(8 位,仅上升沿有效)和控制信号转换为 RGMII 的双沿数据(4 位,上下沿各 2 位): - 利用 ODDR 原语生成双沿数据和控制信号- 时钟同步(直接复用 GMII 时钟作为 RGMII 发送时钟) |
tb (Test Bench) | 无(测试验证) | 测试平台模块,不参与实际接口转换,仅用于仿真验证: - 生成时钟激励(125MHz,50% 占空比) - 驱动输入信号(RGMII 接收数据、GMII 发送数据)递增变化 - 验证输出信号是否符合双向转换逻辑(如双沿数据拼接 / 拆分的正确性) |
双向转换的核心模块:
模块 | 转换方向 | 核心功能 |
---|---|---|
rgmii_rx | RGMII → GMII(接收) | 将 RGMII 的双沿数据(4 位,上下沿各 2 位)和控制信号转换为 GMII 的单沿数据(8 位,仅上升沿有效)。 |
rgmii_tx | GMII → 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
(确保双沿数据均有效时才输出高电平)。
- 数据转换:每个 RGMII 时钟周期传输 4 位(上下沿各 2 位),通过
-
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 侧上下沿数据均被使能。
- 数据转换:GMII 的 8 位单沿数据需拆分为 RGMII 的 4 位双沿数据,其中
② 时钟处理与同步
- 接收方向(RGMII→GMII):
- RGMII 时钟
rgmii_rxc
由 PHY 提供,通过BUFIO
和BUFG
原语优化时钟路径,确保 GMII 侧时钟gmii_rxc
的低抖动和低延迟,满足 GMII 接口的时序要求。
- RGMII 时钟
- 发送方向(GMII→RGMII):
- FPGA 内部时钟
gmii_txc
直接作为 RGMII 时钟rgmii_txc
,需通过时序约束(如时钟频率、占空比)确保与 PHY 的兼容性(通常为 125MHz,50% 占空比)。
- FPGA 内部时钟
4.2 双向转换逻辑的逻辑验证
双向转换的验证逻辑,也就是tb
模块。测试平台通过以下方式验证双向转换的正确性:
- 时钟激励:生成 125MHz 时钟(周期 8ns),模拟 RGMII 和 GMII 的同步时钟。
- 数据递增:
- 当
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
)。
- 当
- 控制信号联动:确保
gmii_rx_en
和rgmii_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(接收方向,rgmii_rx 模块) 2.2 GMII→RGMII(发送方向,rgmii_tx 模块) 三、代码实现 3.1 顶层模块 …...
torch.cat和torch.stack的区别
torch.cat 和 torch.stack 是 PyTorch 中用于组合张量的两个常用函数,它们的核心区别在于输入张量的维度和输出张量的维度变化。以下是详细对比: 1. torch.cat (Concatenate) 作用:沿现有维度拼接多个张量,不创建新维度 输入要求…...
索引下推(Index Condition Pushdown, ICP)
概念 索引下推是一种数据库查询优化技术,通过在存储引擎层面应用部分WHERE条件来减少不必要的数据读取。它特别适用于复合索引的情况,因为它可以在索引扫描阶段就排除不符合全部条件的数据行,而不是将所有可能匹配的记录加载到服务器层再进行…...
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规定,t…...
Django3 - 建站基础
学习开发网站必须了解网站的组成部分、网站类型、运行原理和开发流程。使用Django开发网站必须掌握Django的基本操作,比如创建项目、使用Django的操作指令以及开发过程中的调试方法。 一、网站的定义及组成 网站(Website)是指在因特网上根据一定的规则,…...
UE5蓝图设置界面尺寸大小
UE5蓝图设置界面尺寸大小 Create widget 创建UIadd to Viewport 添加视图get Game User Settings获取游戏用户设置set Screen Resolutions 设置屏幕尺寸大小1920*1080set Fullscreen Mode 设置全屏模式为:窗口化或者全屏Apply Settings 应用设置...
无数字字母RCE
无数字字母RCE,这是一个老生常谈的问题,就是不利用数字和字母构造出webshell,从而能够执行我们的命令。 <?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 中,Blob 数据类型用于存储二进制数据。MySQL 提供了四种不同的 Blob 类型: TINYBLOB: 最大存储长度为 255 个字节。BL…...
2025蓝桥杯C++研究生组真题-上海市省赛
2025蓝桥杯C研究生组真题 A:数位倍数(5分) 问题描述:请问在 1 至 202504(含)中,有多少个数的各个数位之和是 5 的整数倍。例如:5、19、8025 都是这样的数。 A是填空题,…...
原子操作CAS(Compare-And-Swap)和锁
目录 原子操作 优缺点 锁 互斥锁(Mutex) 自旋锁(Spin Lock) 原子性 单核单CPU 多核多CPU 存储体系结构 缓存一致性 写传播(Write Propagation) 事务串行化(Transaction Serialization&#…...
Aspose.Words导出word,服务器用内存流处理,不生成磁盘文件
框架集:.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,用了很多师傅的代码也不成功。但还是需要学习 下载的附件: const express require(express);const app express();const port 3000; const flag process.env.flag;app.ge…...
力扣面试150题--螺旋矩阵
Day 20 题目描述 思路 根据题目描述,我们需要顺时针输出矩阵元素,顺时针说明有四种输出状态,横向从左到右和从右到左,纵向从上到下和从下到上,唯一的难点在于,输出完成一层后,如何进入内层&am…...
智能指针之设计模式2
前面介绍了工厂模式控制了智能指针和资源对象的创建过程,现在介绍一下智能指针是如何利用代理模式来实现“类指针(like-pointer)”的功能,并控制资源对象的销毁过程的。 2、代理模式 代理模式是为其它对象提供一种代理以控制对这…...
【Redis】redis持久化
Redis 持久化 Redis:非关系型的内存数据库 持久化:将数据永久写入磁盘(内存→磁盘) Redis 默认开启了持久化,默认模式为 RDB 为什么需要持久化? Redis 是内存数据库,宕机或关机后数据会丢失。…...
AtCoder Beginner Contest 401 E题 题解
E - Reachable Sethttp://E - Reachable Set 题意概述 : 给定一个无向图, 对于每个 ,解决以下问题: -选择最少的一些顶点,使得删除这些顶点及其关联的所有边后 点1只能到达以内的所有点 牵制芝士 :头文…...
Kubernetes控制平面组件:API Server Webhook 授权机制 详解
云原生学习路线导航页(持续更新中) kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计(一)Kubernetes架构原则和对象设计(二)Kubernetes架构原则和对象设计(三)Kubernetes控…...
【CodeMirror】系列(二)官网示例(六)自动补全、边栏
一、自动补全 codemirror/autocomplete 包提供了在编辑器中显示输入建议的功能。这个示例展示了如何启用该功能以及如何编写自己的补全来源。 自动补全是通过在编辑器的配置项中加入 autocompletion 扩展实现的。有些语言包支持内置的自动补全功能,比如HTML包。 默…...
CSS 表格样式学习笔记
CSS 提供了强大的工具来美化和定制 HTML 表格的外观。通过合理使用 CSS 属性,可以使表格更加美观、易读且功能强大。以下是对 CSS 表格样式的详细学习笔记。 一、表格边框 1. 单独边框 默认情况下,表格的 <table>、<th> 和 <td> 元…...
简单记录一下Android四大组件
1、Android Layout 1.1、LinearLayout 线性布局,子控件按照水平或垂直的方向依次排列,排列方向通过属性android:orientation控制,horizontal为水平排列,vertical为垂直排列。对于同一水平线上的控件,可以调整它的lay…...
在线地图支持天地图和腾讯地图,仪表板和数据大屏支持发布功能,DataEase开源BI工具v2.10.7 LTS版本发布
2025年4月11日,人人可用的开源BI工具DataEase正式发布v2.10.7 LTS版本。 这一版本的功能变动包括:数据源方面,Oracle数据源支持获取和查询物化视图;图表方面,在线地图支持天地图、腾讯地图;新增子弹图&…...
【图像处理基石】什么是通透感?
一、画面的通透感定义 画面的通透感指图像在色彩鲜明度、空间层次感、物体轮廓清晰度三方面的综合表现,具体表现为: 色彩鲜明:颜色纯净且饱和度适中,无灰暗或浑浊感;层次分明:明暗过渡自然,光…...
猫咪如厕检测与分类识别系统系列【六】分类模型训练+混合检测分类+未知目标自动更新
前情提要 家里养了三只猫咪,其中一只布偶猫经常出入厕所。但因为平时忙于学业,没法时刻关注牠的行为。我知道猫咪的如厕频率和时长与健康状况密切相关,频繁如厕可能是泌尿问题,停留过久也可能是便秘或不适。为了更科学地了解牠的如…...
NoSQL入门指南:Redis与MongoDB的Java实战
一、为什么需要NoSQL? 在传统SQL数据库中,数据必须严格遵循预定义的表结构,就像把所有物品整齐摆放在固定尺寸的货架上。而NoSQL(Not Only SQL)数据库则像一个灵活的储物间,允许存储各种类型的数据&#x…...
游戏引擎学习第223天
回顾 今天我们正在进行过场动画序列的制作,因此我想深入探讨这个部分。昨天,我们暂时停止了过场动画的制作,距离最终结局还有一些内容没有完成。今天的目标是继续完成这些内容。 我们已经制作了一个过场动画的系列,并把它们集中…...
【redis进阶二】分布式系统之主从复制结构(1)
目录 一 为什么要有分布式系统? 二 分布式系统涉及到的非常关键的问题:单点问题 三 学习部署主从结构的redis (1)创建一个目录 (2)进入目录拷贝两份原有redis (3)使用vim修改几个选项 (4)启动两个从节点服务器 (5)建立复制,要想配…...
(自用)若依生成左树右表
第一步: 在数据库创建树表和单表: SQL命令: 商品表 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量化入门系列:第六章 VectorBT实战案例:机器学习预测策略 本教程专为中高级开发者设计,系统讲解VectorBT技术在量化交易中的应用。通过结合Tushare数据源和TA-Lib技术指标,深度探索策略开发、回测优化与风险评估的核心方法…...
5G网络下客户端数据业务掉线频繁
MCPTT(Mission Critical Push-to-Talk)客户端的日志,和界面在待机状态下(即没有做通话等业务操作),会频繁提示“离线”。 主要先看有没有丢网,UL BLER有没有问题。确认没有问题。看到业务信道释…...
CPU(中央处理器)
一、CPU的定义与核心作用 CPU 是计算机的核心部件,负责 解释并执行指令、协调各硬件资源 以及 完成数据处理,其性能直接影响计算机的整体效率。 核心功能: 从内存中读取指令并译码。执行算术逻辑运算。控制数据在寄存器、内存和I/O设备间的…...
Java从入门到“放弃”(精通)之旅——程序逻辑控制④
Java从入门到“放弃”(精通)之旅🚀:程序逻辑的完美理解 一、开篇:程序员的"人生选择" 曾经的我,生活就像一段顺序执行的代码: System.out.println("早上8:00起床"); Syste…...
[Dify] 基于明道云实现金融业务中的Confirmation生成功能
在金融业务的日常流程中,交易记录的处理不仅涉及数据录入、流程审批,更重要的是其最终输出形式——交易确认函(Confirmation)。本文将介绍如何通过明道云的打印模板功能,快速、准确地生成符合业务需求的交易Confirmation,提升工作效率与合规性。 为什么需要Confirmation?…...
Qt安卓设备上怎么安装两个不同的Qt应用?
在安卓设备上安装两个不同的Qt应用时,需要确保这两个应用在安卓系统中被视为独立的应用程序。以下是详细的步骤和注意事项,帮助你实现这一目标: 一、修改应用的包名 安卓系统通过应用的包名(package属性)来区分不同的…...
Prompt工程提示词(1-6章)
White graces:个人主页 🐹今日诗词:怅望千秋一洒泪,萧条异代不同时🐹 ⛳️点赞 ☀️收藏⭐️关注💬卑微小博主🙏 ⛳️点赞 ☀️收藏⭐️关注💬卑微小博主🙏 目录 🚀 第…...
0基础 | 硬件滤波 C、RC、LC、π型
一、滤波概念 (一)滤波定义 滤波是将信号中特定波段频率滤除的操作,是抑制和防止干扰的重要措施。通过滤波器实现对特定频率成分的筛选,确保目标信号的纯净度,提升系统稳定性。 (二)滤波器分…...
C++ 编程指南34 - C++ 中 ABI 不兼容的典型情形
一:概述 ABI(Application Binary Interface)是二进制层面的接口规范。如果一个库的 ABI 发生了变化,那么基于旧 ABI 编译的代码可能在运行时与新库不兼容(即使接口名字都一样也不行)。那么在C++中编程中,哪些情形会导致ABI不兼容呢?下面逐一列举一下。 二:C++ 中 ABI…...
【动态规划】深入动态规划:背包问题
文章目录 前言01背包例题一、01背包二、分割等和子集三、目标和四、最后一块石头的重量|| 完全背包例题一、完全背包二、 零钱兑换三、零钱兑换||四、完全平方数 前言 什么是背包问题,怎么解决算法中的背包问题呢? 背包问题 (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——相机基础
一、数字相机基本工作原理 (一)像素概念 数字相机生成二维图像,图像最小单元是像素。 每个像素对应三维世界中某个特定方向,像素值衡量某一时刻来自该方向的光照强度/颜色 ,即相机度量每个像素的光照情况并保存到对…...
入门到精通,C语言十大经典程序
以下是十个经典的C语言程序示例,这些程序涵盖了从基础到稍复杂的应用场景,适合初学者和有一定基础的开发者学习和参考。 1. Hello, World! 这是每个初学者学习编程时的第一个程序,用于验证开发环境是否正确配置。 #include <stdio.h>…...
【毕设】Python构建基于TMDB电影推荐系统
个性化电影推荐系统 这是一个基于FastAPI开发的现代化电影推荐系统,结合了协同过滤和深度学习技术,为用户提供个性化的电影推荐服务。 主要功能 🎯 个性化电影推荐🔍 电影搜索与浏览⭐ 电影评分系统💝 收藏夹功能&a…...
嵌入式常见概念的介绍
目录 一、MCU、MPU、ARM (一)MCU(微控制器) (二)MPU(微处理器) (三)ARM(架构) 二、DSP (一)数字信号处理…...
富兴号:拨云见日,打造普洱品质典范
在高端普洱茶市场的混沌格局中,价格与品质的天平严重失衡,消费者往往深陷 “高价却难觅好茶” 的困境。而新兴品牌富兴号强势崛起,奋力冲破这一迷局,致力于重塑 “号级茶” 的卓越品质,为茶叶赋予珍贵的品鉴与收藏价值…...
【WORD】批量将doc转为docx
具体步骤进行: 打开Word文档,按下AltF11快捷键,打开VBA编辑器。在VBA编辑器中,左侧的“项目资源管理器”窗口会显示当前打开的Word文档相关项目。找到您要添加代码的文档项目(通常以文档名称命名)…...
Linux内存管理架构(1)
0.内存空间架构 1.用户空间 在 Linux 系统中,应用程序通过 malloc() 申请内存,并通过 free() 释放内存时,底层的内存管理是由 glibc(GNU C Library)中的内存分配器实现的。glibc 的内存分配器负责与操作系统的内核交互…...
Ubuntu 各个常见长期支持历史版本与代号
文章目录 1. Ubuntu 历史版本与代号2. 查看当前系统版本 在 Ubuntu 操作系统里,每个版本都有一个别具特色的名字。该名字由一个形容词与一个动物名称构成,且形容词和动物名称的首字母是一样的。例如 “Warty Warthog(长疣的疣猪)”…...
信息安全管理与评估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…...