1 //==========================================
2 // Function : Asynchronous FIFO (w/ 2 asynchronous clocks).
3 // Coder : Alex Claros F.
5 // Notes : This implementation is based on the article
6 // 'Asynchronous FIFO in Virtex-II FPGAs'
7 // writen by Peter Alfke. This TechXclusive
8 // article can be downloaded from the
9 // Xilinx website. It has some minor modifications.
10 //=========================================
15 #(parameter DATA_WIDTH = 8,
17 FIFO_DEPTH = (1 << ADDRESS_WIDTH))
19 (output wire [DATA_WIDTH-1:0] Data_out,
24 input wire [DATA_WIDTH-1:0] Data_in,
26 input wire WriteEn_in,
31 /////Internal connections & variables//////
32 reg [DATA_WIDTH-1:0] Mem [FIFO_DEPTH-1:0];
33 wire [ADDRESS_WIDTH-1:0] pNextWordToWrite, pNextWordToRead;
35 wire NextWriteAddressEn, NextReadAddressEn;
36 wire Set_Status, Rst_Status;
38 wire PresetFull, PresetEmpty;
40 //////////////Code///////////////
42 //(Uses a dual-port RAM).
44 assign Data_out = Mem[pNextWordToRead];
45 // always @ (posedge RClk)
47 // Data_out <= Mem[pNextWordToRead];
48 // if (ReadEn_in & !Empty_out)
51 always @ (posedge WClk)
52 if (WriteEn_in & !Full_out)
53 Mem[pNextWordToWrite] <= Data_in;
55 //Fifo addresses support logic:
56 //'Next Addresses' enable logic:
57 assign NextWriteAddressEn = WriteEn_in & ~Full_out;
58 assign NextReadAddressEn = ReadEn_in & ~Empty_out;
60 //Addreses (Gray counters) logic:
62 .COUNTER_WIDTH( ADDRESS_WIDTH )
64 .GrayCount_out(pNextWordToWrite),
65 .Enable_in(NextWriteAddressEn),
72 .COUNTER_WIDTH( ADDRESS_WIDTH )
74 .GrayCount_out(pNextWordToRead),
75 .Enable_in(NextReadAddressEn),
81 //'EqualAddresses' logic:
82 assign EqualAddresses = (pNextWordToWrite == pNextWordToRead);
84 //'Quadrant selectors' logic:
85 assign Set_Status = (pNextWordToWrite[ADDRESS_WIDTH-2] ~^ pNextWordToRead[ADDRESS_WIDTH-1]) &
86 (pNextWordToWrite[ADDRESS_WIDTH-1] ^ pNextWordToRead[ADDRESS_WIDTH-2]);
88 assign Rst_Status = (pNextWordToWrite[ADDRESS_WIDTH-2] ^ pNextWordToRead[ADDRESS_WIDTH-1]) &
89 (pNextWordToWrite[ADDRESS_WIDTH-1] ~^ pNextWordToRead[ADDRESS_WIDTH-2]);
91 //'Status' latch logic:
92 always @ (Set_Status, Rst_Status, Clear_in) //D Latch w/ Asynchronous Clear & Preset.
93 if (Rst_Status | Clear_in)
94 Status = 0; //Going 'Empty'.
96 Status = 1; //Going 'Full'.
98 //'Full_out' logic for the writing port:
99 assign PresetFull = Status & EqualAddresses; //'Full' Fifo.
101 always @ (posedge WClk, posedge PresetFull) //D Flip-Flop w/ Asynchronous Preset.
107 //'Empty_out' logic for the reading port:
108 assign PresetEmpty = ~Status & EqualAddresses; //'Empty' Fifo.
110 always @ (posedge RClk, posedge PresetEmpty) //D Flip-Flop w/ Asynchronous Preset.