01 【Verilog实战】同步FIFO的设计(附源码RTL/TB)
虚拟机:VMware -14.0.0.24051
环 境:ubuntu 18.04.1
脚 本:makefile(点击查看)
应用工具:vcs 和 verdi
写在前面
- 这个专栏的内容记录的是个人学习过程,博文中贴出来的代码是调试前的代码,方便bug重现。
- 调试后的程序提供下载,【下载地址】
- 发现了一个
Verilog宝藏刷题网站
,网站提供在线仿真环境(点击直达),同时新开了一个<刷题记录>专栏,持续打卡中…
路 线:
- 【verilog实战】同步FIFO设计(附源码RTL/TB)
- 【Verilog实战】异步FIFO设计(附源码RTL/TB)
- 【Verilog实战】UART通信协议,半双工通信方式(附源码RTL/TB)
- 【Verilog实战】SPI协议接口设计(附源码RTL/TB)
- 【Verilog实战】AMBA 3 APB接口设计(附源码RTL/TB)
- 【Verilog实战】AMBA AHB接口设计(附源码RTL/TB)
- 【Verilog实战】AMBA AXI接口设计(附源码RTL/TB)
- 【Verilog实战】UART2APB bridge 设计(附源码RTL/TB)
- 【Verilog实战】AHB2APB bridge 设计(附源码RTL/TB)
文章目录
- 一、学习内容
- 二、基本概念
- 三、Spec
- (1) Function description
- (2) Feature list
- (3) Block diagram
- (4) Interface description
- (5) Timing
- 四、RTL design
- 五、分析和小结
- (1)分析
- (2)小结
- ✍✍☛ [题库入口](https://www.nowcoder.com/link/pc_csdncpt_xlin_verilog)
一、学习内容
- 同步FIFO的写时钟和读时钟为同一个时钟,FIFO内部所有逻辑都是同步逻辑,常常用于交互数据缓冲。
- 典型同步FIFO有三部分组成: (1) FIFO写控制逻辑; (2)FIFO读控制逻辑;(3)FIFO 存储实体(如Memory、Reg)。
- FIFO写控制逻辑主要功能:产生FIFO写地址、写有效信号,同时产生FIFO写满、写错等状态信号;
- FIFO读控制逻辑主要功能:产生FIFO读地址、读有效信号,同时产生FIFO读空、读错等状态信号
二、基本概念
- 同步FIFO的“同步”是什么意思?
- FIFO是什么,有什么用?
- 接口都有什么
- 同步:时钟间有确定的倍数关系或确定的相位关系
- FIFO:Frist-in-first-out,先进先出,是一种数据缓存器,实现速率匹配。
既然是数据缓冲器,那么缓冲器的大小,存储深度,读写地址和存储器空满状态都需要确定。
一般FIFO使用循环指针
(计数溢出自动归零)。一般可以称写指针为头head,读指针为尾tail。初始化时,读写指针指向同一数据地址。
上图可见,FIFO初始化时,WP和RP指针指向同一数据单元。WP指向下一个将要写入的数据单元,RP指向将要读出的数据单元,两者是一个追赶过程。可以设置一个计数器,只写,来一个数据,写一个,写地址,+1,计数器+1,写满为止;只读,来一个,读出一个数据,读地址+1,计数器-1;同时读写,计数器值不变,读写地址均+1。
三、Spec
(1) Function description
同步FIFO实现了对write/read的控制,其接口解决了接口两端数据速率不匹配的问题。
(2) Feature list
- 支持存储宽度、深度可配置
- 时钟工作频率为1MHz
(3) Block diagram
模块主要分为读/写接口、读/写指针、读写指针的比较逻辑和array存储阵列四部分。
- 读/写接口:为模块提供读写数据和读写使能信号;
- 读写指针:主要标志读写指针当前array的地址
- 比较逻辑:
- 使用element counter(elem_cnt)记录FIFO RAM 中的数据个数:
▷ 等于0时,给出empty信号;等于BUF_LENGTH时,给出full信号 - elem_cnt:
▷ 写而未满时增加1
▷ 读而未空时减1
▷ 同时发生读写操作时,elem_cnt不变
(4) Interface description
(5) Timing
分为三部分,写操作,读操作,读写操作。
四、RTL design
- DUT模块
module sync_fifo
#(parameter DATA_WIDTH = 32,parameter DATA_DEPTH = 8 ,parameter PTR_WIDTH = 3
//parameter PTR_WIDTH = $clog2(DATA_DEPTH)
)
(input wire clk_i ,input wire rst_n_i ,//write interfaceinput wire wr_en_i ,input wire [DATA_WIDTH-1:0] wr_data_i,//read interfaceinput wire rd_en_i ,output reg [DATA_WIDTH-1:0] rd_data_o,//Flags_ooutput reg full_o ,output reg empty_o
);reg [DATA_WIDTH-1:0] regs_array [DATA_DEPTH-1:0];reg [PTR_WIDTH-1 :0] wr_ptr ;reg [PTR_WIDTH-1 :0] rd_ptr ;reg [PTR_WIDTH :0] elem_cnt ;reg [PTR_WIDTH :0] elem_cnt_nxt ;//Flagswire full_comb ;wire empty_comb ;/*---------------------------------------------------\--------------- write poiter addr ----------------
\---------------------------------------------------*/
always @ (posedge clk_i or negedge rst_n_i) beginif (!rst_n_i) beginwr_ptr <= 3'b0;endelse if (wr_en_i && !full_o) beginwr_ptr <= wr_ptr + 3'b1;end
end/*---------------------------------------------------\-------------- read poiter addr ------------------
\---------------------------------------------------*/
always @ (posedge clk_i or negedge rst_n_i) beginif (!rst_n_i) beginrd_ptr <= 3'b0;endelse if (rd_en_i && !empty_o) beginrd_ptr <= rd_ptr + 3'b1;end
end/*---------------------------------------------------\--------------- element counter ------------------
\---------------------------------------------------*/always @ (posedge clk_i or negedge rst_n_i) beginif (!rst_n_i) beginelem_cnt <= 4'b0;endelse if (wr_en_i && rd_en_i && !full_o && !empty_o) beginelem_cnt <= elem_cnt;endelse if(wr_en_i && !full_o) beginelem_cnt <= elem_cnt + 1'b1;endelse if(rd_en_i && !empty_o) beginelem_cnt <= elem_cnt - 1'b1;end
end/*---------------------------------------------------\------------- generate the flags -----------------
\---------------------------------------------------*/
always @(*) beginif(!rst_n_i) beginelem_cnt_nxt = 1'b0;endelse if(elem_cnt != 4'd0 && rd_en_i && !empty_o) beginelem_cnt_nxt = elem_cnt - 1'b1; endelse if(elem_cnt != 4'd8 && wr_en_i && !full_o) beginelem_cnt_nxt = elem_cnt + 1'b1; endelse beginelem_cnt_nxt = elem_cnt;end
endassign full_comb = (elem_cnt_nxt == 4'd8);
assign empty_comb = (elem_cnt_nxt == 4'd0);always @ (posedge clk_i or negedge rst_n_i) beginif (!rst_n_i) beginfull_o <= 1'b0;endelse beginfull_o <= full_comb;end
endalways @ (posedge clk_i or negedge rst_n_i) beginif (!rst_n_i) beginempty_o <= 1'b1;endelse beginempty_o <= empty_comb;end
end/*---------------------------------------------------\-------------------- read data -------------------
\---------------------------------------------------*/
always @ (posedge clk_i or negedge rst_n_i) beginif (!rst_n_i) beginrd_data_o <= 32'b0;endelse if(rd_en_i && !empty_o) beginrd_data_o <= regs_array[rd_ptr];end
end/*---------------------------------------------------\------------------- write data -------------------
\---------------------------------------------------*/
reg [PTR_WIDTH:0] i;always @ (posedge clk_i or negedge rst_n_i) beginif (!rst_n_i) beginfor(i=0;i<DATA_DEPTH;i=i+1) beginregs_array[i] <= 32'b0;endendelse if(wr_en_i && !full_o) beginregs_array[wr_ptr] <= wr_data_i;end
endendmodule
- tb
module tb_sync_fifo;reg clk_i ;reg rst_n_i ;reg wr_en_i ;reg [31:0] wr_data_i;reg rd_en_i ;reg [31:0] rd_data_o;wire full_o ;reg empty_o ;initial beginrst_n_i = 1 ;clk_i = 0 ;rd_en_i = 0 ;wr_en_i = 0 ;wr_data_i = 32'b0;#2 rst_n_i = 0 ;#5 rst_n_i = 1 ;
endinitial begin#10 wr_en_i = 1;rd_en_i = 0;#10 wr_en_i = 0;rd_en_i = 1;#10 wr_en_i = 1;rd_en_i = 0;#3 rd_en_i = 1;#10repeat(100) begin#5 wr_en_i = {$random}%2;rd_en_i = {$random}%2;end
endinitial #2000 $finish;always #0.5 clk_i = ~clk_i ;
always #1 wr_data_i = {$random}%10;
sync_fifo u_sync_fifo
(.clk_i (clk_i ),.rst_n_i (rst_n_i ),.wr_en_i (wr_en_i ),.wr_data_i(wr_data_i),.rd_en_i (rd_en_i ),.rd_data_o(rd_data_o),.full_o (full_o ),.empty_o (empty_o )
);initial begin$fsdbDumpfile("sync_fifo.fsdb");$fsdbDumpvars ;$fsdbDumpMDA ;
end
endmodule
五、分析和小结
(1)分析
- 写阶段
复位之后,进行写操作,直至写满,产生满标志后,不再写入新数据。
- 读阶段
进行读操作,直至读空,产生空标志后,不再读出新数据。
- 同时读写阶段
先进行写操作,写入三个新数据之后,同时进行读写操作,期间写入新数据和读出数据,但是elem_cnt计数器不再变化,动态平衡。
(2)小结
设计思路:先分析需求,定义接口,画出具体的实现框图;按照协议和理解,画出相应时序图;看图写程序,验证仿真波形是否与时序图对应。
同步FIFO设计要点是什么时候产生空满标志位,即怎么衡量array被写满或者被读空。在这里,我使用了4bit的elem_cnt表示,通过elem_cnt的值表示当前array存储阵列的资源使用情况。0表示没有数据,即空状态;8表示写满,因为array的存储深度就是8。在spec中提到实现FIFO可配置,在这里只实现了宽度为32bit,深度为8的同步fifo设计,初步验证仿真波形与时序图相对应。
✍✍☛ 题库入口
作者:xlinxdu
版权:本文版权归作者所有
转载:未经作者允许,禁止转载,转载必须保留此段声明,必须在文章中给出原文连接。
01 【Verilog实战】同步FIFO的设计(附源码RTL/TB)相关推荐
- 02【Verilog实战】异步FIFO设计(附源码RTL/TB)
脚 本:makefile 工 具:vcs 和 verdi 文 章:1. 同步FIFO的设计和功能验证(附源码) 2. Verilog的亚稳态现象和跨时钟域处理方法 写在前面 这个专栏的内容记录 ...
- 04【Verilog实战】SPI协议底层硬件接口设计(附源码RTL/TB)
脚 本:makefile 工 具:vcs 和 verdi 写在前面 这个专栏的内容记录的是个人学习过程,博文中贴出来的代码是调试前的代码,方便bug重现. 调试后的程序提供下载,[下载地址] 发现 ...
- 05【Verilog实战】AMBA 3 APB接口设计(附源码RTL/TB)
官方手册:点击下载 脚 本:makefile 工 具:vcs & verdi 写在前面 这个专栏的内容记录的是个人学习过程,博文中贴出来的代码是调试前的代码,方便bug重现. 调试后的程序 ...
- Linux嵌入式驱动开发01——第一个驱动Hello World(附源码)
文章目录 全系列传送门 引言 驱动介绍 Hello World 1. 包含头文件 2. 驱动模块的入口和出口 3. 声明信息 4. 功能实现 完整代码 编译 第一种方法 第二种方法 编译成模块 第一步 ...
- 原生前端实现响应式个人简历网站设计(附源码)
目录 网站站点 所用技术 实现功能 视频展示 源码 网站站点 胜烨的个人网站 所用技术 HTML css JavaScript 实现功能 响应式界面设计 捕捉用户操作 明暗模式 服务器部署 视频展示 ...
- Python实战例子(32个附源码)
Python是一种高级编程语言,具有简洁.清晰的语法,易于理解和使用,因此受到广泛的欢迎.尤其在数据科学.人工智能.机器学习.自然语言处理等领域,Python已成为最受欢迎的编程语言之一.Python ...
- 基于SSM框架图书管理系统开发与设计(附源码资料)-毕业设计
文章目录 1. 适用人群 2. 你将收获 3.项目简介 4.技术实现 5.系统功能 5.1.管理员身份登录 5.1.1.登录 5.1.2.管理员登录首页 5.1.3.借阅管理 5.1.4.图书管理 5 ...
- discuz论坛整合ucenter免激活,同步登录,同步退出解决方案(附源码)
UCenter作为整合用户的这样一个开源插件,对于PHP开发的,甚至其它开发语言如.net,java.asp等开发人员解决多个项目整合到一起,用户进行同步登录,同步退出等,同步消息等都是非常有用的.下 ...
- 100个Python实战练手项目(附源码+素材),学习必备
前言: 不管学习哪门语言都希望能做出实际的东西来,这个实际的东西当然就是项目啦,不用多说大家都知道学编程语言一定要做项目才行. 这里整理了最新32个Python实战项目列表,都有完整且详细的视频教程和 ...
最新文章
- 重磅 | TensorFlow 2.0即将发布,所有tf.contrib将被弃用
- jquery选择器 之 获取父级元素、同级元素、子元素
- K8S面试大通关!赶紧收藏!
- maven仓库配置和 修改阿里云镜像
- Redis-15Redis基础配置文件
- 79. 单词搜索(dfs)
- WCF 第四章 绑定 netMsmqBinding
- discuz!5.5.0安装方法及常见问题解决
- 小学学校计算机教室使用计划,小学电脑室工作计划
- nssl1469-W【dp】
- oracle复杂的子查询,Oracle 子查询(复杂select语句)
- 【Hadoop】Hadoop SocketChannelImpl UnresolvedAddressException
- android 列表上拉加载更多,Android 下拉刷新,上拉加载更多控件–支持ListView,GridView和ScrollView...
- java.lang math 类
- 微信小程序原生自定义组件布局问题
- ESD问题案例分析-智能手表为例
- go语言interface用法
- java中 什么意思?比如130
- model.most_similar
- Android Backup功能之全面实战