1 //////////////////////////////////////////////////////////////////////
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 ////
20 //// Known problems (limits): ////
21 //// Note that the same FIFO is used for both transmission and ////
22 //// reception but the error bit generation is ignored in tx. ////
28 //// - gorban@opencores.org ////
29 //// - Jacob Gorban ////
31 //// Created: 2001/05/12 ////
32 //// Last Updated: 2001/05/17 ////
33 //// (See log for the revision history) ////
36 //////////////////////////////////////////////////////////////////////
38 //// Copyright (C) 2000 Jacob Gorban, gorban@opencores.org ////
40 //// This source file may be used and distributed without ////
41 //// restriction provided that this copyright statement is not ////
42 //// removed from the file and that any derivative work contains ////
43 //// the original copyright notice and the associated disclaimer. ////
45 //// This source file is free software; you can redistribute it ////
46 //// and/or modify it under the terms of the GNU Lesser General ////
47 //// Public License as published by the Free Software Foundation; ////
48 //// either version 2.1 of the License, or (at your option) any ////
49 //// later version. ////
51 //// This source is distributed in the hope that it will be ////
52 //// useful, but WITHOUT ANY WARRANTY; without even the implied ////
53 //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
54 //// PURPOSE. See the GNU Lesser General Public License for more ////
57 //// You should have received a copy of the GNU Lesser General ////
58 //// Public License along with this source; if not, download it ////
59 //// from http://www.opencores.org/lgpl.shtml ////
61 //////////////////////////////////////////////////////////////////////
63 // CVS Revision History
65 // $Log: uart_fifo.v,v $
66 // Revision 1.3 2001/05/31 20:08:01 gorban
67 // FIFO changes and other corrections.
69 // Revision 1.3 2001/05/27 17:37:48 gorban
70 // Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
72 // Revision 1.2 2001/05/17 18:34:18 gorban
73 // First 'stable' release. Should be sythesizable now. Also added new header.
75 // Revision 1.0 2001-05-17 21:27:12+02 jacob
80 `include "timescale.v"
81 `include "uart_defines.v"
83 module uart_fifo (clk,
84 wb_rst_i, data_in, data_out,
86 push, // push strobe, active high
87 pop, // pop strobe, active high
99 parameter fifo_width = `UART_FIFO_WIDTH;
100 parameter fifo_depth = `UART_FIFO_DEPTH;
101 parameter fifo_pointer_w = `UART_FIFO_POINTER_W;
102 parameter fifo_counter_w = `UART_FIFO_COUNTER_W;
108 input [fifo_width-1:0] data_in;
112 output [fifo_width-1:0] data_out;
115 output [fifo_counter_w-1:0] count;
118 wire [fifo_width-1:0] data_out;
121 reg [fifo_width-1:0] fifo[fifo_depth-1:0];
124 reg [fifo_pointer_w-1:0] top;
125 reg [fifo_pointer_w-1:0] bottom;
127 reg [fifo_counter_w-1:0] count;
131 // These registers and signals are to detect rise of of the signals.
132 // Not that it slows the maximum rate by 2, meaning you must reset the signals and then
133 // assert them again for the operation to repeat
134 // This is done to accomodate wait states
138 wire push_rise = push_delay & push;
139 wire pop_rise = pop_delay & pop;
141 wire [fifo_pointer_w-1:0] top_plus_1 = top + 1;
143 always @(posedge clk or posedge wb_rst_i)
146 push_delay <= #1 1'b0;
148 push_delay <= #1 ~push;
151 always @(posedge clk or posedge wb_rst_i)
154 pop_delay <= #1 1'b0;
156 pop_delay <= #1 ~pop;
160 always @(posedge clk or posedge wb_rst_i) // synchronous FIFO
165 // bottom <= #1 1; igor
188 if (fifo_reset) begin
190 // bottom <= #1 1; igor
204 case ({push_rise, pop_rise})
207 // overrun <= #1 1'b0;// Igor Ko se postavita ostaneta aktivna tako dolgo, dokler se ne naredi read LSR registra
209 2'b10 : if (count==fifo_depth) // overrun condition
216 top <= #1 top_plus_1;
217 // fifo[top_plus_1] <= #1 data_in; igor
218 fifo[top] <= #1 data_in;
219 // overrun <= #1 0;// Igor Ko se postavita ostaneta aktivna tako dolgo, dokler se ne naredi read LSR registra
221 count <= #1 count + 1;
225 // overrun <= #1 1'b0; Igor Ko se postavita ostaneta aktivna tako dolgo, dokler se ne naredi read LSR registra
230 bottom <= #1 bottom + 1;
231 // overrun <= #1 1'b0; Igor Ko se postavita ostaneta aktivna tako dolgo, dokler se ne naredi read LSR registra
233 count <= #1 count - 1;
236 bottom <= #1 bottom + 1;
237 top <= #1 top_plus_1;
238 // fifo[top_plus_1] <= #1 data_in; igor
239 fifo[top] <= #1 data_in;
241 // overrun <= #1 1'b0; Igor Ko se postavita ostaneta aktivna tako dolgo, dokler se ne naredi read LSR registra
248 // please note though that data_out is only valid one clock after pop signal
249 assign data_out = fifo[bottom];
251 // Additional logic for detection of error conditions (parity and framing) inside the FIFO
252 // for the Line Status Register bit 7
254 wire [fifo_width-1:0] word0 = fifo[0];
255 wire [fifo_width-1:0] word1 = fifo[1];
256 wire [fifo_width-1:0] word2 = fifo[2];
257 wire [fifo_width-1:0] word3 = fifo[3];
258 wire [fifo_width-1:0] word4 = fifo[4];
259 wire [fifo_width-1:0] word5 = fifo[5];
260 wire [fifo_width-1:0] word6 = fifo[6];
261 wire [fifo_width-1:0] word7 = fifo[7];
263 wire [fifo_width-1:0] word8 = fifo[8];
264 wire [fifo_width-1:0] word9 = fifo[9];
265 wire [fifo_width-1:0] word10 = fifo[10];
266 wire [fifo_width-1:0] word11 = fifo[11];
267 wire [fifo_width-1:0] word12 = fifo[12];
268 wire [fifo_width-1:0] word13 = fifo[13];
269 wire [fifo_width-1:0] word14 = fifo[14];
270 wire [fifo_width-1:0] word15 = fifo[15];
272 // a 1 is returned if any of the error bits in the fifo is 1
273 assign error_bit = |(word0[1:0] | word1[1:0] | word2[1:0] | word3[1:0] |
274 word4[1:0] | word5[1:0] | word6[1:0] | word7[1:0] |
275 word8[1:0] | word9[1:0] | word10[1:0] | word11[1:0] |
276 word12[1:0] | word13[1:0] | word14[1:0] | word15[1:0] );