Verilog实现FIFO专题(3-同步FIFO设计)

FIFO根据输入输出时钟是否一致,分为同步FIFO与异步FIFO。同步FIFO中,读写控制信号以及数据均处于同一时钟域,满足STA分析时一般不会出现亚稳态等不稳定情形;而对于异步FIFO,读写相关信号处于不同时钟域,信号的不同步可能会导致亚稳态,导致FIFO工作异常,设计较为复杂;因此,此处我们首先对较简单的同步FIFO进行分析与设计:

目录

一、端口设计

二、功能描述

三、实现代码

四、参考文献:


一、端口设计

模块端口:

1、时钟信号clk,作为同步FIFO的驱动信号

2、异步复位信号rst_n

// 写FIFO相关

3、数据输入信号din[DW-1:0],作为FIFO数据写入端,DW数据为位宽

4、写使能we

// 读FIFO相关

5、数据输出信号dout[DW-1:0],作为FIFO数据输出端

6、读使能re

// 标志相关

7、FIFO满标志full,FIFO满时不能再写入数据

8、FIFO空标志empty,FIFO空时不能再读出数据

内部信号:

1、读指针wp,作为读地址(FIFO读写只能顺序进行,不能外部设置,因此为内部信号)

2、写指针rp,作为写地址

3、计数cnt,用于空满状态判断

4、[DW-1:0]ram[0:Depth-1],数据存储空间,Depth为FIFO深度

二、功能描述

1、读逻辑:

clk来临,re有效,并且FIFO非空(empty=0)时,将读指针rp对应地址处的数据读出至dout;

2、读指针逻辑:

clk来临,re有效,并且FIFO非空(empty=0)时,进行一次读操作,rp加1(即顺序读出);

3、写逻辑:

clk来临,we有效,并且FIFO不满(full=0)时,将din写入写指针wp对应地址处;

4、读指针逻辑:

clk来临,re有效,并且FIFO不满(full=0)时,进行一次写操作,wp加1(即顺序存储);

5、空满检测逻辑:

用cnt表示FIFO中存储的数据,初始化为0。每进行一次写操作,cnt+1;每进行一次读操作,cnt-1;同时读写一次,cnt不变;

cnt = 0时,FIFO为空,empty = 1;

cnt = depth时,FIFO为满,full = 1;

三、实现代码

模块描述如下:

应注意cnt取值及判断逻辑

`timescale 1ns / 1ps
//
// Company: 
// Engineer: guoliang CLL
// 
// Create Date: 2020/02/27 13:11:04
// Design Name: 
// Module Name: sfifo
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module sfifo
#(parameter DW = 8,AW = 4)//默认数据宽度8,FIFO深度16
(
    input clk,
    input rst_n,
    input we,
    input re,
    input [DW-1:0]din,
    output reg [DW-1:0]dout,
    output empty,
    output full
    );
// internal signal
parameter Depth = 1 << AW;//depth of FIFO 
reg [DW-1:0]ram[0:Depth-1];
reg [AW:0]cnt;
reg [AW-1:0]wp;
reg [AW-1:0]rp;
// FIFO declaration
// 空满检测
assign empty = (cnt==0)?1'b1:1'b0;
assign full = (cnt==Depth)?1'b1:1'b0;
// cnt 计数
always@(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        cnt <= 1'd0;
    else if(!empty & re & !full & we)//同时读写
        cnt <= cnt;
    else if(!full & we)//写
        cnt <= cnt+1;
    else if(!empty & re)//读
        cnt <= cnt-1;
    else 
        cnt <= cnt;
end
// 读指针
always@(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        rp <= 1'b0;
    else if(!empty & re)
        rp <= rp+1'b1;
    else
        rp <= rp;
end
//写指针
always@(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        wp <= 1'b0;
    else if(!full & we)
        wp <= wp+1'b1;
    else
        wp <= wp;
end
// 读操作
always@(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        dout <= {DW{1'bz}};
    else if(!empty & re)
        dout <= ram[rp];
    else
        dout <= dout;
end
//写操作
always@(posedge clk)
begin
    if(!full & we)
        ram[wp] <= din;
    else
        ram[wp] <= ram[wp];
end
endmodule

测试文件如下:

先只写不读;din从0递增;

再只读不写;

最后同时读写;

`timescale 1ns / 1ps
//
// Company: 
// Engineer: guoliang CLL
// 
// Create Date: 2020/02/27 13:49:53
// Design Name: 
// Module Name: sfifo_tsb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module sfifo_tsb(

    );
// port declaration
reg clk;
reg rst_n;
reg we;
reg re;
reg [7:0]din;
wire  [7:0]dout;
wire empty;
wire full;
//clk
initial
begin
    clk = 1'b0;
    forever #10 clk = ~clk;
end
// 
initial
begin
    rst_n = 1'b1;
    din = 1'b0;
    re = 1'b0;
    we = 1'b0;
    #20 rst_n = 1'b0;
    #20 rst_n = 1'b1;
    // write
    we = 1'b1;
    repeat(20) #20 din = din+1'b1;
    // read 
    we = 1'b0;
    re = 1'b1;
    repeat(20) #20; 
    // read and write
    we = 1'b1;
    re = 1'b1;
    din = 1'b0;
    repeat(20) #20 din = din+1'b1;     
end
// inst
sfifo inst(
    .clk(clk),
    .rst_n(rst_n),
    .we(we),
    .re(re),
    .din(din),
    .dout(dout),
    .empty(empty),
    .full(full)
);
endmodule

仿真结果如下:

先只写不读;din从0递增,每个clk来临进行数据存储,cnt+1,直到存满后full=1,不再存入;

Verilog实现FIFO专题(3-同步FIFO设计)_第1张图片

再只读不写;每个clk来临进行数据读出,cnt-1,直到读完后empty=1,不再读出;(注意读出一次数据后,full就为0,即FIFO现在不满)

Verilog实现FIFO专题(3-同步FIFO设计)_第2张图片

 最后同时读写,接上步操作,只有先写入一次后,FIFO才能非空,才能进行读取;因此输出滞后写入一个时钟周期,cnt恒定;

Verilog实现FIFO专题(3-同步FIFO设计)_第3张图片

 仿真验证了同步FIFO功能的正确,表明设计正确;

RTL电路如下:

Verilog实现FIFO专题(3-同步FIFO设计)_第4张图片

四、参考文献:

Verilog 同步 FIFO 设计

Verilog同步FIFO

你可能感兴趣的:(FPGA/Verilog基础)