verilog常考面试题之同步FIFO设计(给定位宽和深度)

在这里插入图片描述
fifo(first in first out)fifo的作用是缓冲,分为同步fifo和异步fifo,跟其他存储单元例如RAM的区别最大在于RAM有地址线,可寻址读写,而FIFO不可寻址,所以读写地址得用读写指针生成。

1.同步fifo的写时钟和读时钟是同一个时钟域(信号基于同一个时钟变化)

2.同步fifo的三部分:

fifo写控制逻辑:产生写地址(决定往哪写,从0开始写)、写有效信号、写满(决定是否还能写)等信号;
fifo读控制逻辑:产生读地址(决定从哪读,从0开始读)、读有效信号、读满(决定是否还能读)等信号;
fifo的存储实体(reg、memory)

例如:给定位宽为8,深度16

一、首先定义参数,方便后续修改或者其他人使用时直接通过传参进行,包括数据位宽、FIFO深度、地址位宽(log2(fifo深度))、读的模式(组合逻辑或者时序逻辑),读指针,写指针,存储状态。接口信号主要是:时钟和复位、写的端口信号、读的端口信号

module
#(
  parameter addr_width=4,
  parameter data_width=8,
  parameter data_depth=1<<addr_width,
)
(input clk,
 input rstn,
 input [data_width-1:0] w_data,
 output [data_width-1:0] r_data,
 input w_en,
 input r_en,
 output full,
 output empty,

 reg [addr_width-1:0] w_pointer,//写指针产生写地址
 reg [addr_width-1:0] r_pointer,//读指针产生读地址
 reg [data_width-1:0]mem[data_depth-1:0]//存储器用于存数据,
 reg [addr_width:0] status,//用于空满状态判断,

二、空满状态判断

assign full=(status==data_depth)?`b1:`b0;
assign empty=(status==0)?`b1:`b0;

三、读写指针的控制:当写(读)指针=深度-1,表示满,写(读)指针清零。当写有效且未满时,写指针加1;当读有效且未空时,读指针减1。

//写
always @(posedge clk or negedge rstn)begin
   if(!rstn)
    w_pointer<=0;
    else if(w_pointer==data_depth-1)
     w_pointer<=0;
     else if(w_en&&~full)
      w_pointer<= w_pointer+1;
    end
// 读  
always @(posedge clk or negedge rstn)begin
   if(!rstn)
    r_pointer<=0;
    else if(r_pointer==data_depth-1)
     r_pointer<=0;
     else if(r_en&&~empty)
      r_pointer<= r_pointer+1;
    end  

四、存储器状态,当同时读写时,保持;写,加1;读,减1。(时序逻辑的else可写可不写,本身带有保持)

always @(posedge clk or negedge rstn)begin
   if(!rstn)
    status<=0;
    else if(w_en && r_en)
     status<=status;
     else if(r_en && ~empty)
      status<= status-1;
      else if(w_en && ~full)
      status<= status+1;
    end  

五、写入数据,将写入的数据存入memory中。数组需要一位一位的索引,一位一位的赋值,因此用了for循环(for循环不耗时)

integer i;
always @(posedge clk or negedge rstn)begin
   if(!rstn)begin
    for(i=0;i<data_depth;i=i+1)
    mem[i]<=0;
    end
    else if(w_en)
    mem[w_pointer]<=w_data;
end

六、读数据

always @(posedge clk or negedge rstn)begin
   if(!rstn)begin
   r_data<=0;
   end
   else if(r_en)
   r_data<=mem[r_pointer];
end
  • 1
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值