【IC每日一题--单bitCDC跨时钟和同步FIFO】

news2024/12/23 4:21:30

IC Daily QA--CDC跨时钟和同步FIFO

  • 1 八股题:CDC跨时钟数据传输问题--单bit跨时钟
    • 1.1 从慢时钟到快时钟--->直接打两拍即可;
    • 1.2 快时钟到慢时钟
      • 1.2.1 脉冲信号展宽+边沿检测
      • 1.2.2 慢到快时钟--握手+边沿
  • 2 手撕题:同步FIFO代码;
    • 1.1 概念
    • 1.2 算法步骤
      • 1.2.1 计数器法判断
      • 1.2.2 读写地址--高位拓展法

本文介绍单bit跨时钟域同步方法以及同步FIFO;

1 八股题:CDC跨时钟数据传输问题–单bit跨时钟

CDC概念:在涉及不同的时钟域(相位差和频率存在差异),可能会导致数据在传输过程中出现亚稳态问题;
CDC基本分类:单bit信号传输(脉冲传输)、多bit信号传输、快到慢时钟、慢到快时钟

1.1 从慢时钟到快时钟—>直接打两拍即可;

按理说,会存在多采样问题,前提是快慢时钟的差距不大;

//==========================================================
//--Author  : colonel
//--Date    : 10-31
//--Module  : sync_1bit_from_slow_2_fast
//--Function: sync 1bit from slow clk to fast clk
//==========================================================

module sync_1bit_from_slow_2_fast(
//==========================< 端口 >=========================
    input wire slow_clk,
    input wire rst_n,
    input wire din,
    input wire fast_clk,
    output wire sync_dout
);
//==========================< 信号 >=========================
reg din_ff0,din_ff1,din_ff2;

//=========================================================
//-- din_ff0 : sync from slow_clk
//=========================================================
always @(posedge slow_clk or negedge rst_n) begin
    if (!rst_n) begin
        din_ff0 <= 1'b0;
    end else begin
        din_ff0 <= din;
    end
end

//=========================================================
//-- din_ff1 : sync from fast_clk
//=========================================================
always @(posedge fast_clk or negedge rst_n) begin
    if (!rst_n) begin
        din_ff1 <= 0;
        din_ff2 <= 0;
    end else begin
        din_ff1 <= din_ff0;
        din_ff2 <= din_ff1;
    end
end

assign sync_dout = din_ff2;

endmodule

1.2 快时钟到慢时钟

可能存在采样丢失的问题;
从快时钟到慢时钟的两种方法:1.信号展宽 + 边沿检测; 2.握手机制;

1.2.1 脉冲信号展宽+边沿检测

脉冲信号展宽+边沿检测:将脉冲信号转换成电平信号再进行边沿检测;
在两次信号之间为电平信号;

电路图如下:


//==========================================================
//--Author  : colonel
//--Date    : 10-31
//--Module  : sync_1bit_from_fast_2_slow_pulse_widen
//--Function: sync 1bit from fast clk to slow clk
//==========================================================
module sync_1bit_from_fast_2_slow_pulse_widen(
//==========================< 端口 >=========================
    input wire fast_clk,
    input wire rst_n,
    input wire din,
    input wire slow_clk,
    output wire dout
);
//==========================< 信号 >=========================
reg din_fast_r;

//=========================================================
//-- din_fast_r: 将脉冲信号在快时钟域展平为电平信号。即展宽脉冲信号。在两次脉冲信号之间为电平信号
//=========================================================
always @(posedge fast_clk or negedge rst_n) begin
    if (!rst_n) begin
        din_fast_r <= 'b0;
    end else begin
        din_fast_r <= din ? (~din_fast_r) : din_fast_r;
    end
end

//==========================< 信号 >=========================
reg data_slow_ff1;
reg data_slow_ff2;
reg data_slow_ff3;

//=========================================================
//-- data_slow_ff1/2/3: 将展宽的脉冲信号在慢时钟域打三拍,并检测边沿
//=========================================================
always @(posedge slow_clk or negedge rst_n) begin
    if (!rst_n) begin
        data_slow_ff1 <= 'b0;
        data_slow_ff2 <= 'b0;
        data_slow_ff3 <= 'b0;
    end else begin
        data_slow_ff1 <= din_fast_r;
        data_slow_ff2 <= data_slow_ff1;
        data_slow_ff3 <= data_slow_ff2;
    end
end

assign dout = data_slow_ff3 ^ data_slow_ff2;  
    
endmodule

1.2.2 慢到快时钟–握手+边沿

  • 将src时钟域的脉冲信号打一拍之后,在dst时钟域内打三拍进行同步,其中第二拍的结果作为dst时钟域的应答信号,第二拍和第三拍的结果做边沿检测,以保证在dst时钟域输出接收到的脉冲信号。

  • 其中第二拍的应答信号,在src时钟域经过两级同步作为src的应答信号,当输入脉冲信号时,src的请求信号有效。当src的应答信号有效时,请求信号无效。

//==========================================================
//--Author  : colonel
//--Date    : 10-31
//--Module  : sync_1bit_from_fast_2_slow_handshake
//--Function: sync 1bit from fast clk to slow clk
//==========================================================
module sync_1bit_from_fast_2_slow_handshake(
//==========================< 端口 >=========================
    input wire fast_clk,
    input wire rst_n,
    input wire din_pulse,
    input wire slow_clk,
    output wire dst_pulse
);
//==========================< 信号 >=========================
reg src_sync_req;
reg src_sync_ack;
reg src_req_ff1,src_req_ff2,src_req_ff3;

//=========================================================
//-- src_sync_req: 
//=========================================================
always @(posedge fast_clk or negedge rst_n) begin
    if (!rst_n) begin
        src_sync_req <= 1'b0;
    end else begin
        if (din_pulse) begin
            src_sync_req <= 1'b1;
        end else if(src_sync_ack) begin
            src_sync_req <= 1'b0;
        end else begin
            src_sync_req <= src_sync_req;
        end
    end
end

//=========================================================
//-- src_req_ff1/2 
//=========================================================
always @(posedge slow_clk or negedge rst_n) begin
    if (!rst_n) begin
        src_req_ff1 <= 'b0;
        src_req_ff2 <= 'b0;
        src_req_ff3 <= 'b0;
    end else begin
        src_req_ff1 <= src_sync_req;
        src_req_ff2 <= src_req_ff1;
        src_req_ff3 <= src_req_ff2;
    end
end

wire dst_sync_ack = src_req_ff2;

//=========================================================
//-- src_sync_ack
//=========================================================
reg dst_sync_ack_ff1;
reg dst_sync_ack_ff2;

always @(posedge fast_clk or negedge rst_n) begin
    if (!rst_n) begin
        dst_sync_ack_ff1 <= 'b0;    
        dst_sync_ack_ff2 <= 'b0;    
    end else begin
        dst_sync_ack_ff1 <= dst_sync_ack;
        dst_sync_ack_ff2 <= dst_sync_ack_ff1;
    end
end

assign src_sync_ack = dst_sync_ack_ff2;

//=========================================================
//-- dst_pulse
//=========================================================
assign dst_pulse = src_req_ff3 & ! src_req_ff2;

endmodule

2 手撕题:同步FIFO代码;

FIFO:用于缓存数据来匹配不同速度之间的操作,从而以稳定的速率进行处理;
IP设计中经常使用到的是同步FIFO;异步FIFO基本用在跨时钟域场景下;
FIFO及先进先出的队列,自己内部管理读写地址(读写地址自增1),不需要向外暴露读写地址端口;

1.1 概念

FIFO存储体:分为用寄存器搭建和SRAM搭建;
寄存器搭建:存储数据量少;SRAM搭建:存储数据量大;
FIFO的重要点在于:FIFO空满的判断,有两种方式:1.是使用计数器;2.使用读写指针判断;
另外FIFO重要原则:空时不再读,满时不再写;

1.2 算法步骤

fifo设计关键:FIFO读写指针的逻辑和生成FIFO 空/满的标志位;

1.2.1 计数器法判断

内部维护一个fifo_cnt的逻辑:

0.复位时,该计数器为0,FIFO中的数据个数为0;
1.当wr_en = rd_en=1时,说明又读又写,计数器不变,FIFO中的数据个数无变化。
2.当wr_en =1,rd_en = 0时且 full=0,则 fifo_cnt +1;表示写操作且 FIFO 未满时候,FIFO 中的数据个数增加了 1 。
3.当wr_en =0,rd_en = 1时且 empty=0,则 fifo_cnt -1; 表示读操作且 FIFO 未满时候,FIFO 中的数据个数减少了 1 。
最后FIFO空满判断逻辑:
fifo_cnt =0 的时候,表示 FIFO 空,需要设置 empty=1;fifo_cnt = fifo的深度 的时候,表示 FIFO现在已经满,需要设置 full=1。

代码如下:

//====================================
//--Author  : colonel
//--Date    : 10-30
//--Module  : sync_fifo
//--Function: the sync clk fifo logic
//====================================

module sync_fifo #(
//==========================< 参数 >=========================
    parameter DATA_WIDTH = 8,
    parameter FIFO_DEPTH = 16
) (
//==========================< 端口 >=========================
    input wire clk,
    input wire rst_n,
    input wire wr_en,
    input wire [DATA_WIDTH -1:0] write_data,
    output wire wr_full,

    input wire rd_en,
    input wire [DATA_WIDTH -1:0] read_data,
    output wire rd_empty

);
//==========================< 参数 >=========================
localparam DATA_DEPTH = $clog2(DATA_WIDTH);

//==========================< 信号 >=========================
reg [DATA_WIDTH -1:0] fifo_mem[FIFO_DEPTH];
reg [DATA_DEPTH -1:0] fifo_cnt;
reg [DATA_DEPTH -1:0] wr_ptr;
reg [DATA_DEPTH -1:0] rd_ptr;


//=========================================================
//-- write_data
//=========================================================
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        fifo_mem[wr_ptr] <= 0;
    end else begin
        if (wr_en && !wr_full) begin
            fifo_mem[wr_ptr] <= write_data;
        end else begin
            fifo_mem[wr_ptr] <= fifo_mem[wr_ptr] ;
        end
    end
end

//=========================================================
//-- wr_ptr
//=========================================================
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        wr_ptr <= 0;
    end else begin
        if(!wr_full && wr_en) begin
            wr_ptr <= wr_ptr + 1'b1;
        end else begin
            wr_ptr <= wr_ptr;
        end
    end
end

//=========================================================
//-- write_data
//=========================================================

always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        fifo_mem[wr_ptr] <= 'b0;
    end else begin
        if(!wr_full && wr_en) begin
            fifo_mem[wr_ptr] <= write_data;
        end else begin
            fifo_mem[wr_ptr] <= fifo_mem[wr_ptr];
        end
    end
end

//=========================================================
//-- rd_ptr
//=========================================================
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        rd_ptr <= 'b0;
    end else begin
        if (!rd_empty && rd_en) begin
            rd_ptr <= rd_ptr + 1'b1;
        end else begin
            rd_ptr <= rd_ptr;
        end
    end
end
    
//=========================================================
//-- read_data
//=========================================================
reg [DATA_WIDTH -1:0] read_data_tmp;
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        read_data_tmp <= 'b0;
    end else begin
        if (!rd_empty && rd_en) begin
            read_data_tmp <= fifo_mem[rd_ptr];
        end else begin
            read_data_tmp <= read_data_tmp;
        end
    end
end

assign read_data = read_data_tmp;

//=========================================================
//-- fifo_cnt
//=========================================================
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        fifo_cnt <= 'b0;
    end else begin
        //--cases:
        if (wr_en && rd_en) begin
            fifo_cnt <= fifo_cnt;
        end else if (wr_en && !rd_en) begin
            fifo_cnt <= fifo_cnt + 1'b1;
        end else if (!wr_en && rd_en) begin
            fifo_cnt <= fifo_cnt - 1'b1;
        end else begin
            fifo_cnt <= fifo_cnt;
        end
    end
end

assign wr_full = fifo_cnt == FIFO_DEPTH;
assign rd_empty= fifo_cnt == 0;

endmodule

1.2.2 读写地址–高位拓展法

  • FIFO读空的情况:(读指针追上写指针)–读写指针实质为读写地址
    ① 在复位操作时,当读写指针相等时,表明 FIFO 为空;
    ② 当读指针读出 FIFO 中最后一 个字后,追赶上了写指针时,表明 FIFO 为空。如下左图。
  • FIFO写满的情况:(写指针追上读指针)
    ① 当读写指针再次相等时,表明 FIFO 为满,这种情况发生在,当写指针转了一圈,折回来(wrapped around) 又追上了读指针。如下右图。
    在这里插入图片描述

拓展高地址位判断法:

  • 当最高位不同,且其他位相同:则表示读指针或者写指针多跑了一圈,而显然不会让读指针多跑一圈,所以可能出现的情况只能是写指针多跑了一圈,就意味着FIFO被写满了。
  • 当最高位相同,且其他位相同:则表示读指针追到了写指针或者写指针追到了读指针,而显然不会让写指针追读指针(这种情况只能是写指针超过读指针一圈),所以可能出现的情况只能是读指针追到了写指针,也就意味着FIFO被读空了。

此处要考虑FIFO深度不是2^N的情况,因此需要把高低位的判断分开;

//==========================================================
//--Author  : colonel
//--Date    : 10-30
//--Module  : sync_fifo_cnt
//--Function: the sync_fifo logic using cnt way
//==========================================================

module sync_fifo_cnt_way #(
//==========================< 参数 >=========================
    parameter DATA_WIDTH = 8,
    parameter FIFO_DEPTH = 16
) (
//==========================< 端口 >=========================
    input wire clk,
    input wire rst_n,
    input wire wr_en,
    input wire [DATA_WIDTH -1:0] write_data,
    output wire wr_full,

    input wire rd_en,
    input wire [DATA_WIDTH -1:0] read_data,
    output wire rd_empty

);
//==========================< 参数 >=========================
localparam DATA_DEPTH = $clog2(DATA_WIDTH);
localparam FIFO_DEPTH_WIDTH = $clog2(FIFO_DEPTH);

//==========================< 信号 >=========================
reg [DATA_WIDTH -1:0] fifo_mem[FIFO_DEPTH];
reg [FIFO_DEPTH_WIDTH -1:0] fifo_cnt;
reg [FIFO_DEPTH_WIDTH -1:0] wr_ptr;
reg [FIFO_DEPTH_WIDTH -1:0] rd_ptr;


//=========================================================
//-- write_data
//=========================================================
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        fifo_mem[wr_ptr] <= 0;
    end else begin
        if (wr_en && !wr_full) begin
            fifo_mem[wr_ptr] <= write_data;
        end else begin
            fifo_mem[wr_ptr] <= fifo_mem[wr_ptr] ;
        end
    end
end

//=========================================================
//-- wr_ptr
//=========================================================
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        wr_ptr <= 0;
    end else begin
        if(!wr_full && wr_en) begin
            wr_ptr <= wr_ptr + 1'b1;
        end else begin
            wr_ptr <= wr_ptr;
        end
    end
end

//=========================================================
//-- write_data
//=========================================================

always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        fifo_mem[wr_ptr] <= 'b0;
    end else begin
        if(!wr_full && wr_en) begin
            fifo_mem[wr_ptr] <= write_data;
        end else begin
            fifo_mem[wr_ptr] <= fifo_mem[wr_ptr];
        end
    end
end

//=========================================================
//-- rd_ptr
//=========================================================
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        rd_ptr <= 'b0;
    end else begin
        if (!rd_empty && rd_en) begin
            rd_ptr <= rd_ptr + 1'b1;
        end else begin
            rd_ptr <= rd_ptr;
        end
    end
end
    
//=========================================================
//-- read_data
//=========================================================
reg [DATA_WIDTH -1:0] read_data_tmp;
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        read_data_tmp <= 'b0;
    end else begin
        if (!rd_empty && rd_en) begin
            read_data_tmp <= fifo_mem[rd_ptr];
        end else begin
            read_data_tmp <= read_data_tmp;
        end
    end
end

assign read_data = read_data_tmp;

//=========================================================
//-- fifo_cnt
//=========================================================
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        fifo_cnt <= 'b0;
    end else begin
        //--cases:
        if (wr_en && rd_en) begin
            fifo_cnt <= fifo_cnt;
        end else if (wr_en && !rd_en) begin
            fifo_cnt <= fifo_cnt + 1'b1;
        end else if (!wr_en && rd_en) begin
            fifo_cnt <= fifo_cnt - 1'b1;
        end else begin
            fifo_cnt <= fifo_cnt;
        end
    end
end

//=========================================================
//-- wr_full,rd_empty
//=========================================================
assign wr_full = fifo_cnt == FIFO_DEPTH;
assign rd_empty= fifo_cnt == 0;

endmodule


//==========================================================
//--Author  : colonel
//--Date    : 10-31
//--Module  : sync_fifo_addy_way
//--Function: the sync_fifo logic using addr way
//==========================================================
module sync_fifo_addr_way #(
//==========================< 参数 >=========================
    parameter DATA_WIDTH = 8,
    parameter FIFO_DEPTH = 16
) (
//==========================< 端口 >=========================
    input wire clk,
    input wire rst_n,
    input wire wr_en,
    input wire [DATA_WIDTH -1:0] write_data,
    output wire wr_full,

    input wire rd_en,
    input wire [DATA_WIDTH -1:0] read_data,
    output wire rd_empty
);
//==========================< 参数 >=========================
localparam DATA_DEPTH = $clog2(DATA_WIDTH);
localparam FIFO_DEPTH_WIDTH = $clog2(FIFO_DEPTH);

//==========================< 信号 >=========================
reg [DATA_WIDTH -1:0] fifo_mem[FIFO_DEPTH -1:0];
reg [FIFO_DEPTH_WIDTH :0] wr_ptr;
reg [FIFO_DEPTH_WIDTH :0] rd_ptr;

//=========================================================
//-- write_data
//=========================================================
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        fifo_mem[wr_ptr] <= 0;
    end else begin
        if (wr_en && !wr_full) begin
            fifo_mem[wr_ptr] <= write_data;
        end else begin
            fifo_mem[wr_ptr] <= fifo_mem[wr_ptr] ;
        end
    end
end

//=========================================================
//-- wr_ptr
//=========================================================
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        wr_ptr <= 0;
    end else begin
        if(!wr_full && wr_en && (wr_ptr[FIFO_DEPTH_WIDTH -1:0] < (FIFO_DEPTH -1))) begin
            wr_ptr <= wr_ptr + 1'b1;
        end else if(!wr_full && wr_en && (wr_ptr[FIFO_DEPTH_WIDTH -1:0] == (FIFO_DEPTH -1))) begin
            wr_ptr[FIFO_DEPTH_WIDTH] <= ~wr_ptr[FIFO_DEPTH_WIDTH];
            wr_ptr[FIFO_DEPTH_WIDTH -1:0] <= 0;
        end else begin
            wr_ptr <= wr_ptr;
        end
    end
end

//=========================================================
//-- write_data
//=========================================================

always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        fifo_mem[wr_ptr] <= 'b0;
    end else begin
        if(!wr_full && wr_en) begin
            fifo_mem[wr_ptr] <= write_data;
        end else begin
            fifo_mem[wr_ptr] <= fifo_mem[wr_ptr];
        end
    end
end

//=========================================================
//-- rd_ptr
//=========================================================
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        rd_ptr <= 'b0;
    end else begin
        if (!rd_empty && rd_en && (rd_ptr[FIFO_DEPTH_WIDTH -1:0] < (FIFO_DEPTH-1))) begin
            rd_ptr <= rd_ptr + 1'b1;
        end else if (!rd_empty && rd_en && (rd_ptr[FIFO_DEPTH_WIDTH -1:0] == (FIFO_DEPTH-1))) begin
            rd_ptr[FIFO_DEPTH_WIDTH] <= ~rd_ptr[FIFO_DEPTH_WIDTH];
            rd_ptr[FIFO_DEPTH_WIDTH -1:0] <= 'b0;
        end else begin
            rd_ptr <= rd_ptr;
        end
    end
end
    
//=========================================================
//-- read_data
//=========================================================
reg [DATA_WIDTH -1:0] read_data_tmp;
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        read_data_tmp <= 'b0;
    end else begin
        if (!rd_empty && rd_en) begin
            read_data_tmp <= fifo_mem[rd_ptr];
        end else begin
            read_data_tmp <= read_data_tmp;
        end
    end
end

assign read_data = read_data_tmp;

//=========================================================
//-- wr_full,rd_empty
//=========================================================
assign wr_full = (wr_ptr[FIFO_DEPTH_WIDTH] != rd_ptr[FIFO_DEPTH_WIDTH]) && (wr_ptr[FIFO_DEPTH_WIDTH -1:0] == rd_ptr[FIFO_DEPTH_WIDTH -1:0]);
assign rd_empty= (wr_ptr[FIFO_DEPTH_WIDTH] == rd_ptr[FIFO_DEPTH_WIDTH]) && (wr_ptr[FIFO_DEPTH_WIDTH -1:0] == rd_ptr[FIFO_DEPTH_WIDTH -1:0]);

endmodule

以上是同步FIFO的两种判断空满标志的方法

[ref]
1.https://kongsny.com/archives/112/
2.https://blog.csdn.net/qq_41895219/article/details/131932672?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-0-131932672-blog-139046484.235v43pc_blog_bottom_relevance_base5&spm=1001.2101.3001.4242.1&utm_relevant_index=3

3.https://blog.csdn.net/qq_41895219/article/details/131932672
4.https://cloud.tencent.com/developer/article/2011110
5.https://blog.csdn.net/weixin_50952710/article/details/128204972

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

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

相关文章

零基础玩转IPC之——如何实现远程实时查看监控视频(P2P)

P2P是peer-to-peer的简称&#xff0c;又称为点对点技术&#xff0c;是没有中心服务器、依靠用户群节点进行信息交换的对等式网络。区别于传统的C/S中央服务器结构&#xff0c;P2P网络中每一个用户节点即是客户端又是服务端&#xff0c;能同时作为服务器给其他节点提供服务。 优…

ubuntu20安装opencv3.2记录

系统环境 ubuntu20安装了ros-noetic&#xff0c;所以系统默认装了opencv4.2.0&#xff0c;但是跑fastlivo推荐的是opencv3.2.0&#xff0c;而且海康相机别人写的ros驱动&#xff08;海康相机ros驱动&#xff09;也是需要opencv3.2.0&#xff0c;最终还是选择安装多版本的openc…

Ecosmos携手第二十六届高交会,开启元宇宙展会新纪元

2024年11月14日至16日&#xff0c;第二十六届中国国际高新技术成果交易会&#xff08;简称“高交会”&#xff09;将在深圳国际会展中心盛大举行。 本届高交会以“科技引领发展 产业融合聚变”为主题&#xff0c;展览面积达40万平方米&#xff0c;将设置22个专业展&#xff0c;…

奇瑞汽车:降阶模型在新能源汽车热管理仿真上的应用

随着新能源汽车的发展&#xff0c;对仿真技术的要求也越来越高。那么奇瑞汽车利用降阶模型在新能源汽车热管理仿真上做了哪些应用呢&#xff1f;本次内容主要从四个方面展开介绍&#xff1a; 1、 奇瑞汽车简介&#xff1b; 2、 热管理降阶模型开发的背景&#xff1b; 3、 高低…

【NLP-06】词形还原(Lemmatization)深度解析与实践

&#x1f9d1; 博主简介&#xff1a;曾任某智慧城市类企业算法总监&#xff0c;目前在美国市场的物流公司从事高级算法工程师一职&#xff0c;深耕人工智能领域&#xff0c;精通python数据挖掘、可视化、机器学习等&#xff0c;发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…

卖三蹦子的wordpress模板

Tricycle三奔子wordpress模板 卖三轮的跨境电商B2B产品展示型网站wordpress模板&#xff0c;助力二大爷的三奔子卖向全球&#xff0c;让在中国遍地热销的三蹦子在海外也大卖. https://www.jianzhanpress.com/?p8178

Java | Leetcode题解之第535题TinyURL的加密与解密

题目&#xff1a; 题解&#xff1a; public class Codec {private Map<Integer, String> dataBase new HashMap<Integer, String>();private Random random new Random();public String encode(String longUrl) {int key;while (true) {key random.nextInt();i…

NFTScan Site:以蓝标认证与高级项目管理功能赋能 NFT 项目

自 NFTScan Site 上线以来&#xff0c;它迅速成为 NFT 市场中的一支重要力量&#xff0c;凭借对各类 NFT 集合、市场以及 NFTfi 项目的认证获得了广泛认可。这个平台帮助许多项目提升了曝光度和可见性&#xff0c;为它们在竞争激烈的 NFT 市场中创造了更大的成功机会。 在最新更…

保研考研机试攻略:python笔记(2)

&#x1f428;&#x1f428;&#x1f428;宝子们好呀&#xff0c;今天我们继续来学习N诺提供的python笔记&#xff0c;fighting&#xff01;( •̀ ω •́ )✧ 对这个系列感兴趣的宝子欢迎关注保研考研机试攻略专栏哦 ~ 目录 &#x1f428;&#x1f428;&#x1f428;4进制转…

【动手学电机驱动】 STM32-FOC(2)STM32 导入和创建项目

STM32-FOC&#xff08;1&#xff09;STM32 电机控制的软件开发环境 STM32-FOC&#xff08;2&#xff09;STM32 导入和创建项目 STM32-FOC&#xff08;3&#xff09;STM32 互补 PWM 输出 STM32-FOC&#xff08;4&#xff09;IHM03 电机控制套件介绍 STM32-FOC&#xff08;5&…

【力扣专题栏】字母异词分组,如何利用强大的容器(unordered_map)解决该问题?

题解目录 1、题目描述解释2、算法原理解析3、代码编写 1、题目描述解释 2、算法原理解析 3、代码编写 class Solution { public:vector<vector<string>> groupAnagrams(vector<string>& strs) {//创建哈希表unordered_map<string,vector<string&g…

vscode clangd for cuda 插件配置

这里写目录标题 1. 下载插件clangd,并且安装server到host2. 配置3. 安装调试插件 1. 下载插件clangd,并且安装server到host 步骤 extension下载 altshiftp, 下服务&#xff0c;如果下不下来请考虑用&#x1fa9c; 下载好后check一下&#xff0c;检查是否正常 正常的标志 注意…

Oracle 11g DataGuard GAP处理

1 说明 在Oracle Data Guard中&#xff0c;GAP是指在备库无法接收到一个或多个来自主库的归档日志文件时发生的情况&#xff0c;会导致数据保护和实时数据复制的能力受到影响。 Oracle Data Guard架构日志同步有三个阶段&#xff1a; 日志发送&#xff1b;日志接收&#xff…

2023年编程语言排行榜

随着编程语言的不断发展&#xff0c;跟踪哪些语言处于领先地位至关重要。在这两部分中&#xff0c;我们将深入研究 2023 年排名前 40 的编程语言&#xff0c;并分析它们脱颖而出的原因。 40 种顶级 TIOBE 编程语言 1. Python 受欢迎程度&#xff1a;非常高学习难度&#xff1…

ELK之路第四步——整合!打通任督二脉

ELK之路第四步——整合&#xff01;打通任督二脉 前言1.架构2.下载资源3.整合开始1.分别启动三个es2.启动kibana3.新建filebeat_logstash.yml配置文件4.修改logstash的启动配置文件5.启动logstash6.启动filebeat7.Kibana查看 4.结语 前言 在开始本篇之前&#xff0c;你需要用到…

Verilog实现的莫尔斯电码发生器

莫尔斯或者摩尔斯电码(Morse Code)&#xff0c;发明于1837年(另有一说是1836年)&#xff0c;通过不同的排列顺序来表达不同的英文字母、数字和标点符号&#xff0c;在这里作一简单处理&#xff0c;仅产生点(Dit)和划(Dah)&#xff0c;时长在0.25秒之内为点&#xff0c;超过为划…

vue3 封装aixos

1. Vue3 封装 aixos 并且 使用 aixos 请求数据 npm install axios # 或者 yarn add axios 2. Vue3 封装 aixos 并且 使用 aixos 请求数据 封装 axios可以帮助我们更好地管理 HTTP 请求&#xff0c;例如添加统一的基础URL、请求头、拦截器等功能。 下面是封装 axios的一个示…

在美团外卖上抢券 Python来实现

在美团外卖上抢券的 Python 实现 在如今的互联网时代&#xff0c;自动化脚本已经成为了许多用户生活中不可或缺的工具。尤其是在购物、抢券等场景中&#xff0c;自动化脚本能够帮助我们节省大量的时间和精力。今天&#xff0c;我们将一起探索如何使用 Python 编写一个简单的脚…

【学术论文投稿】探索嵌入式硬件设计:揭秘智能设备的心脏

【IEEE出版】第六届国际科技创新学术交流大会暨通信、信息系统与软件工程学术会议&#xff08;CISSE 2024&#xff09;_艾思科蓝_学术一站式服务平台 更多学术会议论文投稿请看&#xff1a;https://ais.cn/u/nuyAF3 目录 引言 嵌入式系统简介 嵌入式硬件设计的组成部分 设…

宝藏虚拟化学习资料大全

最近发现了关于虚拟化的宝藏资料&#xff0c;瑞斯拜&#xff01;原文链接如下&#xff1a; 500篇关于虚拟化的经典资料&#xff0c;含CPU虚拟化&#xff0c;磁盘虚拟化&#xff0c;内存虚拟化&#xff0c;IO虚拟化。 目录 &#x1fa90; 虚拟化基础 &#x1f343; 虚拟化分类&…