module ring_buffer #(parameter LEN_ADDR = 6, LEN_CELL = 8)(
output reg [LEN_CELL-1:0] out_data,
output reg [1:0] head_state, // Регистры состояний
output reg [1:0] tail_state, // записи/чтения
input a_rst,
input head_clk, // Синхросигнал для записи
input tail_clk, // Синхросигнал для чтения
input ena,
input [LEN_CELL-1:0] in_data);
reg [LEN_ADDR-1:0] head_ptr; // Указатель на голову буфера
reg [LEN_ADDR-1:0] tail_ptr; // Указатель на хвост буфера
reg [LEN_CELL-1:0] data [0:2**LEN_ADDR-1];
always @ (posedge head_clk or negedge a_rst)
begin
if(!a_rst)
begin
head_ptr <= 0;
head_state <= 0;
end
else
begin
if(ena)
begin
if(tail_ptr-1 == head_ptr)
head_state <= 2'b10; // Буфер полон
else
begin
if(head_clk)
begin
data[head_ptr] = in_data;
head_ptr = head_ptr + 1;
head_state <= 2'b01; // Успешная запись
end
end
end
end
end
always @ (posedge tail_clk or negedge a_rst)
begin
if(!a_rst)
begin
tail_ptr <= 0;
tail_state <= 0;
end
else
begin
if(ena)
begin
if(tail_ptr == head_ptr)
tail_state = 2'b10; // Буфер пуст
else
begin
if(tail_clk)
begin
out_data = data[tail_ptr];
tail_ptr = tail_ptr + 1;
tail_state <= 2'b01; // Успешное чтение
end
end
end
end
end
endmodule