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

Subversion Repositories pci

[/] [pci/] [tags/] [rel_10/] [rtl/] [verilog/] [pci_wbw_fifo_control.v] - Blame information for rev 104

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

powered by: WebSVN 2.1.0

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