同步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 ...
随机推荐
- Android Paint以及ColorFilter等
我们可以通过Paint中大量的setter方法来为画笔设置属性: 这些属性大多我们都可以见名知意,很好理解,即便如此,哥还是带大家过一遍逐个剖析其用法,其中会不定穿插各种绘图类比如Canvas.Xfe ...
- 简单介绍Java的静态分派和动态分派
最近复习JVM的知识,对于静态分派和动态分派的理解有点混乱,于是自己尝试写写代码,在分析中巩固知识. 有如下一段代码,请问每一段分别输出什么? package com.khlin.my.test; c ...
- 一些linux工具在windows版本下的文件放置位置
首先说明一下windows下的常用变量(这里是XP的,win7及以上的C:\Documents and Settings实际为C:\Users) %SystemDrive% 操作系统所在 ...
- Android-原生对话框
package liudeli.ui.all; import android.app.Activity; import android.app.AlertDialog; import android. ...
- 优化MYSQL配置文件MY.INI
table_cache=1024 物理内存越大,设置就越大.默认为2402,调到512-1024最佳.由于每个客户端连接都会至少访问一个表,因此此参数的值与max_connections有关.当某一连 ...
- Time 模块中asctime()、time()、localtime()、ctime()、gmtime()的用法
Time 模块包含了以下内置函数,既有时间处理的,也有转换时间格式的: time.asctime([tupletime]) 接受时间元组并返回一个可读的形式“Tue Dec 11 18:07:14 2 ...
- Transaction And Lock--常用的查询事务和锁的语句
--===================================================== --查看当前运行事务 SET TRANSACTION ISOLATION LEVEL R ...
- uwsgi怎么启动停止
## 二.启动停止重启 uWSGI 通过 xxx.ini 启动后会在相同目录下生成一个 xxx.pid 的文件,里面只有一行内容是 uWSGI 的主进程的进程号. uWSGI 启动:uwsgi --i ...
- pageadminCMS.Net Framework的安装教程
很多用户第一次安装PageAdmin建站系统时候会出现这个错误,主要原因:Net Framework是微软的一个系统组件,基本所有windows平台上开发的产品都需要安装Net Framework,除 ...
- NOIP提高组题目归类+题解摘要(2008-2017)
因为前几天作死立了一个flag说要把NOIP近十年的题目做一做,并写一个题目归类+题解摘要出来,所以这几天就好好的(然而还是颓废了好久)写了一些这些往年的NOIP题目. 这篇博客有什么: 近十年NOI ...