同步FIFO学习
在网上找的一个经典同步FIFO例子。
一、前言
FIFO (First-In-First-Out) 是一种先进先出的数据交互方式,在数字ASIC设计中常常被使用。FIFO按工作时钟域的不同又可以分为:同步FIFO和异步FIFO。
同步FIFO的写时钟和读时钟为同一个时钟,FIFO内部所有逻辑都是同步逻辑,常常用于交互数据缓冲。异步FIFO的写时钟和读时钟为异步时钟,FIFO内部的写逻辑和读逻辑的交互需要异步处理,异步FIFO常用于跨时钟域交互。
本文介绍同步FIFO的典型设计方法。
二、原理
典型同步FIFO有三部分组成: (1) FIFO写控制逻辑; (2)FIFO读控制逻辑; (3)FIFO 存储实体(如Memory、Reg)。
FIFO写控制逻辑主要功能:产生FIFO写地址、写有效信号,同时产生FIFO写满、写错等状态信号;
FIFO读控制逻辑主要功能:产生FIFO读地址、读有效信号,同时产生FIFO读空、读错等状态信号。
如下图所示,FIFO读写过程的地址控制:
(1)当FIFO初始化(复位)时fifo_write_addr与fifo_read_addr同指到0x0,此时FIFO处于空状态;
(2)当FIFO进行写操作时,fifo_write_addr递增(增加到FIFO DEPTH时回绕),与fifo_read_addr错开,此时FIFO处于非空状态;
(3)当FIFO进行读操作时,fifo_read_addr递增;
FIFO空满状态产生:
为产生FIFO空满标志,引入FIFO Count计数器,FIFO Count寄数器用于指示FIFO内部存储数据个数;
(1)当只有写操作时,FIFO Count加1;只有读操作是,FIFO Count减1;其他情况下,FIFO Count保持;
(2)当FIFO Count为0时,说明FIFO为空,fifo_empty置位;
(3)当FIFO Count等于FIFO_DEPTH时,说明FIFO已满,fifo_full置位;
三、代码
//--====================================================================================--
// THIS FILE IS PROVIDED IN SOURCE FORM FOR FREE EVALUATION, FOR EDUCATIONAL USE OR FOR
// PEACEFUL RESEARCH. DO NOT USE IT IN A COMMERCIAL PRODUCT . IF YOU PLAN ON USING THIS
// CODE IN A COMMERCIAL PRODUCT, PLEASE CONTACT JUSTFORYOU200@163.COM TO PROPERLY LICENSE
// ITS USE IN YOUR PRODUCT.
//
// Project : Verilog Common Module
// File Name : sync_fifo_ctrl.v
// Creator(s) : justforyou200@163.com
// Date : 2015/12/01
// Description : A sync fifo ctrl
//
// Modification :
// (1) Initial design 2015-12-01
//
//
//--====================================================================================-- module SYNC_FIFO_CTRL
(
clk ,
rst_n ,
fifo_wr_en ,
fifo_rd_en ,
fifo_wr_data ,
fifo_full ,
fifo_wr_err ,
fifo_empty ,
fifo_rd_err ,
fifo_data_cnt ,
fifo_rd_data
); //PARA DECLARATION
parameter FIFO_DATA_WIDTH = ;
parameter FIFO_ADDR_WIDTH = ; //INPUT DECLARATION
input clk ; //fifo clock
input rst_n ; //fifo clock reset (0: reset)
input fifo_wr_en ; //fifo write enable(1: enable) input fifo_rd_en ; //fifo read enable(1: enable)
input [FIFO_DATA_WIDTH-:] fifo_wr_data ; //fifo write data //OUTPUT DECLARATION
output fifo_full ; //fifo full status
output fifo_wr_err ; //fifo write error status
output fifo_empty ; //fifo empty status
output fifo_rd_err ; //fifo read error status
output [FIFO_ADDR_WIDTH :] fifo_data_cnt; //fifo valid data cnt
output [FIFO_DATA_WIDTH-:] fifo_rd_data ; //fifo read data //INTER DECLARATION
wire fifo_full ; //fifo full status
wire fifo_wr_err ; //fifo write error status
wire fifo_empty ; //fifo empty status
wire fifo_rd_err ; //fifo read error status
reg [FIFO_ADDR_WIDTH :] fifo_data_cnt; //fifo valid data cnt
reg [FIFO_DATA_WIDTH-:] fifo_rd_data ; //fifo read data
reg [FIFO_ADDR_WIDTH-:] fifo_wr_addr ; //fifo write addr
reg [FIFO_ADDR_WIDTH-:] fifo_rd_addr ; //fifo write addr //FIFO MEMORY INSTANCE
reg [FIFO_DATA_WIDTH-:] fifo_mem [{(FIFO_ADDR_WIDTH){'b1}}:0] ;
integer i ; //--========================MODULE SOURCE CODE==========================-- //--=========================================--
// SRAM INSTANCE :
// You Can use Reg Memory or Memory model here;
// FIFO Wdata & FIFO Rdata;
//--=========================================--
always @(posedge clk or negedge rst_n)
begin
if(rst_n == 'b0)
begin
for(i=;i<= {(FIFO_ADDR_WIDTH){'b0}};i=i+1)
fifo_mem[i] <= {(FIFO_DATA_WIDTH){'b0}} ;
end
else if (fifo_wr_en & (~ fifo_full))
fifo_mem[fifo_wr_addr] <= fifo_wr_data ;
end always @(posedge clk or negedge rst_n)
begin
if(rst_n == 'b0)
fifo_rd_data <= {(FIFO_DATA_WIDTH){'b0}} ;
else if (fifo_rd_en & (~ fifo_empty))
fifo_rd_data <= fifo_mem[fifo_rd_addr] ;
end //--=========================================--
// READ CONTROL :
// Read address increase when read enable AND
// Not empty;
//--=========================================--
always @(posedge clk or negedge rst_n)
begin
if(rst_n == 'b0)
fifo_rd_addr <= {(FIFO_ADDR_WIDTH){'b0}} ;
else if (fifo_rd_en & (~ fifo_empty))
fifo_rd_addr <= fifo_rd_addr + 'b1 ;
end //--=========================================--
// WRITE CONTROL :
// Write address increase when write enable AND
// Not full.
//--=========================================--
always @(posedge clk or negedge rst_n)
begin
if(rst_n == 'b0)
fifo_wr_addr <= {(FIFO_ADDR_WIDTH){'b0}} ;
else if (fifo_wr_en & (~ fifo_full))
fifo_wr_addr <= fifo_wr_addr + 'b1 ;
end //--=========================================--
// FIFO DATA CNT :
// Valid Write Only, increase data cnt;
// Valid Read Only, decrease data cnt;
//--=========================================--
always @(posedge clk or negedge rst_n)
begin
if(rst_n == 'b0)
fifo_data_cnt <= {(FIFO_ADDR_WIDTH + ){'b0}} ;
else if (fifo_wr_en & (~ fifo_full) & (~(fifo_rd_en & (~fifo_empty)))) //Valid Write Only, increase data cnt;
fifo_data_cnt <= fifo_data_cnt + 'b1 ;
else if (fifo_rd_en & (~ fifo_empty) & (~(fifo_wr_en & (~fifo_full)))) //Valid Read Only, decrease data cnt;
fifo_data_cnt <= fifo_data_cnt - 'b1 ;
end //--=========================================--
// FIFO Status :
// 1. fifo_empty when cnt ==0 ;
// 2. fifo full when cnt == MAX ;
//--=========================================--
assign fifo_empty = (fifo_data_cnt == ) ;
assign fifo_rd_err = (fifo_data_cnt == ) & fifo_rd_en ; assign fifo_full = (fifo_data_cnt == ({(FIFO_ADDR_WIDTH){'b1}} +1) ) ;
assign fifo_wr_err = (fifo_data_cnt == ({(FIFO_ADDR_WIDTH){'b1}} +1) ) & fifo_wr_en ; endmodule
同步FIFO学习的更多相关文章
- 同步FIFO学习笔记
- Verilog学习笔记简单功能实现(八)...............同步FIFO
Part 1,功能定义: 用16*8 RAM实现一个同步先进先出(FIFO)队列设计.由写使能端控制该数据流的写入FIFO,并由读使能控制FIFO中数据的读出.写入和读出的操作(高电平有效)由时钟的上 ...
- 怎么用Verilog语言描述同步FIFO和异步FIFO
感谢 知乎龚大佬 打杂大佬 网上几个nice的博客(忘了是哪个了....) 前言 虽然FIFO都有IP可以使用,但理解原理还是自己写一个来得透彻. 什么是FIFO? Fist in first out ...
- 同步FIFO design and IP level verification
一.前言 应聘IC前端相关岗位时,FIFO是最常考也是最基本的题目.FIFO经常用于数据缓存.位宽转换.异步时钟域处理.随着芯片规模的快速增长,灵活的system verilog成为设计/验证人员的基 ...
- FIFO学习心得
1,名字.FIFO=First in first out. 2,特点.顺序读入,顺序读出,先入先出. 3,用途.数据缓冲.使两个数据传输速率不一样的设备相匹配. 4,参数. ①,THE WIDTH和T ...
- 同步fifo的verilogHDL设计实例
原创 设计一个fifo,输入16bit,输出16bit的data,寻址宽度5bit,有空满标志. top 层如下所示: /* date : 2014/10/14 version : modelsim ...
- 同步fifo的Verilog实现
FIFO是一种先进先出的数据缓存器,他与普通存储器相比: 优点:没有外部读写地址线,这样使用起来非常简单: 缺点:只能顺序写入数据,顺序的读出数据, 其数据地址由内部读写指针自动加1完成,不能像普通存 ...
- E203 同步fifo
1. 输入端, 输入信号, i_vld,表示输入请求写同步fifo,如果fifo不满,则fifo发送i_rdy 到输入端,开始写fifo.i_vld和i_rdy是写握手信号. 2.输出端 o_rdy表 ...
- 同步fifo与异步fifo
参考以下帖子: https://blog.csdn.net/hengzo/article/details/49683707 https://blog.csdn.net/Times_poem/artic ...
随机推荐
- KindEditor3.x整合教程-Xproer.WordPaster
版权所有 2009-2017 荆门泽优软件有限公司 保留所有权利 官方网站:http://www.ncmem.com/ 产品首页:http://www.ncmem.com/webplug/wordpa ...
- 单例模式、双检测锁定DCL、volatile(转)
单例模式最要关心的则是对象创建的次数以及何时被创建. Singleton模式可以是很简单的,它的全部只需要一个类就可以完成(看看这章可怜的UML图).但是如果在“对象创建的次数以及何时被创 建”这两点 ...
- Android测试入门篇
Android本身是一套软件堆叠(Software Stack),或者成为软件叠层架构,叠层主要分成三层:操作系统.中间件和应用程序. Android构架 1. Application 应用程序层:用 ...
- 【转载】python计算文件的行数和读取某一行内容的实现方法
一.计算文件的行数 最简单的办法是把文件读入一个大的列表中,然后统计列表的长度.如果文件的路径是以参数的形式filepath传递的,那么只用一行代码就可以完成我们的需求了: count = len(o ...
- 【Linux】Vim编辑器
本文基于Debian 1.vim使用简介 1.1vim安装 使用apt安装vim即可: sudo apt-get install vim 1.2 vim编辑器的模式 vim编辑器分为命令模式和编辑模式 ...
- 洛谷P2147[SDOI2008]洞穴勘测(lct)
题目描述 辉辉热衷于洞穴勘测. 某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假 ...
- linux 用户和组
每个用户拥有一个UID,操作系统实际使用的是用户ID,而非用户名 每个用户属于一个主组,而且属于一个或多个附属组 每个组有一个GroupID 每个进程以一个用户身份运行,并受该用户可访问的资源限制 每 ...
- linux 常见命令--系统信息部分
head -n 1 /etc/issue #查看操作系统 cat /etc/redhat-release #查看linux系统版本 cat /proc/meminfo |grep MemTot ...
- ibatis 参数之模糊查询
因项目需要最近使用ibatis,在使用查询语句的时候,想着通用性所以没有在配置文件里用N多的and 语句,而是如下: <select id="getUsersList" re ...
- /Date(1512551901709+0800)/转换
var convertDT=function(dt) { dt.replace(/Date\([\d+]+\)/, function (a) { eval('d = new ' + a) }); al ...