module ring_buffer parameter LEN_ADDR LEN_CELL output reg LEN_CELL-1 o

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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