笔试面试 同步fifo 异步FIFO

本文详细介绍了同步FIFO和异步FIFO的设计原理。同步FIFO关注读写地址累加及读空写满信号,而异步FIFO处理不同时钟域间的地址比较,采用格雷码避免亚稳态影响。文中还讨论了复位优先级、地址转换以及满空信号的判断条件,并提供了Verilog代码和波形图示例。
摘要由CSDN通过智能技术生成

一、同步FIFO

对于同步FIFO,需要注意读写地址的累加;读空和写满信号的产生
代码主要结构:

  1. 写地址产生
  2. 读地址产生
  3. 写入数据
  4. 读出数据
  5. 写满信号
  6. 读空信号
//Description:sync fifo
module sync_fifo
               #(
                  parameter DATA_WIDTH=8,                       //数据位宽
                  parameter ADDR_WIDTH=4                        //FIFO深度
                )
                (
                 input                           clk,           //时钟
                 input                           rst_n,
                 input      [DATA_WIDTH-1:0]     wr_data,       //待写入数据
                 input                           wr_en,         //写使能
                 input                           rd_en,         //读使能
                 output reg [DATA_WIDTH-1:0]     rdata,         //读出数据
                 output reg                      full,          //写满信号
                 output reg                      empty          //读空信号           
                );
                
       
reg     [ADDR_WIDTH-1:0]        wr_addr;                        //写地址
reg     [ADDR_WIDTH-1:0]        rd_addr;                        //读地址
reg     [DATA_WIDTH-1:0]        ram_data[2**ADDR_WIDTH-1:0];    //定义一个ram


//写地址
always@(posedge clk or negedge rst_n)
if(!rst_n)
 begin
    wr_addr<=0;
 end
else if(wr_en&~full)        //写使能信号来临且没有写满时地址自加
 begin
    wr_addr<=wr_addr+1'b1;
 end
else
 begin
    wr_addr<=wr_addr;
 end
 
//读地址
always@(posedge clk or negedge rst_n)
if(!rst_n)
 begin
    rd_addr<=0;
 end
else if(rd_en&~empty)  //读使能信号来临且没有读空时地址自加
 begin
    rd_addr<=rd_addr+1'b1;
 end
else
 begin
    rd_addr<=rd_addr;
 end
 
 
//写入数据
always@(posedge clk) 
if(wr_en&~full)
	ram_data[wr_addr]<=wr_data;
 
//读出数据
always@(posedge clk or negedge rst_n)
if(!rst_n)
 begin
     rdata<=0;
 end
else if(rd_en&~empty)
 begin
     rdata<=ram_data[rd_addr];
 end
else
 begin
     rdata<=rdata;
 end
 
 
//判断写满
always@(posedge clk or negedge rst_n)
if(!rst_n)
 begin
    full<=1'b0;
 end
 //((写地址比读地址少1)或者(写地址为最大、读地址为0)(这两个条件不能合并,否则写地址最大、读地址为0时无法判断为写满)),且写使能来临,读使能为低;
else if(((wr_addr==rd_addr-1)|(wr_addr==2**ADDR_WIDTH-1&&rd_addr==0))&wr_en&~rd_en)
 begin
    full<=1'b1;
 end
else if(full&rd_en) //写满后来一个读信号写满信号拉低
 begin
     full<=1'b0;
 end
 
//判断读空 
always@(posedge clk or negedge rst_n)
if(!rst_n)
 begin
     empty<=1'b0;
 end
else if(((rd_addr+1==wr_addr)|(rd_addr==2**ADDR_WIDTH-1&&wr_addr==0))&rd_en&~wr_en)   
 begin
     empty<=1'b1;
 end
else if(empty&wr_en)
 begin
     empty<=1'b0;
 end
 
endmodule 

二、异步FIFO

  1. 异步FIFO存在两个不同的时钟域,因此读写地址不能直接比较,需要转换为格雷码后再进行比较(由于读写地址的增加是连续的,因此可以将其转换成格雷码,这样可以保证在每个source clock的沿只会有一个bit发生翻转
  • 1
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值