source: XOpenSparcT1/trunk/OC-UART/uart_regs.v @ 6

Revision 6, 28.4 KB checked in by pntsvt00, 13 years ago (diff)

versione iniziale opensparc

Line 
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: not supported by cvs2svn $
65// Revision 1.41  2004/05/21 11:44:41  tadejm
66// Added synchronizer flops for RX input.
67//
68// Revision 1.40  2003/06/11 16:37:47  gorban
69// 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.
70//
71// Revision 1.39  2002/07/29 21:16:18  gorban
72// The uart_defines.v file is included again in sources.
73//
74// Revision 1.38  2002/07/22 23:02:23  gorban
75// Bug Fixes:
76//  * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
77//   Problem reported by Kenny.Tung.
78//  * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
79//
80// Improvements:
81//  * Made FIFO's as general inferrable memory where possible.
82//  So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
83//  This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
84//
85//  * Added optional baudrate output (baud_o).
86//  This is identical to BAUDOUT* signal on 16550 chip.
87//  It outputs 16xbit_clock_rate - the divided clock.
88//  It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
89//
90// Revision 1.37  2001/12/27 13:24:09  mohor
91// lsr[7] was not showing overrun errors.
92//
93// Revision 1.36  2001/12/20 13:25:46  mohor
94// rx push changed to be only one cycle wide.
95//
96// Revision 1.35  2001/12/19 08:03:34  mohor
97// Warnings cleared.
98//
99// Revision 1.34  2001/12/19 07:33:54  mohor
100// Synplicity was having troubles with the comment.
101//
102// Revision 1.33  2001/12/17 10:14:43  mohor
103// Things related to msr register changed. After THRE IRQ occurs, and one
104// character is written to the transmit fifo, the detection of the THRE bit in the
105// LSR is delayed for one character time.
106//
107// Revision 1.32  2001/12/14 13:19:24  mohor
108// MSR register fixed.
109//
110// Revision 1.31  2001/12/14 10:06:58  mohor
111// After reset modem status register MSR should be reset.
112//
113// Revision 1.30  2001/12/13 10:09:13  mohor
114// thre irq should be cleared only when being source of interrupt.
115//
116// Revision 1.29  2001/12/12 09:05:46  mohor
117// LSR status bit 0 was not cleared correctly in case of reseting the FCR (rx fifo).
118//
119// Revision 1.28  2001/12/10 19:52:41  gorban
120// Scratch register added
121//
122// Revision 1.27  2001/12/06 14:51:04  gorban
123// Bug in LSR[0] is fixed.
124// All WISHBONE signals are now sampled, so another wait-state is introduced on all transfers.
125//
126// Revision 1.26  2001/12/03 21:44:29  gorban
127// Updated specification documentation.
128// Added full 32-bit data bus interface, now as default.
129// Address is 5-bit wide in 32-bit data bus mode.
130// Added wb_sel_i input to the core. It's used in the 32-bit mode.
131// Added debug interface with two 32-bit read-only registers in 32-bit mode.
132// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
133// My small test bench is modified to work with 32-bit mode.
134//
135// Revision 1.25  2001/11/28 19:36:39  gorban
136// Fixed: timeout and break didn't pay attention to current data format when counting time
137//
138// Revision 1.24  2001/11/26 21:38:54  gorban
139// Lots of fixes:
140// Break condition wasn't handled correctly at all.
141// LSR bits could lose their values.
142// LSR value after reset was wrong.
143// Timing of THRE interrupt signal corrected.
144// LSR bit 0 timing corrected.
145//
146// Revision 1.23  2001/11/12 21:57:29  gorban
147// fixed more typo bugs
148//
149// Revision 1.22  2001/11/12 15:02:28  mohor
150// lsr1r error fixed.
151//
152// Revision 1.21  2001/11/12 14:57:27  mohor
153// ti_int_pnd error fixed.
154//
155// Revision 1.20  2001/11/12 14:50:27  mohor
156// ti_int_d error fixed.
157//
158// Revision 1.19  2001/11/10 12:43:21  gorban
159// Logic Synthesis bugs fixed. Some other minor changes
160//
161// Revision 1.18  2001/11/08 14:54:23  mohor
162// Comments in Slovene language deleted, few small fixes for better work of
163// old tools. IRQs need to be fix.
164//
165// Revision 1.17  2001/11/07 17:51:52  gorban
166// Heavily rewritten interrupt and LSR subsystems.
167// Many bugs hopefully squashed.
168//
169// Revision 1.16  2001/11/02 09:55:16  mohor
170// no message
171//
172// Revision 1.15  2001/10/31 15:19:22  gorban
173// Fixes to break and timeout conditions
174//
175// Revision 1.14  2001/10/29 17:00:46  gorban
176// fixed parity sending and tx_fifo resets over- and underrun
177//
178// Revision 1.13  2001/10/20 09:58:40  gorban
179// Small synopsis fixes
180//
181// Revision 1.12  2001/10/19 16:21:40  gorban
182// Changes data_out to be synchronous again as it should have been.
183//
184// Revision 1.11  2001/10/18 20:35:45  gorban
185// small fix
186//
187// Revision 1.10  2001/08/24 21:01:12  mohor
188// Things connected to parity changed.
189// Clock devider changed.
190//
191// Revision 1.9  2001/08/23 16:05:05  mohor
192// Stop bit bug fixed.
193// Parity bug fixed.
194// WISHBONE read cycle bug fixed,
195// OE indicator (Overrun Error) bug fixed.
196// PE indicator (Parity Error) bug fixed.
197// Register read bug fixed.
198//
199// Revision 1.10  2001/06/23 11:21:48  gorban
200// DL made 16-bit long. Fixed transmission/reception bugs.
201//
202// Revision 1.9  2001/05/31 20:08:01  gorban
203// FIFO changes and other corrections.
204//
205// Revision 1.8  2001/05/29 20:05:04  gorban
206// Fixed some bugs and synthesis problems.
207//
208// Revision 1.7  2001/05/27 17:37:49  gorban
209// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
210//
211// Revision 1.6  2001/05/21 19:12:02  gorban
212// Corrected some Linter messages.
213//
214// Revision 1.5  2001/05/17 18:34:18  gorban
215// First 'stable' release. Should be sythesizable now. Also added new header.
216//
217// Revision 1.0  2001-05-17 21:27:11+02  jacob
218// Initial revision
219//
220//
221
222// synopsys translate_off
223`include "timescale.v"
224// synopsys translate_on
225
226`include "uart_defines.v"
227
228`define UART_DL1 7:0
229`define UART_DL2 15:8
230
231module uart_regs (clk,
232        wb_rst_i, wb_addr_i, wb_dat_i, wb_dat_o, wb_we_i, wb_re_i, 
233
234// additional signals
235        modem_inputs,
236        stx_pad_o, srx_pad_i,
237
238`ifdef DATA_BUS_WIDTH_8
239`else
240// debug interface signals      enabled
241ier, iir, fcr, mcr, lcr, msr, lsr, rf_count, tf_count, tstate, rstate,
242`endif                         
243        rts_pad_o, dtr_pad_o, int_o
244`ifdef UART_HAS_BAUDRATE_OUTPUT
245        , baud_o
246`endif
247
248        );
249
250input                                                                   clk;
251input                                                                   wb_rst_i;
252input [`UART_ADDR_WIDTH-1:0]            wb_addr_i;
253input [7:0]                                                     wb_dat_i;
254output [7:0]                                                    wb_dat_o;
255input                                                                   wb_we_i;
256input                                                                   wb_re_i;
257
258output                                                                  stx_pad_o;
259input                                                                   srx_pad_i;
260
261input [3:0]                                                     modem_inputs;
262output                                                                  rts_pad_o;
263output                                                                  dtr_pad_o;
264output                                                                  int_o;
265`ifdef UART_HAS_BAUDRATE_OUTPUT
266output  baud_o;
267`endif
268
269`ifdef DATA_BUS_WIDTH_8
270`else
271// if 32-bit databus and debug interface are enabled
272output [3:0]                                                    ier;
273output [3:0]                                                    iir;
274output [1:0]                                                    fcr;  /// bits 7 and 6 of fcr. Other bits are ignored
275output [4:0]                                                    mcr;
276output [7:0]                                                    lcr;
277output [7:0]                                                    msr;
278output [7:0]                                                    lsr;
279output [`UART_FIFO_COUNTER_W-1:0]       rf_count;
280output [`UART_FIFO_COUNTER_W-1:0]       tf_count;
281output [2:0]                                                    tstate;
282output [3:0]                                                    rstate;
283
284`endif
285
286wire [3:0]                                                              modem_inputs;
287reg                                                                             enable;
288`ifdef UART_HAS_BAUDRATE_OUTPUT
289assign baud_o = enable; // baud_o is actually the enable signal
290`endif
291
292
293wire                                                                            stx_pad_o;              // received from transmitter module
294wire                                                                            srx_pad_i;
295wire                                                                            srx_pad;
296
297reg [7:0]                                                               wb_dat_o;
298
299wire [`UART_ADDR_WIDTH-1:0]             wb_addr_i;
300wire [7:0]                                                              wb_dat_i;
301
302
303reg [3:0]                                                               ier;
304reg [3:0]                                                               iir;
305reg [1:0]                                                               fcr;  /// bits 7 and 6 of fcr. Other bits are ignored
306reg [4:0]                                                               mcr;
307reg [7:0]                                                               lcr;
308reg [7:0]                                                               msr;
309reg [15:0]                                                              dl;  // 32-bit divisor latch
310reg [7:0]                                                               scratch; // UART scratch register
311reg                                                                             start_dlc; // activate dlc on writing to UART_DL1
312reg                                                                             lsr_mask_d; // delay for lsr_mask condition
313reg                                                                             msi_reset; // reset MSR 4 lower bits indicator
314//reg                                                                           threi_clear; // THRE interrupt clear flag
315reg [15:0]                                                              dlc;  // 32-bit divisor latch counter
316reg                                                                             int_o;
317
318reg [3:0]                                                               trigger_level; // trigger level of the receiver FIFO
319reg                                                                             rx_reset;
320reg                                                                             tx_reset;
321
322wire                                                                            dlab;                      // divisor latch access bit
323wire                                                                            cts_pad_i, dsr_pad_i, ri_pad_i, dcd_pad_i; // modem status bits
324wire                                                                            loopback;                  // loopback bit (MCR bit 4)
325wire                                                                            cts, dsr, ri, dcd;         // effective signals
326wire                    cts_c, dsr_c, ri_c, dcd_c; // Complement effective signals (considering loopback)
327wire                                                                            rts_pad_o, dtr_pad_o;              // modem control outputs
328
329// LSR bits wires and regs
330wire [7:0]                                                              lsr;
331wire                                                                            lsr0, lsr1, lsr2, lsr3, lsr4, lsr5, lsr6, lsr7;
332reg                                                                             lsr0r, lsr1r, lsr2r, lsr3r, lsr4r, lsr5r, lsr6r, lsr7r;
333wire                                                                            lsr_mask; // lsr_mask
334
335//
336// ASSINGS
337//
338
339assign                                                                  lsr[7:0] = { lsr7r, lsr6r, lsr5r, lsr4r, lsr3r, lsr2r, lsr1r, lsr0r };
340
341assign                                                                  {cts_pad_i, dsr_pad_i, ri_pad_i, dcd_pad_i} = modem_inputs;
342assign                                                                  {cts, dsr, ri, dcd} = ~{cts_pad_i,dsr_pad_i,ri_pad_i,dcd_pad_i};
343
344assign                  {cts_c, dsr_c, ri_c, dcd_c} = loopback ? {mcr[`UART_MC_RTS],mcr[`UART_MC_DTR],mcr[`UART_MC_OUT1],mcr[`UART_MC_OUT2]}
345                                                               : {cts_pad_i,dsr_pad_i,ri_pad_i,dcd_pad_i};
346
347assign                                                                  dlab = lcr[`UART_LC_DL];
348assign                                                                  loopback = mcr[4];
349
350// assign modem outputs
351assign                                                                  rts_pad_o = mcr[`UART_MC_RTS];
352assign                                                                  dtr_pad_o = mcr[`UART_MC_DTR];
353
354// Interrupt signals
355wire                                                                            rls_int;  // receiver line status interrupt
356wire                                                                            rda_int;  // receiver data available interrupt
357wire                                                                            ti_int;   // timeout indicator interrupt
358wire                                                                            thre_int; // transmitter holding register empty interrupt
359wire                                                                            ms_int;   // modem status interrupt
360
361// FIFO signals
362reg                                                                             tf_push;
363reg                                                                             rf_pop;
364wire [`UART_FIFO_REC_WIDTH-1:0]         rf_data_out;
365wire                                                                            rf_error_bit; // an error (parity or framing) is inside the fifo
366wire [`UART_FIFO_COUNTER_W-1:0]         rf_count;
367wire [`UART_FIFO_COUNTER_W-1:0]         tf_count;
368wire [2:0]                                                              tstate;
369wire [3:0]                                                              rstate;
370wire [9:0]                                                              counter_t;
371
372wire                      thre_set_en; // THRE status is delayed one character time when a character is written to fifo.
373reg  [7:0]                block_cnt;   // While counter counts, THRE status is blocked (delayed one character cycle)
374reg  [7:0]                block_value; // One character length minus stop bit
375
376// Transmitter Instance
377wire serial_out;
378
379uart_transmitter transmitter(clk, wb_rst_i, lcr, tf_push, wb_dat_i, enable, serial_out, tstate, tf_count, tx_reset, lsr_mask);
380
381  // Synchronizing and sampling serial RX input
382  uart_sync_flops    i_uart_sync_flops
383  (
384    .rst_i           (wb_rst_i),
385    .clk_i           (clk),
386    .stage1_rst_i    (1'b0),
387    .stage1_clk_en_i (1'b1),
388    .async_dat_i     (srx_pad_i),
389    .sync_dat_o      (srx_pad)
390  );
391  defparam i_uart_sync_flops.width      = 1;
392  defparam i_uart_sync_flops.init_value = 1'b1;
393
394// handle loopback
395wire serial_in = loopback ? serial_out : srx_pad;
396assign stx_pad_o = loopback ? 1'b1 : serial_out;
397
398// Receiver Instance
399uart_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, rx_reset, lsr_mask, rstate, rf_push_pulse);
401
402
403// Asynchronous reading here because the outputs are sampled in uart_wb.v file
404always @(dl or dlab or ier or iir or scratch
405                        or lcr or lsr or msr or rf_data_out or wb_addr_i or wb_re_i)   // asynchrounous reading
406begin
407        case (wb_addr_i)
408                `UART_REG_RB   : wb_dat_o = dlab ? dl[`UART_DL1] : rf_data_out[10:3];
409                `UART_REG_IE    : wb_dat_o = dlab ? dl[`UART_DL2] : ier;
410                `UART_REG_II    : wb_dat_o = {4'b1100,iir};
411                `UART_REG_LC    : wb_dat_o = lcr;
412                `UART_REG_LS    : wb_dat_o = lsr;
413                `UART_REG_MS    : wb_dat_o = msr;
414                `UART_REG_SR    : wb_dat_o = scratch;
415                default:  wb_dat_o = 8'b0; // ??
416        endcase // case(wb_addr_i)
417end // always @ (dl or dlab or ier or iir or scratch...
418
419
420// rf_pop signal handling
421always @(posedge clk or posedge wb_rst_i)
422begin
423        if (wb_rst_i)
424                rf_pop <= #1 0; 
425        else
426        if (rf_pop)     // restore the signal to 0 after one clock cycle
427                rf_pop <= #1 0;
428        else
429        if (wb_re_i && wb_addr_i == `UART_REG_RB && !dlab)
430                rf_pop <= #1 1; // advance read pointer
431end
432
433wire    lsr_mask_condition;
434wire    iir_read;
435wire  msr_read;
436wire    fifo_read;
437wire    fifo_write;
438
439assign lsr_mask_condition = (wb_re_i && wb_addr_i == `UART_REG_LS && !dlab);
440assign iir_read = (wb_re_i && wb_addr_i == `UART_REG_II && !dlab);
441assign msr_read = (wb_re_i && wb_addr_i == `UART_REG_MS && !dlab);
442assign fifo_read = (wb_re_i && wb_addr_i == `UART_REG_RB && !dlab);
443assign fifo_write = (wb_we_i && wb_addr_i == `UART_REG_TR && !dlab);
444
445// lsr_mask_d delayed signal handling
446always @(posedge clk or posedge wb_rst_i)
447begin
448        if (wb_rst_i)
449                lsr_mask_d <= #1 0;
450        else // reset bits in the Line Status Register
451                lsr_mask_d <= #1 lsr_mask_condition;
452end
453
454// lsr_mask is rise detected
455assign lsr_mask = lsr_mask_condition && ~lsr_mask_d;
456
457// msi_reset signal handling
458always @(posedge clk or posedge wb_rst_i)
459begin
460        if (wb_rst_i)
461                msi_reset <= #1 1;
462        else
463        if (msi_reset)
464                msi_reset <= #1 0;
465        else
466        if (msr_read)
467                msi_reset <= #1 1; // reset bits in Modem Status Register
468end
469
470
471//
472//   WRITES AND RESETS   //
473//
474// Line Control Register
475always @(posedge clk or posedge wb_rst_i)
476        if (wb_rst_i)
477                lcr <= #1 8'b00000011; // 8n1 setting
478        else
479        if (wb_we_i && wb_addr_i==`UART_REG_LC)
480                lcr <= #1 wb_dat_i;
481
482// Interrupt Enable Register or UART_DL2
483always @(posedge clk or posedge wb_rst_i)
484        if (wb_rst_i)
485        begin
486                ier <= #1 4'b0000; // no interrupts after reset
487                dl[`UART_DL2] <= #1 8'b0;
488        end
489        else
490        if (wb_we_i && wb_addr_i==`UART_REG_IE)
491                if (dlab)
492                begin
493                        dl[`UART_DL2] <= #1 wb_dat_i;
494                end
495                else
496                        ier <= #1 wb_dat_i[3:0]; // ier uses only 4 lsb
497
498
499// FIFO Control Register and rx_reset, tx_reset signals
500always @(posedge clk or posedge wb_rst_i)
501        if (wb_rst_i) begin
502                fcr <= #1 2'b11; 
503                rx_reset <= #1 0;
504                tx_reset <= #1 0;
505        end else
506        if (wb_we_i && wb_addr_i==`UART_REG_FC) begin
507                fcr <= #1 wb_dat_i[7:6];
508                rx_reset <= #1 wb_dat_i[1];
509                tx_reset <= #1 wb_dat_i[2];
510        end else begin
511                rx_reset <= #1 0;
512                tx_reset <= #1 0;
513        end
514
515// Modem Control Register
516always @(posedge clk or posedge wb_rst_i)
517        if (wb_rst_i)
518                mcr <= #1 5'b0; 
519        else
520        if (wb_we_i && wb_addr_i==`UART_REG_MC)
521                        mcr <= #1 wb_dat_i[4:0];
522
523// Scratch register
524// Line Control Register
525always @(posedge clk or posedge wb_rst_i)
526        if (wb_rst_i)
527                scratch <= #1 0; // 8n1 setting
528        else
529        if (wb_we_i && wb_addr_i==`UART_REG_SR)
530                scratch <= #1 wb_dat_i;
531
532// TX_FIFO or UART_DL1
533always @(posedge clk or posedge wb_rst_i)
534        if (wb_rst_i)
535        begin
536                dl[`UART_DL1]  <= #1 8'b0;
537                tf_push   <= #1 1'b0;
538                start_dlc <= #1 1'b0;
539        end
540        else
541        if (wb_we_i && wb_addr_i==`UART_REG_TR)
542                if (dlab)
543                begin
544                        dl[`UART_DL1] <= #1 wb_dat_i;
545                        start_dlc <= #1 1'b1; // enable DL counter
546                        tf_push <= #1 1'b0;
547                end
548                else
549                begin
550                        tf_push   <= #1 1'b1;
551                        start_dlc <= #1 1'b0;
552                end // else: !if(dlab)
553        else
554        begin
555                start_dlc <= #1 1'b0;
556                tf_push   <= #1 1'b0;
557        end // else: !if(dlab)
558
559// Receiver FIFO trigger level selection logic (asynchronous mux)
560always @(fcr)
561        case (fcr[`UART_FC_TL])
562                2'b00 : trigger_level = 1;
563                2'b01 : trigger_level = 4;
564                2'b10 : trigger_level = 8;
565                2'b11 : trigger_level = 14;
566        endcase // case(fcr[`UART_FC_TL])
567       
568//
569//  STATUS REGISTERS  //
570//
571
572// Modem Status Register
573reg [3:0] delayed_modem_signals;
574always @(posedge clk or posedge wb_rst_i)
575begin
576        if (wb_rst_i)
577          begin
578                msr <= #1 0;
579                delayed_modem_signals[3:0] <= #1 0;
580          end
581        else begin
582                msr[`UART_MS_DDCD:`UART_MS_DCTS] <= #1 msi_reset ? 4'b0 :
583                        msr[`UART_MS_DDCD:`UART_MS_DCTS] | ({dcd, ri, dsr, cts} ^ delayed_modem_signals[3:0]);
584                msr[`UART_MS_CDCD:`UART_MS_CCTS] <= #1 {dcd_c, ri_c, dsr_c, cts_c};
585                delayed_modem_signals[3:0] <= #1 {dcd, ri, dsr, cts};
586        end
587end
588
589
590// Line Status Register
591
592// activation conditions
593assign lsr0 = (rf_count==0 && rf_push_pulse);  // data in receiver fifo available set condition
594assign lsr1 = rf_overrun;     // Receiver overrun error
595assign lsr2 = rf_data_out[1]; // parity error bit
596assign lsr3 = rf_data_out[0]; // framing error bit
597assign lsr4 = rf_data_out[2]; // break error in the character
598assign lsr5 = (tf_count==5'b0 && thre_set_en);  // transmitter fifo is empty
599assign lsr6 = (tf_count==5'b0 && thre_set_en && (tstate == /*`S_IDLE */ 0)); // transmitter empty
600assign lsr7 = rf_error_bit | rf_overrun;
601
602// lsr bit0 (receiver data available)
603reg      lsr0_d;
604
605always @(posedge clk or posedge wb_rst_i)
606        if (wb_rst_i) lsr0_d <= #1 0;
607        else lsr0_d <= #1 lsr0;
608
609always @(posedge clk or posedge wb_rst_i)
610        if (wb_rst_i) lsr0r <= #1 0;
611        else lsr0r <= #1 (rf_count==1 && rf_pop && !rf_push_pulse || rx_reset) ? 0 : // deassert condition
612                                          lsr0r || (lsr0 && ~lsr0_d); // set on rise of lsr0 and keep asserted until deasserted
613
614// lsr bit 1 (receiver overrun)
615reg lsr1_d; // delayed
616
617always @(posedge clk or posedge wb_rst_i)
618        if (wb_rst_i) lsr1_d <= #1 0;
619        else lsr1_d <= #1 lsr1;
620
621always @(posedge clk or posedge wb_rst_i)
622        if (wb_rst_i) lsr1r <= #1 0;
623        else    lsr1r <= #1     lsr_mask ? 0 : lsr1r || (lsr1 && ~lsr1_d); // set on rise
624
625// lsr bit 2 (parity error)
626reg lsr2_d; // delayed
627
628always @(posedge clk or posedge wb_rst_i)
629        if (wb_rst_i) lsr2_d <= #1 0;
630        else lsr2_d <= #1 lsr2;
631
632always @(posedge clk or posedge wb_rst_i)
633        if (wb_rst_i) lsr2r <= #1 0;
634        else lsr2r <= #1 lsr_mask ? 0 : lsr2r || (lsr2 && ~lsr2_d); // set on rise
635
636// lsr bit 3 (framing error)
637reg lsr3_d; // delayed
638
639always @(posedge clk or posedge wb_rst_i)
640        if (wb_rst_i) lsr3_d <= #1 0;
641        else lsr3_d <= #1 lsr3;
642
643always @(posedge clk or posedge wb_rst_i)
644        if (wb_rst_i) lsr3r <= #1 0;
645        else lsr3r <= #1 lsr_mask ? 0 : lsr3r || (lsr3 && ~lsr3_d); // set on rise
646
647// lsr bit 4 (break indicator)
648reg lsr4_d; // delayed
649
650always @(posedge clk or posedge wb_rst_i)
651        if (wb_rst_i) lsr4_d <= #1 0;
652        else lsr4_d <= #1 lsr4;
653
654always @(posedge clk or posedge wb_rst_i)
655        if (wb_rst_i) lsr4r <= #1 0;
656        else lsr4r <= #1 lsr_mask ? 0 : lsr4r || (lsr4 && ~lsr4_d);
657
658// lsr bit 5 (transmitter fifo is empty)
659reg lsr5_d;
660
661always @(posedge clk or posedge wb_rst_i)
662        if (wb_rst_i) lsr5_d <= #1 1;
663        else lsr5_d <= #1 lsr5;
664
665always @(posedge clk or posedge wb_rst_i)
666        if (wb_rst_i) lsr5r <= #1 1;
667        else lsr5r <= #1 (fifo_write) ? 0 :  lsr5r || (lsr5 && ~lsr5_d);
668
669// lsr bit 6 (transmitter empty indicator)
670reg lsr6_d;
671
672always @(posedge clk or posedge wb_rst_i)
673        if (wb_rst_i) lsr6_d <= #1 1;
674        else lsr6_d <= #1 lsr6;
675
676always @(posedge clk or posedge wb_rst_i)
677        if (wb_rst_i) lsr6r <= #1 1;
678        else lsr6r <= #1 (fifo_write) ? 0 : lsr6r || (lsr6 && ~lsr6_d);
679
680// lsr bit 7 (error in fifo)
681reg lsr7_d;
682
683always @(posedge clk or posedge wb_rst_i)
684        if (wb_rst_i) lsr7_d <= #1 0;
685        else lsr7_d <= #1 lsr7;
686
687always @(posedge clk or posedge wb_rst_i)
688        if (wb_rst_i) lsr7r <= #1 0;
689        else lsr7r <= #1 lsr_mask ? 0 : lsr7r || (lsr7 && ~lsr7_d);
690
691// Frequency divider
692always @(posedge clk or posedge wb_rst_i) 
693begin
694        if (wb_rst_i)
695                dlc <= #1 0;
696        else
697                if (start_dlc | ~ (|dlc))
698                        dlc <= #1 dl - 1;               // preset counter
699                else
700                        dlc <= #1 dlc - 1;              // decrement counter
701end
702
703// Enable signal generation logic
704always @(posedge clk or posedge wb_rst_i)
705begin
706        if (wb_rst_i)
707                enable <= #1 1'b0;
708        else
709                if (|dl & ~(|dlc))     // dl>0 & dlc==0
710                        enable <= #1 1'b1;
711                else
712                        enable <= #1 1'b0;
713end
714
715// Delaying THRE status for one character cycle after a character is written to an empty fifo.
716always @(lcr)
717  case (lcr[3:0])
718    4'b0000                             : block_value =  95; // 6 bits
719    4'b0100                             : block_value = 103; // 6.5 bits
720    4'b0001, 4'b1000                    : block_value = 111; // 7 bits
721    4'b1100                             : block_value = 119; // 7.5 bits
722    4'b0010, 4'b0101, 4'b1001           : block_value = 127; // 8 bits
723    4'b0011, 4'b0110, 4'b1010, 4'b1101  : block_value = 143; // 9 bits
724    4'b0111, 4'b1011, 4'b1110           : block_value = 159; // 10 bits
725    4'b1111                             : block_value = 175; // 11 bits
726  endcase // case(lcr[3:0])
727
728// Counting time of one character minus stop bit
729always @(posedge clk or posedge wb_rst_i)
730begin
731  if (wb_rst_i)
732    block_cnt <= #1 8'd0;
733  else
734  if(lsr5r & fifo_write)  // THRE bit set & write to fifo occured
735    block_cnt <= #1 block_value;
736  else
737  if (enable & block_cnt != 8'b0)  // only work on enable times
738    block_cnt <= #1 block_cnt - 1;  // decrement break counter
739end // always of break condition detection
740
741// Generating THRE status enable signal
742assign thre_set_en = ~(|block_cnt);
743
744
745//
746//      INTERRUPT LOGIC
747//
748
749assign rls_int  = ier[`UART_IE_RLS] && (lsr[`UART_LS_OE] || lsr[`UART_LS_PE] || lsr[`UART_LS_FE] || lsr[`UART_LS_BI]);
750assign rda_int  = ier[`UART_IE_RDA] && (rf_count >= {1'b0,trigger_level});
751assign thre_int = ier[`UART_IE_THRE] && lsr[`UART_LS_TFE];
752assign ms_int   = ier[`UART_IE_MS] && (| msr[3:0]);
753assign ti_int   = ier[`UART_IE_RDA] && (counter_t == 10'b0) && (|rf_count);
754
755reg      rls_int_d;
756reg      thre_int_d;
757reg      ms_int_d;
758reg      ti_int_d;
759reg      rda_int_d;
760
761// delay lines
762always  @(posedge clk or posedge wb_rst_i)
763        if (wb_rst_i) rls_int_d <= #1 0;
764        else rls_int_d <= #1 rls_int;
765
766always  @(posedge clk or posedge wb_rst_i)
767        if (wb_rst_i) rda_int_d <= #1 0;
768        else rda_int_d <= #1 rda_int;
769
770always  @(posedge clk or posedge wb_rst_i)
771        if (wb_rst_i) thre_int_d <= #1 0;
772        else thre_int_d <= #1 thre_int;
773
774always  @(posedge clk or posedge wb_rst_i)
775        if (wb_rst_i) ms_int_d <= #1 0;
776        else ms_int_d <= #1 ms_int;
777
778always  @(posedge clk or posedge wb_rst_i)
779        if (wb_rst_i) ti_int_d <= #1 0;
780        else ti_int_d <= #1 ti_int;
781
782// rise detection signals
783
784wire     rls_int_rise;
785wire     thre_int_rise;
786wire     ms_int_rise;
787wire     ti_int_rise;
788wire     rda_int_rise;
789
790assign rda_int_rise    = rda_int & ~rda_int_d;
791assign rls_int_rise       = rls_int & ~rls_int_d;
792assign thre_int_rise   = thre_int & ~thre_int_d;
793assign ms_int_rise        = ms_int & ~ms_int_d;
794assign ti_int_rise        = ti_int & ~ti_int_d;
795
796// interrupt pending flags
797reg     rls_int_pnd;
798reg     rda_int_pnd;
799reg     thre_int_pnd;
800reg     ms_int_pnd;
801reg     ti_int_pnd;
802
803// interrupt pending flags assignments
804always  @(posedge clk or posedge wb_rst_i)
805        if (wb_rst_i) rls_int_pnd <= #1 0; 
806        else 
807                rls_int_pnd <= #1 lsr_mask ? 0 :                                                // reset condition
808                                                        rls_int_rise ? 1 :                                              // latch condition
809                                                        rls_int_pnd && ier[`UART_IE_RLS];       // default operation: remove if masked
810
811always  @(posedge clk or posedge wb_rst_i)
812        if (wb_rst_i) rda_int_pnd <= #1 0; 
813        else 
814                rda_int_pnd <= #1 ((rf_count == {1'b0,trigger_level}) && fifo_read) ? 0 :       // reset condition
815                                                        rda_int_rise ? 1 :                                              // latch condition
816                                                        rda_int_pnd && ier[`UART_IE_RDA];       // default operation: remove if masked
817
818always  @(posedge clk or posedge wb_rst_i)
819        if (wb_rst_i) thre_int_pnd <= #1 0; 
820        else 
821                thre_int_pnd <= #1 fifo_write || (iir_read & ~iir[`UART_II_IP] & iir[`UART_II_II] == `UART_II_THRE)? 0 : 
822                                                        thre_int_rise ? 1 :
823                                                        thre_int_pnd && ier[`UART_IE_THRE];
824
825always  @(posedge clk or posedge wb_rst_i)
826        if (wb_rst_i) ms_int_pnd <= #1 0; 
827        else 
828                ms_int_pnd <= #1 msr_read ? 0 : 
829                                                        ms_int_rise ? 1 :
830                                                        ms_int_pnd && ier[`UART_IE_MS];
831
832always  @(posedge clk or posedge wb_rst_i)
833        if (wb_rst_i) ti_int_pnd <= #1 0; 
834        else 
835                ti_int_pnd <= #1 fifo_read ? 0 : 
836                                                        ti_int_rise ? 1 :
837                                                        ti_int_pnd && ier[`UART_IE_RDA];
838// end of pending flags
839
840// INT_O logic
841always @(posedge clk or posedge wb_rst_i)
842begin
843        if (wb_rst_i)   
844                int_o <= #1 1'b0;
845        else
846                int_o <= #1 
847                                        rls_int_pnd             ?       ~lsr_mask                                       :
848                                        rda_int_pnd             ? 1                                                             :
849                                        ti_int_pnd              ? ~fifo_read                                    :
850                                        thre_int_pnd    ? !(fifo_write & iir_read) :
851                                        ms_int_pnd              ? ~msr_read                                             :
852                                        0;      // if no interrupt are pending
853end
854
855
856// Interrupt Identification register
857always @(posedge clk or posedge wb_rst_i)
858begin
859        if (wb_rst_i)
860                iir <= #1 1;
861        else
862        if (rls_int_pnd)  // interrupt is pending
863        begin
864                iir[`UART_II_II] <= #1 `UART_II_RLS;    // set identification register to correct value
865                iir[`UART_II_IP] <= #1 1'b0;            // and clear the IIR bit 0 (interrupt pending)
866        end else // the sequence of conditions determines priority of interrupt identification
867        if (rda_int)
868        begin
869                iir[`UART_II_II] <= #1 `UART_II_RDA;
870                iir[`UART_II_IP] <= #1 1'b0;
871        end
872        else if (ti_int_pnd)
873        begin
874                iir[`UART_II_II] <= #1 `UART_II_TI;
875                iir[`UART_II_IP] <= #1 1'b0;
876        end
877        else if (thre_int_pnd)
878        begin
879                iir[`UART_II_II] <= #1 `UART_II_THRE;
880                iir[`UART_II_IP] <= #1 1'b0;
881        end
882        else if (ms_int_pnd)
883        begin
884                iir[`UART_II_II] <= #1 `UART_II_MS;
885                iir[`UART_II_IP] <= #1 1'b0;
886        end else        // no interrupt is pending
887        begin
888                iir[`UART_II_II] <= #1 0;
889                iir[`UART_II_IP] <= #1 1'b1;
890        end
891end
892
893endmodule
Note: See TracBrowser for help on using the repository browser.