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