@@ -25,38 +25,52 @@ module async_fifo
25
25
)(
26
26
// Write side of the FIFO
27
27
input wire wr_clk,
28
- input wire awresetn ,
29
- input wire wren ,
30
- input wire [WIDTH- 1 :0 ] data_in ,
28
+ input wire wr_arstn ,
29
+ input wire wr_en ,
30
+ input wire [WIDTH- 1 :0 ] wr_data ,
31
31
output wire wr_full,
32
32
// Read side of the FIFO
33
33
input wire rd_clk,
34
- input wire arresetn ,
35
- input wire rden ,
36
- output wire [WIDTH- 1 :0 ] data_out ,
34
+ input wire rd_arstn ,
35
+ input wire rd_en ,
36
+ output wire [WIDTH- 1 :0 ] rd_data ,
37
37
output wire rd_empty
38
38
);
39
39
40
40
localparam DEPTH = 1 << POINTER;
41
41
42
- reg [POINTER - 1 : 0 ] rd_pointer, rd_sync_1, rd_sync_2;
43
- reg [POINTER- 1 : 0 ] wr_pointer, wr_sync_1, wr_sync_2 ;
44
- wire [POINTER - 1 : 0 ] rd_pointer_g;
45
- wire [POINTER- 1 : 0 ] wr_pointer_g ;
42
+ // Read pointer managed by rd_clk
43
+ reg [POINTER: 0 ] rd_pointer ;
44
+ // Write pointer managed by wr_clk
45
+ reg [POINTER: 0 ] wr_pointer ;
46
46
47
- reg [WIDTH- 1 : 0 ] mem [DEPTH- 1 : 0 ];
47
+ // Pointers used to pass between the domains
48
+ reg [POINTER:0 ] rd_sync_1;
49
+ reg [POINTER:0 ] wr_sync_1;
50
+ reg [POINTER:0 ] rd_sync_2;
51
+ reg [POINTER:0 ] wr_sync_2;
52
+ wire [POINTER:0 ] rd_pointer_g;
53
+ wire [POINTER:0 ] wr_pointer_g;
48
54
49
- wire [POINTER- 1 : 0 ] rd_pointer_sync;
50
- wire [POINTER- 1 : 0 ] wr_pointer_sync;
55
+ // Pointers used across the domains:
56
+
57
+ // Used in write domain
58
+ wire [POINTER:0 ] rd_pointer_sync;
59
+ // Used in read domain
60
+ wire [POINTER:0 ] wr_pointer_sync;
61
+
62
+ // The memory block RAM used to store and
63
+ // pass the information
64
+ reg [WIDTH- 1 :0 ] mem [DEPTH- 1 : 0 ];
51
65
52
66
// Write logic management
53
- always @(posedge wr_clk or posedge awresetn ) begin
54
- if (awresetn == 1'b0 ) begin
67
+ always @(posedge wr_clk or negedge wr_arstn ) begin
68
+ if (wr_arstn == 1'b0 ) begin
55
69
wr_pointer <= 0 ;
56
70
end
57
- else if (wr_full == 1'b0 && wren == 1'b1 ) begin
71
+ else if (wr_full == 1'b0 && wr_en == 1'b1 ) begin
58
72
wr_pointer <= wr_pointer + 1 ;
59
- mem[wr_pointer[POINTER- 1 : 0 ]] <= data_in ;
73
+ mem[wr_pointer[POINTER- 1 : 0 ]] <= wr_data ;
60
74
end
61
75
end
62
76
@@ -67,16 +81,16 @@ module async_fifo
67
81
end
68
82
69
83
// Read logic management
70
- always @(posedge rd_clk or posedge arresetn ) begin
71
- if (arresetn == 1'b0 ) begin
84
+ always @(posedge rd_clk or negedge rd_arstn ) begin
85
+ if (rd_arstn == 1'b0 ) begin
72
86
rd_pointer <= 0 ;
73
87
end
74
- else if (rd_empty == 1'b0 && rden == 1'b1 ) begin
88
+ else if (rd_empty == 1'b0 && rd_en == 1'b1 ) begin
75
89
rd_pointer <= rd_pointer + 1 ;
76
90
end
77
91
end
78
92
79
- assign data_out = mem[rd_pointer[POINTER- 1 : 0 ]];
93
+ assign rd_data = mem[rd_pointer[POINTER- 1 : 0 ]];
80
94
81
95
// Write pointer synchronization with read clock
82
96
always @(posedge rd_clk) begin
@@ -85,13 +99,13 @@ module async_fifo
85
99
end
86
100
87
101
// Binary pointer comparaison
88
- assign wr_full = ((wr_pointer[POINTER- 1 : 0 ] == rd_pointer_sync[POINTER- 1 : 0 ]) &&
89
- (wr_pointer[POINTER] != rd_pointer_sync[POINTER] ));
102
+ // assign wr_full = ((wr_pointer[POINTER-1 : 0] == rd_pointer_sync[POINTER-1 : 0]) &&
103
+ // (wr_pointer[POINTER] != rd_pointer_sync[POINTER] )) ? 1'b1 : 1'b0 ;
90
104
91
105
// Gray counter comparaison
92
- // assign wr_full = ((wr_pointer[POINTER-2 : 0] == rd_pointer_sync[POINTER-2 : 0]) &&
93
- // (wr_pointer[POINTER-1] != rd_pointer_sync[POINTER-1]) &&
94
- // (wr_pointer[POINTER] != rd_pointer_sync[POINTER]));
106
+ assign wr_full = ((wr_pointer[POINTER- 2 : 0 ] == rd_pointer_sync[POINTER- 2 : 0 ]) &&
107
+ (wr_pointer[POINTER- 1 ] != rd_pointer_sync[POINTER- 1 ]) &&
108
+ (wr_pointer[POINTER] != rd_pointer_sync[POINTER])) ? 1'b1 : 1'b0 ;
95
109
96
110
// The FIFO is considered as empty when pointer match the same address
97
111
// No more data remains to read
@@ -106,11 +120,9 @@ module async_fifo
106
120
107
121
// Convert back to binary after the synchronization from
108
122
// the source domain
109
- assign wr_pointer_sync = wr_sync_2 ^ (wr_sync_2 >> 1 ) ^
110
- (wr_sync_2 >> 2 ) ^ (wr_sync_2 >> 3 );
123
+ assign wr_pointer_sync = wr_sync_2 ^ (wr_sync_2 >> 1 ) ^ (wr_sync_2 >> 2 ) ^ (wr_sync_2 >> 3 );
111
124
112
- assign rd_pointer_sync = rd_sync_2 ^ (rd_sync_2 >> 1 ) ^
113
- (rd_sync_2 >> 2 ) ^ (rd_sync_2 >> 3 );
125
+ assign rd_pointer_sync = rd_sync_2 ^ (rd_sync_2 >> 1 ) ^ (rd_sync_2 >> 2 ) ^ (rd_sync_2 >> 3 );
114
126
115
127
endmodule
116
128
0 commit comments