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

Subversion Repositories pci

[/] [pci/] [tags/] [rel_7/] [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 111 simons
// Revision 1.3  2003/07/29 08:20:11  mihad
46
// Found and simulated the problem in the synchronization logic.
47
// Repaired the synchronization logic in the FIFOs.
48
//
49 104 mihad
// Revision 1.2  2003/03/26 13:16:18  mihad
50
// Added the reset value parameter to the synchronizer flop module.
51
// Added resets to all synchronizer flop instances.
52
// Repaired initial sync value in fifos.
53
//
54 88 mihad
// Revision 1.1  2003/01/27 16:49:31  mihad
55
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed.
56
//
57 77 mihad
// Revision 1.6  2002/11/27 20:36:13  mihad
58
// Changed the code a bit to make it more readable.
59
// Functionality not changed in any way.
60
// More robust synchronization in fifos is still pending.
61
//
62
// Revision 1.5  2002/09/30 16:03:04  mihad
63
// Added meta flop module for easier meta stable FF identification during synthesis
64
//
65
// Revision 1.4  2002/09/25 15:53:52  mihad
66
// Removed all logic from asynchronous reset network
67
//
68
// Revision 1.3  2002/02/01 15:25:14  mihad
69
// Repaired a few bugs, updated specification, added test bench files and design document
70
//
71
// Revision 1.2  2001/10/05 08:14:30  mihad
72
// Updated all files with inclusion of timescale file for simulation purposes.
73
//
74
// Revision 1.1.1.1  2001/10/02 15:33:47  mihad
75
// New project directory structure
76
//
77
//
78
 
79
/* FIFO_CONTROL module provides read/write address and status generation for
80
   FIFOs implemented with standard dual port SRAM cells in ASIC or FPGA designs */
81
`include "pci_constants.v"
82
// synopsys translate_off
83
`include "timescale.v"
84
// synopsys translate_on
85
 
86
module pci_wbw_fifo_control
87
(
88
    rclock_in,
89
    wclock_in,
90
    renable_in,
91
    wenable_in,
92
    reset_in,
93
    almost_full_out,
94
    full_out,
95
    empty_out,
96
    waddr_out,
97
    raddr_out,
98
    rallow_out,
99
    wallow_out
100
);
101
 
102
parameter ADDR_LENGTH = 7 ;
103
 
104
// independent clock inputs - rclock_in = read clock, wclock_in = write clock
105
input  rclock_in, wclock_in;
106
 
107
// enable inputs - read address changes on rising edge of rclock_in when reads are allowed
108
//                 write address changes on rising edge of wclock_in when writes are allowed
109
input  renable_in, wenable_in ;
110
 
111
// reset input
112
input  reset_in;
113
 
114
// flush input
115
// input flush_in ; // not used
116
 
117
// almost full and empy status outputs
118
output almost_full_out ;
119
 
120
// full and empty status outputs
121
output full_out, empty_out;
122
 
123
// read and write addresses outputs
124
output [(ADDR_LENGTH - 1):0] waddr_out, raddr_out;
125
 
126
// read and write allow outputs
127
output rallow_out, wallow_out ;
128
 
129
// read address register
130
reg [(ADDR_LENGTH - 1):0] raddr ;
131
 
132
// write address register
133
reg [(ADDR_LENGTH - 1):0] waddr;
134
assign waddr_out = waddr ;
135
 
136
// grey code registers
137 104 mihad
reg [(ADDR_LENGTH - 1):0] wgrey_addr ; // current
138 77 mihad
// grey code register for next write address
139
reg [(ADDR_LENGTH - 1):0] wgrey_next ; // next
140
 
141
// next write gray address calculation - bitwise xor between address and shifted address
142
wire [(ADDR_LENGTH - 2):0] calc_wgrey_next  = waddr[(ADDR_LENGTH - 1):1] ^ waddr[(ADDR_LENGTH - 2):0] ;
143
 
144
// grey code pipeline for read address
145
reg [(ADDR_LENGTH - 1):0] rgrey_minus1 ; // one before current
146
reg [(ADDR_LENGTH - 1):0] rgrey_addr ; // current
147
reg [(ADDR_LENGTH - 1):0] rgrey_next ; // next
148
 
149
// next read gray address calculation - bitwise xor between address and shifted address
150
wire [(ADDR_LENGTH - 2):0] calc_rgrey_next  = raddr[(ADDR_LENGTH - 1):1] ^ raddr[(ADDR_LENGTH - 2):0] ;
151
 
152
// write allow wire - writes are allowed when fifo is not full
153 104 mihad
assign wallow_out = wenable_in & ~full_out ;
154 77 mihad
 
155
// clear generation for FFs and registers
156 104 mihad
wire clear = reset_in ;
157 77 mihad
 
158
//rallow generation
159 104 mihad
assign rallow_out = renable_in & ~empty_out ; // reads allowed if read enable is high and FIFO is not empty
160 77 mihad
 
161
// at any clock edge that rallow is high, this register provides next read address, so wait cycles are not necessary
162
// when FIFO is empty, this register provides actual read address, so first location can be read
163
reg [(ADDR_LENGTH - 1):0] raddr_plus_one ;
164
 
165
// address output mux - when FIFO is empty, current actual address is driven out, when it is non - empty next address is driven out
166
// done for zero wait state burst
167 104 mihad
assign raddr_out = rallow_out ? raddr_plus_one : raddr ;
168 77 mihad
 
169
always@(posedge rclock_in or posedge clear)
170
begin
171
    if (clear)
172
    begin
173
        raddr_plus_one <= #`FF_DELAY 4 ;
174
        raddr          <= #`FF_DELAY 3 ;
175
    end
176 104 mihad
    else if (rallow_out)
177 77 mihad
    begin
178
        raddr_plus_one <= #`FF_DELAY raddr_plus_one + 1'b1 ;
179
        raddr          <= #`FF_DELAY raddr_plus_one ;
180
    end
181
end
182
 
183
/*-----------------------------------------------------------------------------------------------
184
Read address control consists of Read address counter and Grey Address pipeline
185
There are 3 Grey addresses:
186
    - rgrey_minus1 is Grey Code of address one before current address
187
    - rgrey_addr is Grey Code of current read address
188
    - rgrey_next is Grey Code of next read address
189
--------------------------------------------------------------------------------------------------*/
190
// grey coded address pipeline for status generation in read clock domain
191
always@(posedge rclock_in or posedge clear)
192
begin
193
        if (clear)
194
    begin
195
        // initial value is 0
196 104 mihad
        rgrey_minus1 <= #1 0 ;
197
        rgrey_addr   <= #1 1 ;
198 77 mihad
        rgrey_next   <= #`FF_DELAY 3 ;
199
    end
200
    else
201 104 mihad
    if (rallow_out)
202 77 mihad
    begin
203 104 mihad
        rgrey_minus1 <= #1 rgrey_addr ;
204
        rgrey_addr   <= #1 rgrey_next ;
205 77 mihad
        rgrey_next   <= #`FF_DELAY {raddr[ADDR_LENGTH - 1], calc_rgrey_next} ;
206
    end
207
end
208
 
209
/*--------------------------------------------------------------------------------------------
210
Write address control consists of write address counter and Grey Code Register
211
----------------------------------------------------------------------------------------------*/
212
// grey coded address pipeline for status generation in write clock domain
213
always@(posedge wclock_in or posedge clear)
214
begin
215
    if (clear)
216
    begin
217 104 mihad
        wgrey_addr <= #`FF_DELAY 1 ;
218
        wgrey_next <= #1 3         ;
219 77 mihad
    end
220
    else
221 104 mihad
    if (wallow_out)
222 77 mihad
    begin
223 104 mihad
        wgrey_addr <= #`FF_DELAY wgrey_next ;
224
        wgrey_next <= #1 {waddr[(ADDR_LENGTH - 1)], calc_wgrey_next} ;
225 77 mihad
    end
226
end
227
 
228
// write address counter - nothing special - initial value is important though
229
always@(posedge wclock_in or posedge clear)
230
begin
231
    if (clear)
232
        // initial value 4
233
            waddr <= #`FF_DELAY 3 ;
234
    else
235 104 mihad
    if (wallow_out)
236 77 mihad
        waddr <= #`FF_DELAY waddr + 1'b1 ;
237
end
238
 
239
/*------------------------------------------------------------------------------------------------------------------------------
240 104 mihad
Gray coded address of read address decremented by 1 is synchronized to write clock domain and compared to:
241 77 mihad
 
242 104 mihad
- Gray coded write address. If they are equal, fifo is full.
243
 
244
- Gray coded next write address. If they are equal, fifo is almost full.
245 77 mihad
--------------------------------------------------------------------------------------------------------------------------------*/
246
wire [(ADDR_LENGTH - 1):0] wclk_sync_rgrey_minus1 ;
247
reg  [(ADDR_LENGTH - 1):0] wclk_rgrey_minus1 ;
248
 
249 111 simons
pci_synchronizer_flop #(ADDR_LENGTH, 0) i_synchronizer_reg_rgrey_minus1
250 88 mihad
(
251
    .data_in        (rgrey_minus1),
252
    .clk_out        (wclock_in),
253
    .sync_data_out  (wclk_sync_rgrey_minus1),
254
    .async_reset    (clear)
255
) ;
256
 
257
always@(posedge wclock_in or posedge clear)
258 77 mihad
begin
259 88 mihad
    if (clear)
260
    begin
261
        wclk_rgrey_minus1 <= #`FF_DELAY 0 ;
262
    end
263
    else
264
    begin
265
        wclk_rgrey_minus1 <= #`FF_DELAY wclk_sync_rgrey_minus1 ;
266
    end
267 77 mihad
end
268
 
269 104 mihad
assign full_out        = (wgrey_addr == wclk_rgrey_minus1) ;
270
assign almost_full_out = (wgrey_next == wclk_rgrey_minus1) ;
271 77 mihad
 
272
/*------------------------------------------------------------------------------------------------------------------------------
273
Empty control:
274
Gray coded address of next write address is synchronized to read clock domain and compared to Gray coded next read address.
275
If they are equal, fifo is empty.
276
--------------------------------------------------------------------------------------------------------------------------------*/
277
wire [(ADDR_LENGTH - 1):0] rclk_sync_wgrey_next ;
278
reg  [(ADDR_LENGTH - 1):0] rclk_wgrey_next ;
279 111 simons
pci_synchronizer_flop #(ADDR_LENGTH, 3) i_synchronizer_reg_wgrey_next
280 77 mihad
(
281
    .data_in        (wgrey_next),
282
    .clk_out        (rclock_in),
283
    .sync_data_out  (rclk_sync_wgrey_next),
284 88 mihad
    .async_reset    (clear)
285 77 mihad
) ;
286
 
287 88 mihad
always@(posedge rclock_in or posedge clear)
288 77 mihad
begin
289 88 mihad
    if (clear)
290
        rclk_wgrey_next <= #`FF_DELAY 3 ;
291
    else
292
        rclk_wgrey_next <= #`FF_DELAY rclk_sync_wgrey_next ;
293 77 mihad
end
294
 
295 104 mihad
assign empty_out = (rgrey_next == rclk_wgrey_next) ;
296 77 mihad
 
297
endmodule

powered by: WebSVN 2.1.0

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