
《硬件架构的艺术》学习笔记(3.2)---同步FIFO设计
对于深度为4的FIFO出现满时的情况。当wr_ptr指向“3”(DEPTH - 1)时,随后的时钟下wr_ptr指向0等于rd_ptr,此时FIFO满。同理,当读操作使两个指针在下一个时钟相等时,FIFO空。
另一种方式通过指针的形式来直接判断“empty”、“full”信号(指针便是在地址前面多加一位,如上图所示)。首先我们确定一点:写指针是恒领先于读指针的。当读写指针完全相同的情况下,FIFO空;当写指针领先读指针一圈的时候,FIFO满。
发布日期:2021-05-06 19:13:42
浏览次数:19
分类:技术文章
本文共 2562 字,大约阅读时间需要 8 分钟。
同步FIFO设计
对于跨时钟域的数据传输,同步FIFO并不是好选择,异步FIFO才是最好的选择,这是由于同步FIFO的读写时钟相同。那么为什么还要介绍同步FIFO呢???通过学习《硬件架构的艺术》之后,对同步FIFO的“空”“满”标志的生成有了更加深刻的认识,在这里和大家分享、交流一下。
同步FIFO的架构
1)FIFO存储器
**实现功能:**对外部写入数据进行存储;
**verilog实现:**通过一个二维数组来抽象描述, reg [WIDTH:0] mem [DEPTH:0]; 。2)读/写指针
**实现功能:**产生FIFO存储器的读/写地址;
**verilog实现:**读/写指针分别通过2个计数器来实现。
3)状态模块(空/满信号生成)
1. reg寄存器形式输出“empty”、“full”信号

**verilog实现:**生成的信号为reg寄存器类型,没有毛刺。

2. wire线网形式输出“empty”、“full”信号

**verilog实现:**生成的信号为wire线网类型,有毛刺的风险。

3. 上述两种生成“empty”、“full”信号的对比
代码实例 8 * 16同步FIFO
module sync_fifo( input wire clk, input wire rstn, input wire wen, input wire ren, input wire[7:0] data_in, output wire empty, output wire full, output reg [7:0] data_out);reg[7:0] mem[15:0]; wire w_wen;wire r_ren;wire[3:0] waddr;wire[3:0] raddr;reg [4:0] wpoint;reg [4:0] rpoint;assign waddr = wpoint[3:0];assign raddr = rpoint[3:0];assign w_wen = wen & !full; assign r_ren = ren & !empty;// generate wpoint 5bitalways @ (posedge clk or negedge rstn) begin if(rstn == 0) wpoint <= 5'd0; else if(w_wen == 1) wpoint <= wpoint + 1;end// generate rpoint 5bitalways @ (posedge clk or negedge rstn) begin if(rstn == 0) rpoint <= 5'd0; else if(r_ren == 1) rpoint <= rpoint + 1;endalways @ (posedge clk or negedge rstn) begin if(rstn == 0) mem[waddr] <= 8'h00; else if(w_wen == 1) mem[waddr] <= data_in;endalways @ (posedge clk or negedge rstn) begin if(rstn == 0) data_out <= 8'h00; else if(r_ren == 1) data_out <= mem[raddr];end// the first methodreg src_full;always @ (posedge clk or negedge rstn) begin if(rstn == 0) src_full <= 0; else if(ren == 1) src_full <= 0; else if((wen == 1) && (raddr == waddr + 1'b1)) src_full <= 1;endreg src_empty;always @ (posedge clk or negedge rstn) begin if(rstn == 0) src_empty <= 1; else if(wen == 1) src_empty <= 0; else if((ren == 1) && (waddr == raddr + 1'b1)) src_empty <= 1;endassign full = src_full;assign empty = src_empty;// the second method/* assign empty = (wpoint[4] == rpoint[4]) ? ((wpoint[3:0] == rpoint[3:0]) ? 1 : 0) : 0; assign full = (wpoint[4] == rpoint[4]) ? 0 : ((wpoint[3:0] == rpoint[3:0]) ? 1 : 0); */endmodule
发表评论
最新留言
表示我来过!
[***.240.166.169]2025年03月09日 22时45分32秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
8皇后问题 递归 函数调用是重点
2019-03-03
1541 +1 *2 ²
2019-03-03
面试别慌!阿里专家带你从【入门+基础+进阶+项目】攻破SpringBoot
2019-03-03
【Java面试】30个 Java 集合面试必备的问题和答案
2019-03-03
华为鸿蒙到底是不是安卓系统套了个壳?
2019-03-03
fragment中recyclerview的重新加载问题
2019-03-03
window程序设计(1):第一个windows程序
2019-03-03
windows程序设计(4):文本输出
2019-03-03
21.2.3总结
2019-03-03
线性代数和数学期望杂题
2019-03-03
【SSL_P2876】2017年东莞市信息学特长生测试题 工程
2019-03-03
【洛谷_P1433】吃奶酪
2019-03-03
Base理论介绍
2019-03-03
volatile关键字和AtomicInteger
2019-03-03
redisTemplate.opsForHash()
2019-03-03
maven生命周期
2019-03-03
方法的绑定机制-静态绑定和动态绑定
2019-03-03
服务调用
2019-03-03
GateWay限流
2019-03-03