深入讲讲异步FIFO

一、异步 FIFO 的基本概念

1.1 定义与核心作用

        异步 FIFO(Asynchronous FIFO)是一种读写时钟完全独立的先进先出(First-In-First-Out)数据缓冲器,主要用于跨时钟域数据传输场景。在数字系统中,当两个模块工作在不同时钟频率或相位下时,异步 FIFO 可作为数据中转站,解决数据传输中的时序冲突、速率不匹配问题,避免数据丢失或错误。

1.2 与同步 FIFO 的核心区别

二、异步 FIFO 的基本结构

        异步 FIFO 的核心结构由 5 部分组成:

存储单元(RAM);空满检测逻辑(解决跨时钟域问题);写指针(写时钟域);读指针(读时钟域);读写接口(时钟,数据,使能)

2.1 存储单元(Storage Element)

存储单元是 FIFO 的数据缓冲区,在 FPGA 中通常采用两种实现方式:

  • 块 RAM(Block RAM):适用于深度较大的 FIFO(如深度 > 64),资源利用率高,速度快(FPGA 内置的硬核 RAM)。
  • 分布式 RAM(Distributed RAM):适用于小深度 FIFO(如深度≤32),由 LUT(查找表)拼接而成,灵活性高但资源消耗大。

存储单元的核心参数:

  • 数据位宽(DATA_WIDTH):单次传输的数据宽度(如 8/16/32 位)。
  • 深度(DEPTH):可存储的数据个数(通常为 2ⁿ,便于地址编码)。

2.2 指针(Pointers)

指针用于跟踪 FIFO 的读写位置,分为写指针和读指针:

  • 写指针(Write Pointer):在写时钟(wr_clk)驱动下,指示下一个待写入数据的地址;每完成一次写入(wr_en 有效且非满),指针 + 1。
  • 读指针(Read Pointer):在读时钟(rd_clk)驱动下,指示下一个待读出数据的地址;每完成一次读出(rd_en 有效且非空),指针 + 1。

指针的关键特性
指针采用n+1 位二进制编码(n 为地址位宽),其中低 n 位为实际存储地址,最高位(第 n 位)用于区分 “空” 和 “满” 状态(指示指针是否多循环一圈)。例如:深度为 4(2²)的 FIFO,地址位宽 2 位,指针为 3 位(bit2-bit0)

2.3 空满检测逻辑(Empty/Full Logic)

空满状态是 FIFO 的核心控制信号:

  • 空信号(empty):读时钟域输出,指示 FIFO 无数据可读(防止空读错误)。
  • 满信号(full):写时钟域输出,指示 FIFO 无空间可写(防止满写错误)。

核心挑战:读写指针属于不同时钟域,直接跨域比较会导致亚稳态(Metastability),需通过特殊设计实现准确判断。

三、异步 FIFO 的核心技术难点与解决方案

3.1 跨时钟域同步与亚稳态问题

3.1.1 亚稳态产生原因

当一个时钟域的信号(如读指针)直接进入另一个时钟域(如写时钟域)时,若信号在目标时钟的建立时间(Setup Time) 或保持时间(Hold Time) 窗口内变化,触发器会进入亚稳态(输出不稳定),导致后续逻辑错误。

关于亚稳态数据的跳变:

当输入数据在时钟沿附近的 ([T{su}, Th]) 窗口内发生变化(即数据跳变时间落在时钟沿前 (T{su}) 到时钟沿后 (Th) 的区间内),触发器的输出无法稳定到明确的 0 或 1,而是处于介于高电平与低电平之间的不稳定状态,这种状态称为亚稳态。亚稳态的持续时间是随机的,最终会随机稳定到 0 或 1,但在此期间输出信号是不确定的,可能导致后续逻辑错误。

3.1.2 两级同步器解决方案

为解决亚稳态,异步 FIFO 中采用两级 D 触发器同步器(Two-Stage Synchronizer)将指针从一个时钟域同步到另一个时钟域

  • 一级 DFF:捕获输入信号,可能进入亚稳态,但亚稳态持续时间会随时间衰减。
  • 二级 DFF:在一级 DFF 稳定后采样,将亚稳态概率降低到可接受范围(FPGA 中通常可忽略)。

3.2 格雷码(Gray Code)的应用

3.2.1 为什么需要格雷码?

二进制指针在跨域同步时存在 “多位跳变” 问题(如二进制011100跳变 3 位),同步器可能采样到中间错误状态。而格雷码的相邻数值仅一位不同,可最大限度降低同步错误概率。

3.2.2 二进制与格雷码的转换
  • 二进制转格雷码gray_code = binary_code ^ (binary_code >> 1)
    例:4 位二进制0101→格雷码0101 ^ 0010 = 0111
  • 格雷码转二进制binary_code[MSB] = gray_code[MSB]binary_code[i] = binary_code[i+1] ^ gray_code[i](从高位到低位)。
3.2.3 指针编码规则

异步 FIFO 中,读写指针的二进制值先转换为格雷码,再通过两级同步器跨时钟域传输,确保同步后的值接近真实值。

3.3 空满状态的准确判断

3.3.1 空状态(Empty)判断

空状态定义:读指针追上写指针,FIFO 中无数据。
判断逻辑(读时钟域):
读指针格雷码等于同步到读时钟域的写指针格雷码时,FIFO 为空:
empty = (rd_gray == sync_wr_gray_to_rd_clk)

3.3.2 满状态(Full)判断

满状态定义:写指针比读指针多绕 FIFO 一圈(即多走一个深度),FIFO 中数据已满。
判断逻辑(写时钟域):
写指针格雷码的低 n 位等于同步到写时钟域的读指针格雷码的低 n 位,且最高位相反时,FIFO 为满:
full = (wr_gray == {~sync_rd_gray_to_wr_clk[MSB], sync_rd_gray_to_wr_clk[MSB-1:0]})

示例(深度 = 4,指针 3 位):

  • 写指针二进制 = 4(100)→格雷码 = 110;读指针二进制 = 0(000)→格雷码 = 000。
  • 同步到写时钟域的读指针格雷码为 000,满条件:110 == {~000[2], 000[1:0]} → 110 == 100? 不,修正:满条件应为写指针格雷码与同步读指针格雷码的 “高两位相反,低 n 位相同”。
    正确例:写指针格雷码110(100),同步读指针格雷码010(010)→高两位1 vs 0,低两位10 vs 10→满状态。

3.4 类比FIFO工作过程

给异步 FIFO 起个生活化的名字:“跨节奏仓库”

想象你家楼下有个小仓库,专门用来临时放东西。这个仓库有 4 个格子(编号 0、1、2、3),就像 FIFO 的存储空间。

仓库有两个 “操作员”:

  • 写小哥:负责往仓库里存东西(写操作),他干活的节奏是 “每 2 秒存一个”(写时钟,比如 2Hz)。
  • 读小哥:负责从仓库里取东西(读操作),他干活的节奏是 “每 3 秒取一个”(读时钟,比如 3Hz)。

两人节奏不一样(异步),但要同时干活,还不能出问题:不能把仓库塞满了还硬塞(溢出),也不能仓库空了还硬取(读空)。

核心工具:两个 “位置箭头” 和 “同步小纸条”

为了让两人配合好,他们各有一个 “箭头”(指针):

  • 写箭头:写小哥每次存完东西,箭头就往前挪一格,标记 “下一个要存东西的位置”。
  • 读箭头:读小哥每次取完东西,箭头就往前挪一格,标记 “下一个要取东西的位置”。

但两人节奏不一样,互相看不到对方的箭头,所以需要 “同步小纸条”:

写小哥会把自己的箭头位置写在纸条上,传给读小哥(写指针同步到读时钟域),让读小哥知道 “仓库里现在有多少东西可以取”。

  • 读小哥也会把自己的箭头位置写在纸条上,传给写小哥(读指针同步到写时钟域),让写小哥知道 “仓库还有多少空位置可以存”。

具体过程:读写同时进行的一天

初始状态:仓库是空的,写箭头和读箭头都指着 “0 号格子”(刚开始都从 0 开始)。

第 1 秒:写小哥先干活

写小哥带了个 “苹果”,看了看自己的箭头(指着 0),就把苹果放进 0 号格子。存完后,写箭头往前挪一格,指向 1 号格子。
此时仓库里有:0 号格子(苹果)。
写小哥把 “写箭头现在在 1” 写在纸条上,传给读小哥(同步写指针到读端)。

第 3 秒:读小哥第一次干活(读时钟到了)

读小哥收到纸条,看到写箭头在 1,自己的读箭头还在 0。他知道:“写箭头在 1,我在 0,说明 0 号格子有东西可以取!”
于是他取走 0 号格子的苹果,取完后,读箭头往前挪一格,指向 1 号格子。
此时仓库里:空了 0 号格子,还剩(暂时没新东西)。
读小哥把 “读箭头现在在 1” 写在纸条上,传给写小哥(同步读指针到写端)。

第 4 秒:写小哥第二次干活(写时钟到了)

写小哥收到纸条,看到读箭头在 1,自己的写箭头在 1。他知道:“我的箭头和读箭头没重合,仓库没满,可以存!”
于是把 “香蕉” 放进 1 号格子,存完后写箭头挪到 2 号格子。
仓库里现在有:1 号格子(香蕉)。

第 6 秒:写小哥第三次干活

写小哥又存 “橙子” 到 2 号格子,写箭头挪到 3 号格子。
仓库里:1 号(香蕉)、2 号(橙子)。

第 6 秒:读小哥第二次干活(刚好和写小哥同时)

此时读小哥的读时钟也到了(和写小哥存橙子的动作同时发生)。
读小哥看自己的读箭头在 1,同步过来的写箭头在 3(写小哥刚挪到 3)。他知道:“1 号格子有香蕉可以取!”
于是取走 1 号格子的香蕉,读箭头挪到 2 号格子。
仓库里现在剩:2 号格子(橙子)。

第 8 秒:写小哥第四次干活

写小哥存 “葡萄” 到 3 号格子,写箭头本来要挪到 4 号,但仓库只有 4 个格子(0-3),所以绕回 0 号格子(箭头变成 0)。
仓库里现在有:2 号(橙子)、3 号(葡萄)。
写小哥把 “箭头在 0” 同步给读小哥。

第 9 秒:读小哥第三次干活

读小哥看到写箭头同步后是 0,自己的读箭头在 2。他知道:“2 号格子有橙子,取!”
取走橙子,读箭头挪到 3 号格子。
仓库里剩:3 号格子(葡萄)。

第 10 秒:写小哥第五次干活(和读小哥可能有重叠)

写小哥想存 “西瓜”,看自己的箭头在 0,同步过来的读箭头在 3(读小哥刚挪到 3)。
他判断:“我的下一个要存的位置是 0,读箭头在 3,没重合,仓库没满!” 于是把西瓜存到 0 号格子,写箭头挪到 1 号。
仓库里现在有:3 号(葡萄)、0 号(西瓜)。

第 12 秒:读小哥第四次干活

读小哥取走 3 号格子的葡萄,读箭头挪到 0 号格子。
仓库里剩:0 号格子(西瓜)。

就这样,写小哥每 2 秒存一个,读小哥每 3 秒取一个,动作可能重叠(同时进行),但通过 “箭头标记位置” 和 “同步纸条”,写小哥永远知道仓库有没有空位置(不会存满溢出),读小哥永远知道有没有东西可以取(不会取空出错)。

关键总结

  • 异步 FIFO 就像这个 “跨节奏仓库”,写和读可以按自己的节奏同时干。
  • 指针(箭头)标记当前存 / 取的位置,同步后互相 “看一眼” 对方的位置。
  • 空满判断:读箭头追上写箭头(没东西了)就停读;写箭头快追上读箭头(仓库快满了)就停写。
  • 这样即使节奏不同、动作同时发生,数据也不会丢、不会乱~

同步指针的速度(同步操作)和存放东西的速度(读写操作)完全没关系,两者各走各的节奏,互不影响快慢。

四、FPGA中FIFO的应用

 一。FIFO中的FPGA 中主要用于:

  • 跨时钟域数据传输(异步 FIFO)
  • 速率匹配(例如高速发送端→低速接收端)
  • 数据缓冲(突发数据暂存)

核心参数:

  • 深度:可存储的数据个数(如深度 8 表示存 8 个数据)
  • 宽度:每个数据的位宽(如宽度 32bit 表示每个数据 32 位)
  • 空满标志:控制读写操作的关键信号

二、Verilog 代码实现(异步 FIFO)

下面是一个深度为 8、位宽为 8 的异步 FIFO 的完整 Verilog 代码:

module async_fifo #(parameter DATA_WIDTH = 8,   // 数据位宽parameter ADDR_WIDTH = 3    // 地址位宽(2^3=8深度)
)(// 写时钟域input  wire wclk,           // 写时钟input  wire wrst_n,         // 写复位(低有效)input  wire w_en,           // 写使能input  wire [DATA_WIDTH-1:0] w_data,  // 写入数据// 读时钟域input  wire rclk,           // 读时钟input  wire rrst_n,         // 读复位(低有效)input  wire r_en,           // 读使能output reg [DATA_WIDTH-1:0] r_data,   // 读出数据// 状态标志output wire full,           // 满标志output wire empty           // 空标志
);// 内部信号定义reg [ADDR_WIDTH:0] w_ptr_bin;    // 写指针(二进制)reg [ADDR_WIDTH:0] r_ptr_bin;    // 读指针(二进制)reg [ADDR_WIDTH:0] w_ptr_gray;   // 写指针(格雷码)reg [ADDR_WIDTH:0] r_ptr_gray;   // 读指针(格雷码)// 跨时钟域同步的指针reg [ADDR_WIDTH:0] w_ptr_gray_sync1, w_ptr_gray_sync2;reg [ADDR_WIDTH:0] r_ptr_gray_sync1, r_ptr_gray_sync2;// 存储器阵列reg [DATA_WIDTH-1:0] fifo_mem [0:(1<<ADDR_WIDTH)-1];// 二进制转格雷码function [ADDR_WIDTH:0] bin_to_gray(input [ADDR_WIDTH:0] bin);bin_to_gray = bin ^ (bin >> 1);endfunction// 格雷码转二进制function [ADDR_WIDTH:0] gray_to_bin(input [ADDR_WIDTH:0] gray);integer i;reg [ADDR_WIDTH:0] bin;beginbin = gray;for (i = 1; i <= ADDR_WIDTH; i = i + 1)bin = bin ^ (gray >> i);endgray_to_bin = bin;endfunction// 写操作always @(posedge wclk or negedge wrst_n) beginif (!wrst_n) beginw_ptr_bin <= 'b0;w_ptr_gray <= 'b0;endelse if (w_en && !full) beginfifo_mem[w_ptr_bin[ADDR_WIDTH-1:0]] <= w_data;  // 写入数据w_ptr_bin <= w_ptr_bin + 1'b1;                  // 写指针递增w_ptr_gray <= bin_to_gray(w_ptr_bin);           // 更新格雷码指针endend// 读操作always @(posedge rclk or negedge rrst_n) beginif (!rrst_n) beginr_ptr_bin <= 'b0;r_ptr_gray <= 'b0;r_data <= 'b0;endelse if (r_en && !empty) beginr_data <= fifo_mem[r_ptr_bin[ADDR_WIDTH-1:0]];  // 读出数据r_ptr_bin <= r_ptr_bin + 1'b1;                  // 读指针递增r_ptr_gray <= bin_to_gray(r_ptr_bin);           // 更新格雷码指针endend// 两级同步器 - 写指针同步到读时钟域always @(posedge rclk or negedge rrst_n) beginif (!rrst_n) beginw_ptr_gray_sync1 <= 'b0;w_ptr_gray_sync2 <= 'b0;endelse beginw_ptr_gray_sync1 <= w_ptr_gray;w_ptr_gray_sync2 <= w_ptr_gray_sync1;endend// 两级同步器 - 读指针同步到写时钟域always @(posedge wclk or negedge wrst_n) beginif (!wrst_n) beginr_ptr_gray_sync1 <= 'b0;r_ptr_gray_sync2 <= 'b0;endelse beginr_ptr_gray_sync1 <= r_ptr_gray;r_ptr_gray_sync2 <= r_ptr_gray_sync1;endend// 空标志判断(在读时钟域)assign empty = (r_ptr_gray == w_ptr_gray_sync2);// 满标志判断(在写时钟域)assign full = (w_ptr_gray == {~r_ptr_gray_sync2[ADDR_WIDTH:ADDR_WIDTH-1], r_ptr_gray_sync2[ADDR_WIDTH-2:0]});endmodule

三、原语实现

FPGA 厂商提供了专用的存储器原语,例如 Xilinx 的BRAM原语,使用原语可以更高效地实现 FIFO:

module fifo_bram_primitive (input  wire wclk, wrst_n, w_en,input  wire [7:0] w_data,input  wire rclk, rrst_n, r_en,output reg [7:0] r_data,output wire full, empty
);// 地址和计数器reg [2:0] w_addr, r_addr;reg [3:0] count;  // 深度8需要4位计数器// 生成满空标志assign full  = (count == 4'd8);assign empty = (count == 4'd0);// 实例化BRAM原语RAMB16_S8_S8 #(.WRITE_WIDTH_A(8),  // 写端口宽度.WRITE_WIDTH_B(8),  // 读端口宽度.SRVAL_A(8'h00),    // 复位值.SRVAL_B(8'h00)) bram_inst (.CLK_A(wclk),        // 写时钟.EN_A(w_en & !full), // 写使能.WE_A(1'b1),         // 写使能.ADDR_A(w_addr),     // 写地址.DI_A(w_data),       // 写入数据.DO_A(),             // 写端口输出(不用).CLK_B(rclk),        // 读时钟.EN_B(r_en & !empty), // 读使能.WE_B(1'b0),         // 读端口禁止写.ADDR_B(r_addr),     // 读地址.DI_B(8'h00),        // 读端口数据输入(不用).DO_B(r_data)        // 读出数据);// 写地址控制always @(posedge wclk or negedge wrst_n) beginif (!wrst_n)w_addr <= 3'd0;else if (w_en & !full)w_addr <= w_addr + 1'b1;end// 读地址控制always @(posedge rclk or negedge rrst_n) beginif (!rrst_n)r_addr <= 3'd0;else if (r_en & !empty)r_addr <= r_addr + 1'b1;end// 计数器控制(使用写时钟)always @(posedge wclk or negedge wrst_n) beginif (!wrst_n)count <= 4'd0;else begincase ({w_en & !full, r_en & !empty})2'b00: count <= count;      // 无读写2'b01: count <= count - 1;  // 只读2'b10: count <= count + 1;  // 只写2'b11: count <= count;      // 同时读写,计数器不变endcaseendendendmodule

四、IP 核应用

大多数 FPGA 厂商提供了 FIFO 的 IP 核,使用 IP 核可以快速配置和实例化 FIFO

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

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

相关文章

linux81 shell通配符:[list],‘‘ ``““

shell 文件处理工具 grep 别名显示颜色 grep --colorauto ‘root’ passwd alias grep‘grep --colorauto’ vim /etc/bashrc alias grep‘grep --colorauto’ source /etc/bashrc [rootsamba tmp]# grep --colorauto root 2.txt root:x:0:0:root:/root:/bin/bash operator:x:1…

CMake、CMakeLists.txt 基础语法

前言 代码变成可执行文件&#xff0c;叫做编译&#xff08;compile&#xff09;&#xff1b;先编译这个&#xff0c;还是先编译那个&#xff08;即编译的安排&#xff09;&#xff0c;叫做构建&#xff08;build&#xff09;。CMake是最常用的构建工具&#xff0c;诞生于1977年…

《文明5》错误代码0xc0000142修复方法

只要是错误代码为0xc0000142&#xff1f;不管是哪种错误&#xff0c;都是一样的。 修复方法有很多&#xff0c;我先推荐个人认为比较好用的修复方法 方式一&#xff1a;第三方软件修复&#xff1a; 地址在这里获取&#xff1a;修复软件点这里 添加图片注释&#xff0c;不超过 …

【Java面试题】缓存穿透

什么是缓存穿透 缓存穿透是指当秒杀请求在Redis中未命中缓存时&#xff0c;系统会转而查询数据库。若数据库中也不存在该数据&#xff0c;大量此类请求将直接冲击数据库&#xff0c;造成数据库负载激增。解决方案 缓存空值 当我们查询数据库发现数据库当中也不存在该数据时&…

SpringBoot与Rust实战指南

基于Spring Boot和Rust的实用 以下是基于Spring Boot和Rust的实用示例,涵盖常见开发场景,分为Spring Boot(Java)和Rust两部分: Spring Boot 示例 RESTful API 开发 @RestController @RequestMapping("/api") public class UserController {@GetMapping("…

【世纪龙科技】汽车整车维护仿真教学软件-智构整车维护实训

在职业院校汽车专业实训教学中&#xff0c;"设备损耗大、操作风险高、场景覆盖有限"三大痛点长期制约着教学质量提升——传统实训车间里&#xff0c;学生接触实车的机会受限于车辆台套数与维护周期&#xff0c;复杂工位流程难以反复演练&#xff1b;高危操作环节&…

CMake set_source_files_properties使用解析

set_source_files_properties() 是 CMake 中用于精细化控制源文件属性的多功能命令。除了设置编译标志外&#xff0c;它还有许多其他重要用途。以下是全面的用法解析&#xff1a;一、核心功能分类 1. 编译控制 编译器选项&#xff1a;COMPILE_FLAGS / COMPILE_OPTIONSset_sourc…

雷达微多普勒特征代表运动中“事物”的运动部件。

雷达微多普勒特征代表运动中“事物”的运动部件。 即使一个人在椅子上来回摇晃&#xff0c;肉眼看来这个动作也很简单。但对雷达来说&#xff0c;这是微动作的丰富混合&#xff1a;移动膝盖和腿、摆动手臂&#xff0c;甚至是倾斜的椅子。所有这些都会产生独特但复杂的微多普勒特…

FreeRTOS硬件中断发生时的现场

在FreeRTOS中&#xff0c;当硬件中断发生时&#xff0c;当前正在运行的任务会立即被挂起&#xff0c;处理器会跳转到中断相关的中断服务程序中&#xff0c;在中断服务程序执行期间&#xff0c;遵循以下规则&#xff1a;1、中断独占CPU&#xff0c;ISR拥有最高的执行优先级&…

kotlin语法和特性分析

核心设计哲学&#xff1a; 简洁 (Concise): 减少样板代码&#xff08;如 getter/setter、类型推导&#xff09;&#xff0c;让代码表达更直接。安全 (Safe): 从语言层面设计来避免常见错误&#xff08;尤其是空指针异常&#xff09;。互操作性 (Interoperable): 与 Java 无缝集…

二进制数本身没有默认的有符号或无符号解释

文章目录1. ​**​硬件层面&#xff1a;CPU 不区分有符号/无符号​**​2. ​**​解释权在程序员手中​**​3. ​**​默认倾向性&#xff08;非绝对规则&#xff09;​**​4. ​**​如何避免混淆&#xff1f;​**​5. ​**​经典示例​**​总结1. **解释为无符号数&#xff08;U…

(AI) Server (Hardware) Architecture

Overview by Atlas T800 Just found a good product demo. from Huawei for its Atlas T800, here 计算产品3D展示 First turn off all modules and we can delve into how this server is organized. Core This is an AI server with 910B as its main feature, which is …

【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 微博评论数据可视化分析-用户评论词云图实现

大家好&#xff0c;我是java1234_小锋老师&#xff0c;最近写了一套【NLP舆情分析】基于python微博舆情分析可视化系统(flaskpandasecharts)视频教程&#xff0c;持续更新中&#xff0c;计划月底更新完&#xff0c;感谢支持。今天讲解微博评论数据可视化分析-用户评论词云图实现…

【Linux学习|黑马笔记|Day1】Linux初识、安装VMware Workstation、安装CentOS7、远程连接、虚拟机快照

Linux DAY1 前言 因为之前MySQL学到安装Linux版本的MySQL了&#xff0c;需要安装虚拟机等等&#xff0c;所以我打算先学完Linux的全部课程&#xff0c;期间继续学MySQL 文章目录Linux DAY1一.1&#xff09;操作系统概述2&#xff09;Linux初识3&#xff09;虚拟机4.1&#xff…

编程与数学 03-002 计算机网络 13_无线网络技术

编程与数学 03-002 计算机网络 13_无线网络技术一、无线网络的基本概念&#xff08;一&#xff09;无线通信的频段与标准&#xff08;二&#xff09;无线网络的优势与挑战二、无线局域网&#xff08;WLAN&#xff09;&#xff08;一&#xff09;802.11标准系列&#xff08;二&a…

肖特基二极管MBR0540T1G 安森美ON 低电压 高频率 集成电路IC 芯片

MBR0540T1G ON Semiconductor&#xff1a;超低VF肖特基二极管&#xff0c;重新定义电源效率&#xff01;&#x1f525; 一、产品简介 MBR0540T1G 是安森美&#xff08;ON Semiconductor&#xff09;推出的0.5A/40V肖特基势垒二极管&#xff0c;采用专利沟槽结构&#xff0c;专…

windows内核研究(软件调试-调试事件采集)

软件调试调试事件采集前面有说到在调试器和被调试之间会创建一个_DEBUG_OBJECT对象来进行关联调试事件的种类 被调试进程会把一个个的调试事件写到_DEBUG_OBJECT中的一个成员链表中&#xff0c;调试器就通过它们建立的 _DEBUG_OBJECT调试对象获取调式事件&#xff0c;但并不是进…

Web开发-PHP应用组件框架前端模版渲染三方插件富文本编辑器CVE审计

类别组件/框架说明[Web框架]Laravel现代化、功能全面的框架&#xff0c;适合大多数Web应用。Symfony高度模块化、功能强大的框架&#xff0c;适合复杂应用。CodeIgniter轻量级框架&#xff0c;适合快速开发。Zend Framework (Laminas)企业级框架&#xff0c;适合大规模应用&…

Spring Boot Actuator 保姆级教程

1. 引言 Spring Boot Actuator 是一个功能强大的监控工具&#xff0c;能够帮助开发者监控和管理应用的运行状态。通过 Actuator&#xff0c;我们可以轻松获取应用的健康状况、配置信息、性能指标等。本文将一步步引导你如何配置和使用 Actuator&#xff0c;以及如何通过它来监控…

使用 whisper, 音频分割, 初步尝试,切割为小块,效果还不错 1

对于一首歌而言,如何断句?即,一个 mp4 或是 mp3 文件,或是一段录音, 如何使用程序,或是 ai 来断句。分割为一句一句的片段??如果人工来分割,一般是使用 capcut 之类的剪辑软件。但是效率太慢了。所以我想能否设计一个简洁的,自动的程序来处理。这种事情,专业的名称…