FIFO设计
- first in first out,先进先出
- fifo是基于RAM进行设计的
双端口RAM设计(16*8)
- 如果大的RAM可以调用IP
- RAM的关键参数:深度和宽度
module dual_ram
#(
parameter ADDR_WIDTH = 4,
parameter RAM_WIDTH = 8,
parameter DLY=1
)
(
input wire read_clk ,
input wire write_clk ,
input wire [ADDR_WIDTH-1:0] read_addr ,
input wire [ADDR_WIDTH-1:0] write_addr ,
input wire read_allow ,
input wire write_allow ,
input wire [RAM_WIDTH-1:0] write_data ,
output reg [RAM_WIDTH-1:0] read_data
);
reg [RAM_WIDTH-1:0] memory [ADDR_WIDTH-1:0];
always @(posedge read_clk) begin
if(read_allow)
read_data <= #DLY memory[read_addr];
end
always @(posedge write_clk) begin
if(write_allow)
memory[write_addr] <= #DLY write_data;
end
endmodule
单端口ram
module single_port_ram
#(
parameter ADDR_WIDTH = 8,
parameter RAM_WIDTH = 8,
parameter RAM_DEPTH = 255,
parameter DLY = 1
)
(
input wire clk,
input wire rst_n,
input wire [ADDR_WIDTH-1:0] addr,
input wire wr_en, // 1-write 0-read
input wire [RAM_WIDTH-1:0] wdata,
output wire [RAM_WIDTH-1:0] rata
);
reg [RAM_DEPTH-1:0] mem [RAM_WIDTH-1:0];
integer i;
always @(posedge clk or negedge rst_n) begin
if(rst_n)
for(i=0;i<=255;i=i+1) begin
mem[i] = 16'h0000;
end
else if(wr_en)
mem[addr] <= wdata;
end
assign radta = (!wr_en) ? mem[addr] : 16'h0000 ;
// always @(posedge clk or negedge rst_n) begin
// if(!rst_n)
// radta <= 'h0;
// else if(!wr_en)
// r_data <= mem[addr];
// end
endmodule
同步FIFO设计
module sync_fifo_counter
#(
parameter ADDR_WIDTH = 9,
parameter RAM_WIDTH = 8
)
(
input wire fifo_clk,
input wire fifo_rst_n,
input wire read_en,
input wire write_en,
input wire [RAM_WIDTH-1:0] w_data,
output wire [RAM_WIDTH-1:0] r_data,
output reg empty,
output reg full,
output reg [ADDR_WIDTH-1:0] fcounter
);
reg [ADDR_WIDTH-1:0] write_addr;
reg [ADDR_WIDTH-1:0] read_addr;
wire write_allow = write_en && (!empty);
wire read_allow = read_en && (!full);
// empty
always @(posedge fifo_clk or negedge fifo_rst_n) begin
if(fifo_rst_n)
empty <= 1'b1;
else
empty <= (!write_allow) && (fcounter[ADDR_WIDTH-1:1] == 8'h0) && (fcounter[0] == 0||read_allow);
end
// full
always @(posedge fifo_clk or negedge fifo_rst_n) begin
if(fifo_rst_n)
full <= 1'b0;
else
full <= (!read_allow) && (fcounter[ADDR_WIDTH-1:1] == 8'hff) && (fcounter[0] == 1||write_allow);
end
always @(posedge fifo_clk or negedge fifo_rst_n) begin
if(fifo_rst_n)
fcounter <= {ADDR_WIDTH{1'b0}};
else if( (!read_allow) && (write_allow)||(read_allow) && (!write_allow)) begin
if(write_allow)
fcounter <= fcounter + 1'b1;
else
fcounter <= fcounter - 1'b1;
end
end
always @(posedge fifo_clk or negedge fifo_rst_n) begin
if(fifo_rst_n)
write_addr <= {ADDR_WIDTH{1'b0}};
else if(write_allow)
write_addr <= write_addr + 1'b1;
end
always @(posedge fifo_clk or negedge fifo_rst_n) begin
if(fifo_rst_n)
read_addr <= {ADDR_WIDTH{1'b0}};
else if(write_allow)
read_addr <= read_addr + 1'b1;
end
dual_ram u_dual_ram
(
.read_clk (fifo_clk),
.write_clk (fifo_clk),
.read_addr (read_addr),
.write_addr (write_addr),
.read_allow (read_allow),
.write_allow (write_allow),
.write_data (w_data),
.read_data (r_data)
);
endmodule
module sync_fifo
#(
parameter ADDR_WIDTH = 4,
parameter RAM_WIDTH = 8,
parameter RAM_DEPTH = 16
)
(
input wire fifo_clk,
input wire fifo_rst_n,
input wire read_en,
input wire write_en,
input wire [RAM_WIDTH-1:0] w_data,
output reg [RAM_WIDTH-1:0] r_data,
output wire empty,
output wire full
);
// 指针
reg [ADDR_WIDTH:0] write_addr;
reg [ADDR_WIDTH:0] read_addr;
wire [ADDR_WIDTH-1:0] w_addr;
wire [ADDR_WIDTH-1:0] r_addr;
wire write_allow = write_en && (!empty);
wire read_allow = read_en && (!full);
reg [RAM_WIDTH-1:0] mem [RAM_DEPTH-1:0];
always @(posedge fifo_clk or negedge fifo_rst_n) begin
if(!fifo_rst_n)
read_addr <= {ADDR_WIDTH{1'b0}};
else if(read_allow) begin
r_data <= mem[read_addr];
read_addr <= read_addr + 1;
end
end
always @(posedge fifo_clk or negedge fifo_rst_n) begin
if(!fifo_rst_n)
write_addr <= {ADDR_WIDTH{1'b0}};
else if(write_allow) begin
mem[write_addr] <= w_data;
write_addr <= write_addr + 1;
end
end
assign empty = read_addr == write_addr ? 1 : 0;
assign full = (read_addr[ADDR_WIDTH]!=write_addr[ADDR_WIDTH]) &&
(read_addr[ADDR_WIDTH-1:0] == write_addr[ADDR_WIDTH-1:0]);
assign r_addr = read_addr[ADDR_WIDTH-1:0];
assign w_addr = write_addr[ADDR_WIDTH-1:0];
endmodule
module sync_fifo_tb();
parameter ADDR_WIDTH = 4;
parameter RAM_WIDTH = 8;
parameter RAM_DEPTH = 16;
reg fifo_clk;
reg fifo_rst_n;
reg read_en;
reg write_en;
reg [RAM_WIDTH-1:0] w_data;
wire [RAM_WIDTH-1:0] rdata;
wire empty;
wire full;
// 例化模块 - 省略
sync_fifo u_sysc_fifo(
.fifo_clk (fifo_clk ) ,
.fifo_rst_n (fifo_rst_n) ,
.read_en (read_en ) ,
.write_en (write_en ) ,
.w_data (w_data ) ,
.r_data (r_data ) ,
.empty (empty ) ,
.full (full )
);
initial begin
fifo_rst_n = 1;
fifo_clk = 0;
#1 fifo_rst_n = 0;
#5 fifo_rst_n = 1;
end
always #20 fifo_clk = ~fifo_clk;
initial begin
write_en = 0;
#1 write_en = 1;
end
initial begin
read_en = 0;
#650 read_en = 1;
write_en = 0;
end
initial begin
w_data = 8'h0;
#40 w_data = 8'h1;
#40 w_data = 8'h2;
#40 w_data = 8'h3;
#40 w_data = 8'h4;
#40 w_data = 8'h5;
#40 w_data = 8'h6;
#40 w_data = 8'h7;
#40 w_data = 8'h9;
#40 w_data = 8'ha;
#40 w_data = 8'hb;
#40 w_data = 8'hc;
#40 w_data = 8'hd;
#40 w_data = 8'he;
#40 w_data = 8'hf;
#200 $finish;
end
initial begin
$vcdpluson();
end
endmodule
FIFO设计的更多相关文章
- FPGA Asynchronous FIFO设计思路(2)
FPGA Asynchronous FIFO设计思路(2) 首先讨论格雷码的编码方式: 先看4bit的格雷码,当MSB为0时,正向计数,当MSB为1时,即指针已经走过一遍了,最高位翻转,此时的格雷码是 ...
- FPGA Asynchronous FIFO设计思路
FPGA Asynchronous FIFO设计思路 将一个多位宽,且在不停变化的数据从一个时钟域传递到另一个时钟域是比较困难的. 同步FIFO的指针比较好确定,当FIFO counter达到上限值时 ...
- FIFO设计中的深度计算【zz】
FIFO设计中的深度计算: 写时钟频率 w_clk, 读时钟频率 r_clk, 写时钟周期里,每B个时钟周期会有A个数据写入FIFO: 读时钟周期里,每Y个时钟周期会有X个数据读出FIFO: 则,FI ...
- 基于FPGA的异步FIFO设计
今天要介绍的异步FIFO,可以有不同的读写时钟,即不同的时钟域.由于异步FIFO没有外部地址端口,因此内部采用读写指针并顺序读写,即先写进FIFO的数据先读取(简称先进先出).这里的读写指针是异步的, ...
- FIFO设计思考之一
不管同步FIFO还是异步FIFO,设计难点是full/empty状态flag的正确性. 要保证任何情况 FULL时NO WRITE,EMPTY时NO READ.overflow / underflow ...
- 异步FIFO设计
参考http://www.cnblogs.com/BitArt/archive/2013/04/10/3010073.html http://blog.sina.com.cn/s/blog_6d30f ...
- 异步fifo的设计
本文首先对异步 FIFO 设计的重点难点进行分析 最后给出详细代码 一.FIFO简单讲解 FIFO的本质是RAM, 先进先出 重要参数:fifo深度(简单来说就是需要存多少个数据) ...
- 同步fifo的verilogHDL设计实例
原创 设计一个fifo,输入16bit,输出16bit的data,寻址宽度5bit,有空满标志. top 层如下所示: /* date : 2014/10/14 version : modelsim ...
- Verilog设计异步FIFO
转自http://ninghechuan.com 异步FIFO有两个异步时钟,一个端口写入数据,一个端口读出数据.通常被用于数据的跨时钟域的传输. 同步FIFO的设计.一个时钟控制一个计数器,计数器增 ...
- 异步fifo的设计(FPGA)
本文首先对异步 FIFO 设计的重点难点进行分析 最后给出详细代码 一.FIFO简单讲解 FIFO的本质是RAM, 先进先出 重要参数:fifo深度(简单来说就是需要存多少个数据) ...
随机推荐
- 23年底,我出齐了Spring boot,Spring cloud和案例方面的书,正在写一本面试书(代年终总结)
年末了,再来总结一下吧,希望本人明年的年终总结文还能在博客园发. 这次总结的主题是本人出的java书.这几年本人出了不少书,其中有python.redis和Java方面的. 姑且不说其它,java方面 ...
- Python——第四章:生成器(Generators)
生成器(generator): 生成器的本质就是迭代器 创建生成器的两种方案: 1. 生成器函数 2. 生成器表达式 生成器函数 生成器函数中有一个关键 ...
- FlinkSQL实战开发
FlinkSQL实战开发 1.基础知识 FlinkSQL分为Table API和SQL API,是架构于Flink Core之上用SQL予以方便快捷地进行结构化数据处理的上层库. 工作流程 SQL和T ...
- Draco使用笔记(1)——图形解压缩
目录 1. 概述 2. 详论 2.1. 工具 2.2. 代码 1. 概述 Draco是Google开发的图形压缩库,用于压缩和解压缩3D几何网格(geometric mesh)和点云(point cl ...
- 2021平(jia)凡(ban)的一年
0x00 刚刚把<平凡的世界>电视剧看完.也不知道什么原因,又去刷了一遍, 可能是有那么一段时间比较迷茫.加班加到怀疑人生了吧. 记得当年第一次看这本小说还是17年,好像是为了借一本什么书 ...
- Redis核心技术与实战
最近在读一篇关于Redis的专栏,叫做<Redis核心技术与实战>,作者在Redis方面研究颇深,读后非常受益,特在此做记录. 一.Redis基础 1)知识图和问题画像图 Redis知识全 ...
- 云图说|分钟级构建业务大屏——Astro大屏应用
本文分享自华为云社区<[云图说]第271期 Astro Canvas一站式数据可视化开发,分钟级构建业务大屏>,作者:阅识风云 . Astro大屏应用(Astro Canvas)是Astr ...
- 华为云FusionInsight助力宇宙行打造金融数据湖新标杆
摘要:工行采用了华为云FusionInsight MRS大数据存算分离方案,实现了大数据平台与OBS对象存储服务的对接,将原有的HDFS数据无缝迁移到OBS上.在保证性能的前提下,实现了计算与存储独立 ...
- 万物皆可Cassandra:HUAWEI Tag背后的神仙数据库
摘要:在GaussDB(for Cassandra)的支撑下,HUAWEI Tag防丢精灵表现出了非常强大的核心竞争力. 本文分享自华为云社区<万物皆可Cassandra--HUAWEI Tag ...
- AI为啥能读懂说话人的情感?
摘要:本文介绍了语音情感识别领域的发展现状,挑战,重点介绍了处理标注数据缺乏的问题. 本文分享自华为云社区<语音情感识别的应用和挑战>,作者:SSIL_SZT_ZS. 情感在人与人的交流中 ...