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

Subversion Repositories boundaries

[/] [boundaries/] [trunk/] [rtl/] [verilog/] [bc_fifo_basic.v] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 esquehill
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
//// bc_fifo_basic.v                                              ////
4
////                                                              ////
5
//// This file is part of the boundaries opencores effort.        ////
6
//// <http://www.opencores.org/cores/boundaries/>                 ////
7
////                                                              ////
8
//// Module Description:                                          ////
9
////                                                              ////
10
//// Asynchronous Boundary Crossing FIFO                          ////
11
////                                                              ////
12
//// 2 Parameters: Address Width, Data Width                      ////
13
////   Data storage is internally inferred.                       ////
14
////   Protected against read-while-empty and write-while-full    ////
15
////   The minimum address width (AW) is 2.                       ////
16
////                                                              ////
17
//// To Do:                                                       ////
18
//// Verify in silicon.                                           ////
19
////                                                              ////
20
//// Author(s):                                                   ////
21
//// - Shannon Hill                                               ////
22
////   (based on the generic_fifo_dc_gray design from             ////
23
////    Rudolf Usselmann.  This variant infers its own            ////
24
////    data storage, defends itself against write-while-full     ////
25
////    and read-while-empty, and forces its output data to 0     ////
26
////    when empty.)                                              ////
27
////                                                              ////
28
//////////////////////////////////////////////////////////////////////
29
////                                                              ////
30
//// Copyright (C) 2004 Shannon Hill and OPENCORES.ORG            ////
31
////                                                              ////
32
//// This source file may be used and distributed without         ////
33
//// restriction provided that this copyright statement is not    ////
34
//// removed from the file and that any derivative work contains  ////
35
//// the original copyright notice and the associated disclaimer. ////
36
////                                                              ////
37
//// This source file is free software; you can redistribute it   ////
38
//// and/or modify it under the terms of the GNU Lesser General   ////
39
//// Public License as published by the Free Software Foundation; ////
40
//// either version 2.1 of the License, or (at your option) any   ////
41
//// later version.                                               ////
42
////                                                              ////
43
//// This source is distributed in the hope that it will be       ////
44
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
45
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
46
//// PURPOSE. See the GNU Lesser General Public License for more  ////
47
//// details.                                                     ////
48
////                                                              ////
49
//// You should have received a copy of the GNU Lesser General    ////
50
//// Public License along with this source; if not, download it   ////
51
//// from <http://www.opencores.org/lgpl.shtml>                   ////
52
////                                                              ////
53
//////////////////////////////////////////////////////////////////////
54
//
55
// $Id: bc_fifo_basic.v,v 1.1 2004-07-07 12:41:17 esquehill Exp $
56
//
57
// CVS Revision History
58
//
59
// $Log: not supported by cvs2svn $
60
//
61
//
62
module bc_fifo_basic( /*AUTOARG*/
63
// Outputs
64
get_do, get_have, put_need,
65
// Inputs
66
put_rst_i, get_rst_i, get_clk_i, get, put_clk_i, put_di, put
67
);
68
 
69
parameter AW=3;  // default address width
70
parameter DW=8;  // default data width
71
 
72
input            put_rst_i;       // async reset from the put_clk_i domain
73
input            get_rst_i;       // async reset from the get_clk_i domain
74
 
75
input            get_clk_i;
76
output [DW-1:0]  get_do;
77
input            get;
78
output           get_have;        // fifo has 1 or more
79
 
80
input            put_clk_i;
81
input  [DW-1:0]  put_di;
82
input            put;
83
output           put_need;        // fifo has room for 1 more
84
 
85
reg  [AW  :0]    rp_bin;
86
reg  [AW  :0]    rp_gra;
87
reg  [AW  :0]    rp_gra_sync;
88
 
89
reg  [AW  :0]    wp_bin;
90
reg  [AW  :0]    wp_gra;
91
reg  [AW  :0]    wp_gra_sync;
92
 
93
reg              put_full;
94
reg              get_emty;
95
 
96
wire             get_have = ~get_emty;
97
wire             put_need = ~put_full;
98
 
99
reg  [DW-1:0]    mem [0:(1<<AW)-1];    // fifo data
100
 
101
wire [DW-1:0]    get_do = {DW{get_have}} & mem[ rp_bin[AW-1:0] ]; // output data
102
 
103
//////////////////////////
104
 
105
function [AW:0] bin_to_gray;
106
input [AW:0] b;
107
begin
108
 bin_to_gray = b ^ (b>>1);
109
end
110
endfunction
111
 
112
//////////////////////////
113
 
114
function [AW:0] gray_to_bin;
115
input [AW:0] g;
116
reg   [AW:0] b;
117
integer      i;
118
begin
119
 for( i=0; i<=AW; i=i+1 ) b[i] = ^(g>>i);
120
 gray_to_bin = b;
121
end
122
endfunction
123
 
124
////////////////////////////
125
// in the get_clk_i domain
126
////////////////////////////
127
 
128
wire [AW  :0] rp_bin_add1 = rp_bin + 1'd1;
129
wire [AW  :0] rp_gra_add1 = bin_to_gray( rp_bin_add1 );
130
//
131
// get the gray-coded write pointer over to the get_clk_i domain
132
//
133
always @( posedge get_clk_i or posedge get_rst_i ) // put_clk_i to get_clk_i boundary crossing
134
if( get_rst_i )
135
      wp_gra_sync  <= 0;
136
else  wp_gra_sync  <= wp_gra;
137
 
138
//
139
// convert the sampled graycode read pointer to binary
140
//
141
// wire [AW  :0] wp_bin_sync = gray_to_bin( wp_gra_sync );
142
 
143
// compare the write pointer and read pointer
144
//
145
// set  empty when: getting AND the next read pointer == the current write pointer
146
// hold empty when: read pointer == write pointer
147
// clr  empty when: read pointer no longer equal to write pointer
148
//
149
always @( posedge get_clk_i or posedge get_rst_i )
150
if( get_rst_i )
151
begin
152
     rp_bin   <= 0;
153
     rp_gra   <= 0;
154
     get_emty <= 1'b1;
155
end
156
else
157
begin
158
 
159
     get_emty <=       ( rp_gra      == wp_gra_sync )  |
160
   ( get & ~get_emty & ( rp_gra_add1 == wp_gra_sync ) );
161
 
162
 if( get & ~get_emty )
163
  begin
164
     rp_bin   <= rp_bin_add1;
165
     rp_gra   <= rp_gra_add1;
166
  end
167
end
168
 
169
////////////////////////////////
170
// over in the put_clk_i domain
171
////////////////////////////////
172
 
173
wire [AW  :0] wp_bin_add1 = wp_bin + 1'd1;
174
wire [AW  :0] wp_gra_add1 = bin_to_gray( wp_bin_add1 );
175
//
176
// get the gray-coded read pointer over to the put_clk_i domain
177
//
178
always @( posedge put_clk_i or posedge put_rst_i )  // get_clk_i to put_clk_i boundary crossing
179
if( put_rst_i )
180
     rp_gra_sync  <= 0;
181
else rp_gra_sync  <= rp_gra;
182
//
183
// convert the sampled graycode read pointer to binary
184
//
185
wire [AW  :0] rp_bin_sync = gray_to_bin( rp_gra_sync );
186
 
187
// compare the read pointer and write pointer
188
//
189
// set  full when: putting AND the next write pointer ==  read pointer
190
// hold full when: full and write pointer == read pointer
191
// clr  full when: write pointer no longer equal to read pointer
192
//
193
always @( posedge put_clk_i or posedge put_rst_i )
194
if( put_rst_i )
195
 begin
196
     wp_bin   <= 0;
197
     wp_gra   <= 0;
198
     put_full <= 1'b0;
199
 end
200
else
201
begin
202
           put_full <=
203
  (                   ( wp_bin[     AW-1:0] == rp_bin_sync[AW-1:0] ) & ( wp_bin[     AW] != rp_bin_sync[AW] ) ) |
204
  ( put & ~put_full & ( wp_bin_add1[AW-1:0] == rp_bin_sync[AW-1:0] ) & ( wp_bin_add1[AW] != rp_bin_sync[AW] ) );
205
 
206
if( put & ~put_full )
207
 begin
208
     wp_bin   <= wp_bin_add1;
209
     wp_gra   <= wp_gra_add1;
210
 end
211
end
212
 
213
always @( posedge put_clk_i )
214
if( put & ~put_full ) mem[ wp_bin[AW-1:0] ] <= put_di;  // do the data write
215
 
216
endmodule

powered by: WebSVN 2.1.0

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