任意宽度与深度的异步fifo设计

设计要求

实现2的幂深度的异步fifo,要求空满状态监测,空时不可读,满时不可写。

设计思路

 

 

1.端口与中间信号定义

input  wclk ,wrstn,wr,wdata //write时钟域中时钟信号,复位信号,wr使能信号,wdata写入数据

input rclk ,rrstn,rd  //read时钟域中的时钟,复位信号,读使能信号

output  full empty rdata // 满/空标志 ,rd后读出的数据。

middle signal  addr_w[depth:0] addr_r[depth:0]  //写地址,读地址,位宽多一位

gray_addr_w   gray_addr_r //将写读地址转化为格雷码,位宽同addr,多一位判断

reg [width-1:0] regs [fifo_depth-1:0] // 寄存器regs由fifo_depth个小寄存器构成,每个小寄存器的位宽是width    (fifo_depth == 2^depth)

2.参数化

深度即是fifo中寄存数据个数,宽度即是数据位宽,用传参的方式定义。即module name #(parameter ....)();

3.addr

写操作在wclk进行,每次wr有效,addr_w自加一。读操作同理。

4.gray

异步fifo涉及两个时钟域,为减少资源使用的同时兼顾数据传输的稳定性,选择格雷码配合数据传输。题目要求2的幂的深度,故可以直接使用格雷码,若有其他要求,可在格雷码的基础上进行删改或者查表,来保证二级制码转换而成的码具有格雷码的特性,

将addr转化为格雷码:gray <= (addr >> 1 ) ^  addr;

值得注意的是,原addr最高位仅用于判断空满状态,地址由其他位存储。转换后的gray仅仅用于比对空满状态,无存储地址的功能。

也就是说,地址由原时钟域的addr存储,同时在原时钟域产生一个addr的格雷码,传输到另一时钟域,再与另一时钟域的addr所产生的gray比对,来判断空满状态。

若两格雷码完全相同,即可判断为空状态,若两格雷码前两位相反,其余位相同,可判断为满状态。

5.gray传输

格雷码可由组合逻辑产生,亦可在always块中由寄存器存储。值得注意的是,若由组合逻辑产生,在跨时钟传输之前,需要在原时钟域中打一拍以消除因由组合逻辑延迟产生的毛刺。之后在通过二级同步器以传入另一时钟域

6.regs赋值与读取

integer i; //位宽为32,需注意
always@(posedge wclk or negedge wrstn)
begin
  if(!wrstn)
    begin
      for(i=0;i<fifo_depth;i=i+1)
        begin
          regs[i] <= 0;
        end
      end
  else if (allow_wr) //即判断状态为非满:assign allow wr =wr && full;
    begin
      regs[addr_w[depth-1:0]] <= wdata;
    end
end                

  rdata同理。

总结

addr负责给地址,gray负责判断空满,rags负责寄存数据,wdata写入,rdata读出,完成异步fifo功能。

仿真效果

vcs+verdi:

 

 

spyglass lint && cdc:

 

 warning均为 ignored

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值