////////////////////////////////////////////////////////////////////// //// //// //// uart_regs.v //// //// //// //// //// //// This file is part of the "UART 16550 compatible" project //// //// http://www.opencores.org/cores/uart16550/ //// //// //// //// Documentation related to this project: //// //// - http://www.opencores.org/cores/uart16550/ //// //// //// //// Projects compatibility: //// //// - WISHBONE //// //// RS232 Protocol //// //// 16550D uart (mostly supported) //// //// //// //// Overview (main Features): //// //// Registers of the uart 16550 core //// //// //// //// Known problems (limits): //// //// Inserts 1 wait state in all WISHBONE transfers //// //// //// //// To Do: //// //// Nothing or verification. //// //// //// //// Author(s): //// //// - gorban@opencores.org //// //// - Jacob Gorban //// //// - Igor Mohor (igorm@opencores.org) //// //// //// //// Created: 2001/05/12 //// //// Last Updated: (See log for the revision history //// //// //// //// //// ////////////////////////////////////////////////////////////////////// //// //// //// Copyright (C) 2000, 2001 Authors //// //// //// //// This source file may be used and distributed without //// //// restriction provided that this copyright statement is not //// //// removed from the file and that any derivative work contains //// //// the original copyright notice and the associated disclaimer. //// //// //// //// This source file is free software; you can redistribute it //// //// and/or modify it under the terms of the GNU Lesser General //// //// Public License as published by the Free Software Foundation; //// //// either version 2.1 of the License, or (at your option) any //// //// later version. //// //// //// //// This source is distributed in the hope that it will be //// //// useful, but WITHOUT ANY WARRANTY; without even the implied //// //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// //// PURPOSE. See the GNU Lesser General Public License for more //// //// details. //// //// //// //// You should have received a copy of the GNU Lesser General //// //// Public License along with this source; if not, download it //// //// from http://www.opencores.org/lgpl.shtml //// //// //// ////////////////////////////////////////////////////////////////////// // // CVS Revision History // // $Log: uart_regs.v,v $ // Revision 1.42 2004/11/22 09:21:59 igorm // Timeout interrupt should be generated only when there is at least ony // character in the fifo. // // Revision 1.41 2004/05/21 11:44:41 tadejm // Added synchronizer flops for RX input. // // Revision 1.40 2003/06/11 16:37:47 gorban // 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. // // Revision 1.39 2002/07/29 21:16:18 gorban // The uart_defines.v file is included again in sources. // // Revision 1.38 2002/07/22 23:02:23 gorban // Bug Fixes: // * Possible loss of sync and bad reception of stop bit on slow baud rates fixed. // Problem reported by Kenny.Tung. // * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers. // // Improvements: // * Made FIFO's as general inferrable memory where possible. // So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx). // This saves about 1/3 of the Slice count and reduces P&R and synthesis times. // // * Added optional baudrate output (baud_o). // This is identical to BAUDOUT* signal on 16550 chip. // It outputs 16xbit_clock_rate - the divided clock. // It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use. // // Revision 1.37 2001/12/27 13:24:09 mohor // lsr[7] was not showing overrun errors. // // Revision 1.36 2001/12/20 13:25:46 mohor // rx push changed to be only one cycle wide. // // Revision 1.35 2001/12/19 08:03:34 mohor // Warnings cleared. // // Revision 1.34 2001/12/19 07:33:54 mohor // Synplicity was having troubles with the comment. // // Revision 1.33 2001/12/17 10:14:43 mohor // Things related to msr register changed. After THRE IRQ occurs, and one // character is written to the transmit fifo, the detection of the THRE bit in the // LSR is delayed for one character time. // // Revision 1.32 2001/12/14 13:19:24 mohor // MSR register fixed. // // Revision 1.31 2001/12/14 10:06:58 mohor // After reset modem status register MSR should be reset. // // Revision 1.30 2001/12/13 10:09:13 mohor // thre irq should be cleared only when being source of interrupt. // // Revision 1.29 2001/12/12 09:05:46 mohor // LSR status bit 0 was not cleared correctly in case of reseting the FCR (rx fifo). // // Revision 1.28 2001/12/10 19:52:41 gorban // Scratch register added // // Revision 1.27 2001/12/06 14:51:04 gorban // Bug in LSR[0] is fixed. // All WISHBONE signals are now sampled, so another wait-state is introduced on all transfers. // // Revision 1.26 2001/12/03 21:44:29 gorban // Updated specification documentation. // Added full 32-bit data bus interface, now as default. // Address is 5-bit wide in 32-bit data bus mode. // Added wb_sel_i input to the core. It's used in the 32-bit mode. // Added debug interface with two 32-bit read-only registers in 32-bit mode. // Bits 5 and 6 of LSR are now only cleared on TX FIFO write. // My small test bench is modified to work with 32-bit mode. // // Revision 1.25 2001/11/28 19:36:39 gorban // Fixed: timeout and break didn't pay attention to current data format when counting time // // Revision 1.24 2001/11/26 21:38:54 gorban // Lots of fixes: // Break condition wasn't handled correctly at all. // LSR bits could lose their values. // LSR value after reset was wrong. // Timing of THRE interrupt signal corrected. // LSR bit 0 timing corrected. // // Revision 1.23 2001/11/12 21:57:29 gorban // fixed more typo bugs // // Revision 1.22 2001/11/12 15:02:28 mohor // lsr1r error fixed. // // Revision 1.21 2001/11/12 14:57:27 mohor // ti_int_pnd error fixed. // // Revision 1.20 2001/11/12 14:50:27 mohor // ti_int_d error fixed. // // Revision 1.19 2001/11/10 12:43:21 gorban // Logic Synthesis bugs fixed. Some other minor changes // // Revision 1.18 2001/11/08 14:54:23 mohor // Comments in Slovene language deleted, few small fixes for better work of // old tools. IRQs need to be fix. // // Revision 1.17 2001/11/07 17:51:52 gorban // Heavily rewritten interrupt and LSR subsystems. // Many bugs hopefully squashed. // // Revision 1.16 2001/11/02 09:55:16 mohor // no message // // Revision 1.15 2001/10/31 15:19:22 gorban // Fixes to break and timeout conditions // // Revision 1.14 2001/10/29 17:00:46 gorban // fixed parity sending and tx_fifo resets over- and underrun // // Revision 1.13 2001/10/20 09:58:40 gorban // Small synopsis fixes // // Revision 1.12 2001/10/19 16:21:40 gorban // Changes data_out to be synchronous again as it should have been. // // Revision 1.11 2001/10/18 20:35:45 gorban // small fix // // Revision 1.10 2001/08/24 21:01:12 mohor // Things connected to parity changed. // Clock devider changed. // // Revision 1.9 2001/08/23 16:05:05 mohor // Stop bit bug fixed. // Parity bug fixed. // WISHBONE read cycle bug fixed, // OE indicator (Overrun Error) bug fixed. // PE indicator (Parity Error) bug fixed. // Register read bug fixed. // // Revision 1.10 2001/06/23 11:21:48 gorban // DL made 16-bit long. Fixed transmission/reception bugs. // // Revision 1.9 2001/05/31 20:08:01 gorban // FIFO changes and other corrections. // // Revision 1.8 2001/05/29 20:05:04 gorban // Fixed some bugs and synthesis problems. // // Revision 1.7 2001/05/27 17:37:49 gorban // Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file. // // Revision 1.6 2001/05/21 19:12:02 gorban // Corrected some Linter messages. // // Revision 1.5 2001/05/17 18:34:18 gorban // First 'stable' release. Should be sythesizable now. Also added new header. // // Revision 1.0 2001-05-17 21:27:11+02 jacob // Initial revision // `timescale 1 ns / 10 ps module uart_regs(clk, wb_rst_i, wb_addr_i, wb_dat_i, wb_dat_o, wb_we_i, wb_re_i, modem_inputs, stx_pad_o, srx_pad_i, rts_pad_o, dtr_pad_o, int_o, baud_o) ; input clk; input wb_rst_i; input [(3 - 1):0] wb_addr_i; input [7:0] wb_dat_i; output [7:0] wb_dat_o; input wb_we_i; input wb_re_i; output stx_pad_o; input srx_pad_i; input [3:0] modem_inputs; output rts_pad_o; output dtr_pad_o; output int_o; output baud_o; reg enable; wire srx_pad; reg [7:0] wb_dat_o; reg [3:0] ier; reg [3:0] iir; reg [1:0] fcr; reg [4:0] mcr; reg [7:0] lcr; reg [7:0] msr; reg [15:0] dl; reg [7:0] scratch; reg start_dlc; reg lsr_mask_d; reg msi_reset; reg [15:0] dlc; reg [3:0] trigger_level; reg rx_reset; reg tx_reset; wire dlab; wire cts_pad_i; wire dsr_pad_i; wire ri_pad_i; wire dcd_pad_i; wire loopback; wire cts; wire dsr; wire ri; wire dcd; wire cts_c; wire dsr_c; wire ri_c; wire dcd_c; reg int_o; wire [7:0] lsr; wire lsr0; wire lsr1; wire lsr2; wire lsr3; wire lsr4; wire lsr5; wire lsr6; wire lsr7; reg lsr0r; reg lsr1r; reg lsr2r; reg lsr3r; reg lsr4r; reg lsr5r; reg lsr6r; reg lsr7r; wire lsr_mask; wire rls_int; wire rda_int; wire ti_int; wire thre_int; wire ms_int; reg tf_push; reg rf_pop; wire [(11 - 1):0] rf_data_out; wire rf_error_bit; wire [(5 - 1):0] rf_count; wire [(5 - 1):0] tf_count; wire [2:0] tstate; wire [3:0] rstate; wire [9:0] counter_t; wire thre_set_en; reg [7:0] block_cnt; reg [7:0] block_value; wire serial_out; wire serial_in = (loopback ? serial_out : srx_pad); wire rf_overrun; wire rf_push_pulse; wire lsr_mask_condition; wire iir_read; wire msr_read; wire fifo_read; wire fifo_write; reg [3:0] delayed_modem_signals; reg lsr0_d; reg lsr1_d; reg lsr2_d; reg lsr3_d; reg lsr4_d; reg lsr5_d; reg lsr6_d; reg lsr7_d; reg rls_int_d; reg thre_int_d; reg ms_int_d; reg ti_int_d; reg rda_int_d; wire rls_int_rise; wire thre_int_rise; wire ms_int_rise; wire ti_int_rise; wire rda_int_rise; reg rls_int_pnd; reg rda_int_pnd; reg thre_int_pnd; reg ms_int_pnd; reg ti_int_pnd; defparam i_uart_sync_flops.width = 1; defparam i_uart_sync_flops.init_value = 1'b1; assign baud_o = enable; assign lsr[7:0] = {lsr7r, lsr6r, lsr5r, lsr4r, lsr3r, lsr2r, lsr1r, lsr0r}; assign {cts_pad_i, dsr_pad_i, ri_pad_i, dcd_pad_i} = modem_inputs; assign {cts, dsr, ri, dcd} = (~{cts_pad_i, dsr_pad_i, ri_pad_i, dcd_pad_i}); assign {cts_c, dsr_c, ri_c, dcd_c} = (loopback ? {mcr[1], mcr[0], mcr[2], mcr[3]} : {cts_pad_i, dsr_pad_i, ri_pad_i, dcd_pad_i}); assign dlab = lcr[7]; assign loopback = mcr[4]; assign rts_pad_o = mcr[1]; assign dtr_pad_o = mcr[0]; assign stx_pad_o = (loopback ? 1'b1 : serial_out); assign lsr_mask_condition = ((wb_re_i && (wb_addr_i == 3'd5)) && (!dlab) ); assign iir_read = ((wb_re_i && (wb_addr_i == 3'd2)) && (!dlab)); assign msr_read = ((wb_re_i && (wb_addr_i == 3'd6)) && (!dlab)); assign fifo_read = ((wb_re_i && (wb_addr_i == 3'b0)) && (!dlab)); assign fifo_write = ((wb_we_i && (wb_addr_i == 3'b0)) && (!dlab)); assign lsr_mask = (lsr_mask_condition && (~lsr_mask_d)); assign lsr0 = ((rf_count == 0) && rf_push_pulse); assign lsr1 = rf_overrun; assign lsr2 = rf_data_out[1]; assign lsr3 = rf_data_out[0]; assign lsr4 = rf_data_out[2]; assign lsr5 = (tf_count != 5'b01111); assign lsr6 = (((tf_count == 5'b0) && thre_set_en) && (tstate == 0)); assign lsr7 = (rf_error_bit | rf_overrun); assign thre_set_en = (~(|block_cnt)); assign rls_int = (ier[2] && (((lsr[1] || lsr[2]) || lsr[3]) || lsr[4])); assign rda_int = (ier[0] && (rf_count >= {1'b0, trigger_level})); assign thre_int = (ier[1] && lsr[5]); assign ms_int = (ier[3] && (|msr[3:0])); assign ti_int = ((ier[0] && (counter_t == 10'b0)) && (|rf_count)); assign rda_int_rise = (rda_int & (~rda_int_d)); assign rls_int_rise = (rls_int & (~rls_int_d)); assign thre_int_rise = (thre_int & (~thre_int_d)); assign ms_int_rise = (ms_int & (~ms_int_d)); assign ti_int_rise = (ti_int & (~ti_int_d)); uart_transmitter transmitter(clk, wb_rst_i, lcr, tf_push, wb_dat_i, enable, serial_out, tstate, tf_count, tx_reset, lsr_mask); uart_sync_flops i_uart_sync_flops( .rst_i (wb_rst_i), .clk_i (clk), .stage1_rst_i (1'b0), .stage1_clk_en_i (1'b1), .async_dat_i (srx_pad_i), .sync_dat_o (srx_pad)); uart_receiver receiver(clk, wb_rst_i, lcr, rf_pop, serial_in, enable, counter_t, rf_count, rf_data_out, rf_error_bit, rf_overrun, rx_reset, lsr_mask, rstate, rf_push_pulse); always @(dl or dlab or ier or iir or scratch or lcr or lsr or msr or rf_data_out or wb_addr_i or wb_re_i) begin case (wb_addr_i) 3'b0: wb_dat_o = (dlab ? dl[7:0] : rf_data_out[10:3]); 3'b1: wb_dat_o = (dlab ? dl[15:8] : ier); 3'd2: wb_dat_o = {4'b1100, iir}; 3'd3: wb_dat_o = lcr; 3'd5: wb_dat_o = lsr; 3'd6: wb_dat_o = msr; 3'd7: wb_dat_o = scratch; default: wb_dat_o = 8'b0; endcase end always @(posedge clk or posedge wb_rst_i) begin if (wb_rst_i) begin rf_pop <= #(1) 0; end else if (rf_pop) begin rf_pop <= #(1) 0; end else if ((wb_re_i && (wb_addr_i == 3'b0)) && (!dlab)) begin rf_pop <= #(1) 1; end end always @(posedge clk or posedge wb_rst_i) begin if (wb_rst_i) begin lsr_mask_d <= #(1) 0; end else begin lsr_mask_d <= #(1) lsr_mask_condition; end end always @(posedge clk or posedge wb_rst_i) begin if (wb_rst_i) begin msi_reset <= #(1) 1; end else if (msi_reset) begin msi_reset <= #(1) 0; end else if (msr_read) begin msi_reset <= #(1) 1; end end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin lcr <= #(1) 8'b00000011; end else if (wb_we_i && (wb_addr_i == 3'd3)) begin lcr <= #(1) wb_dat_i; end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin ier <= #(1) 4'b0; dl[15:8] <= #(1) 8'b0; end else if (wb_we_i && (wb_addr_i == 3'b1)) begin if (dlab) begin dl[15:8] <= #(1) wb_dat_i; end else begin ier <= #(1) wb_dat_i[3:0]; end end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin fcr <= #(1) 2'b11; rx_reset <= #(1) 0; tx_reset <= #(1) 0; end else if (wb_we_i && (wb_addr_i == 3'd2)) begin fcr <= #(1) wb_dat_i[7:6]; rx_reset <= #(1) wb_dat_i[1]; tx_reset <= #(1) wb_dat_i[2]; end else begin rx_reset <= #(1) 0; tx_reset <= #(1) 0; end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin mcr <= #(1) 5'b0; end else if (wb_we_i && (wb_addr_i == 3'd4)) begin mcr <= #(1) wb_dat_i[4:0]; end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin scratch <= #(1) 0; end else if (wb_we_i && (wb_addr_i == 3'd7)) begin scratch <= #(1) wb_dat_i; end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin dl[7:0] <= #(1) 8'b0; tf_push <= #(1) 1'b0; start_dlc <= #(1) 1'b0; end else if (wb_we_i && (wb_addr_i == 3'b0)) begin if (dlab) begin dl[7:0] <= #(1) wb_dat_i; start_dlc <= #(1) 1'b1; tf_push <= #(1) 1'b0; end else begin tf_push <= #(1) 1'b1; start_dlc <= #(1) 1'b0; end end else begin start_dlc <= #(1) 1'b0; tf_push <= #(1) 1'b0; end always @(fcr) case (fcr[1:0]) 2'b0: trigger_level = 1; 2'b1: trigger_level = 4; 2'b10: trigger_level = 8; 2'b11: trigger_level = 14; endcase always @(posedge clk or posedge wb_rst_i) begin if (wb_rst_i) begin msr <= #(1) 0; delayed_modem_signals[3:0] <= #(1) 0; end else begin msr[3:0] <= #(1) (msi_reset ? 4'b0 : (msr[3:0] | ({dcd, ri, dsr, cts} ^ delayed_modem_signals[3:0]))); msr[7:4] <= #(1) {dcd_c, ri_c, dsr_c, cts_c}; delayed_modem_signals[3:0] <= #(1) {dcd, ri, dsr, cts}; end end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin lsr0_d <= #(1) 0; end else begin lsr0_d <= #(1) lsr0; end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin lsr0r <= #(1) 0; end else begin lsr0r <= #(1) (((((rf_count == 1) && rf_pop) && (!rf_push_pulse)) || rx_reset) ? 0 : (lsr0r || (lsr0 && (~lsr0_d)))); end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin lsr1_d <= #(1) 0; end else begin lsr1_d <= #(1) lsr1; end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin lsr1r <= #(1) 0; end else begin lsr1r <= #(1) (lsr_mask ? 0 : (lsr1r || (lsr1 && (~lsr1_d)))); end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin lsr2_d <= #(1) 0; end else begin lsr2_d <= #(1) lsr2; end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin lsr2r <= #(1) 0; end else begin lsr2r <= #(1) (lsr_mask ? 0 : (lsr2r || (lsr2 && (~lsr2_d)))); end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin lsr3_d <= #(1) 0; end else begin lsr3_d <= #(1) lsr3; end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin lsr3r <= #(1) 0; end else begin lsr3r <= #(1) (lsr_mask ? 0 : (lsr3r || (lsr3 && (~lsr3_d)))); end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin lsr4_d <= #(1) 0; end else begin lsr4_d <= #(1) lsr4; end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin lsr4r <= #(1) 0; end else begin lsr4r <= #(1) (lsr_mask ? 0 : (lsr4r || (lsr4 && (~lsr4_d)))); end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin lsr5_d <= #(1) 1; end else begin lsr5_d <= #(1) lsr5; end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin lsr5r <= #(1) 1; end else begin lsr5r <= #(1) lsr5; end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin lsr6_d <= #(1) 1; end else begin lsr6_d <= #(1) lsr6; end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin lsr6r <= #(1) 1; end else begin lsr6r <= #(1) (fifo_write ? 0 : (lsr6r || (lsr6 && (~lsr6_d)))); end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin lsr7_d <= #(1) 0; end else begin lsr7_d <= #(1) lsr7; end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin lsr7r <= #(1) 0; end else begin lsr7r <= #(1) (lsr_mask ? 0 : (lsr7r || (lsr7 && (~lsr7_d)))); end always @(posedge clk or posedge wb_rst_i) begin if (wb_rst_i) begin dlc <= #(1) 0; end else if (start_dlc | (~(|dlc))) begin dlc <= #(1) (dl - 1); end else begin dlc <= #(1) (dlc - 1); end end always @(posedge clk or posedge wb_rst_i) begin if (wb_rst_i) begin enable <= #(1) 1'b0; end else if ((|dl) & (~(|dlc))) begin enable <= #(1) 1'b1; end else begin enable <= #(1) 1'b0; end end always @(lcr) case (lcr[3:0]) 4'b0: block_value = 95; 4'd4: block_value = 103; 4'b1, 4'd8: block_value = 111; 4'b1100: block_value = 119; 4'd2, 4'd5, 4'd9: block_value = 127; 4'd3, 4'd6, 4'd10, 4'b1101: block_value = 143; 4'd7, 4'b1011, 4'b1110: block_value = 159; 4'b1111: block_value = 175; endcase always @(posedge clk or posedge wb_rst_i) begin if (wb_rst_i) begin block_cnt <= #(1) 8'b0; end else if (lsr5r & fifo_write) begin block_cnt <= #(1) block_value; end else if (enable & (block_cnt != 8'b0)) begin block_cnt <= #(1) (block_cnt - 1); end end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin rls_int_d <= #(1) 0; end else begin rls_int_d <= #(1) rls_int; end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin rda_int_d <= #(1) 0; end else begin rda_int_d <= #(1) rda_int; end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin thre_int_d <= #(1) 0; end else begin thre_int_d <= #(1) thre_int; end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin ms_int_d <= #(1) 0; end else begin ms_int_d <= #(1) ms_int; end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin ti_int_d <= #(1) 0; end else begin ti_int_d <= #(1) ti_int; end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin rls_int_pnd <= #(1) 0; end else begin rls_int_pnd <= #(1) (lsr_mask ? 0 : (rls_int_rise ? 1 : (rls_int_pnd && ier[2]))); end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin rda_int_pnd <= #(1) 0; end else begin rda_int_pnd <= #(1) (((rf_count == {1'b0, trigger_level}) && fifo_read ) ? 0 : (rda_int_rise ? 1 : (rda_int_pnd && ier[0]))); end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin thre_int_pnd <= #(1) 0; end else begin thre_int_pnd <= #(1) ((fifo_write || ((iir_read & (~iir[0])) & ( iir[3:1] == 3'b1))) ? 0 : (thre_int_rise ? 1 : (thre_int_pnd && ier[1]))); end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin ms_int_pnd <= #(1) 0; end else begin ms_int_pnd <= #(1) (msr_read ? 0 : (ms_int_rise ? 1 : (ms_int_pnd && ier[3]))); end always @(posedge clk or posedge wb_rst_i) if (wb_rst_i) begin ti_int_pnd <= #(1) 0; end else begin ti_int_pnd <= #(1) (fifo_read ? 0 : (ti_int_rise ? 1 : (ti_int_pnd && ier[0]))); end always @(posedge clk or posedge wb_rst_i) begin if (wb_rst_i) begin int_o <= #(1) 1'b0; end else begin int_o <= #(1) (rls_int_pnd ? (~lsr_mask) : (rda_int_pnd ? 1 : ( ti_int_pnd ? (~fifo_read) : (thre_int_pnd ? (!(fifo_write & iir_read)) : (ms_int_pnd ? (~msr_read) : 0))))); end end always @(posedge clk or posedge wb_rst_i) begin if (wb_rst_i) begin iir <= #(1) 1; end else if (rls_int_pnd) begin iir[3:1] <= #(1) 3'd3; iir[0] <= #(1) 1'b0; end else if (rda_int) begin iir[3:1] <= #(1) 3'd2; iir[0] <= #(1) 1'b0; end else if (ti_int_pnd) begin iir[3:1] <= #(1) 3'd6; iir[0] <= #(1) 1'b0; end else if (thre_int_pnd) begin iir[3:1] <= #(1) 3'b1; iir[0] <= #(1) 1'b0; end else if (ms_int_pnd) begin iir[3:1] <= #(1) 3'b0; iir[0] <= #(1) 1'b0; end else begin iir[3:1] <= #(1) 0; iir[0] <= #(1) 1'b1; end end endmodule