同步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 ...
随机推荐
- 在word上写博客直接发到CSDN
目前大部分的博客作者在写博客这件事情上都会遇到以下3个痛点:1.所有博客平台关闭了文档发布接口,用户无法使用Word,Windows Live Writer等工具来发布博客.2.发布到博客或公众号平台 ...
- U盘安装Centos6.2
原文地址:http://www.dedecms.com/knowledge/servers/linux-bsd/2012/0819/8452.html. 第一步:制作系统U盘(略). 第二步:设置BI ...
- Java如何实现按指定行读取文件
最近在开发实战中,遇到了一个这样的技术情景: 把log4j生成的日志文件定时刷进MySQL数据库,比如三个小时刷一次,那么每次刷数据的时候,如何控制文件读取是从上一次文件读取结束的地方开始继续读取的? ...
- 解决centOS 本地可以访问 外部主机不能访问的问题
但是centos中的防火墙规则比较严密 用curl http://localhost:10000 可以看到内容,但是外部无法访问,原因是防火墙没有开启10000端口,需要将10000端口加入到信任规则 ...
- Redis 七月小说网的爬虫缓存设计
一.爬虫策略 1.主服务器先根据spider.all set排重,再 lpush request_url 到spider.wait List中,并且 sadd request_url 到 set中: ...
- WPF MaterialDesignInXamlToolkit锁屏恢复后页面冻结的问题
在做WPF项目时,用到 MaterialDesignInXamlToolkit 开源项目.结果客户用的时候发现这个问题,锁屏后,界面不刷新. 如果不用MaterialDesign,测试后不会出现这个问 ...
- [C#]合并单元格(行、列)
详细链接:https://shop499704308.taobao.com/?spm=a1z38n.10677092.card.11.594c1debsAGeak説明:控件ID指的是页面上面的Grid ...
- Robotlegs2的Starling扩展
有个老外写了robotleges2的starling扩展,地址是 https://github.com/brean/robotlegs2-starling-viewmap 需要注意的是要先创建一个基于 ...
- bitcoin script
P2PK P2PKH,MS,P2SH,OP_RETURN 等的区别 1.P2PK pay_to_public_key pubkey script: <pubkey> OP_CHECKSIG ...
- nginx location 与 rewrite详解 (转)
点我