//-----------------------------------------------------
        // Имя модуля : aFifo
        // Имя файла : aFifo.v
        // Функц. назначение : Асинхронный (однотактовый) FIFO
        // Программист : portal-ed.ru/
        //-----------------------------------------------------
        module aFifo
        #(parameter DATA_WIDTH = 8,
        ADDRESS_WIDTH = 4,
        FIFO_DEPTH = (1 << ADDRESS_WIDTH))
        //Чтение порта
        (output reg [DATA_WIDTH-1:0] Data_out,
        output reg Empty_out,
        input wire ReadEn_in,
        input wire RClk,
        //Запись в порт
        input wire [DATA_WIDTH-1:0] Data_in,
        output reg Full_out,
        input wire WriteEn_in,
        input wire WClk,
        input wire Clear_in);
        /////Внутренние связи и переменные//////
        reg [DATA_WIDTH-1:0] Mem [FIFO_DEPTH-1:0];
        wire [ADDRESS_WIDTH-1:0] pNextWordToWrite, pNextWordToRead;
        wire EqualAddresses;
        wire NextWriteAddressEn, NextReadAddressEn;
        wire Set_Status, Rst_Status;
        reg Status;
        wire PresetFull, PresetEmpty;
        //////////////Начало кода///////////////
        //Логические порты данных:
        //(Использование двойной RAM).
        //'Data_out:
        always @ (posedge RClk)
           if (ReadEn_in & !Empty_out)
           Data_out <= Mem[pNextWordToRead];
        //'Data_in’:
        always @ (posedge WClk)
           if (WriteEn_in & !Full_out)
              Mem[pNextWordToWrite] <= Data_in;
        //Логическая поддержка Fifo:
        //'Next Addresses' логическое разрешение:
        assign NextWriteAddressEn = WriteEn_in & ~Full_out;
        assign NextReadAddressEn = ReadEn_in & ~Empty_out;
        //Addreses (Счетчик Грэя):
        GrayCounter GrayCounter_pWr
        (.GrayCount_out(pNextWordToWrite),
        .Enable_in(NextWriteAddressEn),
        .Clear_in(Clear_in),
        .Clk(WClk)
        );
        GrayCounter GrayCounter_pRd
        (.GrayCount_out(pNextWordToRead),
        .Enable_in(NextReadAddressEn),
        .Clear_in(Clear_in),
        .Clk(RClk)
        );
        //'EqualAddresses':
        assign EqualAddresses = (pNextWordToWrite == pNextWordToRead);
        //'Quadrant selectors’:
        assign Set_Status = (pNextWordToWrite[ADDRESS_WIDTH-2] ~^ pNextWordToRead[ADDRESS_WIDTH-1]) &
        (pNextWordToWrite[ADDRESS_WIDTH-1] ^ pNextWordToRead[ADDRESS_WIDTH-2]);
        assign Rst_Status = (pNextWordToWrite[ADDRESS_WIDTH-2] ^ pNextWordToRead[ADDRESS_WIDTH-1]) &
        (pNextWordToWrite[ADDRESS_WIDTH-1] ~^ pNextWordToRead[ADDRESS_WIDTH-2]);
        //'Status' защелка:
        always @ (Set_Status, Rst_Status, Clear_in) //D Latch w/ Asynchronous Clear & Preset.
           if (Rst_Status | Clear_in)
              Status = 0; //Going 'Empty'.
              else if (Set_Status)
              Status = 1; //Going 'Full'.
        //'Full_out' запись в порт:
        assign PresetFull = Status & EqualAddresses; //'Полный' Fifo.
        always @ (posedge WClk, posedge PresetFull) //D-триггер с
        // асинхронной предустановкой
        if (PresetFull)
            Full_out <= 1;
            else
            Full_out <= 0;
        //'Empty_out' чтение из порта:
        assign PresetEmpty = ~Status & EqualAddresses; //'Пустой' Fifo.
        always @ (posedge RClk, posedge PresetEmpty) // D-триггер с
        // асинхронной предустановкой
        if (PresetEmpty)
            Empty_out <= 1;
            else
                 Empty_out <= 0;
        endmodule