本文使用 Zhihu On VSCode 创作并发布

跨时钟域同步(异步FIFO)

之前学习了跨时钟域下的单bit信号同步的方法,这些单bit信号多是作为控制信号或者标志信号来使用,再实际的项目中,处理多bit数据也是十分常见的,即数据的同步。
异步FIFO的实现其实本质上和双口RAM是一样的,其实现思路就是将数据在src_clk的时钟下写入自己设定大小的ram中,然后通过读时钟des_clk从ram中将数据读出来即可。
本次还是以一个具体的例子来说明其实现,现在我们从一个较低的时钟域进入到一个较高的时钟域中,低时钟域的数据信号为8bit数据,现在需要将其缓存,并转换成32bit的信号送入32位宽的总线上进行传输。具体实现代码如下:

module nsync_fifo(input src_clk,input rst_n,input des_clk,input [8-1:0] fifo_data_in,input fifo_data_in_vaild,output reg  fifo_data_out_vaild,output [32-1:0] fifo_data_out);// write fifo
reg [1:0] buffer_wr_addr;
reg [32-1:0] temp_buffer;
always @(posedge src_clk or negedge rst_n)
beginif (!rst_n)beginbuffer_wr_addr <= 2'b00;endelsebeginbuffer_wr_addr <= (fifo_data_in_vaild) ? buffer_wr_addr + 1'b1 : buffer_wr_addr;end
endalways @(posedge src_clk)
beginif (fifo_data_in_vaild)begincase(buffer_wr_addr)2'd0:temp_buffer[0+:8] <=  fifo_data_in;2'd1:temp_buffer[8+:8] <=  fifo_data_in;2'd2:temp_buffer[16+:8] <=  fifo_data_in;2'd3:temp_buffer[24+:8] <=  fifo_data_in;endcaseend
end//gen wr_fifo signal && sync
reg fifo_wr;
reg fifo_wr_sync;
wire fifo_wr_clr;
reg fifo_wr_dfb;
always @(posedge src_clk)
beginfifo_wr <= (&buffer_wr_addr & fifo_data_in_vaild);
endassign fifo_wr_clr = !rst_n | fifo_wr_sync;  // feed backalways @(posedge fifo_wr or posedge fifo_wr_clr)
beginif (fifo_wr_clr)beginfifo_wr_dfb <= 1'b0;endelse beginfifo_wr_dfb <= 1'b1;end
endalways @(posedge des_clk)   // under des_clk sampled
beginfifo_wr_sync <= fifo_wr_dfb;
end// recv fifo
wire recv_fifo_wr;
reg [1:0] recv_fifo_wr_addr;assign recv_fifo_wr = fifo_wr_sync;
always @(posedge des_clk or rst_n)
beginif (!rst_n)beginrecv_fifo_wr_addr <= 2'b00;endelsebeginrecv_fifo_wr_addr <= (recv_fifo_wr) ? recv_fifo_wr_addr + 1'b1 : recv_fifo_wr_addr;end
end// sync fifo data
reg [32-1:0] fifo_0;
reg [32-1:0] fifo_1;
always @(posedge des_clk)
beginif (recv_fifo_wr)  // only buffer_wr_addr == 3 genbegincase (recv_fifo_wr_addr[0])1'b0 : fifo_0 <= temp_buffer;1'b1 : fifo_1 <= temp_buffer; endcaseend
end// read data from recv fifo
wire [1:0] recv_fifo_cnt;
wire recv_fifo_full;
wire recv_fifo_ready;
reg [1:0] recv_fifo_rd_addr;
assign recv_fifo_ready = | recv_fifo_cnt;
assign recv_fifo_full = recv_fifo_cnt[1]; // 2'b11 = 3
assign recv_fifo_cnt = recv_fifo_wr_addr - recv_fifo_rd_addr;always @(posedge des_clk or negedge rst_n)
beginif (!rst_n)beginrecv_fifo_rd_addr <= 2'b00;endelsebeginrecv_fifo_rd_addr <= (recv_fifo_ready) ? recv_fifo_rd_addr + 1'b1 : recv_fifo_rd_addr;end
endreg [32-1:0] recv_fifo_data;
always @(*)
begincase(recv_fifo_rd_addr[0])1'b0 : recv_fifo_data = fifo_0;1'b1 : recv_fifo_data = fifo_1;endcase
end// out
assign fifo_data_out = recv_fifo_data;
always @(posedge des_clk or negedge rst_n)
beginif(!rst_n)beginfifo_data_out_vaild <= 1'b0;endelsebeginfifo_data_out_vaild <= recv_fifo_ready;end
endendmodule

从上面的代码可以发现,我这里将src_clk中的写信号fifo_wr通过上章讲解的单bit反馈同步方法同步到了des_clk的时钟域下fifo_wr_sync;这样后续的信号处理造作就可以在我们的目标时钟des_clk下进行操作了。因为这里需要缓存的数据很少,地址线就显得比较简单了,通过一个简单的乒乓操作不断将数据从buffer中写入fifo_0和fifo_1中;只要fifo不空,就开始读数据。时序如下:

Image

异步fifo_跨时钟域同步(异步FIFO)相关推荐

  1. FPGA跨时钟域处理方法FIFO

    1.1 FPGA跨时钟域处理方法FIFO 1.1.1 本节目录 1)本节目录: 2)本节引言: 3)FPGA简介: 4)FPGA跨时钟域处理方法FIFO: 5)结束语. 1.1.2 本节引言 &quo ...

  2. 为什么多比特不能采用打两拍的方法进行跨时钟域同步?

    (1)为什么多比特不能采用打两拍的方法进行跨时钟域同步? 原因1:假设从时域A垮到时域B,是域A从00变到11,在时域B还能采样到从00变到11吗?在时域B中,时钟的上升沿来的时间是肯定一致的,但是各 ...

  3. FPGA笔记2——跨时钟域同步信号方法

    亚稳态 触发器是FPGA设计中最常用的基本器件.触发器工作过程中存在数据的建立(setup)和保持(hold)时间.对于使用上升沿触发的触发器来说,建立时间就是在时钟上升沿到来之前,触发器数据端数据保 ...

  4. 跨时钟域同步1---亚稳态的产生和解决方案

    以下内容参考自:<正点原子逻辑设计指南> 逻辑设计中一般存在多个时钟,那么信号在多个时钟之间如何切换呢?这个就涉及到了异步电路设计,异步电路设计也是逻辑设计中非常重要的设计,可以说异步处理 ...

  5. 跨时钟域同步-结绳法

    结绳法的主要思想是利用数据的边沿做时钟,将脉冲延长,直到采集到数据,然后复位. 上图是结绳法的电路示意图,这里需要注意的是,clkB域需要等待三个clkB才会在最后一个寄存器输出并完成输入端的复位.所 ...

  6. 异步时钟引起的亚稳态问题和跨时钟域电路设计

    本文总结由数字电路设计的异步时钟引起的亚稳态问题,并针对亚稳态问题提出的处理方法和跨时钟域电路设计方法.重点是分析由异步时钟引起的跨时钟域CDC问题,后续将会总结由复位引起的电路亚稳态问题. 一.亚稳 ...

  7. 跨时钟域传输和Verilog代码

    文章目录 基本概念 一.单bit信号 1.慢时钟域信号同步到快时钟域 2.快时钟域信号同步到慢时钟域 3.结绳法处理单bit信号跨时钟域 二.多bit控制信号跨时钟域同步 三.多bit数据流跨时钟域同 ...

  8. 跨时钟域的亚稳态处理、为什么要打两拍不是打一拍、为什么打两拍能有效?...

    转自|https://blog.csdn.net/Hide_in_Code/article/details/126600563 整理|比特波特 个人疑惑 在学习 "跨时钟域的亚稳态的应对措施 ...

  9. 【Chips】跨时钟域的亚稳态处理、为什么要打两拍不是打一拍、为什么打两拍能有效?

    Title: 跨时钟域的亚稳态处理.为什么要打两拍不是打一拍.为什么打两拍能有效? 前言 个人颜色习惯: 黑色加粗:突出显示: 红色:重要: 洋红色:产生的疑问 question: 蓝色:个人思考 或 ...

最新文章

  1. pyhon滤镜详细教程
  2. Java 异常处理的误区和经验总结--转载
  3. sql server 海量数据速度提升:SQL优化-索引(7) 【转】
  4. 深入浅出学Hive:Hive参数
  5. Linux中source是什么指令?
  6. sap相关性不能被编译_经典综述编译丨生物硝化抑制丨NAT PLANTS:现代农业中的氮转化和生物硝化抑制作用...
  7. CocosCreator发布web-desktop获取本地资源
  8. C语言练字用小软件 — Practise_Calligraphy_1.0(ANSI)
  9. Openssl genrsa命令
  10. D. Binary Spiders(思维+字典树)
  11. 罗切斯特大学排名计算机排名,2020年罗切斯特大学QS世界排名
  12. 收藏||二叉树的遍历:颜色标记法(前序、中序、后序通用)
  13. 技术总监是干什么的?
  14. Node.js + Socket.io 实现一对一即时聊天
  15. 案件精灵9判断坐标颜色变化发出提示音(按键精灵9接收通知必备)
  16. Fiddler 的几个用法
  17. 计算机应用基础教学课三维目标,《计算机应用基础》项目教学课程教案.doc
  18. 艾司博讯:拼多多畅销榜热卖指数怎么算
  19. 南方电网要的计算机二级吗,考南方电网需要过计算机二级和英语四级么
  20. 网络流(所有常用类型网络流算法的模板)

热门文章

  1. 显示当前没有家庭组计算机,已创建家庭组且加入家庭组,但显示“当前没有其他可用的家庭组计算机?”...
  2. python函数type的用意_python中type()是什么意思
  3. C++全局变量和局部变量名称可以相同
  4. matlab/ansys协同的一个例子
  5. CNN中的卷积操作与权值共享
  6. OpenCV与图像处理学习十一——分水岭算法(含代码)
  7. tensorflow实现反卷积
  8. Docker 原理、学习教程
  9. CompletableFuture详解~thenCompose
  10. Spring Data JPA 从入门到精通~Naming命名策略详解及其实践