//----------------------------------------------------- // Имя модуля : syn_fifo // Имя файла : syn_fifo.v // Функц. назначение : Синхронный (однотактовый) FIFO // Программист : www.portal-ed.ru //----------------------------------------------------- module syn_fifo ( clk , // Тактовый вход rst , // Высокий уровень - сброс wr_cs , // Запись, выбор блока rd_cs , // Чтение, выбор блока data_in , // Входные данные rd_en , // Разрешение чтения wr_en , // Разрешение записи data_out , // Выходные данные empty , // FIFO пустой full // FIFO полный ); // Константы FIFO parameter DATA_WIDTH = 8; parameter ADDR_WIDTH = 8; parameter RAM_DEPTH = (1 << ADDR_WIDTH); // Объявление портов input clk ; input rst ; input wr_cs ; input rd_cs ; input rd_en ; input wr_en ; input [DATA_WIDTH-1:0] data_in ; output full ; output empty ; output [DATA_WIDTH-1:0] data_out ; //-----------Внутренние переменные------------------- reg [ADDR_WIDTH-1:0] wr_pointer; reg [ADDR_WIDTH-1:0] rd_pointer; reg [ADDR_WIDTH :0] status_cnt; reg [DATA_WIDTH-1:0] data_out ; wire [DATA_WIDTH-1:0] data_ram ; //-----------Заданные переменные--------------- assign full = (status_cnt == (RAM_DEPTH-1)); assign empty = (status_cnt == 0); //-----------Начало кода--------------------------- always @ (posedge clk or posedge rst) begin : WRITE_POINTER if (rst) begin wr_pointer <= 0; end else if (wr_cs && wr_en ) begin wr_pointer <= wr_pointer + 1; end end always @ (posedge clk or posedge rst) begin : READ_POINTER if (rst) begin rd_pointer <= 0; end else if (rd_cs && rd_en ) begin rd_pointer <= rd_pointer + 1; end end always @ (posedge clk or posedge rst) begin : READ_DATA if (rst) begin data_out <= 0; end else if (rd_cs && rd_en ) begin data_out <= data_ram; end end always @ (posedge clk or posedge rst) begin : STATUS_COUNTER if (rst) begin status_cnt <= 0; // Чтение, но запись end else if ((rd_cs && rd_en) && !(wr_cs && wr_en) && (status_cnt != 0)) begin status_cnt <= status_cnt - 1; // Запись, но не чтение end else if ((wr_cs && wr_en) && !(rd_cs && rd_en) && (status_cnt != RAM_DEPTH)) begin status_cnt <= status_cnt + 1; end end ram_dp_ar_aw #(DATA_WIDTH,ADDR_WIDTH)DP_RAM ( .address_0 (wr_pointer) , // Вход address_0 .data_0 (data_in) , // Двунаправленный порт data_0 .cs_0 (wr_cs) , // Выбор блока .we_0 (wr_en) , // Разрешение записи .oe_0 (1'b0) , // Разрешение выхода .address_1 (rd_pointer) , // Вход address_q .data_1 (data_ram) , // Двунаправленный порт data_1 .cs_1 (rd_cs) , // Выбор блока .we_1 (1'b0) , // Разрешение чтения .oe_1 (rd_en) // Разрешение выхода ); endmodule