单口 RAM
module BRAM_PORTA(
input clka,
input ena,
input wea,
input [3:0] addra,
input [15:0] dina,
output reg [15:0] douta
);
reg [15:0] mem [15:0];
always @(posedge clka)begin
if(ena)begin
if(wea)begin//写数据
mem[addra] <= dina;
douta <= 16'bzzzzzzzzzzzzzzzz;
end
else begin //读数据
douta <= mem[addra];
mem[addra] <= mem[addra];
end
end
else
douta <= 16'bzzzzzzzzzzzzzzzz;
end
endmodule
同步 FIFO
`define INDEX 6
`define WIDTH 16
`define DEPTH 64
module Sync_FIFO(
input clk,
input rst_n,
input re,
input we,
input [`WIDTH-1:0] din,
output empty,
output full,
output reg [`INDEX-1:0] fifo_cnt,
output reg [`WIDTH-1:0] dout
);
reg [`WIDTH-1:0] mem [`DEPTH-1:0];
reg [`INDEX-1:0] raddr;
reg [`INDEX-1:0] waddr;
// 1、空满标志;
assign empty = (fifo_cnt == 0) ? 1:0;
assign full = (fifo_cnt == `DEPTH-1) ? 1:0;
// 2、读写计数;
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
fifo_cnt <= 0;
else begin
if((!empty && re)&&(!full && we))// 同时读写,计数不变;
fifo_cnt <= fifo_cnt;
else if(!empty && re)// 读数据,计数减一;
fifo_cnt <= fifo_cnt - 1'b1;
else if(!full && we)// 写数据,计数加一;
fifo_cnt <= fifo_cnt + 1'b1;
else
fifo_cnt <= fifo_cnt;
end
end
// 3、读写数据;
always @(posedge clk or negedge rst_n)begin// 读数据;
if(!rst_n)
dout <= 0;
else begin
if(!empty && re)
dout <= mem[raddr];
else
dout <= dout;
end
end
always @(posedge clk)begin// 写数据;
if(!full && we)
mem[raddr] <= din;
else
mem[raddr] <= mem[waddr];
end
// 4、读写地址;
always @(posedge clk or negedge rst_n)begin// 写地址;
if(!rst_n)
waddr <= 0;
else begin
if(!full && we)
waddr <= waddr + 1'b1;
else
waddr <= waddr;
end
end
always @(posedge clk or negedge rst_n)begin// 读地址;
if(!rst_n)
raddr <= 0;
else begin
if(!empty && re)
raddr <= raddr + 1'b1;
else
raddr <= raddr;
end
end
endmodule
异步 FIFO
`define INDEX 6 // FIFO 索引;
`define WIDTH 16 // FIFO 宽度;
`define DEPTH 64 // FIFO 深度;
module Async_FIFO(
input rd_clk,
input wr_clk,
input rst_n,
input re,
input we,
input [`WIDTH-1:0] din,
output empty,
output full,
output [`WIDTH-1:0] dout
);
reg [`WIDTH-1:0] mem [`DEPTH-1:0];
wire [`INDEX-1:0] raddr;
wire [`INDEX-1:0] waddr;
reg [`INDEX:0] wbin,rbin;
wire [`INDEX:0] wbin_next,rbin_next,wgray_next,rgray_next;
reg [`INDEX:0] rp,wr1_rp,wr2_rp,wp,rd1_wp,rd2_wp;
// 1、空满标志;
// 可能需要延时;
assign empty = (rd2_wp == rgray_next) ? 1:0;
assign full = ({~wr2_rp[`INDEX:`INDEX-1],wr2_rp[`INDEX-2:0]} == wgray_next) ? 1:0;// 高两位不同,取反;
// 2、读计数;
// 产生读地址 raddr + 读地址自增 + 将普通二进制码转化为格雷码,并赋给读指针 rp;
// 将读指针 rp 同步到写时钟域;
always @(posedge rd_clk or negedge rst_n)begin
if(!rst_n)
{rbin,rp} <= 0;
else
{rbin,rp} <= {rbin_next,rgray_next};
end
assign raddr = rbin[`INDEX-1:0];// 抛弃高位;
assign rbin_next = rbin + (!empty && re);// 地址加一;
assign rgray_next = rbin_next ^ (rbin_next > > 1);// 转为格雷码,右移 + 异或;
always @(posedge wr_clk or negedge rst_n)begin
if(!rst_n)
{wr2_rp,wr1_rp} <= 0;
else
{wr2_rp,wr1_rp} <= {wr1_rp,rp};
end
// 3、写计数;
// 产生写地址 waddr + 写地址自增 + 将普通二进制码转化为格雷码,并赋给写指针 wp;
// 将写指针 wp 同步到读时钟域;
always @(posedge wr_clk or negedge rst_n)begin
if(!rst_n)
{wbin,wp} <= 0;
else
{wbin,wp} <= {wbin_next,wgray_next};
end
assign waddr = wbin[`INDEX-1:0];// 抛弃高位;
assign wbin_next = wbin + (!full && we);// 地址加一;
assign wgray_next = wbin_next ^ (wbin_next > > 1);// 转为格雷码,右移 + 异或;
always @(posedge rd_clk or negedge rst_n)begin
if(!rst_n)
{rd2_wp,rd1_wp} <= 0;
else
{rd2_wp,rd1_wp} <= {rd1_wp,wp}; // 多比特的,但是只有单比特发生变化,属于单比特处理领域;
end
// 4、异步读数据;
assign dout = mem[raddr];
// 5、同步写数据;
always @(posedge wr_clk)begin
if(!full && we)
mem[waddr] <= din;
else
mem[waddr] <= mem[waddr];
end
endmodule
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。
举报投诉
-
RAM
+关注
关注
8文章
1367浏览量
114518 -
二进制
+关注
关注
2文章
793浏览量
41593 -
FIFO芯片
+关注
关注
0文章
10浏览量
8801 -
FIFO存储
+关注
关注
0文章
103浏览量
5963 -
CLK
+关注
关注
0文章
127浏览量
17122
发布评论请先 登录
相关推荐
同步FIFO设计详解及代码分享
FIFO (先入先出, First In First Out )存储器,在 FPGA 和数字 IC 设计中非常常用。 根据接入的时钟信号,可以分为同步 FIFO 和异步
发表于 06-27 10:24
•2022次阅读
高速异步FIFO的设计与实现
本文主要研究了用FPGA 芯片内部的EBRSRAM 来实现异步FIFO 设计方案,重点阐述了异步FIFO 的标志信号——空/满状态的设计思路,并且用VHDL 语言实现,最后进行了仿真验
发表于 01-13 17:11
•40次下载
Camera Link接口的异步FIFO设计与实现
介绍了异步FIFO在Camera Link接口中的应用,将Camera Link接口中的帧有效信号FVAL和行有效信号LVAL引入到异步FIFO的设计中。分析了FPGA中设计
发表于 07-28 16:08
•32次下载
异步FIFO结构及FPGA设计
摘要:首先介绍异步FIFO的概念、应用及其结构,然后分析实现异步FIFO的难点问题及其解决办法;在传统设计的基础上提出一种新颖的电路结构并对其进行
发表于 06-20 12:46
•3851次阅读
异步FIFO的设计分析及详细代码
本文首先对异步 FIFO 设计的重点难点进行分析,最后给出详细代码。 一、FIFO简单讲解 FIFO的本质是RAM, 先进先出 重要参数:
发表于 11-15 12:52
•8561次阅读
基于FPGA的异步FIFO设计方法详解
在现代电路设计中,一个系统往往包含了多个时钟,如何在异步时钟间传递数据成为一个很重要的问题,而使用异步FIFO可以有效地解决这个问题。异步FIFO
发表于 07-17 08:33
•8319次阅读
基于异步FIFO结构原理
在现代的集成电路芯片中,随着设计规模的不断扩大,一个系统中往往含有数个时钟。多时钟域带来的一个问题就是,如何设计异步时钟之间的接口电路。异步FIFO(Firstln F irsto ut)是解决这个
发表于 02-07 14:22
•0次下载
异步fifo详解
和写入数据(对于大型数据存储,在性能上必然缓慢),其数据地址是由内部读写指针自动加一完成的,不能像普通的存储器一样,由地址线决定读取或者写入某个特定地址的数据,按读写是否为相同时钟域分为同步和异步FIFO,这里主要介绍
FIFO设计—同步FIFO
FIFO是异步数据传输时常用的存储器,多bit数据异步传输时,无论是从快时钟域到慢时钟域,还是从慢时钟域到快时钟域,都可以使用FIFO处理。
发表于 05-26 16:12
•1488次阅读
同步FIFO和异步FIFO区别介绍
,并且间隔时间长,也就是突发写入。那么通过设置一定深度的FIFO,可以起到数据暂存的功能,且使得后续处理流程平滑。 时钟域的隔离:主要用异步FIFO。对于不同时钟域的数据传输,可以通过FIFO
评论