OpenCores
URL https://opencores.org/ocsvn/xge_mac/xge_mac/trunk

Subversion Repositories xge_mac

[/] [xge_mac/] [trunk/] [rtl/] [verilog/] [generic_fifo_ctrl.v] - Blame information for rev 11

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 antanguay
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  File name "generic_fifo_ctrl.v"                             ////
4
////                                                              ////
5
////  This file is part of the "10GE MAC" project                 ////
6
////  http://www.opencores.org/cores/xge_mac/                     ////
7
////                                                              ////
8
////  Author(s):                                                  ////
9
////      - A. Tanguay (antanguay@opencores.org)                  ////
10
////                                                              ////
11
//////////////////////////////////////////////////////////////////////
12
////                                                              ////
13
//// Copyright (C) 2008 AUTHORS. All rights reserved.             ////
14
////                                                              ////
15
//// This source file may be used and distributed without         ////
16
//// restriction provided that this copyright statement is not    ////
17
//// removed from the file and that any derivative work contains  ////
18
//// the original copyright notice and the associated disclaimer. ////
19
////                                                              ////
20
//// This source file is free software; you can redistribute it   ////
21
//// and/or modify it under the terms of the GNU Lesser General   ////
22
//// Public License as published by the Free Software Foundation; ////
23
//// either version 2.1 of the License, or (at your option) any   ////
24
//// later version.                                               ////
25
////                                                              ////
26
//// This source is distributed in the hope that it will be       ////
27
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
28
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
29
//// PURPOSE.  See the GNU Lesser General Public License for more ////
30
//// details.                                                     ////
31
////                                                              ////
32
//// You should have received a copy of the GNU Lesser General    ////
33
//// Public License along with this source; if not, download it   ////
34
//// from http://www.opencores.org/lgpl.shtml                     ////
35
////                                                              ////
36
//////////////////////////////////////////////////////////////////////
37
 
38
 
39
module generic_fifo_ctrl(
40
 
41
    wclk,
42
    wrst_n,
43
    wen,
44
    wfull,
45
    walmost_full,
46
 
47
    mem_wen,
48
    mem_waddr,
49
 
50
    rclk,
51
    rrst_n,
52
    ren,
53
    rempty,
54
    ralmost_empty,
55
 
56
    mem_ren,
57
    mem_raddr
58
);
59
 
60
//---
61
// Parameters
62
 
63
parameter AWIDTH = 3;
64
parameter RAM_DEPTH = (1 << AWIDTH);
65
parameter EARLY_READ = 0;
66
parameter CLOCK_CROSSING = 1;
67
parameter ALMOST_EMPTY_THRESH = 1;
68
parameter ALMOST_FULL_THRESH = RAM_DEPTH-2;
69
 
70
//---
71
// Ports
72
 
73
input              wclk;
74
input              wrst_n;
75
input              wen;
76
output             wfull;
77
output             walmost_full;
78
 
79
output             mem_wen;
80
output [AWIDTH:0]  mem_waddr;
81
 
82
input              rclk;
83
input              rrst_n;
84
input              ren;
85
output             rempty;
86
output             ralmost_empty;
87
 
88
output             mem_ren;
89
output [AWIDTH:0]  mem_raddr;
90
 
91
 
92
 
93
//---
94
// Local declarations
95
 
96
// Registers
97
 
98
reg  [AWIDTH:0]   wr_ptr;
99
reg  [AWIDTH:0]   rd_ptr;
100
reg  [AWIDTH:0]   next_rd_ptr;
101
 
102
// Combinatorial
103
 
104
wire [AWIDTH:0]   wr_gray;
105 11 antanguay
reg  [AWIDTH:0]   wr_gray_reg;
106 2 antanguay
reg  [AWIDTH:0]   wr_gray_meta;
107
reg  [AWIDTH:0]   wr_gray_sync;
108
reg  [AWIDTH:0]   wck_rd_ptr;
109
wire [AWIDTH:0]   wck_level;
110
 
111
wire [AWIDTH:0]   rd_gray;
112 11 antanguay
reg  [AWIDTH:0]   rd_gray_reg;
113 2 antanguay
reg  [AWIDTH:0]   rd_gray_meta;
114
reg  [AWIDTH:0]   rd_gray_sync;
115
reg  [AWIDTH:0]   rck_wr_ptr;
116
wire [AWIDTH:0]   rck_level;
117
 
118
wire [AWIDTH:0]   depth;
119
wire [AWIDTH:0]   empty_thresh;
120
wire [AWIDTH:0]   full_thresh;
121
 
122
// Variables
123
 
124
integer         i;
125
 
126
//---
127
// Assignments
128
 
129
assign depth = RAM_DEPTH[AWIDTH:0];
130
assign empty_thresh = ALMOST_EMPTY_THRESH[AWIDTH:0];
131
assign full_thresh = ALMOST_FULL_THRESH[AWIDTH:0];
132
 
133
assign wfull = (wck_level == depth);
134
assign walmost_full = (wck_level >= (depth - full_thresh));
135
assign rempty = (rck_level == 0);
136
assign ralmost_empty = (rck_level <= empty_thresh);
137
 
138
//---
139
// Write Pointer
140
 
141
always @(posedge wclk or negedge wrst_n)
142
begin
143
    if (!wrst_n) begin
144
        wr_ptr <= {(AWIDTH+1){1'b0}};
145
    end
146
    else if (wen && !wfull) begin
147
        wr_ptr <= wr_ptr + {{(AWIDTH){1'b0}}, 1'b1};
148
    end
149
end
150
 
151
//---
152
// Read Pointer
153
 
154
always @(ren, rd_ptr, rck_wr_ptr)
155
begin
156
    next_rd_ptr = rd_ptr;
157
    if (ren && rd_ptr != rck_wr_ptr) begin
158
        next_rd_ptr = rd_ptr + {{(AWIDTH){1'b0}}, 1'b1};
159
    end
160
end
161
 
162
always @(posedge rclk or negedge rrst_n)
163
begin
164
    if (!rrst_n) begin
165
        rd_ptr <= {(AWIDTH+1){1'b0}};
166
    end
167
    else begin
168
        rd_ptr <= next_rd_ptr;
169
    end
170
end
171
 
172
//---
173
// Binary to Gray conversion
174
 
175
assign wr_gray = wr_ptr ^ (wr_ptr >> 1);
176
assign rd_gray = rd_ptr ^ (rd_ptr >> 1);
177
 
178
//---
179
// Gray to Binary conversion
180
 
181
always @(wr_gray_sync)
182
begin
183
    rck_wr_ptr[AWIDTH] = wr_gray_sync[AWIDTH];
184
    for (i = 0; i < AWIDTH; i = i + 1) begin
185
        rck_wr_ptr[AWIDTH-i-1] = rck_wr_ptr[AWIDTH-i] ^ wr_gray_sync[AWIDTH-i-1];
186
    end
187
end
188
 
189
always @(rd_gray_sync)
190
begin
191
    wck_rd_ptr[AWIDTH] = rd_gray_sync[AWIDTH];
192
    for (i = 0; i < AWIDTH; i = i + 1) begin
193
        wck_rd_ptr[AWIDTH-i-1] = wck_rd_ptr[AWIDTH-i] ^ rd_gray_sync[AWIDTH-i-1];
194
    end
195
end
196
 
197
//---
198
// Clock-Domain Crossing
199
 
200
generate
201
    if (CLOCK_CROSSING) begin
202
 
203
        // Instantiate metastability flops
204
        always @(posedge rclk or negedge rrst_n)
205
        begin
206
            if (!rrst_n) begin
207 11 antanguay
                rd_gray_reg <= {(AWIDTH+1){1'b0}};
208 2 antanguay
                wr_gray_meta <= {(AWIDTH+1){1'b0}};
209
                wr_gray_sync <= {(AWIDTH+1){1'b0}};
210
            end
211
            else begin
212 11 antanguay
                rd_gray_reg <= rd_gray;
213
                wr_gray_meta <= wr_gray_reg;
214 2 antanguay
                wr_gray_sync <= wr_gray_meta;
215
            end
216
        end
217
 
218
        always @(posedge wclk or negedge wrst_n)
219
        begin
220
            if (!wrst_n) begin
221 11 antanguay
                wr_gray_reg <= {(AWIDTH+1){1'b0}};
222 2 antanguay
                rd_gray_meta <= {(AWIDTH+1){1'b0}};
223
                rd_gray_sync <= {(AWIDTH+1){1'b0}};
224
            end
225
            else begin
226 11 antanguay
                wr_gray_reg <= wr_gray;
227
                rd_gray_meta <= rd_gray_reg;
228 2 antanguay
                rd_gray_sync <= rd_gray_meta;
229
            end
230
        end
231
    end
232
    else begin
233
 
234
        // No clock domain crossing
235
        always @(wr_gray or rd_gray)
236
        begin
237
            wr_gray_sync = wr_gray;
238
            rd_gray_sync = rd_gray;
239
        end
240
    end
241
endgenerate
242
 
243
//---
244
// FIFO Level
245
 
246
assign wck_level = wr_ptr - wck_rd_ptr;
247
assign rck_level = rck_wr_ptr - rd_ptr;
248
 
249
//---
250
// Memory controls
251
 
252
assign  mem_waddr = wr_ptr;
253
assign  mem_wen = wen && !wfull;
254
 
255
generate
256
    if (EARLY_READ) begin
257
 
258
        // With early read, data will be present at output
259
        // before ren is asserted. Usufull if we want to add
260 11 antanguay
        // an output register and not add latency.
261 2 antanguay
        assign mem_raddr = next_rd_ptr;
262
        assign mem_ren = 1'b1;
263
 
264
    end
265
    else begin
266
 
267
        assign mem_raddr = rd_ptr;
268
        assign mem_ren = ren;
269
 
270
    end
271
endgenerate
272
 
273
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.