同步FIFO--方法二:将地址位扩展,对地址最高位进行空满判断

因为FIFO的特点为先入先出,则写入FIFO的起始地址均为0,读取地址也从0开始,当读地址与写地址相同时,则可判断FIFO为空,当读地址与写地址除最高位相反,其他位相同时,则可判断FIFO为满 -- 假设RAM深度为8,扩展后的地址为4位。开始写入4个数据,此时写地址为0100,读地址此时为0000;然后开始读数据,读完4个数据后,读地址此时为0100,此时可判断FIFO为空,后对FIFO进行写数据,连续写入8个数据,此时写地址为1100,已知深度为8,判断FIFO为满,此时的写读地址比较发现:最高位相反,其余位相同。

module sync_fifo_2(clk,rst,w_en,r_en,w_data,r_data,full,empty);

input clk;
input rst;
input w_en;
input r_en;
input [7:0]w_data;
output [7:0]r_data;
output full;
output empty;

wire full,empty;
reg [7:0]r_data;
reg [7:0]mem[15:0];
wire [3:0]w_addr_a,r_addr_a;
reg [4:0]w_addr_e,r_addr_e;

assign w_addr_a=w_addr_e[3:0];
assign r_addr_a=r_addr_e[3:0];

always @(posedge clk or negedge rst)
    begin
    if(!rst)
        begin
           r_addr_e<=5'b0;
        end
    else
        begin
        if(empty==0 && r_en==1)
            begin
            r_data<=mem[r_addr_a];
            r_addr_e<=r_addr_e+1;
            end
         end
    end
always @(posedge clk or negedge rst)
    begin
    if(!rst)
        begin
           w_addr_e<=5'b0;
        end
    else
        begin
        if(full==0 && w_en==1)
            begin
            mem[w_addr_a]<=w_data;
            w_addr_e<=w_addr_e+1;
            end
         end
    end
assign empty=(r_addr_e==w_addr_e)?1:0;
assign full=(r_addr_e[4]!=w_addr_e[4] && r_addr_e[3:0]==w_addr_e[3:0])?1:0;//空信号较易判断,满信号需要判断最高位和其他位
endmodule

tb:

`timescale 1ns/1ps
module sync_fifo_2_tb;
reg clk;
reg rst;
reg w_en;
reg r_en;
reg [7:0]w_data;
wire [7:0]r_data;
wire full;
wire empty;

sync_fifo_2 u1(clk,rst,w_en,r_en,w_data,r_data,full,empty);
initial
begin
rst=1;
clk=0;
#1 rst=0;
#5 rst=1;
end

initial
begin
w_en=0;
#1 w_en=1;
end

initial
begin
  $vcdpluson;
end

initial
begin
r_en=0;
#650 r_en=1;w_en=0;
end

always #20 clk=~clk;

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'h8;
#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;
#700 $finish;
end
endmodule


 

 






posted @ 2020-07-27 21:25  影-fish  阅读(1574)  评论(0编辑  收藏  举报