同步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


 

 







免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM