• 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设计的更多相关文章

  1. FPGA Asynchronous FIFO设计思路(2)

    FPGA Asynchronous FIFO设计思路(2) 首先讨论格雷码的编码方式: 先看4bit的格雷码,当MSB为0时,正向计数,当MSB为1时,即指针已经走过一遍了,最高位翻转,此时的格雷码是 ...

  2. FPGA Asynchronous FIFO设计思路

    FPGA Asynchronous FIFO设计思路 将一个多位宽,且在不停变化的数据从一个时钟域传递到另一个时钟域是比较困难的. 同步FIFO的指针比较好确定,当FIFO counter达到上限值时 ...

  3. FIFO设计中的深度计算【zz】

    FIFO设计中的深度计算: 写时钟频率 w_clk, 读时钟频率 r_clk, 写时钟周期里,每B个时钟周期会有A个数据写入FIFO: 读时钟周期里,每Y个时钟周期会有X个数据读出FIFO: 则,FI ...

  4. 基于FPGA的异步FIFO设计

    今天要介绍的异步FIFO,可以有不同的读写时钟,即不同的时钟域.由于异步FIFO没有外部地址端口,因此内部采用读写指针并顺序读写,即先写进FIFO的数据先读取(简称先进先出).这里的读写指针是异步的, ...

  5. FIFO设计思考之一

    不管同步FIFO还是异步FIFO,设计难点是full/empty状态flag的正确性. 要保证任何情况 FULL时NO WRITE,EMPTY时NO READ.overflow / underflow ...

  6. 异步FIFO设计

    参考http://www.cnblogs.com/BitArt/archive/2013/04/10/3010073.html http://blog.sina.com.cn/s/blog_6d30f ...

  7. 异步fifo的设计

    本文首先对异步 FIFO 设计的重点难点进行分析 最后给出详细代码 一.FIFO简单讲解 FIFO的本质是RAM, 先进先出 重要参数:fifo深度(简单来说就是需要存多少个数据)           ...

  8. 同步fifo的verilogHDL设计实例

    原创 设计一个fifo,输入16bit,输出16bit的data,寻址宽度5bit,有空满标志. top 层如下所示: /* date : 2014/10/14 version : modelsim ...

  9. Verilog设计异步FIFO

    转自http://ninghechuan.com 异步FIFO有两个异步时钟,一个端口写入数据,一个端口读出数据.通常被用于数据的跨时钟域的传输. 同步FIFO的设计.一个时钟控制一个计数器,计数器增 ...

  10. 异步fifo的设计(FPGA)

    本文首先对异步 FIFO 设计的重点难点进行分析 最后给出详细代码 一.FIFO简单讲解 FIFO的本质是RAM, 先进先出 重要参数:fifo深度(简单来说就是需要存多少个数据)           ...

随机推荐

  1. 被面试官PUA了:创建索引时一定会锁表?

    索引主要是用于提高数据检索速度的一种机制,通过索引数据库可以快速定位到目标数据的位置,而不需要遍历整个数据集,它就像书籍的目录部分,有它的存在,可以大大加速查询的效率. 那么问题来了:在创建索引时一定 ...

  2. Swagger2的接口配置

    Swagger2的接口配置 /** * Swagger2的接口配置 * * @author ruoyi */ @Configuration public class SwaggerConfig { / ...

  3. ElasticSearch之虚拟内存

    查看当前Linux系统中vm.max_map_count变量的值,命令如下: sysctl vm.max_map_count 执行结果的样例,如下: vm.max_map_count = 65530 ...

  4. ElasticSearch之cat allocation API

    查看各节点上各个shard的硬件使用情况,命令样例如下: curl -X GET "https://localhost:9200/_cat/allocation?v=true&pre ...

  5. 用 Socket.D 替代原生 WebSocket 做前端开发

    socket.d.js 是基于 websocket 包装的 socket.d 协议的实现.就是用 ws 传输数据,但功能更强大. 功能 原生 websocket socket.d 说明 listen ...

  6. 提取 PE文件 / 目标程序 的各种信息

    前段时间项目需要实现对 Windows PE 文件版本信息的提取,如文件说明.文件版本.产品名称.版权.原始文件名等信息.获取这些信息在 Windows 下当然有一系列的 API 函数供调用,简单方便 ...

  7. C++ 学习宝藏网站分享

    C++ 学习宝藏网站分享 1. C++ 在线参考手册 Cppreference https://zh.cppreference.com C++ 开发者必备的在线参考手册,是我最常访问的 C++ 网站之 ...

  8. 华为云MVP朱有鹏:做IoT开发乐趣无穷,年轻开发者更要厚积薄发

    [摘要] 可以预见的是,AIoT会是未来一段时间主流的技术趋势方向,当前也有不少科技巨头涌入其中,蓄势待发,而5G的到来加速了AIoT产业的扩张速度,所以如华为云MVP朱有鹏所说,年轻的开发者应该要拥 ...

  9. 云小课|MRS基础原理之ClickHouse组件介绍

    阅识风云是华为云信息大咖,擅长将复杂信息多元化呈现,其出品的一张图(云图说).深入浅出的博文(云小课)或短视频(云视厅)总有一款能让您快速上手华为云.更多精彩内容请单击此处. 摘要:在2016年开源的 ...

  10. Go语言逆向技术:恢复函数名称算法

    摘要:在对程序做安全审计.漏洞检测时,通常都需要对程序做逆向分析,本文在没有符号表的情况下,提出了一种恢复函数名称的算法,方便对go语言二进制文件进行逆向分析,提升分析效率. 本文分享自华为云社区&l ...