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深度(简单来说就是需要存多少个数据) ...
随机推荐
- 【Dotnet 工具箱】推荐一个 Flutter 和 .NET 开源的实时聊天 APP
1. 推荐一个 Flutter 和 .NET 开源的实时聊天 APP Heyy-chat-app Heyy-chat-app 是一个开源的聊天应用,使用 Flutter.Asp.Net Core We ...
- Oracle-lsnrctl监听进程控制
LSNRCTL> help The following operations are available An asterisk (*) denotes a modifier or extend ...
- 华企盾科技:智能AI自动化研判分析服务系统概述
由中企网安全资子公司北京华企盾科技有限责任公司开发的<智能AI自动化研判分析服务系统>,获得国家版权局颁发的计算机软件著作权登记证书. 智能AI自动化研判分析服务系统是基于人工智能.大数据 ...
- 在arm架构的银河麒麟系统部署Redis
以下是在arm架构的银河麒麟系统上部署Redis的详细步骤: 1. 创建文件夹 首先,在合适的位置创建必要的文件夹.在本例中,我们将创建/opt/redis和/usr/src/redis两个文件夹. ...
- 使用kubeadm在Centos8上部署kubernetes1.18
// 查看系统版本 cat /etc/centos-release CentOS Linux release 8.1.1911 (Core) // 如果系统环境为8.0(云服务器默认最大安装环境为8. ...
- vulnhub - Fawks - writeup
信息收集 目标开放了21的ftp有匿名登录,除此之外还有常规的80,和连个ssh的端口. 80端口的是一张图片,就是哈利波特的海报图. anonymous空密码登上去有一个文件下载下来是二进制的文件 ...
- QRCoder1.4.3生成二维码,不依赖System.Drawing,解决"未能找到类型或命名空间名QRCode","及ImageFormatPng仅在windows上受支持"
生成二维码1(简单) 包引用: <PackageReference Include="QRCoder" Version="1.4.3" /> usi ...
- 解决 cv2.destroyAllWindows() 无效问题
方法一 示例代码: import cv2 import numpy as npimg = np.zeros((512,512),np.uint8)#生成一个空灰度图像 cv2.line(img,(0, ...
- Asp .Net Core 系列: 集成 Consul 实现 服务注册与健康检查
目录 什么是 Consul? 安装和运行 Consul Asp .Net Core 如何集成 Consul 实现服务注册和健康检查 Consul.AspNetCore 中的 AddConsul 和 A ...
- 2023“强网杯”部分WP
强网先锋 SpeedUp 题目 我的解答: 分析代码可知是求2的27次方的阶乘的每一位的和. 使用在线网址直接查看:https://oeis.org/A244060/list 然后sha256加密 f ...