Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Questions on Asynchronous FIFO

Status
Not open for further replies.

promach

Advanced Member level 4
Joined
Feb 22, 2016
Messages
1,199
Helped
2
Reputation
4
Reaction score
5
Trophy points
1,318
Activity points
11,636
As in https://github.com/KastnerRG/riffa/blob/master/fpga/riffa_hdl/async_fifo.v#L76-L79 , could anyone advise on the differences in the context of purpose of the parameters ?

wire [C_DEPTH_BITS-1:0] wWrPtr;
wire [C_DEPTH_BITS-1:0] wRdPtr;
wire [C_DEPTH_BITS-1:0] wWrPtrP1;
wire [C_DEPTH_BITS-1:0] wRdPtrP1;


Code Verilog - [expand]
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
// ----------------------------------------------------------------------
// Copyright (c) 2016, The Regents of the University of California All
// rights reserved.
// 
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// 
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
// 
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
// 
//     * Neither the name of The Regents of the University of California
//       nor the names of its contributors may be used to endorse or
//       promote products derived from this software without specific
//       prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL REGENTS OF THE
// UNIVERSITY OF CALIFORNIA BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
// TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
// ----------------------------------------------------------------------
//----------------------------------------------------------------------------
// Filename:            async_fifo.v
// Version:             1.00.a
// Verilog Standard:    Verilog-2001
// Description:         Asynchronous capable parameterized FIFO. As with all
// traditional FIFOs, the RD_DATA will be valid one cycle following a RD_EN 
// assertion. RD_EMPTY will remain low until the cycle following the last RD_EN 
// assertion. Note, that RD_EMPTY may actually be high on the same cycle that 
// RD_DATA contains valid data.
// Author:              Matt Jacobsen
// History:             @mattj: Version 2.0
// Additional Comments: Based on design by CE Cummings in Simulation and 
// Synthesis Techniques for Asynchronous FIFO Design with Asynchronous Pointer 
// Comparisons
//-----------------------------------------------------------------------------
`timescale 1ns/1ns
module async_fifo #(
    parameter C_WIDTH = 32, // Data bus width
    parameter C_DEPTH = 1024,   // Depth of the FIFO
    // Local parameters
    parameter C_REAL_DEPTH = 2**clog2(C_DEPTH),
    parameter C_DEPTH_BITS = clog2(C_REAL_DEPTH),
    parameter C_DEPTH_P1_BITS = clog2(C_REAL_DEPTH+1)
)
(
    input RD_CLK,                           // Read clock
    input RD_RST,                           // Read synchronous reset
    input WR_CLK,                           // Write clock
    input WR_RST,                           // Write synchronous reset
    input [C_WIDTH-1:0] WR_DATA,            // Write data input (WR_CLK)
    input WR_EN,                            // Write enable, high active (WR_CLK)
    output [C_WIDTH-1:0] RD_DATA,           // Read data output (RD_CLK)
    input RD_EN,                            // Read enable, high active (RD_CLK)
    output WR_FULL,                         // Full condition (WR_CLK)
    output RD_EMPTY                         // Empty condition (RD_CLK)
);
 
`include "functions.vh"
 
wire                        wCmpEmpty;
wire                        wCmpFull;
wire    [C_DEPTH_BITS-1:0]  wWrPtr;
wire    [C_DEPTH_BITS-1:0]  wRdPtr;
wire    [C_DEPTH_BITS-1:0]  wWrPtrP1;
wire    [C_DEPTH_BITS-1:0]  wRdPtrP1;
 
 
// Memory block (synthesis attributes applied to this module will
// determine the memory option).
ram_2clk_1w_1r #(.C_RAM_WIDTH(C_WIDTH), .C_RAM_DEPTH(C_REAL_DEPTH)) mem (
    .CLKA(WR_CLK),
    .ADDRA(wWrPtr),
    .WEA(WR_EN & !WR_FULL),
    .DINA(WR_DATA),
    .CLKB(RD_CLK),
    .ADDRB(wRdPtr),
    .DOUTB(RD_DATA)
);
 
 
// Compare the pointers.
async_cmp #(.C_DEPTH_BITS(C_DEPTH_BITS)) asyncCompare (
    .WR_RST(WR_RST),
    .WR_CLK(WR_CLK),
    .RD_RST(RD_RST),
    .RD_CLK(RD_CLK),
    .RD_VALID(RD_EN & !RD_EMPTY),
    .WR_VALID(WR_EN & !WR_FULL),
    .EMPTY(wCmpEmpty), 
    .FULL(wCmpFull),
    .WR_PTR(wWrPtr), 
    .WR_PTR_P1(wWrPtrP1), 
    .RD_PTR(wRdPtr), 
    .RD_PTR_P1(wRdPtrP1)
);
 
 
// Calculate empty
rd_ptr_empty #(.C_DEPTH_BITS(C_DEPTH_BITS)) rdPtrEmpty (
    .RD_EMPTY(RD_EMPTY), 
    .RD_PTR(wRdPtr),
    .RD_PTR_P1(wRdPtrP1),
    .CMP_EMPTY(wCmpEmpty), 
    .RD_EN(RD_EN),
    .RD_CLK(RD_CLK), 
    .RD_RST(RD_RST)
);
 
 
// Calculate full
wr_ptr_full #(.C_DEPTH_BITS(C_DEPTH_BITS)) wrPtrFull (
    .WR_CLK(WR_CLK), 
    .WR_RST(WR_RST),
    .WR_EN(WR_EN),
    .WR_FULL(WR_FULL), 
    .WR_PTR(wWrPtr),
    .WR_PTR_P1(wWrPtrP1),
    .CMP_FULL(wCmpFull)
);
 
endmodule
 
 
module async_cmp #(
  parameter C_DEPTH_BITS = 4,
  // Local parameters
  parameter N = C_DEPTH_BITS-1
)
(
    input WR_RST,
    input WR_CLK,
    input RD_RST,
    input RD_CLK,
    input RD_VALID,
    input WR_VALID,
    output EMPTY, 
    output FULL, 
    input [C_DEPTH_BITS-1:0] WR_PTR, 
    input [C_DEPTH_BITS-1:0] RD_PTR, 
    input [C_DEPTH_BITS-1:0] WR_PTR_P1, 
    input [C_DEPTH_BITS-1:0] RD_PTR_P1
);
  
reg             rDir=0;
wire            wDirSet = (  (WR_PTR[N]^RD_PTR[N-1]) & ~(WR_PTR[N-1]^RD_PTR[N]));
wire            wDirClr = ((~(WR_PTR[N]^RD_PTR[N-1]) &  (WR_PTR[N-1]^RD_PTR[N])) | WR_RST);
 
reg             rRdValid=0;
reg             rEmpty=1;
reg             rFull=0;
wire            wATBEmpty = ((WR_PTR == RD_PTR_P1) && (RD_VALID | rRdValid));
wire            wATBFull = ((WR_PTR_P1 == RD_PTR) && WR_VALID);
wire            wEmpty = ((WR_PTR == RD_PTR) && !rDir);
wire            wFull = ((WR_PTR == RD_PTR) && rDir);
 
assign EMPTY = wATBEmpty || rEmpty;
assign FULL  = wATBFull || rFull;
 
always @(posedge wDirSet or posedge wDirClr)
if (wDirClr) 
    rDir <= 1'b0;
else
    rDir <= 1'b1;
 
always @(posedge RD_CLK) begin
    rEmpty <= (RD_RST ? 1'd1 : wEmpty);
    rRdValid <= (RD_RST ? 1'd0 : RD_VALID);
end
 
always @(posedge WR_CLK) begin
    rFull <= (WR_RST ? 1'd0 : wFull);
end
 
endmodule 
 
 
module rd_ptr_empty #(
    parameter C_DEPTH_BITS = 4
)
(
    input RD_CLK, 
    input RD_RST,
    input RD_EN, 
    output RD_EMPTY,
    output [C_DEPTH_BITS-1:0] RD_PTR,
    output [C_DEPTH_BITS-1:0] RD_PTR_P1,
    input CMP_EMPTY 
);
 
reg                         rEmpty=1;
reg                         rEmpty2=1;
reg     [C_DEPTH_BITS-1:0]  rRdPtr=0;
reg     [C_DEPTH_BITS-1:0]  rRdPtrP1=0;
reg     [C_DEPTH_BITS-1:0]  rBin=0;
reg     [C_DEPTH_BITS-1:0]  rBinP1=1;
wire    [C_DEPTH_BITS-1:0]  wGrayNext;
wire    [C_DEPTH_BITS-1:0]  wGrayNextP1;
wire    [C_DEPTH_BITS-1:0]  wBinNext;
wire    [C_DEPTH_BITS-1:0]  wBinNextP1;
 
assign RD_EMPTY = rEmpty;
assign RD_PTR = rRdPtr;
assign RD_PTR_P1 = rRdPtrP1;
 
// Gray coded pointer
always @(posedge RD_CLK or posedge RD_RST) begin
    if (RD_RST) begin
        rBin <= #1 0;
        rBinP1 <= #1 1;
        rRdPtr <= #1 0;
        rRdPtrP1 <= #1 0;
    end
    else begin
        rBin <= #1 wBinNext;
        rBinP1 <= #1 wBinNextP1;
        rRdPtr <= #1 wGrayNext;
        rRdPtrP1 <= #1 wGrayNextP1;
    end
end
 
// Increment the binary count if not empty
assign wBinNext = (!rEmpty ? rBin + RD_EN : rBin);
assign wBinNextP1 = (!rEmpty ? rBinP1 + RD_EN : rBinP1);
assign wGrayNext = ((wBinNext>>1) ^ wBinNext); // binary-to-gray conversion
assign wGrayNextP1 = ((wBinNextP1>>1) ^ wBinNextP1); // binary-to-gray conversion
 
always @(posedge RD_CLK) begin
    if (CMP_EMPTY)
        {rEmpty, rEmpty2} <= #1 2'b11;
    else
        {rEmpty, rEmpty2} <= #1 {rEmpty2, CMP_EMPTY};
end
 
endmodule
 
 
module wr_ptr_full #(
    parameter C_DEPTH_BITS = 4
)
(
    input WR_CLK, 
    input WR_RST,
    input WR_EN,
    output WR_FULL, 
    output [C_DEPTH_BITS-1:0] WR_PTR, 
    output [C_DEPTH_BITS-1:0] WR_PTR_P1, 
    input CMP_FULL
);
 
reg                         rFull=0;
reg                         rFull2=0;
reg     [C_DEPTH_BITS-1:0]  rPtr=0;
reg     [C_DEPTH_BITS-1:0]  rPtrP1=0;
reg     [C_DEPTH_BITS-1:0]  rBin=0;
reg     [C_DEPTH_BITS-1:0]  rBinP1=1;
wire    [C_DEPTH_BITS-1:0]  wGrayNext;
wire    [C_DEPTH_BITS-1:0]  wGrayNextP1;
wire    [C_DEPTH_BITS-1:0]  wBinNext;
wire    [C_DEPTH_BITS-1:0]  wBinNextP1;
 
assign WR_FULL = rFull;
assign WR_PTR = rPtr;
assign WR_PTR_P1 = rPtrP1;
 
// Gray coded pointer
always @(posedge WR_CLK or posedge WR_RST) begin
    if (WR_RST) begin
        rBin <= #1 0;
        rBinP1 <= #1 1;
        rPtr <= #1 0;
        rPtrP1 <= #1 0;
    end
    else begin
        rBin <= #1 wBinNext;
        rBinP1 <= #1 wBinNextP1;
        rPtr <= #1 wGrayNext;
        rPtrP1 <= #1 wGrayNextP1;
    end
end
 
// Increment the binary count if not full
assign wBinNext = (!rFull ? rBin + WR_EN : rBin);
assign wBinNextP1 = (!rFull ? rBinP1 + WR_EN : rBinP1);
assign wGrayNext = ((wBinNext>>1) ^ wBinNext); // binary-to-gray conversion
assign wGrayNextP1 = ((wBinNextP1>>1) ^ wBinNextP1); // binary-to-gray conversion
 
always @(posedge WR_CLK) begin
    if (WR_RST) 
        {rFull, rFull2} <= #1 2'b00;
    else if (CMP_FULL) 
        {rFull, rFull2} <= #1 2'b11;
    else
        {rFull, rFull2} <= #1 {rFull2, CMP_FULL};
end
 
endmodule



- - - Updated - - -

For lines 103 and 114 in the same verilog code, what is the semantic difference between EMPTY in async_cmp and RD_EMPTY in rd_ptr_empty ? Both are indirectly related by the signal wCmpEmpty.

.EMPTY(wCmpEmpty),

.RD_EMPTY(RD_EMPTY),

- - - Updated - - -

Besides, does anyone have any clue why 'rCount < 2' as in https://github.com/KastnerRG/riffa/blob/master/fpga/riffa_hdl/async_fifo_fwft.v#L79 ?

wire wRen = RD_EN || (rCount < 2'd2);


Code Verilog - [expand]
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// ----------------------------------------------------------------------
// Copyright (c) 2016, The Regents of the University of California All
// rights reserved.
// 
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// 
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
// 
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
// 
//     * Neither the name of The Regents of the University of California
//       nor the names of its contributors may be used to endorse or
//       promote products derived from this software without specific
//       prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL REGENTS OF THE
// UNIVERSITY OF CALIFORNIA BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
// TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
// ----------------------------------------------------------------------
//----------------------------------------------------------------------------
// Filename:            async_fifo_fwft.v
// Version:             1.00.a
// Verilog Standard:    Verilog-2001
// Description:         An asynchronous capable parameterized FIFO. As with all
// first word fall through FIFOs, the RD_DATA will be valid when RD_EMPTY is 
// low. Asserting RD_EN will consume the current RD_DATA value and cause the 
// next value (if it exists) to appear on RD_DATA on the following cycle. Be sure 
// to check if RD_EMPTY is low each cycle to determine if RD_DATA is valid.
// Author:              Matt Jacobsen
// History:             @mattj: Version 2.0
//-----------------------------------------------------------------------------
`timescale 1ns/1ns
module async_fifo_fwft #(
    parameter C_WIDTH = 32, // Data bus width
    parameter C_DEPTH = 1024,   // Depth of the FIFO
    // Local parameters
    parameter C_REAL_DEPTH = 2**clog2(C_DEPTH),
    parameter C_DEPTH_BITS = clog2s(C_REAL_DEPTH),
    parameter C_DEPTH_P1_BITS = clog2s(C_REAL_DEPTH+1)
)
(
    input RD_CLK,                           // Read clock
    input RD_RST,                           // Read synchronous reset
    input WR_CLK,                           // Write clock
    input WR_RST,                           // Write synchronous reset
    input [C_WIDTH-1:0] WR_DATA,            // Write data input (WR_CLK)
    input WR_EN,                            // Write enable, high active (WR_CLK)
    output [C_WIDTH-1:0] RD_DATA,           // Read data output (RD_CLK)
    input RD_EN,                            // Read enable, high active (RD_CLK)
    output WR_FULL,                         // Full condition (WR_CLK)
    output RD_EMPTY                         // Empty condition (RD_CLK)
);
 
`include "functions.vh"
 
reg     [C_WIDTH-1:0]           rData=0;
reg     [C_WIDTH-1:0]           rCache=0;
reg     [1:0]                   rCount=0;
reg                             rFifoDataValid=0;
reg                             rDataValid=0;
reg                             rCacheValid=0;
wire    [C_WIDTH-1:0]           wData;
wire                            wEmpty;
wire                            wRen = RD_EN || (rCount < 2'd2);
 
 
assign RD_DATA = rData;
assign RD_EMPTY = !rDataValid;
 
 
// Wrapped non-FWFT FIFO (synthesis attributes applied to this module will
// determine the memory option).
async_fifo #(.C_WIDTH(C_WIDTH), .C_DEPTH(C_DEPTH)) fifo (
    .WR_CLK(WR_CLK),
    .WR_RST(WR_RST),
    .RD_CLK(RD_CLK),
    .RD_RST(RD_RST),
    .WR_EN(WR_EN),
    .WR_DATA(WR_DATA),
    .WR_FULL(WR_FULL),
    .RD_EN(wRen),
    .RD_DATA(wData),
    .RD_EMPTY(wEmpty)
);
 
always @ (posedge RD_CLK) begin
    if (RD_RST) begin
        rCount <= #1 0;
        rDataValid <= #1 0;
        rCacheValid <= #1 0;
        rFifoDataValid <= #1 0;
    end
    else begin
        // Keep track of the count
        rCount <= #1 rCount + (wRen & !wEmpty) - (!RD_EMPTY & RD_EN);
 
        // Signals when wData from FIFO is valid
        rFifoDataValid <= #1 (wRen & !wEmpty);
 
        // Keep rData up to date
        if (rFifoDataValid) begin
            if (RD_EN | !rDataValid) begin
                rData <= #1 wData;
                rDataValid <= #1 1'd1;
                rCacheValid <= #1 1'd0;
            end
            else begin
                rCacheValid <= #1 1'd1;
            end
            rCache  <= #1 wData;
        end
        else begin
            if (RD_EN | !rDataValid) begin
                rData <= #1 rCache;
                rDataValid <= #1 rCacheValid;
                rCacheValid <= #1 1'd0;
            end
        end
    end
end
 
endmodule

 

it looks like wCmpEmpty is not strictly synchronized to either rd_clk or wr_clk. There is some logic that is used that probably enforces some garuntee on the behavior. The signal is then (maybe?) resynchronized to the rd_clk domain as RD_EMPTY.

I am suspicious of this method. In a quick glance, I didn't see any comments, testbenches, or relevant constraints. Perhaps they are documented outside of code. Maybe the testbench is in another project. Maybe the constraints are generated by some build script.
 

Please, dont cross post. If you want an answer to a question, it is much easier if you ask the question here.
I also hope you dont plan on running this through your formal tool. Formal is not really designed for clock domain crossing, or at least they usually have special apps to do it. Much easier in a simulator.
 


@TrickyDicky

I gave that link because I found that the code there is using too much logic (it has both 'asynchronous' and 'asynchronous' empty signals), and make understanding complicated compared to the following:

ebssy2dpqpzz.png
 

What is your end goal? if you are designing for FPGA, why not just use the FIFOs provided by the FPGA vendor?
 

In the attached PDF (The Art of Hardware Architecture Design Methods and Techniques for Digital Circuits.pdf (2.64 MB) ) page 85:

If the synchronized read pointer’s MSB is high, the second MSB of the synchronized read pointer (rd_ptr_sync) is inverted before doing a comparison against a (n − 1) bit write pointer.

Why invert second MSB only when the MSB is high ?

The second MSB in (2) above is calculated by XORing the first two MSBs of the pointer

Why don't the other bits need XOR operations ? Why only the second MSB of read pointer need XOR operation ?



Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
module Gray_to_Binary ( din ,dout );
 
output [3:0] dout ;
 
input [3:0] din ;
 
assign dout[3] = din[3];
assign dout[2] = din[3]^din[2];
assign dout[1] = din[3]^din[2]^din[1];
assign dout[0] = din[3]^din[2]^din[1]^din[0];
 
endmodule



Moderator action: deleted ebook attachement
 
Last edited by a moderator:

If the synchronized read pointer’s MSB is high, the second MSB of the synchronized read pointer (rd_ptr_sync) is inverted before doing a comparison against a (n − 1) bit write pointer.

Could anyone explain why ?

3ZNs7KU.png 0ZEDmgS.png
 

It seems to me that the second MSB inversion is for solving the wrong FULL assertion in the case of rd_ptr=7 and wr_ptr=8

However, what about rd_ptr=7 and wr_ptr=6 instead ? This also does not generate the correct FULL signal ?
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top