//----------------------------------------------------- // Имя модуля : aFifo // Имя файла : aFifo.v // Функц. назначение : Асинхронный (однотактовый) FIFO // Программист : www.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