同步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 ...
随机推荐
- opencv——pcb上找圆mark点(模板匹配)
#include "stdafx.h" #include <cv.h> #include <highgui.h> #include <cxcore.h ...
- CSS选择器与jQuery选择器的异同:一些特殊的选择器
在CSS3选择器标淮草案定义的选择器语法中,jQuery支持相当完整的一套子集,同时还添加了一些非标准但很有用的伪类.下面是一些jQuery扩展的选择器:(来自http://www.cnblogs.c ...
- [LeetCode 题解]: Longest Substring Without Repeating Characters
Given a string, find the length of the longest substring without repeating characters. For example, ...
- SQL 语句case when
简介 case when 一般有两种书写方式,多用于查询判断 1. case 列名 when '' then '空' ' then '成功' ' then '失败' else '其他' end as ...
- 升级实体框架EntityFramework6.0
首先安装nuget 管理器 https://visualstudiogallery.msdn.microsoft.com/4ec1526c-4a8c-4a84-b702-b21a8f5293ca 安装 ...
- C# 等待框
今天发现dev控件自带了等待框,调用方便,而且不会阻塞主线程. 拉一个窗体,界面上放两个按钮,显示等待框,隐藏. <Window x:Class="WaitDialogTest.Mai ...
- 使用纯真IP库获取用户端地理位置信息
引言 在一些电商类或者引流类的网站中经常会有获取用户地理位置信息的需求,下面我分享一个用纯真IP库获取用户地理位置信息的方案. 正文 第一步:本文的方案是基于纯真IP库的,所以首先要去下载最新的纯真I ...
- Visual Studio 2015 Update 2 发布
2016年3月30日,微软发布了Visual Studio 2015 Update 2 . 更新内容: Visual Studio Visual Studio Tools for Apache Co ...
- ajax 跨域访问的解决方案
ajax 跨域访问的解决方案 一.什么是跨域: 1.什么样的请求属于跨域: 域名,端口有任何一个不相同都属于跨域: 二.跨域的常用几种解决方案: 1.jsonp: 2.iframe: 3.webcon ...
- BZOJ 4817: [Sdoi2017]树点涂色(LCT+树剖+线段树)
题目描述 Bob有一棵 nn 个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同. 定义一条路径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. Bob ...