For Asynchronous FIFO, the two most important aspects are address control and the generation of null and full flags. First, the address control is the read address and write address respectively. Each read/write operation should add 1. the count is twice the ram depth. When the read/write address is equal, the null flag is valid. When the highest bit of the read/write address is equal to the other digits, the full flag is valid. The storage part is implemented using dual-port RAM.
The following is the specific sample code in OpenGL:
Module afifo (r_clk, w_clk, rst_n, data_in, data_out, We, re, empty, full );
Input r_clk, w_clk, rst_n, re, We;
Output empty, full;
Input [7:0] data_in;
Output [7:0] data_out;
Wire [4: 0] waddr, raddr;
Wire [4: 0] g_waddr, g_raddr;
// Empty full
Assign empty = (raddr = waddr );
Assign full = (raddr [] = waddr []) & (raddr [4] = (~ Waddr [4]);
Wire wenable = We &&(~ Full );
Wire renable = Re &&(~ Empty );
Afifo_control afifo_control1 (
. R_clk (r_clk ),
. W_clk (w_clk ),
. Rst_n (rst_n ),
. We (wenable ),
. Re (renable ),
. Raddr (raddr ),
. Waddr (waddr)
);
Dualram dualram_inst (
. Data (data_in ),
. Rdaddress (raddr [3: 0]),
. Rdclock (r_clk ),
. Wraddress (waddr [3: 0]),
. Wrclock (w_clk ),
. Wren (wenable ),
. Q (data_out)
);
Endmodule
Module afifo_control (r_clk, w_clk, rst_n, We, re, raddr, waddr );
Input r_clk, w_clk, rst_n, We, re;
Output Reg [4: 0] raddr, waddr;
Always @ (posedge r_clk or negedge rst_n)
If (! Rst_n) begin
Raddr <= 3'd0;
End
Else if (re) begin
Raddr <= raddr + 1' B1;
End
Always @ (posedge w_clk or negedge rst_n)
If (! Rst_n) begin
Waddr <= 3'd0;
End
Else if (we) begin
Waddr <= waddr + 1 'b1;
End
Endmodule
Testbench is as follows:
'Timescale 1 NS/1 PS
Module afifo_vlg_tst ();
// Constants
// General purpose registers
// Reg eachvec;
// Test vector input registers
Reg [7:0] data_in;
Reg r_clk;
Reg re;
Reg rst_n;
Reg w_clk;
Reg we;
// Wires
Wire [7:0] data_out;
Wire empty;
Wire Full;
// Assign statements (if any)
Afifo I1 (
// Port map-connection between master ports and signals/registers
. Data_in (data_in ),
. Data_out (data_out ),
. Empty (empty ),
. Full (full ),
. R_clk (r_clk ),
. Re (RE ),
. Rst_n (rst_n ),
. W_clk (w_clk ),
. We (we)
);
Initial
Begin
#0; rst_n = 1; data_in = 100; Re = 0; We = 0;
#50; rst_n = 0;
#50; rst_n = 1;
#20; Re = 1;
#20; Re = 0;
#20; We = 1;
#60; data_in = 180;
#2000; We = 0; Re = 1;
#3000; Re = 0;
#100; $ stop ();
End
Always
// Optional sensiti#list
// @ (Event1 or event2 or... eventn)
Begin
// Code executes for every event on sensitisponlist
// Insert code here --> begin
#10 r_clk = 1; w_clk = 0;
#10 r_clk = 0; w_clk = 1;
// @ Eachvec;
// --> End
End
Endmodule
Asynchronous FIFO Programming