Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | ////////////////////////////////////////////////////////////////////// |
2 | //// //// | |
3 | //// uart_regs.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 | //// Registers of the uart 16550 core //// | |
19 | //// //// | |
20 | //// Known problems (limits): //// | |
21 | //// Inserts 1 wait state in all WISHBONE transfers //// | |
22 | //// //// | |
23 | //// To Do: //// | |
24 | //// Nothing or verification. //// | |
25 | //// //// | |
26 | //// Author(s): //// | |
27 | //// - gorban@opencores.org //// | |
28 | //// - Jacob Gorban //// | |
29 | //// - Igor Mohor (igorm@opencores.org) //// | |
30 | //// //// | |
31 | //// Created: 2001/05/12 //// | |
32 | //// Last Updated: (See log for the revision history //// | |
33 | //// //// | |
34 | //// //// | |
35 | ////////////////////////////////////////////////////////////////////// | |
36 | //// //// | |
37 | //// Copyright (C) 2000, 2001 Authors //// | |
38 | //// //// | |
39 | //// This source file may be used and distributed without //// | |
40 | //// restriction provided that this copyright statement is not //// | |
41 | //// removed from the file and that any derivative work contains //// | |
42 | //// the original copyright notice and the associated disclaimer. //// | |
43 | //// //// | |
44 | //// This source file is free software; you can redistribute it //// | |
45 | //// and/or modify it under the terms of the GNU Lesser General //// | |
46 | //// Public License as published by the Free Software Foundation; //// | |
47 | //// either version 2.1 of the License, or (at your option) any //// | |
48 | //// later version. //// | |
49 | //// //// | |
50 | //// This source is distributed in the hope that it will be //// | |
51 | //// useful, but WITHOUT ANY WARRANTY; without even the implied //// | |
52 | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// | |
53 | //// PURPOSE. See the GNU Lesser General Public License for more //// | |
54 | //// details. //// | |
55 | //// //// | |
56 | //// You should have received a copy of the GNU Lesser General //// | |
57 | //// Public License along with this source; if not, download it //// | |
58 | //// from http://www.opencores.org/lgpl.shtml //// | |
59 | //// //// | |
60 | ////////////////////////////////////////////////////////////////////// | |
61 | // | |
62 | // CVS Revision History | |
63 | // | |
64 | // $Log: uart_regs.v,v $ | |
65 | // Revision 1.42 2004/11/22 09:21:59 igorm | |
66 | // Timeout interrupt should be generated only when there is at least ony | |
67 | // character in the fifo. | |
68 | // | |
69 | // Revision 1.41 2004/05/21 11:44:41 tadejm | |
70 | // Added synchronizer flops for RX input. | |
71 | // | |
72 | // Revision 1.40 2003/06/11 16:37:47 gorban | |
73 | // 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. | |
74 | // | |
75 | // Revision 1.39 2002/07/29 21:16:18 gorban | |
76 | // The uart_defines.v file is included again in sources. | |
77 | // | |
78 | // Revision 1.38 2002/07/22 23:02:23 gorban | |
79 | // Bug Fixes: | |
80 | // * Possible loss of sync and bad reception of stop bit on slow baud rates fixed. | |
81 | // Problem reported by Kenny.Tung. | |
82 | // * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers. | |
83 | // | |
84 | // Improvements: | |
85 | // * Made FIFO's as general inferrable memory where possible. | |
86 | // So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx). | |
87 | // This saves about 1/3 of the Slice count and reduces P&R and synthesis times. | |
88 | // | |
89 | // * Added optional baudrate output (baud_o). | |
90 | // This is identical to BAUDOUT* signal on 16550 chip. | |
91 | // It outputs 16xbit_clock_rate - the divided clock. | |
92 | // It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use. | |
93 | // | |
94 | // Revision 1.37 2001/12/27 13:24:09 mohor | |
95 | // lsr[7] was not showing overrun errors. | |
96 | // | |
97 | // Revision 1.36 2001/12/20 13:25:46 mohor | |
98 | // rx push changed to be only one cycle wide. | |
99 | // | |
100 | // Revision 1.35 2001/12/19 08:03:34 mohor | |
101 | // Warnings cleared. | |
102 | // | |
103 | // Revision 1.34 2001/12/19 07:33:54 mohor | |
104 | // Synplicity was having troubles with the comment. | |
105 | // | |
106 | // Revision 1.33 2001/12/17 10:14:43 mohor | |
107 | // Things related to msr register changed. After THRE IRQ occurs, and one | |
108 | // character is written to the transmit fifo, the detection of the THRE bit in the | |
109 | // LSR is delayed for one character time. | |
110 | // | |
111 | // Revision 1.32 2001/12/14 13:19:24 mohor | |
112 | // MSR register fixed. | |
113 | // | |
114 | // Revision 1.31 2001/12/14 10:06:58 mohor | |
115 | // After reset modem status register MSR should be reset. | |
116 | // | |
117 | // Revision 1.30 2001/12/13 10:09:13 mohor | |
118 | // thre irq should be cleared only when being source of interrupt. | |
119 | // | |
120 | // Revision 1.29 2001/12/12 09:05:46 mohor | |
121 | // LSR status bit 0 was not cleared correctly in case of reseting the FCR (rx fifo). | |
122 | // | |
123 | // Revision 1.28 2001/12/10 19:52:41 gorban | |
124 | // Scratch register added | |
125 | // | |
126 | // Revision 1.27 2001/12/06 14:51:04 gorban | |
127 | // Bug in LSR[0] is fixed. | |
128 | // All WISHBONE signals are now sampled, so another wait-state is introduced on all transfers. | |
129 | // | |
130 | // Revision 1.26 2001/12/03 21:44:29 gorban | |
131 | // Updated specification documentation. | |
132 | // Added full 32-bit data bus interface, now as default. | |
133 | // Address is 5-bit wide in 32-bit data bus mode. | |
134 | // Added wb_sel_i input to the core. It's used in the 32-bit mode. | |
135 | // Added debug interface with two 32-bit read-only registers in 32-bit mode. | |
136 | // Bits 5 and 6 of LSR are now only cleared on TX FIFO write. | |
137 | // My small test bench is modified to work with 32-bit mode. | |
138 | // | |
139 | // Revision 1.25 2001/11/28 19:36:39 gorban | |
140 | // Fixed: timeout and break didn't pay attention to current data format when counting time | |
141 | // | |
142 | // Revision 1.24 2001/11/26 21:38:54 gorban | |
143 | // Lots of fixes: | |
144 | // Break condition wasn't handled correctly at all. | |
145 | // LSR bits could lose their values. | |
146 | // LSR value after reset was wrong. | |
147 | // Timing of THRE interrupt signal corrected. | |
148 | // LSR bit 0 timing corrected. | |
149 | // | |
150 | // Revision 1.23 2001/11/12 21:57:29 gorban | |
151 | // fixed more typo bugs | |
152 | // | |
153 | // Revision 1.22 2001/11/12 15:02:28 mohor | |
154 | // lsr1r error fixed. | |
155 | // | |
156 | // Revision 1.21 2001/11/12 14:57:27 mohor | |
157 | // ti_int_pnd error fixed. | |
158 | // | |
159 | // Revision 1.20 2001/11/12 14:50:27 mohor | |
160 | // ti_int_d error fixed. | |
161 | // | |
162 | // Revision 1.19 2001/11/10 12:43:21 gorban | |
163 | // Logic Synthesis bugs fixed. Some other minor changes | |
164 | // | |
165 | // Revision 1.18 2001/11/08 14:54:23 mohor | |
166 | // Comments in Slovene language deleted, few small fixes for better work of | |
167 | // old tools. IRQs need to be fix. | |
168 | // | |
169 | // Revision 1.17 2001/11/07 17:51:52 gorban | |
170 | // Heavily rewritten interrupt and LSR subsystems. | |
171 | // Many bugs hopefully squashed. | |
172 | // | |
173 | // Revision 1.16 2001/11/02 09:55:16 mohor | |
174 | // no message | |
175 | // | |
176 | // Revision 1.15 2001/10/31 15:19:22 gorban | |
177 | // Fixes to break and timeout conditions | |
178 | // | |
179 | // Revision 1.14 2001/10/29 17:00:46 gorban | |
180 | // fixed parity sending and tx_fifo resets over- and underrun | |
181 | // | |
182 | // Revision 1.13 2001/10/20 09:58:40 gorban | |
183 | // Small synopsis fixes | |
184 | // | |
185 | // Revision 1.12 2001/10/19 16:21:40 gorban | |
186 | // Changes data_out to be synchronous again as it should have been. | |
187 | // | |
188 | // Revision 1.11 2001/10/18 20:35:45 gorban | |
189 | // small fix | |
190 | // | |
191 | // Revision 1.10 2001/08/24 21:01:12 mohor | |
192 | // Things connected to parity changed. | |
193 | // Clock devider changed. | |
194 | // | |
195 | // Revision 1.9 2001/08/23 16:05:05 mohor | |
196 | // Stop bit bug fixed. | |
197 | // Parity bug fixed. | |
198 | // WISHBONE read cycle bug fixed, | |
199 | // OE indicator (Overrun Error) bug fixed. | |
200 | // PE indicator (Parity Error) bug fixed. | |
201 | // Register read bug fixed. | |
202 | // | |
203 | // Revision 1.10 2001/06/23 11:21:48 gorban | |
204 | // DL made 16-bit long. Fixed transmission/reception bugs. | |
205 | // | |
206 | // Revision 1.9 2001/05/31 20:08:01 gorban | |
207 | // FIFO changes and other corrections. | |
208 | // | |
209 | // Revision 1.8 2001/05/29 20:05:04 gorban | |
210 | // Fixed some bugs and synthesis problems. | |
211 | // | |
212 | // Revision 1.7 2001/05/27 17:37:49 gorban | |
213 | // Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file. | |
214 | // | |
215 | // Revision 1.6 2001/05/21 19:12:02 gorban | |
216 | // Corrected some Linter messages. | |
217 | // | |
218 | // Revision 1.5 2001/05/17 18:34:18 gorban | |
219 | // First 'stable' release. Should be sythesizable now. Also added new header. | |
220 | // | |
221 | // Revision 1.0 2001-05-17 21:27:11+02 jacob | |
222 | // Initial revision | |
223 | // | |
224 | ||
225 | `timescale 1 ns / 10 ps | |
226 | module uart_regs(clk, wb_rst_i, wb_addr_i, wb_dat_i, wb_dat_o, wb_we_i, wb_re_i, | |
227 | modem_inputs, stx_pad_o, srx_pad_i, rts_pad_o, dtr_pad_o, int_o, baud_o) | |
228 | ; | |
229 | ||
230 | input clk; | |
231 | input wb_rst_i; | |
232 | input [(3 - 1):0] wb_addr_i; | |
233 | input [7:0] wb_dat_i; | |
234 | output [7:0] wb_dat_o; | |
235 | input wb_we_i; | |
236 | input wb_re_i; | |
237 | output stx_pad_o; | |
238 | input srx_pad_i; | |
239 | input [3:0] modem_inputs; | |
240 | output rts_pad_o; | |
241 | output dtr_pad_o; | |
242 | output int_o; | |
243 | output baud_o; | |
244 | ||
245 | reg enable; | |
246 | wire srx_pad; | |
247 | reg [7:0] wb_dat_o; | |
248 | reg [3:0] ier; | |
249 | reg [3:0] iir; | |
250 | reg [1:0] fcr; | |
251 | reg [4:0] mcr; | |
252 | reg [7:0] lcr; | |
253 | reg [7:0] msr; | |
254 | reg [15:0] dl; | |
255 | reg [7:0] scratch; | |
256 | reg start_dlc; | |
257 | reg lsr_mask_d; | |
258 | reg msi_reset; | |
259 | reg [15:0] dlc; | |
260 | reg [3:0] trigger_level; | |
261 | reg rx_reset; | |
262 | reg tx_reset; | |
263 | wire dlab; | |
264 | wire cts_pad_i; | |
265 | wire dsr_pad_i; | |
266 | wire ri_pad_i; | |
267 | wire dcd_pad_i; | |
268 | wire loopback; | |
269 | wire cts; | |
270 | wire dsr; | |
271 | wire ri; | |
272 | wire dcd; | |
273 | wire cts_c; | |
274 | wire dsr_c; | |
275 | wire ri_c; | |
276 | wire dcd_c; | |
277 | reg int_o; | |
278 | wire [7:0] lsr; | |
279 | wire lsr0; | |
280 | wire lsr1; | |
281 | wire lsr2; | |
282 | wire lsr3; | |
283 | wire lsr4; | |
284 | wire lsr5; | |
285 | wire lsr6; | |
286 | wire lsr7; | |
287 | reg lsr0r; | |
288 | reg lsr1r; | |
289 | reg lsr2r; | |
290 | reg lsr3r; | |
291 | reg lsr4r; | |
292 | reg lsr5r; | |
293 | reg lsr6r; | |
294 | reg lsr7r; | |
295 | wire lsr_mask; | |
296 | wire rls_int; | |
297 | wire rda_int; | |
298 | wire ti_int; | |
299 | wire thre_int; | |
300 | wire ms_int; | |
301 | reg tf_push; | |
302 | reg rf_pop; | |
303 | wire [(11 - 1):0] rf_data_out; | |
304 | wire rf_error_bit; | |
305 | wire [(5 - 1):0] rf_count; | |
306 | wire [(5 - 1):0] tf_count; | |
307 | wire [2:0] tstate; | |
308 | wire [3:0] rstate; | |
309 | wire [9:0] counter_t; | |
310 | wire thre_set_en; | |
311 | reg [7:0] block_cnt; | |
312 | reg [7:0] block_value; | |
313 | wire serial_out; | |
314 | wire serial_in = (loopback ? serial_out : srx_pad); | |
315 | wire rf_overrun; | |
316 | wire rf_push_pulse; | |
317 | wire lsr_mask_condition; | |
318 | wire iir_read; | |
319 | wire msr_read; | |
320 | wire fifo_read; | |
321 | wire fifo_write; | |
322 | reg [3:0] delayed_modem_signals; | |
323 | reg lsr0_d; | |
324 | reg lsr1_d; | |
325 | reg lsr2_d; | |
326 | reg lsr3_d; | |
327 | reg lsr4_d; | |
328 | reg lsr5_d; | |
329 | reg lsr6_d; | |
330 | reg lsr7_d; | |
331 | reg rls_int_d; | |
332 | reg thre_int_d; | |
333 | reg ms_int_d; | |
334 | reg ti_int_d; | |
335 | reg rda_int_d; | |
336 | wire rls_int_rise; | |
337 | wire thre_int_rise; | |
338 | wire ms_int_rise; | |
339 | wire ti_int_rise; | |
340 | wire rda_int_rise; | |
341 | reg rls_int_pnd; | |
342 | reg rda_int_pnd; | |
343 | reg thre_int_pnd; | |
344 | reg ms_int_pnd; | |
345 | reg ti_int_pnd; | |
346 | ||
347 | defparam i_uart_sync_flops.width = 1; | |
348 | defparam i_uart_sync_flops.init_value = 1'b1; | |
349 | ||
350 | assign baud_o = enable; | |
351 | assign lsr[7:0] = {lsr7r, lsr6r, lsr5r, lsr4r, lsr3r, lsr2r, lsr1r, | |
352 | lsr0r}; | |
353 | assign {cts_pad_i, dsr_pad_i, ri_pad_i, dcd_pad_i} = modem_inputs; | |
354 | assign {cts, dsr, ri, dcd} = (~{cts_pad_i, dsr_pad_i, ri_pad_i, | |
355 | dcd_pad_i}); | |
356 | assign {cts_c, dsr_c, ri_c, dcd_c} = (loopback ? {mcr[1], mcr[0], | |
357 | mcr[2], mcr[3]} : {cts_pad_i, dsr_pad_i, ri_pad_i, dcd_pad_i}); | |
358 | assign dlab = lcr[7]; | |
359 | assign loopback = mcr[4]; | |
360 | assign rts_pad_o = mcr[1]; | |
361 | assign dtr_pad_o = mcr[0]; | |
362 | assign stx_pad_o = (loopback ? 1'b1 : serial_out); | |
363 | assign lsr_mask_condition = ((wb_re_i && (wb_addr_i == 3'd5)) && (!dlab) | |
364 | ); | |
365 | assign iir_read = ((wb_re_i && (wb_addr_i == 3'd2)) && (!dlab)); | |
366 | assign msr_read = ((wb_re_i && (wb_addr_i == 3'd6)) && (!dlab)); | |
367 | assign fifo_read = ((wb_re_i && (wb_addr_i == 3'b0)) && (!dlab)); | |
368 | assign fifo_write = ((wb_we_i && (wb_addr_i == 3'b0)) && (!dlab)); | |
369 | assign lsr_mask = (lsr_mask_condition && (~lsr_mask_d)); | |
370 | assign lsr0 = ((rf_count == 0) && rf_push_pulse); | |
371 | assign lsr1 = rf_overrun; | |
372 | assign lsr2 = rf_data_out[1]; | |
373 | assign lsr3 = rf_data_out[0]; | |
374 | assign lsr4 = rf_data_out[2]; | |
375 | assign lsr5 = (tf_count != 5'b01111); | |
376 | assign lsr6 = (((tf_count == 5'b0) && thre_set_en) && (tstate == 0)); | |
377 | assign lsr7 = (rf_error_bit | rf_overrun); | |
378 | assign thre_set_en = (~(|block_cnt)); | |
379 | assign rls_int = (ier[2] && (((lsr[1] || lsr[2]) || lsr[3]) || lsr[4])); | |
380 | assign rda_int = (ier[0] && (rf_count >= {1'b0, trigger_level})); | |
381 | assign thre_int = (ier[1] && lsr[5]); | |
382 | assign ms_int = (ier[3] && (|msr[3:0])); | |
383 | assign ti_int = ((ier[0] && (counter_t == 10'b0)) && (|rf_count)); | |
384 | assign rda_int_rise = (rda_int & (~rda_int_d)); | |
385 | assign rls_int_rise = (rls_int & (~rls_int_d)); | |
386 | assign thre_int_rise = (thre_int & (~thre_int_d)); | |
387 | assign ms_int_rise = (ms_int & (~ms_int_d)); | |
388 | assign ti_int_rise = (ti_int & (~ti_int_d)); | |
389 | ||
390 | uart_transmitter transmitter(clk, wb_rst_i, lcr, tf_push, wb_dat_i, | |
391 | enable, serial_out, tstate, tf_count, tx_reset, lsr_mask); | |
392 | uart_sync_flops i_uart_sync_flops( | |
393 | .rst_i (wb_rst_i), | |
394 | .clk_i (clk), | |
395 | .stage1_rst_i (1'b0), | |
396 | .stage1_clk_en_i (1'b1), | |
397 | .async_dat_i (srx_pad_i), | |
398 | .sync_dat_o (srx_pad)); | |
399 | uart_receiver receiver(clk, wb_rst_i, lcr, rf_pop, serial_in, enable, | |
400 | counter_t, rf_count, rf_data_out, rf_error_bit, rf_overrun, | |
401 | rx_reset, lsr_mask, rstate, rf_push_pulse); | |
402 | ||
403 | always @(dl or dlab or ier or iir or scratch or lcr or lsr or msr or | |
404 | rf_data_out or wb_addr_i or wb_re_i) begin | |
405 | case (wb_addr_i) | |
406 | 3'b0: | |
407 | wb_dat_o = (dlab ? dl[7:0] : rf_data_out[10:3]); | |
408 | 3'b1: | |
409 | wb_dat_o = (dlab ? dl[15:8] : ier); | |
410 | 3'd2: | |
411 | wb_dat_o = {4'b1100, iir}; | |
412 | 3'd3: | |
413 | wb_dat_o = lcr; | |
414 | 3'd5: | |
415 | wb_dat_o = lsr; | |
416 | 3'd6: | |
417 | wb_dat_o = msr; | |
418 | 3'd7: | |
419 | wb_dat_o = scratch; | |
420 | default: | |
421 | wb_dat_o = 8'b0; | |
422 | endcase | |
423 | end | |
424 | always @(posedge clk or posedge wb_rst_i) begin | |
425 | if (wb_rst_i) begin | |
426 | rf_pop <= #(1) 0; | |
427 | end | |
428 | else if (rf_pop) begin | |
429 | rf_pop <= #(1) 0; | |
430 | end | |
431 | else if ((wb_re_i && (wb_addr_i == 3'b0)) && (!dlab)) begin | |
432 | rf_pop <= #(1) 1; | |
433 | end | |
434 | end | |
435 | always @(posedge clk or posedge wb_rst_i) begin | |
436 | if (wb_rst_i) begin | |
437 | lsr_mask_d <= #(1) 0; | |
438 | end | |
439 | else begin | |
440 | lsr_mask_d <= #(1) lsr_mask_condition; | |
441 | end | |
442 | end | |
443 | always @(posedge clk or posedge wb_rst_i) begin | |
444 | if (wb_rst_i) begin | |
445 | msi_reset <= #(1) 1; | |
446 | end | |
447 | else if (msi_reset) begin | |
448 | msi_reset <= #(1) 0; | |
449 | end | |
450 | else if (msr_read) begin | |
451 | msi_reset <= #(1) 1; | |
452 | end | |
453 | end | |
454 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
455 | lcr <= #(1) 8'b00000011; | |
456 | end | |
457 | else if (wb_we_i && (wb_addr_i == 3'd3)) begin | |
458 | lcr <= #(1) wb_dat_i; | |
459 | end | |
460 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
461 | ier <= #(1) 4'b0; | |
462 | dl[15:8] <= #(1) 8'b0; | |
463 | end | |
464 | else if (wb_we_i && (wb_addr_i == 3'b1)) begin | |
465 | if (dlab) begin | |
466 | dl[15:8] <= #(1) wb_dat_i; | |
467 | end | |
468 | else begin | |
469 | ier <= #(1) wb_dat_i[3:0]; | |
470 | end | |
471 | end | |
472 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
473 | fcr <= #(1) 2'b11; | |
474 | rx_reset <= #(1) 0; | |
475 | tx_reset <= #(1) 0; | |
476 | end | |
477 | else if (wb_we_i && (wb_addr_i == 3'd2)) begin | |
478 | fcr <= #(1) wb_dat_i[7:6]; | |
479 | rx_reset <= #(1) wb_dat_i[1]; | |
480 | tx_reset <= #(1) wb_dat_i[2]; | |
481 | end | |
482 | else | |
483 | begin | |
484 | rx_reset <= #(1) 0; | |
485 | tx_reset <= #(1) 0; | |
486 | end | |
487 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
488 | mcr <= #(1) 5'b0; | |
489 | end | |
490 | else if (wb_we_i && (wb_addr_i == 3'd4)) begin | |
491 | mcr <= #(1) wb_dat_i[4:0]; | |
492 | end | |
493 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
494 | scratch <= #(1) 0; | |
495 | end | |
496 | else if (wb_we_i && (wb_addr_i == 3'd7)) begin | |
497 | scratch <= #(1) wb_dat_i; | |
498 | end | |
499 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
500 | dl[7:0] <= #(1) 8'b0; | |
501 | tf_push <= #(1) 1'b0; | |
502 | start_dlc <= #(1) 1'b0; | |
503 | end | |
504 | else if (wb_we_i && (wb_addr_i == 3'b0)) begin | |
505 | if (dlab) begin | |
506 | dl[7:0] <= #(1) wb_dat_i; | |
507 | start_dlc <= #(1) 1'b1; | |
508 | tf_push <= #(1) 1'b0; | |
509 | end | |
510 | else | |
511 | begin | |
512 | tf_push <= #(1) 1'b1; | |
513 | start_dlc <= #(1) 1'b0; | |
514 | end | |
515 | end | |
516 | else | |
517 | begin | |
518 | start_dlc <= #(1) 1'b0; | |
519 | tf_push <= #(1) 1'b0; | |
520 | end | |
521 | always @(fcr) case (fcr[1:0]) | |
522 | 2'b0: | |
523 | trigger_level = 1; | |
524 | 2'b1: | |
525 | trigger_level = 4; | |
526 | 2'b10: | |
527 | trigger_level = 8; | |
528 | 2'b11: | |
529 | trigger_level = 14; | |
530 | endcase | |
531 | always @(posedge clk or posedge wb_rst_i) begin | |
532 | if (wb_rst_i) begin | |
533 | msr <= #(1) 0; | |
534 | delayed_modem_signals[3:0] <= #(1) 0; | |
535 | end | |
536 | else | |
537 | begin | |
538 | msr[3:0] <= #(1) (msi_reset ? 4'b0 : (msr[3:0] | ({dcd, ri, dsr, | |
539 | cts} ^ delayed_modem_signals[3:0]))); | |
540 | msr[7:4] <= #(1) {dcd_c, ri_c, dsr_c, cts_c}; | |
541 | delayed_modem_signals[3:0] <= #(1) {dcd, ri, dsr, cts}; | |
542 | end | |
543 | end | |
544 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
545 | lsr0_d <= #(1) 0; | |
546 | end | |
547 | else begin | |
548 | lsr0_d <= #(1) lsr0; | |
549 | end | |
550 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
551 | lsr0r <= #(1) 0; | |
552 | end | |
553 | else begin | |
554 | lsr0r <= #(1) (((((rf_count == 1) && rf_pop) && (!rf_push_pulse)) || | |
555 | rx_reset) ? 0 : (lsr0r || (lsr0 && (~lsr0_d)))); | |
556 | end | |
557 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
558 | lsr1_d <= #(1) 0; | |
559 | end | |
560 | else begin | |
561 | lsr1_d <= #(1) lsr1; | |
562 | end | |
563 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
564 | lsr1r <= #(1) 0; | |
565 | end | |
566 | else begin | |
567 | lsr1r <= #(1) (lsr_mask ? 0 : (lsr1r || (lsr1 && (~lsr1_d)))); | |
568 | end | |
569 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
570 | lsr2_d <= #(1) 0; | |
571 | end | |
572 | else begin | |
573 | lsr2_d <= #(1) lsr2; | |
574 | end | |
575 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
576 | lsr2r <= #(1) 0; | |
577 | end | |
578 | else begin | |
579 | lsr2r <= #(1) (lsr_mask ? 0 : (lsr2r || (lsr2 && (~lsr2_d)))); | |
580 | end | |
581 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
582 | lsr3_d <= #(1) 0; | |
583 | end | |
584 | else begin | |
585 | lsr3_d <= #(1) lsr3; | |
586 | end | |
587 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
588 | lsr3r <= #(1) 0; | |
589 | end | |
590 | else begin | |
591 | lsr3r <= #(1) (lsr_mask ? 0 : (lsr3r || (lsr3 && (~lsr3_d)))); | |
592 | end | |
593 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
594 | lsr4_d <= #(1) 0; | |
595 | end | |
596 | else begin | |
597 | lsr4_d <= #(1) lsr4; | |
598 | end | |
599 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
600 | lsr4r <= #(1) 0; | |
601 | end | |
602 | else begin | |
603 | lsr4r <= #(1) (lsr_mask ? 0 : (lsr4r || (lsr4 && (~lsr4_d)))); | |
604 | end | |
605 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
606 | lsr5_d <= #(1) 1; | |
607 | end | |
608 | else begin | |
609 | lsr5_d <= #(1) lsr5; | |
610 | end | |
611 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
612 | lsr5r <= #(1) 1; | |
613 | end | |
614 | else begin | |
615 | lsr5r <= #(1) lsr5; | |
616 | end | |
617 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
618 | lsr6_d <= #(1) 1; | |
619 | end | |
620 | else begin | |
621 | lsr6_d <= #(1) lsr6; | |
622 | end | |
623 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
624 | lsr6r <= #(1) 1; | |
625 | end | |
626 | else begin | |
627 | lsr6r <= #(1) (fifo_write ? 0 : (lsr6r || (lsr6 && (~lsr6_d)))); | |
628 | end | |
629 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
630 | lsr7_d <= #(1) 0; | |
631 | end | |
632 | else begin | |
633 | lsr7_d <= #(1) lsr7; | |
634 | end | |
635 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
636 | lsr7r <= #(1) 0; | |
637 | end | |
638 | else begin | |
639 | lsr7r <= #(1) (lsr_mask ? 0 : (lsr7r || (lsr7 && (~lsr7_d)))); | |
640 | end | |
641 | always @(posedge clk or posedge wb_rst_i) begin | |
642 | if (wb_rst_i) begin | |
643 | dlc <= #(1) 0; | |
644 | end | |
645 | else if (start_dlc | (~(|dlc))) begin | |
646 | dlc <= #(1) (dl - 1); | |
647 | end | |
648 | else begin | |
649 | dlc <= #(1) (dlc - 1); | |
650 | end | |
651 | end | |
652 | always @(posedge clk or posedge wb_rst_i) begin | |
653 | if (wb_rst_i) begin | |
654 | enable <= #(1) 1'b0; | |
655 | end | |
656 | else if ((|dl) & (~(|dlc))) begin | |
657 | enable <= #(1) 1'b1; | |
658 | end | |
659 | else begin | |
660 | enable <= #(1) 1'b0; | |
661 | end | |
662 | end | |
663 | always @(lcr) case (lcr[3:0]) | |
664 | 4'b0: | |
665 | block_value = 95; | |
666 | 4'd4: | |
667 | block_value = 103; | |
668 | 4'b1, 4'd8: | |
669 | block_value = 111; | |
670 | 4'b1100: | |
671 | block_value = 119; | |
672 | 4'd2, 4'd5, 4'd9: | |
673 | block_value = 127; | |
674 | 4'd3, 4'd6, 4'd10, 4'b1101: | |
675 | block_value = 143; | |
676 | 4'd7, 4'b1011, 4'b1110: | |
677 | block_value = 159; | |
678 | 4'b1111: | |
679 | block_value = 175; | |
680 | endcase | |
681 | always @(posedge clk or posedge wb_rst_i) begin | |
682 | if (wb_rst_i) begin | |
683 | block_cnt <= #(1) 8'b0; | |
684 | end | |
685 | else if (lsr5r & fifo_write) begin | |
686 | block_cnt <= #(1) block_value; | |
687 | end | |
688 | else if (enable & (block_cnt != 8'b0)) begin | |
689 | block_cnt <= #(1) (block_cnt - 1); | |
690 | end | |
691 | end | |
692 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
693 | rls_int_d <= #(1) 0; | |
694 | end | |
695 | else begin | |
696 | rls_int_d <= #(1) rls_int; | |
697 | end | |
698 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
699 | rda_int_d <= #(1) 0; | |
700 | end | |
701 | else begin | |
702 | rda_int_d <= #(1) rda_int; | |
703 | end | |
704 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
705 | thre_int_d <= #(1) 0; | |
706 | end | |
707 | else begin | |
708 | thre_int_d <= #(1) thre_int; | |
709 | end | |
710 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
711 | ms_int_d <= #(1) 0; | |
712 | end | |
713 | else begin | |
714 | ms_int_d <= #(1) ms_int; | |
715 | end | |
716 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
717 | ti_int_d <= #(1) 0; | |
718 | end | |
719 | else begin | |
720 | ti_int_d <= #(1) ti_int; | |
721 | end | |
722 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
723 | rls_int_pnd <= #(1) 0; | |
724 | end | |
725 | else begin | |
726 | rls_int_pnd <= #(1) (lsr_mask ? 0 : (rls_int_rise ? 1 : (rls_int_pnd | |
727 | && ier[2]))); | |
728 | end | |
729 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
730 | rda_int_pnd <= #(1) 0; | |
731 | end | |
732 | else begin | |
733 | rda_int_pnd <= #(1) (((rf_count == {1'b0, trigger_level}) && fifo_read | |
734 | ) ? 0 : (rda_int_rise ? 1 : (rda_int_pnd && ier[0]))); | |
735 | end | |
736 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
737 | thre_int_pnd <= #(1) 0; | |
738 | end | |
739 | else begin | |
740 | thre_int_pnd <= #(1) ((fifo_write || ((iir_read & (~iir[0])) & ( | |
741 | iir[3:1] == 3'b1))) ? 0 : (thre_int_rise ? 1 : (thre_int_pnd | |
742 | && ier[1]))); | |
743 | end | |
744 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
745 | ms_int_pnd <= #(1) 0; | |
746 | end | |
747 | else begin | |
748 | ms_int_pnd <= #(1) (msr_read ? 0 : (ms_int_rise ? 1 : (ms_int_pnd && | |
749 | ier[3]))); | |
750 | end | |
751 | always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin | |
752 | ti_int_pnd <= #(1) 0; | |
753 | end | |
754 | else begin | |
755 | ti_int_pnd <= #(1) (fifo_read ? 0 : (ti_int_rise ? 1 : (ti_int_pnd && | |
756 | ier[0]))); | |
757 | end | |
758 | always @(posedge clk or posedge wb_rst_i) begin | |
759 | if (wb_rst_i) begin | |
760 | int_o <= #(1) 1'b0; | |
761 | end | |
762 | else begin | |
763 | int_o <= #(1) (rls_int_pnd ? (~lsr_mask) : (rda_int_pnd ? 1 : ( | |
764 | ti_int_pnd ? (~fifo_read) : (thre_int_pnd ? (!(fifo_write & | |
765 | iir_read)) : (ms_int_pnd ? (~msr_read) : 0))))); | |
766 | end | |
767 | end | |
768 | always @(posedge clk or posedge wb_rst_i) begin | |
769 | if (wb_rst_i) begin | |
770 | iir <= #(1) 1; | |
771 | end | |
772 | else if (rls_int_pnd) begin | |
773 | iir[3:1] <= #(1) 3'd3; | |
774 | iir[0] <= #(1) 1'b0; | |
775 | end | |
776 | else if (rda_int) begin | |
777 | iir[3:1] <= #(1) 3'd2; | |
778 | iir[0] <= #(1) 1'b0; | |
779 | end | |
780 | else if (ti_int_pnd) begin | |
781 | iir[3:1] <= #(1) 3'd6; | |
782 | iir[0] <= #(1) 1'b0; | |
783 | end | |
784 | else if (thre_int_pnd) begin | |
785 | iir[3:1] <= #(1) 3'b1; | |
786 | iir[0] <= #(1) 1'b0; | |
787 | end | |
788 | else if (ms_int_pnd) begin | |
789 | iir[3:1] <= #(1) 3'b0; | |
790 | iir[0] <= #(1) 1'b0; | |
791 | end | |
792 | else | |
793 | begin | |
794 | iir[3:1] <= #(1) 0; | |
795 | iir[0] <= #(1) 1'b1; | |
796 | end | |
797 | end | |
798 | endmodule |