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

异步FIFO设计

1 FIFO简介

FIFO的本质是RAM,具有先进先出的特性。

FIFO的基本使用原则:空时不能读,满时不能写

FIFO的两个重要参数:宽度和深度

FIFO的两种类型:

  • 同步FIFO:读写时钟相同,通常用来做数据缓存
  • 异步FIFO:读写时钟不同,通常用来做跨时钟域处理

2 异步FIFO设计要点

2.1 空满信号产生的原理

读空信号:

  • 复位的时候(读指针和写指针相等),读空信号有效
  • 读指针赶上写指针的时候,读空信号有效

写满信号:

  • 写指针赶上读指针的时候

2.2 空满指针跨时钟域处理,为什么要使用Gray信号进行同步

空满信号是通过读写指针的比较来产生,但是读指针属于读时钟域,写指针属于写时钟域,读写指针的比较有一个跨时钟域的问题,因此需要对读写指针进行信号的同步:

  • 将写指针同步到读时钟域,然后读指针再和同步后的写指针比较,产生读空信号
  • 将读指针同步到写时钟域,然后写指针再和同步后的读指针比较,产生写满信号

使用格雷码Gray表示的读写指针用两级寄存器同步:
同步过程的亚稳态问题是无法解决的,需要保证即使出现亚稳态也不影响设计的功能

  1. 如果使用二进制编码表示的读写指针进行同步,当出现亚稳态的时候,将会影响设计的功能。
    例如现在将写指针同步到读时钟域,去判断读空信号。写指针0111–>1000,同时有4bit数据发生跳变,在亚稳态的影响下,同步后的写指针的数值可能是0000-1111之间的任何一个数值。本来应该判空的,但是现在没有判空,将会读取错误的数据,使得设计出现问题。
  2. 如果使用格雷码表示的读写指针进行同步,即使出现亚稳态,也不会影响设计的功能。
    格雷码的特点是,相邻的编码之间每次只有1bit数据发生变化。那么这1bit数据如果发生亚稳态会影响设计的功能吗?答案是不会。例如现在还是将写指针同步到读时钟域,去判断读空信号。假设格雷码写指针从0000->0001,写指针同步出错,出错的结果只能是0000->0000,即写指针不变。这种结果最多就是让空信号标志在FIFO不是真正空的时候产生,而不会产生空读的情形。只会影响FIFO的效率,而不会影响到FIFO的功能。
    所以Gray码保证的是同步后的读写指针即使在出错的情形下依然能够保证FIFO功能的正确性

2.3 设计的时候,读写指针的同步至少需要消耗两个时钟周期,肯定会使得空满信号的判断有延迟,会不会导致设计出错??

假设现在将写指针同步到读时钟域再和读指针比较进行FIFO空状态判断,因为在同步写指针时需要时间,而在这个同步的时间内有可能还会写入新的数据,因此同步后的写指针一定是小于或者等于当前实际的写指针,所以此时判断FIFO为空不一定是真空,这样更加保守,一共不会出现空读的情况,虽然会影响FIFO的性能,但是并不会出错。

同理将读指针同步到写时钟域再和写指针比较进行FIFO满状态判断,同步后的读指针一定是小于或者等于当前的读指针,所以此时判断FIFO为满不一定是真满,这样更保守,肯定不会出错。

总结来说异步逻辑转到同步逻辑不可避免需要额外的时钟开销,这会导致满空趋于保守,会稍微有性能损失,但是不会出错

2.4 读写时钟不同频,在同步的过程中,可能会有指针遗漏,是否会影响功能?

异步FIFO两端的时钟不是同频的,或者读快写慢,或者读慢写快,慢的时钟域同步到快的时钟域不会出现漏掉指针的情况,但是将指针从快的时钟域同步到慢的时钟域时可能会有指针遗漏。

举例:假设读慢写快

进行满标志判断的时候,需要将读指针同步到写时钟域,因为写时钟快,不会发生读指针同步遗漏的情况,但是由于同步需要消耗至少两个时钟周期,导致读指针同步延迟,读时钟域rd_ptr=3,但是写时钟域的sync_rd_ptr=2,这样可能会导致满标志信号提前产生,满并非真满,但是不影响FIFO功能。

进行空标志判断的时候,需要将写指针同步到读时钟域,因为读时钟慢,会发生写指针同步遗漏的情况,不用关心漏掉哪几个,而是担心漏掉的指针是否会对设计产生影响,比如写指针从0写到10,期间读时钟域只同步捕捉到了3、5、8这三个写指针而漏掉了其他指针。当同步到8这个写指针时,真实的写指针可能已经写到10 ,相当于在读时钟域还没来得及觉察的情况下,写时钟域可能偷偷写了数据到FIFO去,这样在判断它是不是空的时候会出现不是真正空的情况,漏掉的指针不会对FIFO的逻辑操作产生影响(即不会影响,FIFO在满的时候写数据,空的时候读数据,造成的功能错误),只会影响FIFO的工作效率。

总而言之,实际的读/写指针大于同步之后的读/写指针的数值,这种情况不会影响FIFO的功能,只会影响FIFO的效率。(2.3和2.4)均是这种情况

2.5 二进制转Gray码

原理
在这里插入图片描述
代码
在这里插入图片描述

代码编写思路
大概就是格雷码最高位与二进制码一致,其余各位为二进制码对应位与其相邻的高位异或,如格雷码的第二位为二进制的第二位与二进制码的第三位异或。因此实现代码则为二进制码本身与逻辑右移一位后的二进制码异或即可得。
在这里插入图片描述

2.6 Gray码转二进制

原理
在这里插入图片描述
在这里插入图片描述

代码
在这里插入图片描述

代码编写思路
二进制码的最高位与格雷码最高位保持一致,其余通过自生移位与异或得到,如b[2]为格雷码逻辑右移两位(逻辑右移,最高位补0)再自身四位异或,0与任何数异或均为其本身。
在这里插入图片描述

2.7 读空的条件是写指针等于读指针,写满的条件也是写指针等于读指针,到底如何区分呢?

二进制码判断空满:指针的位宽多定义一位
假设要设计深度为 8 的异步FIFO,此时定义读写指针只需要 3 位(2^3=8)就够用了,
但是我们在设计时将指针的位宽设计成 4 位,最高位的作用就是区分是读空还是写满。
具体判断规则如下:

  • 当最高位相同,其余位相同认为是读空
  • 当最高位不同,其余位相同认为是写满

格雷码判断空满:指针的位宽多定义一位
在设计中判断是读指针是否等于写指针的时候,用的是读写指针的格雷码形式
具体判断规则如下:

  • 当最高位和次高位相同,其余位相同认为是读空

  • 当最高位和次高位不同,其余位相同认为是写满

    因为格雷码是一种镜像码, 例如读指针指向 8,写指针指向 7 ,我们可以知道此时此刻并不是读空状态也不是写满状态;
    (7对应的格雷码0100;8对应得格雷码1100) 但是如果按照二进制码得判断规则,最高位不同,其余位相同,就会误判出现写满信号;因此格雷码判断空满的条件和二进制判断空满的规则不相同。

3 RTL

一个典型的FIFO模块结构如下所示:
在这里插入图片描述
下面是参考上图进行的实现(略有不同):

module async_fifo#(parameter   DEPTH   =   16,parameter   WIDTH   =   8
)(input                   wr_clk  ,input                   wr_rstn ,input                   wr_en   ,input       [WIDTH-1:0] wr_data ,input                   rd_clk  ,input                   rd_rstn ,input                   rd_en   ,output  reg [WIDTH-1:0] rd_data ,output                  rempty   ,output                  wfull    
);//------------------------------------------------------------------------------------
//                              internal vars         
//------------------------------------------------------------------------------------reg     [WIDTH-1:0] fifo_ram    [DEPTH-1:0];reg     [$clog2(DEPTH):0] wr_ptr;
reg     [$clog2(DEPTH):0] rd_ptr;wire    [$clog2(DEPTH):0] wr_ptr_g;
wire    [$clog2(DEPTH):0] rd_ptr_g;
reg     [$clog2(DEPTH):0] wr_ptr_g_d1;
reg     [$clog2(DEPTH):0] rd_ptr_g_d1;
reg     [$clog2(DEPTH):0] wr_ptr_g_d2;
reg     [$clog2(DEPTH):0] rd_ptr_g_d2;wire    [$clog2(DEPTH)-1:0] wr_addr;
wire    [$clog2(DEPTH)-1:0] rd_addr;//------------------------------------------------------------------------------------
//                             wr_ptr && rd_ptr       
//------------------------------------------------------------------------------------always@(posedge wr_clk or negedge wr_rstn)beginif(!wr_rstn)wr_ptr <= 0;else if(wr_en && !wfull)wr_ptr <= wr_ptr + 1'b1;
endalways@(posedge rd_clk or negedge rd_rstn)beginif(!rd_rstn)rd_ptr <= 0;else if(rd_en && !rempty)rd_ptr <= rd_ptr + 1'b1;
end//------------------------------------------------------------------------------------
//                             wfull && rempty       
//------------------------------------------------------------------------------------
assign wr_ptr_g = (wr_ptr >> 1) ^ wr_ptr;
assign rd_ptr_g = (rd_ptr >> 1) ^ rd_ptr;always@(posedge rd_clk or negedge rd_rstn )begin//write_ptr_g sync to read domainif(!rd_rstn){wr_ptr_g_d2,wr_ptr_g_d1} <= 0;else {wr_ptr_g_d2,wr_ptr_g_d1} <= {wr_ptr_g_d1,wr_ptr_g};
endalways@(posedge wr_clk or negedge wr_rstn)begin//read_ptr_g sync to write domainif(!wr_rstn){rd_ptr_g_d2,rd_ptr_g_d1} <= 0;else {rd_ptr_g_d2,rd_ptr_g_d1} <= {rd_ptr_g_d1,rd_ptr_g};
endassign rempty = (rd_ptr_g == wr_ptr_g_d2);
assign wfull = wr_ptr_g == {~rd_ptr_g_d2[$clog2(DEPTH):$clog2(DEPTH)-1],rd_ptr_g_d2[$clog2(DEPTH)-2:0]};//------------------------------------------------------------------------------------
//                             write && read       
//------------------------------------------------------------------------------------assign wr_addr = wr_ptr[$clog2(DEPTH)-1:0];
assign rd_addr = rd_ptr[$clog2(DEPTH)-1:0];always@(posedge wr_clk)if(wr_en && !wfull)fifo_ram[wr_addr] <= wr_data;always@(posedge rd_clk)if(rd_en && !rempty)rd_data <= fifo_ram[rd_addr];endmodule

4 Testbench

pattern只写不读、pattern只读不写、pattern写比读快

`timescale 1ns / 1psmodule tb_async_fifo();//---------------------------------------------------parameter WIDTH = 3;
parameter DEPTH = 32;reg                   wr_clk  ;
reg                   wr_rstn ;
reg                   wr_en   ;
reg       [WIDTH-1:0] wr_data ;
reg                   rd_clk  ;
reg                   rd_rstn ;
reg                   rd_en   ;
wire   [WIDTH-1:0]    rd_data ;
wire                  empty   ;
wire                  full    ;//---------------------------------------------------initial beginwr_clk = 0;forever #10 wr_clk = ~wr_clk;//50MHz
end
initial beginrd_clk = 0;forever #12.5 rd_clk = ~rd_clk;//40MHz
endinitial beginrd_rstn = 0;wr_rstn = 0;#103 ;rd_rstn = 1;wr_rstn = 1;
end//pattern1
initial beginwr_en   = 0;wr_data = 0;#203;wr_en = 1;repeat(32) @(posedge wr_clk)begin#1;wr_data = wr_data + 1;end#1;wr_en = 0;
end//pattern2
initial beginrd_en = 0;#3000;rd_en = 1;repeat(32) @(posedge rd_clk)beginend#1;rd_en = 0;
end//pattern3
initial beginrd_en = 0;wr_en = 0;#6000;wr_en = 1;rd_en = 1;repeat(300) @(posedge wr_clk)begin#1;wr_data = wr_data + 1;end#1;wr_en = 0;repeat(32) @(posedge rd_clk)beginend#1;rd_en = 0;
end
//---------------------------------------------------async_fifo#(.DEPTH(DEPTH),.WIDTH(WIDTH)
) u_async_fifo(.wr_clk  (wr_clk  ),.wr_rstn (wr_rstn ),.wr_en   (wr_en   ),.wr_data (wr_data ),.rd_clk  (rd_clk  ),.rd_rstn (rd_rstn ),.rd_en   (rd_en   ),.rd_data (rd_data ),.empty   (empty   ),.full    (full    )
);endmodule

pattern读比写快

`timescale 1ns / 1psmodule tb_async_fifo_w_slow();//---------------------------------------------------parameter WIDTH = 3;
parameter DEPTH = 32;reg                   wr_clk  ;
reg                   wr_rstn ;
reg                   wr_en   ;
reg       [WIDTH-1:0] wr_data ;
reg                   rd_clk  ;
reg                   rd_rstn ;
reg                   rd_en   ;
wire   [WIDTH-1:0]    rd_data ;
wire                  empty   ;
wire                  full    ;//---------------------------------------------------initial beginwr_clk = 0;forever #10 wr_clk = ~wr_clk;//50MHz
endinitial beginrd_clk = 0;forever #8 rd_clk = ~rd_clk;//62.5MHz
endinitial beginrd_rstn = 0;wr_rstn = 0;#103 ;rd_rstn = 1;wr_rstn = 1;
end//pattern1
initial beginwr_en   = 0;wr_data = 0;#203;wr_en = 1;repeat(32) @(posedge wr_clk)begin#1;wr_data = wr_data + 1;end#1;wr_en = 0;
end//pattern2
initial beginrd_en = 0;#3000;rd_en = 1;repeat(32) @(posedge rd_clk)beginend#1;rd_en = 0;
end//pattern3
initial beginrd_en = 0;wr_en = 0;#6000;wr_en = 1;rd_en = 1;repeat(300) @(posedge wr_clk)begin#1;wr_data = wr_data + 1;end#1;wr_en = 0;repeat(32) @(posedge rd_clk)beginend#1;rd_en = 0;
end
//---------------------------------------------------async_fifo#(.DEPTH(DEPTH),.WIDTH(WIDTH)
) u_async_fifo(.wr_clk  (wr_clk  ),.wr_rstn (wr_rstn ),.wr_en   (wr_en   ),.wr_data (wr_data ),.rd_clk  (rd_clk  ),.rd_rstn (rd_rstn ),.rd_en   (rd_en   ),.rd_data (rd_data ),.empty   (empty   ),.full    (full    )
);endmodule

pattern读写一样快

`timescale 1ns / 1psmodule tb_async_fifo_w_equal();//---------------------------------------------------parameter WIDTH = 3;
parameter DEPTH = 32;reg                   wr_clk  ;
reg                   wr_rstn ;
reg                   wr_en   ;
reg       [WIDTH-1:0] wr_data ;
reg                   rd_clk  ;
reg                   rd_rstn ;
reg                   rd_en   ;
wire   [WIDTH-1:0]    rd_data ;
wire                  empty   ;
wire                  full    ;//---------------------------------------------------initial beginwr_clk = 0;forever #10 wr_clk = ~wr_clk;//50MHz
endinitial beginrd_clk = 0;#8;forever #10 rd_clk = ~rd_clk;//50MHz
endinitial beginrd_rstn = 0;wr_rstn = 0;#103 ;rd_rstn = 1;wr_rstn = 1;
end//pattern1
initial beginwr_en   = 0;wr_data = 0;#203;wr_en = 1;repeat(32) @(posedge wr_clk)begin#1;wr_data = wr_data + 1;end#1;wr_en = 0;
end//pattern2
initial beginrd_en = 0;#3000;rd_en = 1;repeat(32) @(posedge rd_clk)beginend#1;rd_en = 0;
end//pattern3
initial beginrd_en = 0;wr_en = 0;#6000;wr_en = 1;rd_en = 1;repeat(300) @(posedge wr_clk)begin#1;wr_data = wr_data + 1;end#1;wr_en = 0;repeat(32) @(posedge rd_clk)beginend#1;rd_en = 0;
end
//---------------------------------------------------async_fifo#(.DEPTH(DEPTH),.WIDTH(WIDTH)
) u_async_fifo(.wr_clk  (wr_clk  ),.wr_rstn (wr_rstn ),.wr_en   (wr_en   ),.wr_data (wr_data ),.rd_clk  (rd_clk  ),.rd_rstn (rd_rstn ),.rd_en   (rd_en   ),.rd_data (rd_data ),.empty   (empty   ),.full    (full    )
);endmodule

参考博客:
https://zhuanlan.zhihu.com/p/551351794
https://blog.csdn.net/ZZ2588/article/details/122347438
https://blog.csdn.net/spx1164376416/article/details/121086907
https://zhuanlan.zhihu.com/p/344170711
https://wuzhikai.blog.csdn.net/article/details/121152844
https://blog.csdn.net/JustinLee2015/article/details/106527301/
https://blog.csdn.net/wuzhikaidetb/article/details/123570799
https://blog.csdn.net/weixin_44348260/article/details/119612998

相关文章:

异步FIFO设计

1 FIFO简介 FIFO的本质是RAM&#xff0c;具有先进先出的特性。 FIFO的基本使用原则&#xff1a;空时不能读&#xff0c;满时不能写 FIFO的两个重要参数&#xff1a;宽度和深度 FIFO的两种类型&#xff1a; 同步FIFO&#xff1a;读写时钟相同&#xff0c;通常用来做数据缓存…...

学习python和anaconda的经验

PYTHON 1 常用命令 1.1 1.1 注释 Python注释多行的方法有以下三种:使用ctrl+/实现多行注释、在每一行的开头使用shift+#键、输入’‘’ ‘’或者"“” “”",将要注释的代码插在中间 1.2 def init( ):函数 区分两个函数: 1.def init(self): 这种形式在__init_…...

【Linux】多线程【上】

文章目录 前言1、Linux线程概念1-1、什么是线程&#xff1f;1-1-1、如何看待页表1-1-2、回顾进程地址空间1-1-3、页表怎么进行虚拟地址到物理地址的映射的&#xff1f;1-1-4、Linux中线程的概念&#xff08;重点&#xff09;1-1-5、原生线程库1-1-6、代码测试1-1-7、知识点&…...

生成式人工智能在高等教育 IT 中的作用

作者&#xff1a;Jared Pane 通过将你大学的数据与公共 LLMs 和 Elasticsearch 安全集成来找到你需要的答案。 根据 2023 年 4 月 EDUCAUSE 的一项调查&#xff0c;83% 的受访者表示&#xff0c;生成式人工智能将在未来三到五年内深刻改变高等教育。 学术界很快就询问和想象生…...

黑龙江省DCMM认证、CSMM认证、CMMM认证、知识产权等政策奖励

2023年8月28日 为深入落实党的二十大精神&#xff0c;认真落实省第十三次党代会关于创新龙江建设的部署要求&#xff0c;全面贯彻新发展理念&#xff0c;融入和服务构建新发展格局&#xff0c;实施创新驱动发展战略&#xff0c;着力建设创新龙江&#xff0c;不断塑造振兴发展新…...

腾讯云2023年云服务器优惠活动价格表

腾讯云经常推出各种云产品优惠活动&#xff0c;为了帮助大家更好地了解腾讯云服务器的价格和优惠政策&#xff0c;下面给大家分享腾讯云最新云服务器优惠活动价格表&#xff0c;助力大家轻松上云&#xff01; 一、轻量应用服务器优惠活动价格表 1、轻量应用服务器&#xff1a;…...

Sleuth--链路追踪

1 链路追踪介绍 在大型系统的微服务化构建中&#xff0c;一个系统被拆分成了许多模块。这些模块负责不同的功能&#xff0c;组合成系统&#xff0c;最终可以提供丰富的功能。在这种架构中&#xff0c;一次请求往往需要涉及到多个服务。互联网应用构建在不同的软件模块集上&…...

MyBatis初级

文章目录 一、mybatis1、概念2、JDBC缺点2.1、之前jdbc操作2.2 、原始jdbc操作的分析 3、mybatis的使用3.1、导入maven依赖3.2、新建表3.3、实体类3.4、编写mybatis的配置文件3.5、编写接口 和 映射文件3.6、编写测试类3.7、注意事项 4、代理方式开发5、mybatis和spring整合5.1…...

Spring 学习(二)AOP

一、什么是AOP Aspect Oriented Programming&#xff0c;即面向切面编程。对一个大型项目的代码而言&#xff0c;整个系统要求关注安全检查、日志、事务等功能&#xff0c;这些功能实际上“横跨”多个业务方法。在一般的OOP编程里&#xff0c;需要在每一个业务方法内添加相关非…...

笔记1.1 计算机网络基本概念

计算机网络是通信技术与计算机技术紧密结合的产物 通信系统模型&#xff1a; 计算机网络是一种通信网络 计算机网络是互连的、自洽的计算机集合。 互连&#xff1a;互联互通 自洽&#xff1a;无主从关系 通过交换网络互连主机 Internet&#xff1a;数以百万计的互连的计算设…...

液压切管机配套用液压泵站比例阀放大器

液压切管机配套用液压泵站是液压系统的动力源&#xff0c;可按机械设备工况需要提供一定压力、流量和清洁度的工作介质。它由泵组、油箱组件、控温组件、滤油器组件及蓄能器组件等组合而成&#xff0c;液压泵站主要服务于大型管道工程。...

C++ Primer Plus 第七章笔记

目录 函数基本知识 没有返回值的函数&#xff1a;void函数 有返回值的函数&#xff1a; 函数原型 1.为什么需要函数原型&#xff1f; 2.函数原型的语法 3.函数原型的功能 按值传递函数参数 形参和实参 局部变量 参数问题 使用const指针参数 调用自身的函数&#xf…...

常用数据库的 API - 开篇

API API 这个词在大多数人看来可能和 CNS 差不多&#xff0c;前者天天听说就是用不上&#xff0c;后者天天读就是发不了。 不过&#xff0c;通过今天的一个简短介绍&#xff0c;今后 API 这个东西你就用上了&#xff0c;因为在文章最后我将会展示一个最最基础且高频的 API 使…...

C++之生成详细汇编代码(二百一十六)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…...

AIGC|当一个程序员学会用AI来辅助编程实践

一、辅助编程 作为主要以 JAVA 语言为核心的后端开发者&#xff0c;其实&#xff0c;早些时间我也用过比如 Codota、Tabnine、Github 的 Copilot、阿里的 AI Coding Assistant 等 IDEA 插件&#xff0c;但是我并没有觉得很惊奇&#xff0c;感觉就是生成一些代码片段罢了&#x…...

9.14号作业

仿照vector手动实现自己的myVector&#xff0c;最主要实现二倍扩容功能 有些功能&#xff0c;不会 #include <iostream>using namespace std; //创建vector类 class Vector { private:int *data;int size;int capacity; public://无参构造Vector(){}//拷贝构造Vector(c…...

【面试题】C/C++ 中指针和引用的区别

指针是一个独立的对象&#xff0c;它可以指向不同的变量或对象&#xff0c;可以重新赋值给其他变量。而引用是已存在的变量的别名&#xff0c;它必须在定义时初始化&#xff0c;并且不能重新绑定到另一个变量。指针可以是空指针&#xff08;nullptr&#xff09;&#xff0c;它不…...

spring boot 整合多数据源

多数据源产生的场景 一般情况下&#xff0c;不会有多数据源这样的场景出现&#xff0c;但老项目或者特殊需求的项目&#xff0c;可能会有这样的场景 同一个应用需要访问两个数据库不用数据库中间件的读写分离 注入数据源选择的时机 声明两个数据源实例&#xff0c;在getConnect…...

数据集成:数据挖掘的准备工作之一

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ &#x1f434;作者&#xff1a;秋无之地 &#x1f434;简介&#xff1a;CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作&#xff0c;主要擅长领域有&#xff1a;爬虫、后端、大数据…...

xml配置文件密码特殊字符处理

错误姿势&#xff1a; 正确姿势&#xff1a;采取转义符的方式 常用转义符&#xff1a;...

免费豆包大模型API代理部署指南:原理、实战与安全实践

1. 项目概述&#xff1a;一个免费且强大的大模型API代理 最近在折腾大语言模型应用开发的朋友&#xff0c;估计都绕不开一个核心痛点&#xff1a;API调用成本。无论是OpenAI的GPT系列&#xff0c;还是国内外的其他主流模型&#xff0c;按Token计费的模式在频繁调试和原型验证阶…...

火山引擎AgentKit实战:从零构建企业级AI智能体应用

1. 从零到一&#xff1a;AgentKit代码工坊深度解析与实战指南如果你正在寻找一个能快速上手、功能强大的企业级AI Agent开发平台&#xff0c;那么火山引擎的AgentKit绝对值得你花时间深入研究。最近&#xff0c;我花了大量时间泡在它的官方代码示例仓库bytedance/agentkit-samp…...

唐山暖气片测评:河北卓兴材质散热佳但价格略高,适合这类人群

在唐山暖气片市场&#xff0c;众多厂家各展风采。本次测评旨在为对唐山暖气片感兴趣的人群&#xff0c;提供客观、真实的产品信息。参与本次测评的产品来自河北卓兴散热器有限公司。本次测评主要基于以下几个核心维度&#xff1a;1. 材质质量&#xff08;40%&#xff09;&#…...

基于Next.js 14与Sanity构建高性能个人博客:全栈技术栈解析与实践

1. 项目概述&#xff1a;一个现代、高性能的个人博客系统 最近在折腾个人博客&#xff0c;发现了一个非常亮眼的开源项目——CaliCastle/cali.so。这不仅仅是一个博客模板&#xff0c;更是一个集成了当前前端最佳实践的完整个人网站解决方案。原作者Cali&#xff08;Calvin&am…...

多源视频流时空配准,搭建跨摄像机一体化轨迹推演计算平台

多源视频流时空配准&#xff0c;搭建跨摄像机一体化轨迹推演计算平台在数字孪生与视频孪生全域空间智能感知的建设进程中&#xff0c;各类管控场景普遍部署多品牌、多焦距、多布设姿态的异构摄像设备&#xff0c;衍生出大量编码格式各异、传输时延参差、时钟相位错位的多源异步…...

深入浅出:用Grad-CAM解锁Swin Transformer的视觉注意力

1. 为什么需要理解Swin Transformer的视觉注意力&#xff1f; 当你第一次看到Swin Transformer在图像分类任务中表现出色时&#xff0c;可能会好奇它到底"看"到了图像的哪些部分。传统的卷积神经网络&#xff08;CNN&#xff09;通过局部感受野逐步提取特征&#xff…...

以太网技术演进:从标准统一到多速率并行发展的深度解析

1. 以太网演进&#xff1a;从有序增长到“混沌”繁荣如果你在2015年前后关注过网络技术&#xff0c;可能会觉得以太网的世界突然变得有点“乱”。不再是那个我们熟悉的、每隔几年速度就提升十倍的规律节奏。当时&#xff0c;IEEE 802.3工作组内部同时推进着2.5G、5G、25G乃至40…...

别再死记硬背了!手把手教你选对PPP定位模型:UC、UD、UofC、SD到底怎么用?

精密单点定位模型实战指南&#xff1a;如何根据场景选择UC、UD、UofC与SD 在GNSS高精度定位领域&#xff0c;精密单点定位&#xff08;PPP&#xff09;技术已成为科研与工程应用的核心工具。面对UC、UD、UofC、SD四种主流模型&#xff0c;许多工程师常陷入选择困境——不同模型…...

Windows安卓应用安装器:终极免费方案,3分钟搞定电脑运行安卓应用!

Windows安卓应用安装器&#xff1a;终极免费方案&#xff0c;3分钟搞定电脑运行安卓应用&#xff01; 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 你是否曾经遇到过…...

Taotoken多模型聚合平台为arm7边缘AI应用提供稳定API服务

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 Taotoken多模型聚合平台为arm7边缘AI应用提供稳定API服务 对于在arm7架构硬件上部署轻量级AI应用的开发者而言&#xff0c;将大模型…...