参考博客:https://blog.csdn.net/hengzo/article/details/49683707

1、基本框图

  1)双端口RAM加两个读写指针

  2)写数据、写使能、写满;读数据、读使能、读满

2、代码思路

  

  1)Full和Empty的产生:使用fifo_counter记录FIFO RAM中的数据个数,等于0时,给出empty信号,等于BUF_LENGTH时,给出full信号

  2)fifo_counter的更新:发生有效写操作时+1,发生有效读操作时-1,同时发生读写操作时不变

  3)读写指针的控制:读写指针宽度与地址宽度相当,地址增加而溢出后,自动变成0。循环指针。初始时刻都指到0,发生有效写时写指针+1,写指针指向将要写的地址;发生有效读时读指针-1,读指针指向将要读的地址。

3、代码

`timescale 1ns / 1ps

module synchronous_fifo
#(parameter BUF_WIDTH=, //地址宽度为3,
parameter BUF_SIZE=) //数据个数,FIFO深度
(
input clk,
input rst_n,
input wr_en,
input rd_en,
input [:] buf_in,
output [:] buf_out,
output buf_full,
output buf_empty,
output [BUF_WIDTH:] fifo_cnt
); reg [:] buf_mem [:BUF_SIZE-]; // 双端口RAM
reg [BUF_WIDTH-:] rd_ptr,wr_ptr; // 读写指针
reg [:] buf_out_reg;
reg [BUF_WIDTH:] fifo_cnt_reg; // 存入数据的计数,0-8,位宽要比地址位宽大1 //========= 写入 ============
always @(posedge clk) begin
if(wr_en&&!buf_full) begin
buf_mem[wr_ptr] <= buf_in;
end
end //========= 读出 ============
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
buf_out_reg <= 'd0;
end
else begin
if(rd_en&&!buf_empty) begin
buf_out_reg <= buf_mem[rd_ptr];
end
else buf_out_reg <= buf_out_reg;
end
end assign buf_out = buf_out_reg; //========= 数据计数 ============
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
fifo_cnt_reg <= {(BUF_WIDTH+){'b0}};
end
else begin
if((wr_en&&!buf_full)&&((rd_en&&!buf_empty)))
fifo_cnt_reg <= fifo_cnt_reg;
else if(wr_en&&!buf_full)
fifo_cnt_reg <= fifo_cnt_reg+'b1;
else if(rd_en&&!buf_empty)
fifo_cnt_reg <= fifo_cnt_reg-'b1;
else fifo_cnt_reg <= fifo_cnt_reg;
end
end
assign fifo_cnt = fifo_cnt_reg; //========= 读写指针控制 ============
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
rd_ptr <= {BUF_WIDTH{'b0}};
end
else begin
if(rd_en&&!buf_empty) rd_ptr <= rd_ptr + 'b1;
else rd_ptr <= rd_ptr;
end
end always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
wr_ptr <= {BUF_WIDTH{'b0}};
end
else begin
if(wr_en&&!buf_full) wr_ptr <= wr_ptr + 'b1;
else wr_ptr <= wr_ptr;
end
end //========= 空满判断 ============
assign buf_full = (fifo_cnt_reg == BUF_SIZE)?'b1:1'b0;
assign buf_empty = (fifo_cnt_reg == {(BUF_WIDTH+){'b0}})?1'b1:'b0; endmodule

his is a Full version of ISim.
Time resolution is ps
Simulator is doing circuit initialization process.
Finished circuit initialization process.
Push
Push
------Poped:
Push
Push
Push
Push
Push
Push
Push
---Cannot push : Buffer Full---
---Cannot push : Buffer Full---
---Cannot push : Buffer Full---
---Cannot push : Buffer Full---
---Cannot push : Buffer Full---
---Cannot push : Buffer Full---
------Poped:
Push
------Poped:
------Poped:
------Poped:
------Poped:
Push
------Poped:
Push
------Poped:
------Poped:
------Poped:
------Poped:
------Poped:
---Cannot Pop: Buffer Empty---
---Cannot Pop: Buffer Empty---
---Cannot Pop: Buffer Empty---
---Cannot Pop: Buffer Empty---
---Cannot Pop: Buffer Empty---
---Cannot Pop: Buffer Empty---
Push
------Poped:

最新文章

  1. 动态生成一个设定好特殊样式的Tlabel,快速生成代码
  2. 利用SQL语句查询一个数据库中的所有表
  3. 还是说Memory Model,gcc的__sync_synchronize真是太坑爹了
  4. hive报错 Another instance of Derby may have already booted the database
  5. JavaScript中的面向对象的讨论(转)
  6. PHP学习笔记二十【静态方法】
  7. 【原创】ASP.NET Web开发,实现打印Log日志,步骤详解
  8. Android Volley 之自定义Request
  9. 如何通过Spring Boot配置动态数据源访问多个数据库
  10. 【LaTeX排版】LaTeX论文排版&lt;三&gt;
  11. FG面经: Interval问题合集
  12. python – 基于pandas中的列中的值从DataFrame中选择行
  13. Linux知识扩展一:执行前为什么加./
  14. “C++的数组不支持多态”?
  15. 《HTTP权威指南》学习笔记——URL和资源
  16. pip常用操作指令
  17. 移植Max中的控制器到Unity - 前言
  18. C# winform 多线程异步操作线程启动暂停与恢复
  19. 抓取DUMP日志
  20. UVA 10288 Coupons---概率 &amp;&amp; 分数类模板

热门文章

  1. what is muxing and demuxing
  2. The Top 500 Worst Passwords (2008)
  3. POJ_1166_暴搜
  4. Mysql的基本查询语句
  5. Go语言实现:【剑指offer】最小的K个数
  6. 通过open上网并设置开机自启与自动连接
  7. 卫星轨道相关笔记SGP4
  8. Mysql 初始化 及 密码管理
  9. 单元测试-xUnit总结
  10. Java连载89-SorteSet、Comparable接口