Синхронный FIFO

//-----------------------------------------------------
// Имя модуля : 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