Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / fpga / opencores / uart_rfifo.v
CommitLineData
86530b38
AT
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`timescale 1 ns / 10 ps
147module uart_rfifo(clk, wb_rst_i, data_in, data_out, push, pop, overrun, count,
148 error_bit, fifo_reset, reset_status);
149
150 parameter fifo_width = 8;
151 parameter fifo_depth = 16;
152 parameter fifo_pointer_w = 4;
153 parameter fifo_counter_w = 5;
154
155 input clk;
156 input wb_rst_i;
157 input push;
158 input pop;
159 input [(fifo_width - 1):0]
160 data_in;
161 input fifo_reset;
162 input reset_status;
163 output [(fifo_width - 1):0]
164 data_out;
165 output overrun;
166 output [(fifo_counter_w - 1):0]
167 count;
168 output error_bit;
169
170 wire [7:0] data8_out;
171
172 reg [2:0] fifo[(fifo_depth - 1):0];
173 reg [(fifo_pointer_w - 1):0]
174 top;
175 reg [(fifo_pointer_w - 1):0]
176 bottom;
177 reg overrun;
178 reg [(fifo_counter_w - 1):0]
179 count;
180 wire [(fifo_pointer_w - 1):0]
181 top_plus_1 = (top + 1'b1);
182 wire [2:0] word0 = fifo[0];
183 wire [2:0] word1 = fifo[1];
184 wire [2:0] word2 = fifo[2];
185 wire [2:0] word3 = fifo[3];
186 wire [2:0] word4 = fifo[4];
187 wire [2:0] word5 = fifo[5];
188 wire [2:0] word6 = fifo[6];
189 wire [2:0] word7 = fifo[7];
190 wire [2:0] word8 = fifo[8];
191 wire [2:0] word9 = fifo[9];
192 wire [2:0] word10 = fifo[10];
193 wire [2:0] word11 = fifo[11];
194 wire [2:0] word12 = fifo[12];
195 wire [2:0] word13 = fifo[13];
196 wire [2:0] word14 = fifo[14];
197 wire [2:0] word15 = fifo[15];
198
199 assign data_out = {data8_out, fifo[bottom]};
200 assign error_bit = (|(((((((((((((((word0[2:0] | word1[2:0]) |
201 word2[2:0]) | word3[2:0]) | word4[2:0]) | word5[2:0]) |
202 word6[2:0]) | word7[2:0]) | word8[2:0]) | word9[2:0]) |
203 word10[2:0]) | word11[2:0]) | word12[2:0]) | word13[2:0]) |
204 word14[2:0]) | word15[2:0]));
205
206 raminfr #(fifo_pointer_w, 8, fifo_depth) rfifo(
207 .clk (clk),
208 .we (push),
209 .a (top),
210 .dpra (bottom),
211 .di (data_in[(fifo_width -
212 1):(fifo_width - 8)]),
213 .dpo (data8_out));
214
215 always @(posedge clk or posedge wb_rst_i) begin
216 if (wb_rst_i) begin
217 top <= #(1) 0;
218 bottom <= #(1) 1'b0;
219 count <= #(1) 0;
220 fifo[0] <= #(1) 0;
221 fifo[1] <= #(1) 0;
222 fifo[2] <= #(1) 0;
223 fifo[3] <= #(1) 0;
224 fifo[4] <= #(1) 0;
225 fifo[5] <= #(1) 0;
226 fifo[6] <= #(1) 0;
227 fifo[7] <= #(1) 0;
228 fifo[8] <= #(1) 0;
229 fifo[9] <= #(1) 0;
230 fifo[10] <= #(1) 0;
231 fifo[11] <= #(1) 0;
232 fifo[12] <= #(1) 0;
233 fifo[13] <= #(1) 0;
234 fifo[14] <= #(1) 0;
235 fifo[15] <= #(1) 0;
236 end
237 else if (fifo_reset) begin
238 top <= #(1) 0;
239 bottom <= #(1) 1'b0;
240 count <= #(1) 0;
241 fifo[0] <= #(1) 0;
242 fifo[1] <= #(1) 0;
243 fifo[2] <= #(1) 0;
244 fifo[3] <= #(1) 0;
245 fifo[4] <= #(1) 0;
246 fifo[5] <= #(1) 0;
247 fifo[6] <= #(1) 0;
248 fifo[7] <= #(1) 0;
249 fifo[8] <= #(1) 0;
250 fifo[9] <= #(1) 0;
251 fifo[10] <= #(1) 0;
252 fifo[11] <= #(1) 0;
253 fifo[12] <= #(1) 0;
254 fifo[13] <= #(1) 0;
255 fifo[14] <= #(1) 0;
256 fifo[15] <= #(1) 0;
257 end
258 else
259 begin
260 case ({push, pop})
261 2'b10:
262 if (count < fifo_depth) begin
263 top <= #(1) top_plus_1;
264 fifo[top] <= #(1) data_in[2:0];
265 count <= #(1) (count + 1'b1);
266 end
267 2'b1:
268 if (count > 0) begin
269 fifo[bottom] <= #(1) 0;
270 bottom <= #(1) (bottom + 1'b1);
271 count <= #(1) (count - 1'b1);
272 end
273 2'b11: begin
274 bottom <= #(1) (bottom + 1'b1);
275 top <= #(1) top_plus_1;
276 fifo[top] <= #(1) data_in[2:0];
277 end
278 default:
279 ;
280 endcase
281 end
282 end
283 always @(posedge clk or posedge wb_rst_i) begin
284 if (wb_rst_i) begin
285 overrun <= #(1) 1'b0;
286 end
287 else if (fifo_reset | reset_status) begin
288 overrun <= #(1) 1'b0;
289 end
290 else if ((push & (~pop)) & (count == fifo_depth)) begin
291 overrun <= #(1) 1'b1;
292 end
293 end
294endmodule