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

Subversion Repositories pci

[/] [pci/] [trunk/] [rtl/] [verilog/] [pci_wbw_fifo_control.v] - Blame information for rev 154

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 77 mihad
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  File name "wbw_fifo_control.v"                              ////
4
////                                                              ////
5
////  This file is part of the "PCI bridge" project               ////
6
////  http://www.opencores.org/cores/pci/                         ////
7
////                                                              ////
8
////  Author(s):                                                  ////
9
////      - Miha Dolenc (mihad@opencores.org)                     ////
10
////                                                              ////
11
////  All additional information is avaliable in the README       ////
12
////  file.                                                       ////
13
////                                                              ////
14
////                                                              ////
15
//////////////////////////////////////////////////////////////////////
16
////                                                              ////
17
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org          ////
18
////                                                              ////
19
//// This source file may be used and distributed without         ////
20
//// restriction provided that this copyright statement is not    ////
21
//// removed from the file and that any derivative work contains  ////
22
//// the original copyright notice and the associated disclaimer. ////
23
////                                                              ////
24
//// This source file is free software; you can redistribute it   ////
25
//// and/or modify it under the terms of the GNU Lesser General   ////
26
//// Public License as published by the Free Software Foundation; ////
27
//// either version 2.1 of the License, or (at your option) any   ////
28
//// later version.                                               ////
29
////                                                              ////
30
//// This source is distributed in the hope that it will be       ////
31
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
32
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
33
//// PURPOSE.  See the GNU Lesser General Public License for more ////
34
//// details.                                                     ////
35
////                                                              ////
36
//// You should have received a copy of the GNU Lesser General    ////
37
//// Public License along with this source; if not, download it   ////
38
//// from http://www.opencores.org/lgpl.shtml                     ////
39
////                                                              ////
40
//////////////////////////////////////////////////////////////////////
41
//
42
// CVS Revision History
43
//
44
// $Log: not supported by cvs2svn $
45 153 mihad
// Revision 1.4  2003/08/14 13:06:03  simons
46
// synchronizer_flop replaced with pci_synchronizer_flop, artisan ram instance updated.
47
//
48 111 simons
// Revision 1.3  2003/07/29 08:20:11  mihad
49
// Found and simulated the problem in the synchronization logic.
50
// Repaired the synchronization logic in the FIFOs.
51
//
52 104 mihad
// Revision 1.2  2003/03/26 13:16:18  mihad
53
// Added the reset value parameter to the synchronizer flop module.
54
// Added resets to all synchronizer flop instances.
55
// Repaired initial sync value in fifos.
56
//
57 88 mihad
// Revision 1.1  2003/01/27 16:49:31  mihad
58
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed.
59
//
60 77 mihad
// Revision 1.6  2002/11/27 20:36:13  mihad
61
// Changed the code a bit to make it more readable.
62
// Functionality not changed in any way.
63
// More robust synchronization in fifos is still pending.
64
//
65
// Revision 1.5  2002/09/30 16:03:04  mihad
66
// Added meta flop module for easier meta stable FF identification during synthesis
67
//
68
// Revision 1.4  2002/09/25 15:53:52  mihad
69
// Removed all logic from asynchronous reset network
70
//
71
// Revision 1.3  2002/02/01 15:25:14  mihad
72
// Repaired a few bugs, updated specification, added test bench files and design document
73
//
74
// Revision 1.2  2001/10/05 08:14:30  mihad
75
// Updated all files with inclusion of timescale file for simulation purposes.
76
//
77
// Revision 1.1.1.1  2001/10/02 15:33:47  mihad
78
// New project directory structure
79
//
80
//
81
 
82
/* FIFO_CONTROL module provides read/write address and status generation for
83
   FIFOs implemented with standard dual port SRAM cells in ASIC or FPGA designs */
84
`include "pci_constants.v"
85
// synopsys translate_off
86
`include "timescale.v"
87
// synopsys translate_on
88
 
89
module pci_wbw_fifo_control
90
(
91
    rclock_in,
92
    wclock_in,
93
    renable_in,
94
    wenable_in,
95
    reset_in,
96
    almost_full_out,
97
    full_out,
98
    empty_out,
99
    waddr_out,
100
    raddr_out,
101
    rallow_out,
102 153 mihad
    wallow_out,
103
        half_full_out ////Robert, burst issue
104 77 mihad
);
105
 
106 153 mihad
parameter ADDR_LENGTH = 7;
107 77 mihad
 
108
// independent clock inputs - rclock_in = read clock, wclock_in = write clock
109
input  rclock_in, wclock_in;
110
 
111
// enable inputs - read address changes on rising edge of rclock_in when reads are allowed
112
//                 write address changes on rising edge of wclock_in when writes are allowed
113
input  renable_in, wenable_in ;
114
 
115
// reset input
116
input  reset_in;
117
 
118
// flush input
119
// input flush_in ; // not used
120
 
121
// almost full and empy status outputs
122
output almost_full_out ;
123
 
124
// full and empty status outputs
125
output full_out, empty_out;
126
 
127
// read and write addresses outputs
128
output [(ADDR_LENGTH - 1):0] waddr_out, raddr_out;
129
 
130
// read and write allow outputs
131
output rallow_out, wallow_out ;
132
 
133 153 mihad
output half_full_out;
134
 
135 77 mihad
// read address register
136
reg [(ADDR_LENGTH - 1):0] raddr ;
137
 
138
// write address register
139
reg [(ADDR_LENGTH - 1):0] waddr;
140
assign waddr_out = waddr ;
141
 
142
// grey code registers
143 104 mihad
reg [(ADDR_LENGTH - 1):0] wgrey_addr ; // current
144 77 mihad
// grey code register for next write address
145
reg [(ADDR_LENGTH - 1):0] wgrey_next ; // next
146
 
147
// next write gray address calculation - bitwise xor between address and shifted address
148
wire [(ADDR_LENGTH - 2):0] calc_wgrey_next  = waddr[(ADDR_LENGTH - 1):1] ^ waddr[(ADDR_LENGTH - 2):0] ;
149
 
150
// grey code pipeline for read address
151
reg [(ADDR_LENGTH - 1):0] rgrey_minus1 ; // one before current
152
reg [(ADDR_LENGTH - 1):0] rgrey_addr ; // current
153
reg [(ADDR_LENGTH - 1):0] rgrey_next ; // next
154
 
155
// next read gray address calculation - bitwise xor between address and shifted address
156
wire [(ADDR_LENGTH - 2):0] calc_rgrey_next  = raddr[(ADDR_LENGTH - 1):1] ^ raddr[(ADDR_LENGTH - 2):0] ;
157
 
158
// write allow wire - writes are allowed when fifo is not full
159 104 mihad
assign wallow_out = wenable_in & ~full_out ;
160 77 mihad
 
161
// clear generation for FFs and registers
162 104 mihad
wire clear = reset_in ;
163 77 mihad
 
164
//rallow generation
165 104 mihad
assign rallow_out = renable_in & ~empty_out ; // reads allowed if read enable is high and FIFO is not empty
166 77 mihad
 
167
// at any clock edge that rallow is high, this register provides next read address, so wait cycles are not necessary
168
// when FIFO is empty, this register provides actual read address, so first location can be read
169
reg [(ADDR_LENGTH - 1):0] raddr_plus_one ;
170
 
171 153 mihad
 
172
wire [ADDR_LENGTH :0] fifo_fullness; //Robert, burst issue
173
 
174
//Robert, burst issue
175
assign fifo_fullness = (waddr > raddr) ? ({1'b0, waddr} - {1'b0, raddr}) : ({1'b1, waddr} - {1'b0, raddr});
176
assign half_full_out   = fifo_fullness[(ADDR_LENGTH - 1)] ;
177
//Robert, burst issue
178
 
179
 
180 77 mihad
// address output mux - when FIFO is empty, current actual address is driven out, when it is non - empty next address is driven out
181
// done for zero wait state burst
182 104 mihad
assign raddr_out = rallow_out ? raddr_plus_one : raddr ;
183 77 mihad
 
184
always@(posedge rclock_in or posedge clear)
185
begin
186
    if (clear)
187
    begin
188
        raddr_plus_one <= #`FF_DELAY 4 ;
189
        raddr          <= #`FF_DELAY 3 ;
190
    end
191 104 mihad
    else if (rallow_out)
192 77 mihad
    begin
193
        raddr_plus_one <= #`FF_DELAY raddr_plus_one + 1'b1 ;
194
        raddr          <= #`FF_DELAY raddr_plus_one ;
195
    end
196
end
197
 
198
/*-----------------------------------------------------------------------------------------------
199
Read address control consists of Read address counter and Grey Address pipeline
200
There are 3 Grey addresses:
201
    - rgrey_minus1 is Grey Code of address one before current address
202
    - rgrey_addr is Grey Code of current read address
203
    - rgrey_next is Grey Code of next read address
204
--------------------------------------------------------------------------------------------------*/
205
// grey coded address pipeline for status generation in read clock domain
206
always@(posedge rclock_in or posedge clear)
207
begin
208
        if (clear)
209
    begin
210
        // initial value is 0
211 104 mihad
        rgrey_minus1 <= #1 0 ;
212
        rgrey_addr   <= #1 1 ;
213 77 mihad
        rgrey_next   <= #`FF_DELAY 3 ;
214
    end
215
    else
216 104 mihad
    if (rallow_out)
217 77 mihad
    begin
218 104 mihad
        rgrey_minus1 <= #1 rgrey_addr ;
219
        rgrey_addr   <= #1 rgrey_next ;
220 77 mihad
        rgrey_next   <= #`FF_DELAY {raddr[ADDR_LENGTH - 1], calc_rgrey_next} ;
221
    end
222
end
223
 
224
/*--------------------------------------------------------------------------------------------
225
Write address control consists of write address counter and Grey Code Register
226
----------------------------------------------------------------------------------------------*/
227
// grey coded address pipeline for status generation in write clock domain
228
always@(posedge wclock_in or posedge clear)
229
begin
230
    if (clear)
231
    begin
232 104 mihad
        wgrey_addr <= #`FF_DELAY 1 ;
233
        wgrey_next <= #1 3         ;
234 77 mihad
    end
235
    else
236 104 mihad
    if (wallow_out)
237 77 mihad
    begin
238 104 mihad
        wgrey_addr <= #`FF_DELAY wgrey_next ;
239
        wgrey_next <= #1 {waddr[(ADDR_LENGTH - 1)], calc_wgrey_next} ;
240 77 mihad
    end
241
end
242
 
243
// write address counter - nothing special - initial value is important though
244
always@(posedge wclock_in or posedge clear)
245
begin
246
    if (clear)
247
        // initial value 4
248
            waddr <= #`FF_DELAY 3 ;
249
    else
250 104 mihad
    if (wallow_out)
251 77 mihad
        waddr <= #`FF_DELAY waddr + 1'b1 ;
252
end
253
 
254
/*------------------------------------------------------------------------------------------------------------------------------
255 104 mihad
Gray coded address of read address decremented by 1 is synchronized to write clock domain and compared to:
256 77 mihad
 
257 104 mihad
- Gray coded write address. If they are equal, fifo is full.
258
 
259
- Gray coded next write address. If they are equal, fifo is almost full.
260 77 mihad
--------------------------------------------------------------------------------------------------------------------------------*/
261
wire [(ADDR_LENGTH - 1):0] wclk_sync_rgrey_minus1 ;
262
reg  [(ADDR_LENGTH - 1):0] wclk_rgrey_minus1 ;
263
 
264 111 simons
pci_synchronizer_flop #(ADDR_LENGTH, 0) i_synchronizer_reg_rgrey_minus1
265 88 mihad
(
266
    .data_in        (rgrey_minus1),
267
    .clk_out        (wclock_in),
268
    .sync_data_out  (wclk_sync_rgrey_minus1),
269
    .async_reset    (clear)
270
) ;
271
 
272
always@(posedge wclock_in or posedge clear)
273 77 mihad
begin
274 88 mihad
    if (clear)
275
    begin
276
        wclk_rgrey_minus1 <= #`FF_DELAY 0 ;
277
    end
278
    else
279
    begin
280
        wclk_rgrey_minus1 <= #`FF_DELAY wclk_sync_rgrey_minus1 ;
281
    end
282 77 mihad
end
283
 
284 104 mihad
assign full_out        = (wgrey_addr == wclk_rgrey_minus1) ;
285
assign almost_full_out = (wgrey_next == wclk_rgrey_minus1) ;
286 77 mihad
 
287
/*------------------------------------------------------------------------------------------------------------------------------
288
Empty control:
289
Gray coded address of next write address is synchronized to read clock domain and compared to Gray coded next read address.
290
If they are equal, fifo is empty.
291
--------------------------------------------------------------------------------------------------------------------------------*/
292
wire [(ADDR_LENGTH - 1):0] rclk_sync_wgrey_next ;
293
reg  [(ADDR_LENGTH - 1):0] rclk_wgrey_next ;
294 111 simons
pci_synchronizer_flop #(ADDR_LENGTH, 3) i_synchronizer_reg_wgrey_next
295 77 mihad
(
296
    .data_in        (wgrey_next),
297
    .clk_out        (rclock_in),
298
    .sync_data_out  (rclk_sync_wgrey_next),
299 88 mihad
    .async_reset    (clear)
300 77 mihad
) ;
301
 
302 88 mihad
always@(posedge rclock_in or posedge clear)
303 77 mihad
begin
304 88 mihad
    if (clear)
305
        rclk_wgrey_next <= #`FF_DELAY 3 ;
306
    else
307
        rclk_wgrey_next <= #`FF_DELAY rclk_sync_wgrey_next ;
308 77 mihad
end
309
 
310 104 mihad
assign empty_out = (rgrey_next == rclk_wgrey_next) ;
311 77 mihad
 
312
endmodule

powered by: WebSVN 2.1.0

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