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
68
|
module fifo
#( type data_t = bit
, DEPTH_BITS = 10
)
( input bit clock_in
, input bit clock_out
, input bit reset
, output bit in_ready
, input bit in_valid
, input data_t in_data
, input bit out_ready
, output bit out_valid
, output data_t out_data
);
localparam DEPTH = 1<<DEPTH_BITS;
typedef bit [DEPTH_BITS-1:0] addr_t;
data_t data [DEPTH-1:0];
addr_t oldest, youngest;
bit oldest_wrap, youngest_wrap;
addr_t oldest_grey, youngest_grey;
always @(posedge clock_in, posedge reset) begin
if (reset) begin
in_ready = 0;
youngest = 0;
youngest_wrap = 0;
youngest_grey = 0;
end else begin
if (in_ready && in_valid) begin
data[youngest] = in_data;
if (++youngest == 0)
++youngest_wrap;
end
youngest_grey = youngest ^ (youngest >> 1);
in_ready = oldest_grey != youngest_grey || youngest_wrap == oldest_wrap;
end
end
always @(posedge clock_out, posedge reset) begin
if (reset) begin
out_valid = 0;
oldest = 0;
oldest_wrap = 0;
oldest_grey = 0;
end else begin
if (out_ready && out_valid) begin
if (++oldest == 0)
++oldest_wrap;
end
oldest_grey = oldest ^ (oldest >> 1);
out_valid = oldest_grey != youngest_grey || youngest_wrap != oldest_wrap;
out_data = data[oldest];
end
end
endmodule
|