异步FIFO设计
1 FIFO简介
FIFO的本质是RAM
,具有先进先出的特性。
FIFO的基本使用原则:空时不能读,满时不能写
FIFO的两个重要参数:宽度和深度
FIFO的两种类型:
- 同步FIFO:读写时钟相同,通常用来做数据缓存
- 异步FIFO:读写时钟不同,通常用来做跨时钟域处理
2 异步FIFO设计要点
2.1 空满信号产生的原理
读空信号:
- 复位的时候(读指针和写指针相等),读空信号有效
- 读指针赶上写指针的时候,读空信号有效
写满信号:
- 写指针赶上读指针的时候
2.2 空满指针跨时钟域处理,为什么要使用Gray信号进行同步
空满信号是通过读写指针的比较来产生,但是读指针属于读时钟域,写指针属于写时钟域,读写指针的比较有一个跨时钟域的问题,因此需要对读写指针进行信号的同步:
- 将写指针同步到读时钟域,然后读指针再和同步后的写指针比较,产生读空信号
- 将读指针同步到写时钟域,然后写指针再和同步后的读指针比较,产生写满信号
使用格雷码Gray
表示的读写指针用两级寄存器同步:
同步过程的亚稳态问题是无法解决的,需要保证即使出现亚稳态也不影响设计的功能
- 如果使用二进制编码表示的读写指针进行同步,当出现亚稳态的时候,将会影响设计的功能。
例如现在将写指针同步到读时钟域,去判断读空信号。写指针0111–>1000,同时有4bit数据发生跳变,在亚稳态的影响下,同步后的写指针的数值可能是0000-1111之间的任何一个数值。本来应该判空的,但是现在没有判空,将会读取错误的数据,使得设计出现问题。 - 如果使用格雷码表示的读写指针进行同步,即使出现亚稳态,也不会影响设计的功能。
格雷码的特点是,相邻的编码之间每次只有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,具有先进先出的特性。 FIFO的基本使用原则:空时不能读,满时不能写 FIFO的两个重要参数:宽度和深度 FIFO的两种类型: 同步FIFO:读写时钟相同,通常用来做数据缓存…...
学习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、什么是线程?1-1-1、如何看待页表1-1-2、回顾进程地址空间1-1-3、页表怎么进行虚拟地址到物理地址的映射的?1-1-4、Linux中线程的概念(重点)1-1-5、原生线程库1-1-6、代码测试1-1-7、知识点&…...
生成式人工智能在高等教育 IT 中的作用
作者:Jared Pane 通过将你大学的数据与公共 LLMs 和 Elasticsearch 安全集成来找到你需要的答案。 根据 2023 年 4 月 EDUCAUSE 的一项调查,83% 的受访者表示,生成式人工智能将在未来三到五年内深刻改变高等教育。 学术界很快就询问和想象生…...
黑龙江省DCMM认证、CSMM认证、CMMM认证、知识产权等政策奖励
2023年8月28日 为深入落实党的二十大精神,认真落实省第十三次党代会关于创新龙江建设的部署要求,全面贯彻新发展理念,融入和服务构建新发展格局,实施创新驱动发展战略,着力建设创新龙江,不断塑造振兴发展新…...
腾讯云2023年云服务器优惠活动价格表
腾讯云经常推出各种云产品优惠活动,为了帮助大家更好地了解腾讯云服务器的价格和优惠政策,下面给大家分享腾讯云最新云服务器优惠活动价格表,助力大家轻松上云! 一、轻量应用服务器优惠活动价格表 1、轻量应用服务器:…...
Sleuth--链路追踪
1 链路追踪介绍 在大型系统的微服务化构建中,一个系统被拆分成了许多模块。这些模块负责不同的功能,组合成系统,最终可以提供丰富的功能。在这种架构中,一次请求往往需要涉及到多个服务。互联网应用构建在不同的软件模块集上&…...
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,即面向切面编程。对一个大型项目的代码而言,整个系统要求关注安全检查、日志、事务等功能,这些功能实际上“横跨”多个业务方法。在一般的OOP编程里,需要在每一个业务方法内添加相关非…...
笔记1.1 计算机网络基本概念
计算机网络是通信技术与计算机技术紧密结合的产物 通信系统模型: 计算机网络是一种通信网络 计算机网络是互连的、自洽的计算机集合。 互连:互联互通 自洽:无主从关系 通过交换网络互连主机 Internet:数以百万计的互连的计算设…...
液压切管机配套用液压泵站比例阀放大器
液压切管机配套用液压泵站是液压系统的动力源,可按机械设备工况需要提供一定压力、流量和清洁度的工作介质。它由泵组、油箱组件、控温组件、滤油器组件及蓄能器组件等组合而成,液压泵站主要服务于大型管道工程。...
C++ Primer Plus 第七章笔记
目录 函数基本知识 没有返回值的函数:void函数 有返回值的函数: 函数原型 1.为什么需要函数原型? 2.函数原型的语法 3.函数原型的功能 按值传递函数参数 形参和实参 局部变量 参数问题 使用const指针参数 调用自身的函数…...
常用数据库的 API - 开篇
API API 这个词在大多数人看来可能和 CNS 差不多,前者天天听说就是用不上,后者天天读就是发不了。 不过,通过今天的一个简短介绍,今后 API 这个东西你就用上了,因为在文章最后我将会展示一个最最基础且高频的 API 使…...
C++之生成详细汇编代码(二百一十六)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…...
AIGC|当一个程序员学会用AI来辅助编程实践
一、辅助编程 作为主要以 JAVA 语言为核心的后端开发者,其实,早些时间我也用过比如 Codota、Tabnine、Github 的 Copilot、阿里的 AI Coding Assistant 等 IDEA 插件,但是我并没有觉得很惊奇,感觉就是生成一些代码片段罢了&#x…...
9.14号作业
仿照vector手动实现自己的myVector,最主要实现二倍扩容功能 有些功能,不会 #include <iostream>using namespace std; //创建vector类 class Vector { private:int *data;int size;int capacity; public://无参构造Vector(){}//拷贝构造Vector(c…...
【面试题】C/C++ 中指针和引用的区别
指针是一个独立的对象,它可以指向不同的变量或对象,可以重新赋值给其他变量。而引用是已存在的变量的别名,它必须在定义时初始化,并且不能重新绑定到另一个变量。指针可以是空指针(nullptr),它不…...
spring boot 整合多数据源
多数据源产生的场景 一般情况下,不会有多数据源这样的场景出现,但老项目或者特殊需求的项目,可能会有这样的场景 同一个应用需要访问两个数据库不用数据库中间件的读写分离 注入数据源选择的时机 声明两个数据源实例,在getConnect…...
数据集成:数据挖掘的准备工作之一
⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ 🐴作者:秋无之地 🐴简介:CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作,主要擅长领域有:爬虫、后端、大数据…...
xml配置文件密码特殊字符处理
错误姿势: 正确姿势:采取转义符的方式 常用转义符:...
遥感数据与作物模型同化
基于过程的作物生长模拟模型DSSAT是现代农业系统研究的有力工具,可以定量描述作物生长发育和产量形成过程及其与气候因子、土壤环境、品种类型和技术措施之间的关系,为不同条件下作物生长发育及产量预测、栽培管理、环境评价以及未来气候变化评估等提供了…...
UI库DHTMLX Suite v8.2发布全新表单组件,让Web表单实现高度可定制!
DHTMLX Suite v8.2日前已正式发布,此版本的核心是DHTMLX Form,这个小部件接收了4个备受期待的新控件,如Fieldset、Avatar、Toggle和ToggleGroup。官方技术团队还为Grid和TreeGrid小部件中的页眉/页脚工具提示提供了一系列新的配置选项等。 在…...
河北省图书馆典藏《乡村振兴振兴战略下传统村落文化旅游设计》许少辉八一新著
河北省图书馆典藏《乡村振兴振兴战略下传统村落文化旅游设计》许少辉八一新著...
什么是卷积002
文章目录 前言1.卷积网络和传统网络区别2.卷积神经网络整体架构1.输入层2. 卷积层3.池化层4.全连接层 5.神经网络6.经典网络1.Alexnet2. Vgg3.Resnet 残差网络-特征提取 7.感受野 前言 大纲目录 首先链接图像颜色通道 1.卷积网络和传统网络区别 右边的就是CNN,卷…...
黑马JVM总结(八)
(1)StringTable面试题 1.8 1.6时 (2)StringTable的位置 jvm1.6时StringTable是常量池的一部分,它随着常量池存储在永久代当中,在1.7、1.8中从永久代变成了堆中,为什么做这个更改呢?…...
开源网安入选广东省网络空间安全标准化技术委员会新技术及应用安全技术工作组成员单位
近日,第二届广东省网络空间安全标准化技术委员会(GD/TC 124)(以下简称省网安标委)正式成立。为进一步发挥省网安标委在支撑网络强国建设、推进网络安全产业高质量发展过程中,示范引领核心技术攻关、创新产品…...
Nginx配置指南:如何定位、解读与优化Linux上的Nginx设置
🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🐅🐾猫头虎建议程序员必备技术栈一览表📖: 🛠️ 全栈技术 Full Stack: 📚…...
辉瑞与吉利德科学:制药巨头的新冠病毒之战
来源:猛兽财经 作者:猛兽财经 总结: (1)猛兽财经认为,华尔街低估了辉瑞(PFE)和吉利德科学(GILD)的前景,因为它们在开发新冠病毒疫苗和药物方面都…...
x86架构基础汇编知识
通用寄存器 EAX 32位 函数返回值 AX 低16位 AH 高八位 AL 低八位 EBX 32位 ECX 32位 循环次数,this指针 EDX 32位 EBP 32位 栈底寄存器 ESP 32位 栈顶寄存器 ESI 源索引寄存器 EDI 目标索引寄存器 EIP 无法直接通过汇编操作 例子 mov al,0xff …...
ThreadLocal的原理
ThreadLocal是Java中的一个类,它提供了线程本地变量的功能。每个线程都可以独立地访问自己的ThreadLocal变量,并且不会受到其他线程的干扰。 public class ThreadLocal<T> { ThreadLocal的原理是通过使用一个ThreadLocalMap来存储每个线程的变量副…...
做软件贵还是做网站贵/新产品的推广销售方法
package com.jh.test01;public class AutoLion {// 属性: 颜色 黄色String color "黄色";// 函数:跑,叫;// 跑public void run() {System.out.println("跑得很快哦");}// 叫public String bark() {return"吼--叫";}/** 获取颜色的函数。*/ // i…...
wordpress商城 注册/百度网站制作
前言我个人还在使用PHP5.6,7.3的话纯粹是拿来做测试的,因为PHP7已经支持强类型了,不再支持根据字符串调用函数的方法了,所以我的个人项目的PHP版本停留在了5.6。最近的话想折腾一下,试试PHP5.6、7.3和Tomcat7、8、9的各…...
有没有网站教做美食的/seo监控
在之前讨论HashMap与HashTable时提到过,HashMap没有任何关于线程安全的处理,所以它不适合线程不安全的场景,而HashTable所有的操作方法都是加锁的,所以它是线程安全的,但是由于HashTable的一些设计上的缺陷比如每一次p…...
安徽池州网站制作/推广工具有哪些
1.将后台返回的JSON数据存入浏览器sessionStorage: sessionStorage.setItem(‘key’,JSON.stringify(value)); 2.从sessionStorage中取出数据 var data JSON.parse(sessionStorage.getItem(‘key’)); 如果直接存,后台console.log(json)出来的会变成[object&am…...
中高端网站建设公司/关键词智能调词工具
2019独角兽企业重金招聘Python工程师标准>>> 查看某个表的建表语句 :show create table data_statdata; drop index ts on data_statdata; 索引是加速查询的主要手段,特别对于涉及多个表的查询更是如此。本节中,将介绍索引的作用…...
做网站编程时容易遇到的问题/百度seo正规优化
datediff()函数返回两个日期之间的时间。 detediff(datepart,startdate.endddate) satrtdate和enddate是你要计算的开始时间和截止时间 datepart可以是下面的值: 年,月 ,周,日,时,分,秒 举…...