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