Merged r9433:9527 from features/gr-usrp2 into trunk. Adds usrp2 and gr-usrp2 top...
[debian/gnuradio] / usrp2 / fpga / opencores / uart16550 / rtl / verilog / uart_rfifo.v
1 //////////////////////////////////////////////////////////////////////
2 ////                                                              ////
3 ////  uart_rfifo.v (Modified from uart_fifo.v)                    ////
4 ////                                                              ////
5 ////                                                              ////
6 ////  This file is part of the "UART 16550 compatible" project    ////
7 ////  http://www.opencores.org/cores/uart16550/                   ////
8 ////                                                              ////
9 ////  Documentation related to this project:                      ////
10 ////  - http://www.opencores.org/cores/uart16550/                 ////
11 ////                                                              ////
12 ////  Projects compatibility:                                     ////
13 ////  - WISHBONE                                                  ////
14 ////  RS232 Protocol                                              ////
15 ////  16550D uart (mostly supported)                              ////
16 ////                                                              ////
17 ////  Overview (main Features):                                   ////
18 ////  UART core receiver FIFO                                     ////
19 ////                                                              ////
20 ////  To Do:                                                      ////
21 ////  Nothing.                                                    ////
22 ////                                                              ////
23 ////  Author(s):                                                  ////
24 ////      - gorban@opencores.org                                  ////
25 ////      - Jacob Gorban                                          ////
26 ////      - Igor Mohor (igorm@opencores.org)                      ////
27 ////                                                              ////
28 ////  Created:        2001/05/12                                  ////
29 ////  Last Updated:   2002/07/22                                  ////
30 ////                  (See log for the revision history)          ////
31 ////                                                              ////
32 ////                                                              ////
33 //////////////////////////////////////////////////////////////////////
34 ////                                                              ////
35 //// Copyright (C) 2000, 2001 Authors                             ////
36 ////                                                              ////
37 //// This source file may be used and distributed without         ////
38 //// restriction provided that this copyright statement is not    ////
39 //// removed from the file and that any derivative work contains  ////
40 //// the original copyright notice and the associated disclaimer. ////
41 ////                                                              ////
42 //// This source file is free software; you can redistribute it   ////
43 //// and/or modify it under the terms of the GNU Lesser General   ////
44 //// Public License as published by the Free Software Foundation; ////
45 //// either version 2.1 of the License, or (at your option) any   ////
46 //// later version.                                               ////
47 ////                                                              ////
48 //// This source is distributed in the hope that it will be       ////
49 //// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
50 //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
51 //// PURPOSE.  See the GNU Lesser General Public License for more ////
52 //// details.                                                     ////
53 ////                                                              ////
54 //// You should have received a copy of the GNU Lesser General    ////
55 //// Public License along with this source; if not, download it   ////
56 //// from http://www.opencores.org/lgpl.shtml                     ////
57 ////                                                              ////
58 //////////////////////////////////////////////////////////////////////
59 //
60 // CVS Revision History
61 //
62 // $Log: uart_rfifo.v,v $
63 // Revision 1.4  2003/07/11 18:20:26  gorban
64 // added clearing the receiver fifo statuses on resets
65 //
66 // Revision 1.3  2003/06/11 16:37:47  gorban
67 // This fixes errors in some cases when data is being read and put to the FIFO at the same time. Patch is submitted by Scott Furman. Update is very recommended.
68 //
69 // Revision 1.2  2002/07/29 21:16:18  gorban
70 // The uart_defines.v file is included again in sources.
71 //
72 // Revision 1.1  2002/07/22 23:02:23  gorban
73 // Bug Fixes:
74 //  * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
75 //   Problem reported by Kenny.Tung.
76 //  * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
77 //
78 // Improvements:
79 //  * Made FIFO's as general inferrable memory where possible.
80 //  So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
81 //  This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
82 //
83 //  * Added optional baudrate output (baud_o).
84 //  This is identical to BAUDOUT* signal on 16550 chip.
85 //  It outputs 16xbit_clock_rate - the divided clock.
86 //  It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
87 //
88 // Revision 1.16  2001/12/20 13:25:46  mohor
89 // rx push changed to be only one cycle wide.
90 //
91 // Revision 1.15  2001/12/18 09:01:07  mohor
92 // Bug that was entered in the last update fixed (rx state machine).
93 //
94 // Revision 1.14  2001/12/17 14:46:48  mohor
95 // overrun signal was moved to separate block because many sequential lsr
96 // reads were preventing data from being written to rx fifo.
97 // underrun signal was not used and was removed from the project.
98 //
99 // Revision 1.13  2001/11/26 21:38:54  gorban
100 // Lots of fixes:
101 // Break condition wasn't handled correctly at all.
102 // LSR bits could lose their values.
103 // LSR value after reset was wrong.
104 // Timing of THRE interrupt signal corrected.
105 // LSR bit 0 timing corrected.
106 //
107 // Revision 1.12  2001/11/08 14:54:23  mohor
108 // Comments in Slovene language deleted, few small fixes for better work of
109 // old tools. IRQs need to be fix.
110 //
111 // Revision 1.11  2001/11/07 17:51:52  gorban
112 // Heavily rewritten interrupt and LSR subsystems.
113 // Many bugs hopefully squashed.
114 //
115 // Revision 1.10  2001/10/20 09:58:40  gorban
116 // Small synopsis fixes
117 //
118 // Revision 1.9  2001/08/24 21:01:12  mohor
119 // Things connected to parity changed.
120 // Clock devider changed.
121 //
122 // Revision 1.8  2001/08/24 08:48:10  mohor
123 // FIFO was not cleared after the data was read bug fixed.
124 //
125 // Revision 1.7  2001/08/23 16:05:05  mohor
126 // Stop bit bug fixed.
127 // Parity bug fixed.
128 // WISHBONE read cycle bug fixed,
129 // OE indicator (Overrun Error) bug fixed.
130 // PE indicator (Parity Error) bug fixed.
131 // Register read bug fixed.
132 //
133 // Revision 1.3  2001/05/31 20:08:01  gorban
134 // FIFO changes and other corrections.
135 //
136 // Revision 1.3  2001/05/27 17:37:48  gorban
137 // Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
138 //
139 // Revision 1.2  2001/05/17 18:34:18  gorban
140 // First 'stable' release. Should be sythesizable now. Also added new header.
141 //
142 // Revision 1.0  2001-05-17 21:27:12+02  jacob
143 // Initial revision
144 //
145 //
146
147 // synopsys translate_off
148 `include "timescale.v"
149 // synopsys translate_on
150
151 `include "uart_defines.v"
152
153 module uart_rfifo (clk, 
154         wb_rst_i, data_in, data_out,
155 // Control signals
156         push, // push strobe, active high
157         pop,   // pop strobe, active high
158 // status signals
159         overrun,
160         count,
161         error_bit,
162         fifo_reset,
163         reset_status
164         );
165
166
167 // FIFO parameters
168 parameter fifo_width = `UART_FIFO_WIDTH;
169 parameter fifo_depth = `UART_FIFO_DEPTH;
170 parameter fifo_pointer_w = `UART_FIFO_POINTER_W;
171 parameter fifo_counter_w = `UART_FIFO_COUNTER_W;
172
173 input                           clk;
174 input                           wb_rst_i;
175 input                           push;
176 input                           pop;
177 input   [fifo_width-1:0]        data_in;
178 input                           fifo_reset;
179 input       reset_status;
180
181 output  [fifo_width-1:0]        data_out;
182 output                          overrun;
183 output  [fifo_counter_w-1:0]    count;
184 output                          error_bit;
185
186 wire    [fifo_width-1:0]        data_out;
187 wire [7:0] data8_out;
188 // flags FIFO
189 reg     [2:0]   fifo[fifo_depth-1:0];
190
191 // FIFO pointers
192 reg     [fifo_pointer_w-1:0]    top;
193 reg     [fifo_pointer_w-1:0]    bottom;
194
195 reg     [fifo_counter_w-1:0]    count;
196 reg                             overrun;
197
198 wire [fifo_pointer_w-1:0] top_plus_1 = top + 1'b1;
199
200 raminfr #(fifo_pointer_w,8,fifo_depth) rfifo  
201         (.clk(clk), 
202                         .we(push), 
203                         .a(top), 
204                         .dpra(bottom), 
205                         .di(data_in[fifo_width-1:fifo_width-8]), 
206                         .dpo(data8_out)
207                 ); 
208
209 always @(posedge clk or posedge wb_rst_i) // synchronous FIFO
210 begin
211         if (wb_rst_i)
212         begin
213                 top             <= #1 0;
214                 bottom          <= #1 1'b0;
215                 count           <= #1 0;
216                 fifo[0] <= #1 0;
217                 fifo[1] <= #1 0;
218                 fifo[2] <= #1 0;
219                 fifo[3] <= #1 0;
220                 fifo[4] <= #1 0;
221                 fifo[5] <= #1 0;
222                 fifo[6] <= #1 0;
223                 fifo[7] <= #1 0;
224                 fifo[8] <= #1 0;
225                 fifo[9] <= #1 0;
226                 fifo[10] <= #1 0;
227                 fifo[11] <= #1 0;
228                 fifo[12] <= #1 0;
229                 fifo[13] <= #1 0;
230                 fifo[14] <= #1 0;
231                 fifo[15] <= #1 0;
232         end
233         else
234         if (fifo_reset) begin
235                 top             <= #1 0;
236                 bottom          <= #1 1'b0;
237                 count           <= #1 0;
238                 fifo[0] <= #1 0;
239                 fifo[1] <= #1 0;
240                 fifo[2] <= #1 0;
241                 fifo[3] <= #1 0;
242                 fifo[4] <= #1 0;
243                 fifo[5] <= #1 0;
244                 fifo[6] <= #1 0;
245                 fifo[7] <= #1 0;
246                 fifo[8] <= #1 0;
247                 fifo[9] <= #1 0;
248                 fifo[10] <= #1 0;
249                 fifo[11] <= #1 0;
250                 fifo[12] <= #1 0;
251                 fifo[13] <= #1 0;
252                 fifo[14] <= #1 0;
253                 fifo[15] <= #1 0;
254         end
255   else
256         begin
257                 case ({push, pop})
258                 2'b10 : if (count<fifo_depth)  // overrun condition
259                         begin
260                                 top       <= #1 top_plus_1;
261                                 fifo[top] <= #1 data_in[2:0];
262                                 count     <= #1 count + 1'b1;
263                         end
264                 2'b01 : if(count>0)
265                         begin
266         fifo[bottom] <= #1 0;
267                                 bottom   <= #1 bottom + 1'b1;
268                                 count    <= #1 count - 1'b1;
269                         end
270                 2'b11 : begin
271                                 bottom   <= #1 bottom + 1'b1;
272                                 top       <= #1 top_plus_1;
273                                 fifo[top] <= #1 data_in[2:0];
274                         end
275     default: ;
276                 endcase
277         end
278 end   // always
279
280 always @(posedge clk or posedge wb_rst_i) // synchronous FIFO
281 begin
282   if (wb_rst_i)
283     overrun   <= #1 1'b0;
284   else
285   if(fifo_reset | reset_status) 
286     overrun   <= #1 1'b0;
287   else
288   if(push & ~pop & (count==fifo_depth))
289     overrun   <= #1 1'b1;
290 end   // always
291
292
293 // please note though that data_out is only valid one clock after pop signal
294 assign data_out = {data8_out,fifo[bottom]};
295
296 // Additional logic for detection of error conditions (parity and framing) inside the FIFO
297 // for the Line Status Register bit 7
298
299 wire    [2:0]   word0 = fifo[0];
300 wire    [2:0]   word1 = fifo[1];
301 wire    [2:0]   word2 = fifo[2];
302 wire    [2:0]   word3 = fifo[3];
303 wire    [2:0]   word4 = fifo[4];
304 wire    [2:0]   word5 = fifo[5];
305 wire    [2:0]   word6 = fifo[6];
306 wire    [2:0]   word7 = fifo[7];
307
308 wire    [2:0]   word8 = fifo[8];
309 wire    [2:0]   word9 = fifo[9];
310 wire    [2:0]   word10 = fifo[10];
311 wire    [2:0]   word11 = fifo[11];
312 wire    [2:0]   word12 = fifo[12];
313 wire    [2:0]   word13 = fifo[13];
314 wire    [2:0]   word14 = fifo[14];
315 wire    [2:0]   word15 = fifo[15];
316
317 // a 1 is returned if any of the error bits in the fifo is 1
318 assign  error_bit = |(word0[2:0]  | word1[2:0]  | word2[2:0]  | word3[2:0]  |
319                               word4[2:0]  | word5[2:0]  | word6[2:0]  | word7[2:0]  |
320                               word8[2:0]  | word9[2:0]  | word10[2:0] | word11[2:0] |
321                               word12[2:0] | word13[2:0] | word14[2:0] | word15[2:0] );
322
323 endmodule