1 //////////////////////////////////////////////////////////////////////
3 //// uart_rfifo.v (Modified from uart_fifo.v) ////
6 //// This file is part of the "UART 16550 compatible" project ////
7 //// http://www.opencores.org/cores/uart16550/ ////
9 //// Documentation related to this project: ////
10 //// - http://www.opencores.org/cores/uart16550/ ////
12 //// Projects compatibility: ////
14 //// RS232 Protocol ////
15 //// 16550D uart (mostly supported) ////
17 //// Overview (main Features): ////
18 //// UART core receiver FIFO ////
24 //// - gorban@opencores.org ////
25 //// - Jacob Gorban ////
26 //// - Igor Mohor (igorm@opencores.org) ////
28 //// Created: 2001/05/12 ////
29 //// Last Updated: 2002/07/22 ////
30 //// (See log for the revision history) ////
33 //////////////////////////////////////////////////////////////////////
35 //// Copyright (C) 2000, 2001 Authors ////
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. ////
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. ////
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 ////
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 ////
58 //////////////////////////////////////////////////////////////////////
60 // CVS Revision History
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
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.
69 // Revision 1.2 2002/07/29 21:16:18 gorban
70 // The uart_defines.v file is included again in sources.
72 // Revision 1.1 2002/07/22 23:02:23 gorban
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.
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.
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.
88 // Revision 1.16 2001/12/20 13:25:46 mohor
89 // rx push changed to be only one cycle wide.
91 // Revision 1.15 2001/12/18 09:01:07 mohor
92 // Bug that was entered in the last update fixed (rx state machine).
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.
99 // Revision 1.13 2001/11/26 21:38:54 gorban
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.
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.
111 // Revision 1.11 2001/11/07 17:51:52 gorban
112 // Heavily rewritten interrupt and LSR subsystems.
113 // Many bugs hopefully squashed.
115 // Revision 1.10 2001/10/20 09:58:40 gorban
116 // Small synopsis fixes
118 // Revision 1.9 2001/08/24 21:01:12 mohor
119 // Things connected to parity changed.
120 // Clock devider changed.
122 // Revision 1.8 2001/08/24 08:48:10 mohor
123 // FIFO was not cleared after the data was read bug fixed.
125 // Revision 1.7 2001/08/23 16:05:05 mohor
126 // Stop bit 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.
133 // Revision 1.3 2001/05/31 20:08:01 gorban
134 // FIFO changes and other corrections.
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.
139 // Revision 1.2 2001/05/17 18:34:18 gorban
140 // First 'stable' release. Should be sythesizable now. Also added new header.
142 // Revision 1.0 2001-05-17 21:27:12+02 jacob
147 // synopsys translate_off
148 `include "timescale.v"
149 // synopsys translate_on
151 `include "uart_defines.v"
153 module uart_rfifo (clk,
154 wb_rst_i, data_in, data_out,
156 push, // push strobe, active high
157 pop, // pop strobe, active high
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;
177 input [fifo_width-1:0] data_in;
181 output [fifo_width-1:0] data_out;
183 output [fifo_counter_w-1:0] count;
186 wire [fifo_width-1:0] data_out;
187 wire [7:0] data8_out;
189 reg [2:0] fifo[fifo_depth-1:0];
192 reg [fifo_pointer_w-1:0] top;
193 reg [fifo_pointer_w-1:0] bottom;
195 reg [fifo_counter_w-1:0] count;
198 wire [fifo_pointer_w-1:0] top_plus_1 = top + 1'b1;
200 raminfr #(fifo_pointer_w,8,fifo_depth) rfifo
205 .di(data_in[fifo_width-1:fifo_width-8]),
209 always @(posedge clk or posedge wb_rst_i) // synchronous FIFO
234 if (fifo_reset) begin
258 2'b10 : if (count<fifo_depth) // overrun condition
260 top <= #1 top_plus_1;
261 fifo[top] <= #1 data_in[2:0];
262 count <= #1 count + 1'b1;
266 fifo[bottom] <= #1 0;
267 bottom <= #1 bottom + 1'b1;
268 count <= #1 count - 1'b1;
271 bottom <= #1 bottom + 1'b1;
272 top <= #1 top_plus_1;
273 fifo[top] <= #1 data_in[2:0];
280 always @(posedge clk or posedge wb_rst_i) // synchronous FIFO
285 if(fifo_reset | reset_status)
288 if(push & ~pop & (count==fifo_depth))
293 // please note though that data_out is only valid one clock after pop signal
294 assign data_out = {data8_out,fifo[bottom]};
296 // Additional logic for detection of error conditions (parity and framing) inside the FIFO
297 // for the Line Status Register bit 7
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];
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];
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] );