OpenCores
URL https://opencores.org/ocsvn/systemverilog-uart16550/systemverilog-uart16550/trunk

Subversion Repositories systemverilog-uart16550

[/] [systemverilog-uart16550/] [trunk/] [rtl/] [uart_register.sv] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 hiroshi
/* *****************************************************************************
2
   * title:         uart_16550_rll module                                      *
3
   * description:   RS232 Protocol 16550D uart (mostly supported)              *
4
   * languages:     systemVerilog                                              *
5
   *                                                                           *
6
   * Copyright (C) 2010 miyagi.hiroshi                                         *
7
   *                                                                           *
8
   * This library is free software; you can redistribute it and/or             *
9
   * modify it under the terms of the GNU Lesser General Public                *
10
   * License as published by the Free Software Foundation; either              *
11
   * version 2.1 of the License, or (at your option) any later version.        *
12
   *                                                                           *
13
   * This library is distributed in the hope that it will be useful,           *
14
   * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
15
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
16
   * Lesser General Public License for more details.                           *
17
   *                                                                           *
18
   * You should have received a copy of the GNU Lesser General Public          *
19
   * License along with this library; if not, write to the Free Software       *
20
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111*1307  USA *
21
   *                                                                           *
22
   *         ***  GNU LESSER GENERAL PUBLIC LICENSE  ***                       *
23
   *           from http://www.gnu.org/licenses/lgpl.txt                       *
24
   *****************************************************************************
25
   *                            redleaflogic,ltd                               *
26
   *                    miyagi.hiroshi@redleaflogic.biz                        *
27
   *          $Id: uart_register.sv 108 2010-03-30 02:56:26Z hiroshi $         *
28
   ***************************************************************************** */
29
 
30
`ifdef SYN
31
/* empty */
32
`else
33
timeunit      1ps ;
34
timeprecision 1ps ;
35
`endif
36
 
37
import uart_package:: * ;
38
module uart_register
39
  (
40
   input wire     clk_i,
41
   input wire     nrst_i,
42
   wb_bus         wb_bus,
43
   uart_bus       uart_bus,
44
   output u_reg_t u_reg,
45
   fifo_bus       fifo_pop_trans,
46
   fifo_bus       fifo_push_rec,
47
   input wire     timeout_signal,
48
   input wire     overrun,
49
   input wire     rec_buf_empty,
50
   input wire     trans_buf_empty
51
   ) ;
52
 
53
   localparam   WRITE                  = 1'b1 ;
54
   localparam   READ                   = 1'b0 ;
55
   localparam   ENABLE                 = 1'b1 ;
56
   localparam   DISABLE                = 1'b0 ;
57
 
58
   fifo_bus
59
     fifo_pop_rec(.clk_i(clk_i)),
60
     fifo_push_trans(.clk_i(clk_i)) ;
61
 
62
   logic [31:0]   rdat ;
63
 
64
   wire [31:0]    dat_i  = wb_bus.dat_i ;
65
   wire           we_i   = wb_bus.we_i ;
66
 
67
`ifdef ALIGN_4B
68
   wire           uart_stb = wb_bus.cyc_i == 1'b1 && wb_bus.stb_i == 1'b1 && wb_bus.sel_i == 4'b1111 ;
69
   wire           stb_rxd_fifo = uart_stb == 1'b1 && wb_bus.adr_i[4:2] == UART_RXD && u_reg.line_control_reg.divisor_access == 1'b0 ;
70
   wire           stb_txd_fifo = uart_stb == 1'b1 && wb_bus.adr_i[4:2] == UART_TXD && u_reg.line_control_reg.divisor_access == 1'b0 ;
71
   wire           stb_interrupt_enable_reg  = uart_stb == 1'b1 && wb_bus.adr_i[4:2] == UART_INTERRUPT_ENABLE ;
72
   wire           stb_interrupt_ident_reg   = uart_stb == 1'b1 && wb_bus.adr_i[4:2] == UART_INTERRUPT_IDENT ;
73
   wire           stb_fifo_control_reg      = uart_stb == 1'b1 && wb_bus.adr_i[4:2] == UART_FIFO_CONTROL ;
74
   wire           stb_line_control_reg      = uart_stb == 1'b1 && wb_bus.adr_i[4:2] == UART_LINE_CONTROL ;
75
   wire           stb_modem_control_reg     = uart_stb == 1'b1 && wb_bus.adr_i[4:2] == UART_MODEM_CONTROL ;
76
   wire           stb_line_status_reg       = uart_stb == 1'b1 && wb_bus.adr_i[4:2] == UART_LINE_STATUS ;
77
   wire           stb_modem_status_reg      = uart_stb == 1'b1 && wb_bus.adr_i[4:2] == UART_MODEM_STATUS ;
78
   wire           stb_scratch_reg           = uart_stb == 1'b1 && wb_bus.adr_i[4:2] == UART_SCRATCH ;
79
   wire           stb_baud_reg = uart_stb == 1'b1 && wb_bus.adr_i[4:2] == UART_BAUD && u_reg.line_control_reg.divisor_access == 1'b1 ;
80
`else
81
   wire           uart_stb = wb_bus.cyc_i == 1'b1 && wb_bus.stb_i == 1'b1 ;
82
   wire           stb_rxd_fifo = wb_bus.sel_i[0] == 1'b1 && uart_stb == 1'b1 && wb_bus.adr_i[2:0] == UART_RXD && u_reg.line_control_reg.divisor_access == 1'b0 ;
83
   wire           stb_txd_fifo = wb_bus.sel_i[0] == 1'b1 && uart_stb == 1'b1 && wb_bus.adr_i[2:0] == UART_TXD && u_reg.line_control_reg.divisor_access == 1'b0 ;
84
   wire           stb_interrupt_enable_reg  = wb_bus.sel_i[1] == 1'b1 && uart_stb == 1'b1 && wb_bus.adr_i[2:0] == UART_INTERRUPT_ENABLE ;
85
   wire           stb_interrupt_ident_reg   = wb_bus.sel_i[2] == 1'b1 && uart_stb == 1'b1 && wb_bus.adr_i[2:0] == UART_INTERRUPT_IDENT ;
86
   wire           stb_fifo_control_reg      = wb_bus.sel_i[2] == 1'b1 && uart_stb == 1'b1 && wb_bus.adr_i[2:0] == UART_FIFO_CONTROL ;
87
   wire           stb_line_control_reg      = wb_bus.sel_i[3] == 1'b1 && uart_stb == 1'b1 && wb_bus.adr_i[2:0] == UART_LINE_CONTROL ;
88
   wire           stb_modem_control_reg     = wb_bus.sel_i[0] == 1'b1 && uart_stb == 1'b1 && wb_bus.adr_i[2:0] == UART_MODEM_CONTROL ;
89
   wire           stb_line_status_reg       = wb_bus.sel_i[1] == 1'b1 && uart_stb == 1'b1 && wb_bus.adr_i[2:0] == UART_LINE_STATUS ;
90
   wire           stb_modem_status_reg      = wb_bus.sel_i[2] == 1'b1 && uart_stb == 1'b1 && wb_bus.adr_i[2:0] == UART_MODEM_STATUS ;
91
   wire           stb_scratch_reg           = wb_bus.sel_i[3] == 1'b1 && uart_stb == 1'b1 && wb_bus.adr_i[2:0] == UART_SCRATCH ;
92
   wire           stb_baud_reg = wb_bus.sel_i[0] == 1'b1 && uart_stb == 1'b1 && wb_bus.adr_i[2:0] == UART_BAUD && u_reg.line_control_reg.divisor_access == 1'b1 ;
93
`endif
94
   // -- assign wb_bus.intr_o = u_reg.interrupt_identification.intr_active == 1'b1 ;
95
   assign wb_bus.intr_o = u_reg.interrupt_pending_reg.modem_status ||
96
                          u_reg.interrupt_pending_reg.transmitter_holding_register_empty ||
97
                          u_reg.interrupt_pending_reg.timeout_indication ||
98
                          u_reg.interrupt_pending_reg.receiver_data_available ||
99
                          u_reg.interrupt_pending_reg.receiver_line_status ;
100
 
101
   assign wb_bus.dat_o  = rdat ;
102
   assign wb_bus.ack_o  = uart_stb == 1'b1 ; // no wait
103
   assign dat_i         = wb_bus.dat_i ;
104
 
105
   // -- uart line :: read for manual -> 4.6 Modem Control Register (MCR) --
106
   assign uart_bus.dtr_o = u_reg.modem_control_reg.dtr == 1'b0 ;
107
   assign uart_bus.rts_o = u_reg.modem_control_reg.rts == 1'b0 ;
108
 
109
   wire           cts = u_reg.modem_control_reg.loopback == 1'b1 ? uart_bus.rts_o : uart_bus.cts_i == 1'b0 ;
110
   wire           dsr = u_reg.modem_control_reg.loopback == 1'b1 ? uart_bus.dtr_o : uart_bus.dsr_i == 1'b0 ;
111
   wire           ri  = u_reg.modem_control_reg.loopback == 1'b1 ? u_reg.modem_control_reg.out1 : uart_bus.ri_i == 1'b0 ;
112
   wire           dcd = u_reg.modem_control_reg.loopback == 1'b1 ? u_reg.modem_control_reg.out2 : uart_bus.dcd_i == 1'b0 ;
113
 
114
`ifdef ALIGN_4B
115
   // -- data read selector --
116
   always_comb begin
117
      unique case ({
118
                    stb_baud_reg,
119
                    stb_scratch_reg,
120
                    stb_rxd_fifo,
121
                    stb_interrupt_enable_reg,
122
                    stb_interrupt_ident_reg,
123
                    stb_line_control_reg,
124
                    stb_modem_control_reg,
125
                    stb_line_status_reg,
126
                    stb_modem_status_reg
127
                    })
128
        9'h100 : rdat = {24'h0, u_reg.baud_reg} ;
129
        9'h080 : rdat = {24'h0, u_reg.scratch_reg} ;
130
        9'h040 : rdat = {24'h0, fifo_pop_rec.pop_dat[7:0]} ;
131
        9'h020 : rdat = {24'h0, u_reg.interrupt_enable_reg} ;
132
        9'h010 : rdat = {24'h0, u_reg.interrupt_ident_reg} ;
133
        9'h008 : rdat = {24'h0, u_reg.line_control_reg} ;
134
        9'h004 : rdat = {24'h0, u_reg.modem_control_reg} ;
135
        9'h002 : rdat = {24'h0, u_reg.line_status_reg} ;
136
        9'h001 : rdat = {24'h0, u_reg.modem_status_reg} ;
137
        default : rdat = 32'h0 ;
138
      endcase
139
   end
140
`else // ALINE_1B
141
   assign rdat[7:0]  =  stb_rxd_fifo == 1'b1             ? fifo_pop_rec.pop_dat[7:0]  : 8'h0 |
142
                        stb_baud_reg == 1'b1             ? u_reg.baud_reg             : 8'h0 ;
143
   assign rdat[15:8] =  stb_interrupt_enable_reg == 1'b1 ? u_reg.interrupt_enable_reg : 8'h0 |
144
                        stb_line_status_reg == 1'b1      ? u_reg.line_status_reg      : 8'h0 ;
145
   assign rdat[23:16] = stb_interrupt_ident_reg          ? u_reg.interrupt_ident_reg  : 8'h0 |
146
                        stb_modem_status_reg == 1'b1     ? u_reg.modem_status_reg     : 8'h0 ;
147
   assign rdat[31:24] = stb_line_control_reg == 1'b1     ? u_reg.line_control_reg     : 8'h0 |
148
                        stb_scratch_reg == 1'b1          ? u_reg.scratch_reg          : 8'h0 ;
149
`endif
150
 
151
   // -- fifo signal --
152
   wire         fifo_rec_reset    =  u_reg.fifo_control_reg.receiver_fifo_reset == 1'b1 ;
153
   wire         fifo_trans_reset  =  u_reg.fifo_control_reg.transmitter_fifo_reset == 1'b1 ;
154
   wire         all_error_rec ;
155
 
156
   // -- recevied fifo --
157
   uart_fifo #(.DATA_WIDTH(11), .ADDR_WIDTH(4)) fifo_rec
158
     (
159
      .clk_i(clk_i),
160
      .nrst_i(nrst_i),
161
      .clear(fifo_rec_reset),
162
      .almost_empty_level(u_reg.fifo_control_reg.define_fifo_trigger_level),
163
      .fifo_pop(fifo_pop_rec.pop_slave_mp),
164
      .fifo_push(fifo_push_rec.push_slave_mp),
165
      .all_error(all_error_rec)
166
      ) ;
167
 
168
   // -- transmitter fifo --
169
   uart_fifo #(.DATA_WIDTH(11), .ADDR_WIDTH(4)) fifo_trans
170
     (
171
      .clk_i(clk_i),
172
      .nrst_i(nrst_i),
173
      .clear(fifo_trans_reset),
174
      .almost_empty_level(u_reg.fifo_control_reg.define_fifo_trigger_level),
175
      .fifo_pop(fifo_pop_trans.pop_slave_mp),
176
      .fifo_push(fifo_push_trans.push_slave_mp),
177
      .all_error() /* N.C. */
178
      ) ;
179
 
180
   // -------------------
181
   // -- UART REGISTER --
182
   // -------------------
183
 
184
   assign fifo_push_trans.push = stb_txd_fifo == 1'b1 && we_i == WRITE ;
185
   assign fifo_push_trans.push_dat = dat_i[7:0] ;
186
   assign fifo_pop_rec.pop = stb_rxd_fifo == 1'b1 && we_i == READ ;
187
 
188
   // -- interrupt enable register --
189
   always_ff @(posedge clk_i, negedge nrst_i) begin
190
      if(nrst_i == 1'b0)
191
        u_reg.interrupt_enable_reg <= 'h0 ;
192
      else if(stb_interrupt_enable_reg == 1'b1 && we_i == WRITE)
193
        u_reg.interrupt_enable_reg <= dat_i[7:0] ;
194
      else
195
        u_reg.interrupt_enable_reg <= u_reg.interrupt_enable_reg[7:0] ;
196
   end
197
 
198
   // -- fifo control register write only --
199
   always_ff @(posedge clk_i, negedge nrst_i) begin
200
      if(nrst_i == 1'b0)
201
        u_reg.fifo_control_reg <= 'hc0 ;
202
      else if(stb_fifo_control_reg == 1'b1 && we_i == WRITE)
203
        u_reg.fifo_control_reg <= dat_i[7:0] ;
204
      else begin
205
        u_reg.fifo_control_reg[7:3] <= u_reg.fifo_control_reg[7:3] ;
206
        u_reg.fifo_control_reg[2:1] <= 2'b00 ;                        // -- fifo_cleaer
207
        u_reg.fifo_control_reg[0] <= u_reg.fifo_control_reg[0] ;
208
      end
209
   end
210
 
211
   // -- line control register --
212
   always_ff @(posedge clk_i, negedge nrst_i) begin
213
      if(nrst_i == 1'b0)
214
        u_reg.line_control_reg <= 'h03 ;
215
      else if(stb_line_control_reg == 1'b1 && we_i == WRITE)
216
        u_reg.line_control_reg <= dat_i[7:0] ;
217
      else
218
        u_reg.line_control_reg <= u_reg.line_control_reg[7:0] ;
219
   end
220
 
221
   // -- modem control register --
222
   always_ff @(posedge clk_i, negedge nrst_i) begin
223
      if(nrst_i == 1'b0)
224
        u_reg.modem_control_reg <= 'h0 ;
225
      else if(stb_modem_control_reg == 1'b1 && we_i == WRITE)
226
        u_reg.modem_control_reg <= dat_i[7:0] ;
227
      else
228
        u_reg.modem_control_reg <= u_reg.modem_control_reg[7:0] ;
229
   end
230
 
231
   // -- scratch register --
232
   always_ff @(posedge clk_i, negedge nrst_i) begin
233
      if(nrst_i == 1'b0)
234
        u_reg.scratch_reg <= 'h0 ;
235
      else if(stb_scratch_reg == 1'b1 && we_i == WRITE)
236
        u_reg.scratch_reg <= dat_i[7:0] ;
237
      else
238
        u_reg.scratch_reg <= u_reg.scratch_reg[7:0] ;
239
   end
240
 
241
   // -- scratch register --
242
   always_ff @(posedge clk_i, negedge nrst_i) begin
243
      if(nrst_i == 1'b0)
244
        u_reg.baud_reg <= 'h0 ;
245
      else if(stb_baud_reg == 1'b1 && we_i == WRITE)
246
        u_reg.baud_reg <= dat_i[7:0] ;
247
      else
248
        u_reg.baud_reg <= u_reg.baud_reg[7:0] ;
249
   end
250
 
251
   // -- read for manual - 4.7 Line Status Register (LSR)
252
   always_ff @(posedge clk_i, negedge nrst_i) begin
253
      if(nrst_i == 1'b0) begin
254
         {u_reg.line_status_reg.data_ready,
255
          u_reg.line_status_reg.trans_fifo_empty,
256
          u_reg.line_status_reg.trans_empty} <= #1 3'h0 ;
257
      end
258
      else begin
259
         u_reg.line_status_reg.data_ready       <= #1 fifo_pop_rec.empty == 1'b0 ;
260
         u_reg.line_status_reg.trans_fifo_empty <= #1 fifo_push_trans.empty ;
261
         u_reg.line_status_reg.trans_empty      <= #1 fifo_push_trans.empty | trans_buf_empty ;
262
      end
263
   end // always_ff @ (posedge clk_i, negedge nrst_i)
264
 
265
   // -- overrun error --
266
   logic overrun_err_r ;
267
   always_ff @(posedge clk_i, negedge nrst_i) begin
268
      if(nrst_i == 1'b0)
269
        overrun_err_r <= #1 1'b1 ;
270
      else
271
        overrun_err_r <= #1 overrun ;
272
   end
273
   wire overrun_err_set = overrun & ~overrun_err_r ;
274
   wire overrun_err_clr = we_i == READ && stb_line_status_reg == 1'b1 ;
275
 
276
   always_ff @(posedge clk_i, negedge nrst_i) begin
277
      if(nrst_i == 1'b0)
278
        u_reg.line_status_reg.overrun_err <= #1 1'b0 ;
279
      else if(overrun_err_set == 1'b1)
280
        u_reg.line_status_reg.overrun_err <= #1 1'b1 ;
281
      else if(overrun_err_clr == 1'b1)
282
        u_reg.line_status_reg.overrun_err <= #1 1'b0 ;
283
      else
284
        u_reg.line_status_reg.overrun_err <= #1 u_reg.line_status_reg.overrun_err ;
285
   end
286
 
287
   // -- parity error --
288
   logic parity_err_r ;
289
   always_ff @(posedge clk_i, negedge nrst_i) begin
290
      if(nrst_i == 1'b0)
291
        parity_err_r <= #1 1'b1 ;
292
      else
293
        parity_err_r <= #1  fifo_pop_rec.pop_dat[10] ;
294
   end
295
   wire parity_err_set = fifo_pop_rec.pop_dat[10] & ~parity_err_r ;
296
   wire parity_err_clr = we_i == READ && stb_line_status_reg == 1'b1 ;
297
 
298
   always_ff @(posedge clk_i, negedge nrst_i) begin
299
      if(nrst_i == 1'b0)
300
        u_reg.line_status_reg.parity_err <= #1 1'b0 ;
301
      else if(parity_err_set == 1'b1)
302
        u_reg.line_status_reg.parity_err <= #1 1'b1 ;
303
      else if(parity_err_clr == 1'b1)
304
        u_reg.line_status_reg.parity_err <= #1 1'b0 ;
305
      else
306
        u_reg.line_status_reg.parity_err <= #1 u_reg.line_status_reg.parity_err ;
307
   end
308
 
309
   // -- framing error --
310
   logic framing_err_r ;
311
   always_ff @(posedge clk_i, negedge nrst_i) begin
312
      if(nrst_i == 1'b0)
313
        framing_err_r <= #1 1'b1 ;
314
      else
315
        framing_err_r <= #1  fifo_pop_rec.pop_dat[9] ;
316
   end
317
   wire framing_err_set = fifo_pop_rec.pop_dat[9] & ~framing_err_r ;
318
   wire framing_err_clr = we_i == READ && stb_line_status_reg == 1'b1 ;
319
 
320
   always_ff @(posedge clk_i, negedge nrst_i) begin
321
      if(nrst_i == 1'b0)
322
        u_reg.line_status_reg.framing_err <= #1 1'b0 ;
323
      else if(framing_err_set == 1'b1)
324
        u_reg.line_status_reg.framing_err <= #1 1'b1 ;
325
      else if(framing_err_clr == 1'b1)
326
        u_reg.line_status_reg.framing_err <= #1 1'b0 ;
327
      else
328
        u_reg.line_status_reg.framing_err <= #1 u_reg.line_status_reg.framing_err ;
329
   end
330
 
331
   // -- break interrupt indicator --
332
   logic break_intr_r ;
333
   always_ff @(posedge clk_i, negedge nrst_i) begin
334
      if(nrst_i == 1'b0)
335
        break_intr_r <= #1 1'b1 ;
336
      else
337
        break_intr_r <= #1  fifo_pop_rec.pop_dat[8] ;
338
   end
339
   wire break_intr_set = fifo_pop_rec.pop_dat[8] & ~break_intr_r ;
340
   wire break_intr_clr = we_i == READ && stb_line_status_reg == 1'b1 ;
341
 
342
   always_ff @(posedge clk_i, negedge nrst_i) begin
343
      if(nrst_i == 1'b0)
344
        u_reg.line_status_reg.break_intr <= #1 1'b0 ;
345
      else if(break_intr_set == 1'b1)
346
        u_reg.line_status_reg.break_intr <= #1 1'b1 ;
347
      else if(break_intr_clr == 1'b1)
348
        u_reg.line_status_reg.break_intr <= #1 1'b0 ;
349
      else
350
        u_reg.line_status_reg.break_intr <= #1 u_reg.line_status_reg.break_intr ;
351
   end
352
 
353
   // -- parity error or framing error or break indication --
354
   logic all_error_r ;
355
   always_ff @(posedge clk_i, negedge nrst_i) begin
356
      if(nrst_i == 1'b0)
357
        all_error_r <= #1 1'b1 ;
358
      else
359
        all_error_r <= #1  all_error_rec | overrun ;
360
   end
361
   wire all_error_set = all_error_rec & ~all_error_r ;
362
   wire all_error_clr = we_i == READ && stb_line_status_reg == 1'b1 ;
363
 
364
   always_ff @(posedge clk_i, negedge nrst_i) begin
365
      if(nrst_i == 1'b0)
366
        u_reg.line_status_reg.all_error <= #1 1'b0 ;
367
      else if(all_error_set == 1'b1)
368
        u_reg.line_status_reg.all_error <= #1 1'b1 ;
369
      else if(all_error_clr == 1'b1)
370
        u_reg.line_status_reg.all_error <= #1 1'b0 ;
371
      else
372
        u_reg.line_status_reg.all_error <= #1 u_reg.line_status_reg.all_error ;
373
   end
374
 
375
   // -- read for manual - 4.8 Modem Status Register (MSR)
376
   wire [3:0] modem_cont = {dcd, ri, dsr, cts} ;
377
   logic [3:0] modem_contl ;
378
   always_ff @(posedge clk_i, negedge nrst_i) begin
379
      if(nrst_i == 1'b0)
380
       modem_contl <= #1 4'h0 ;
381
      else
382
        modem_contl <= #1 modem_cont ;
383
   end
384
 
385
   wire [3:0]  modem_pulse = modem_cont ^ modem_contl ;
386
 
387
   always_ff @(posedge clk_i, negedge nrst_i) begin
388
      if(nrst_i == 1'b0)
389
        u_reg.modem_status_reg[3:0] <= #1 0 ;
390
      else if(stb_modem_status_reg == 1'b1 && we_i == READ)
391
        u_reg.modem_status_reg[3:0] <= #1 0 ;
392
      else if(modem_pulse != 4'h0) begin
393
         u_reg.modem_status_reg[3:0] <= #1 modem_pulse ;
394
      end
395
      else
396
        u_reg.modem_status_reg[3:0] <= #1 u_reg.modem_status_reg[3:0] ;
397
   end
398
 
399
   always_ff @(posedge clk_i, negedge nrst_i) begin
400
      if(nrst_i == 1'b0)
401
        u_reg.modem_status_reg[7:4] <= #1 0 ;
402
      else
403
        u_reg.modem_status_reg[7:4] <= modem_cont ;
404
   end
405
 
406
   // -- read for manual - 4.3 Interrupt Identification Register (IIR) --
407
   always_ff @(posedge clk_i, negedge nrst_i) begin
408
      if(nrst_i == 1'b0) begin
409
         u_reg.interrupt_ident_reg.interrupt_identification <= #1 NO_INTERRUPT ;
410
         u_reg.interrupt_ident_reg.ignored_74_value_hC <= #1 4'hC ;
411
      end
412
      else begin
413
         priority casex({u_reg.interrupt_pending_reg.receiver_line_status,
414
                       u_reg.interrupt_pending_reg.receiver_data_available,
415
                       u_reg.interrupt_pending_reg.timeout_indication,
416
                       u_reg.interrupt_pending_reg.transmitter_holding_register_empty,
417
                       u_reg.interrupt_pending_reg.modem_status})
418
           5'b1xxxx : u_reg.interrupt_ident_reg.interrupt_identification <= #1 REC_LINE_STATUS ;
419
           5'b01xxx : u_reg.interrupt_ident_reg.interrupt_identification <= #1 REC_DATA_AVAILABLE ;
420
           5'b001xx : u_reg.interrupt_ident_reg.interrupt_identification <= #1 TIME_OUT ;
421
           5'b0001x : u_reg.interrupt_ident_reg.interrupt_identification <= #1 TRANS_REG_EMPTY ;
422
           5'b00001 : u_reg.interrupt_ident_reg.interrupt_identification <= #1 MODEM_STATUS ;
423
           default : u_reg.interrupt_ident_reg <= #1 {4'hC, NO_INTERRUPT} ;
424
         endcase // case (u_reg.interrupt_pending_reg.receiver_line_status,...
425
      end // else: !if(nrst_i == 1'b0)
426
   end
427
 
428
   // -- interrupt paending register --
429
   wire receiver_data_available_reset ;
430
   logic [4:0] interrupt_pending_reg_set_r ;
431
   wire [4:0] interrupt_pending_reg_reset
432
              = {
433
                 (stb_modem_status_reg == 1'b1 && we_i == 1'b0),
434
                 ((stb_txd_fifo == 1'b1 && we_i == WRITE) || (stb_interrupt_ident_reg == 1'b1 && we_i == READ)),
435
                 (stb_rxd_fifo == 1'b1 && we_i == READ),
436
                 (receiver_data_available_reset == 1'b1),
437
                 (stb_line_status_reg == 1'b1 && we_i == READ)
438
                 } ;
439
 
440
 
441
   wire       modem_status_intr = |modem_pulse[3:0] ;
442
   wire       transmitter_holding_regster_empty_intr = fifo_pop_trans.empty & trans_buf_empty ;
443
   wire       timeout_indication_intr = timeout_signal ;
444
   wire       receiver_data_available_intr = fifo_push_rec.almost_full ;
445
   //   wire       receiver_line_status_intr = all_error_rec | overrun ;
446
   wire       receiver_line_status_intr ;
447
   assign     receiver_line_status_intr = u_reg.line_status_reg.break_intr |
448
                                          u_reg.line_status_reg.framing_err |
449
                                          u_reg.line_status_reg.parity_err |
450
                                          u_reg.line_status_reg.overrun_err ;
451
 
452
   wire [4:0] interrupt_pending_reg_set_w
453
              = {
454
                 (modem_status_intr == 1'b1                      && u_reg.interrupt_enable_reg.modem_status == 1'b1),
455
                 (transmitter_holding_regster_empty_intr == 1'b1 && u_reg.interrupt_enable_reg.trans_holding_reg_empty == 1'b1),
456
                 (timeout_indication_intr == 1'b1                && u_reg.interrupt_enable_reg.rec_data_available == 1'b1),
457
                 (receiver_data_available_intr == 1'b1           && u_reg.interrupt_enable_reg.rec_data_available == 1'b1),
458
                 (receiver_line_status_intr == 1'b1              && u_reg.interrupt_enable_reg.rec_line_status == 1'b1)
459
                 } ;
460
 
461
   wire [4:0] interrupt_pending_reg_set = interrupt_pending_reg_set_w & ~(interrupt_pending_reg_set_r) ;
462
 
463
   always_ff @(posedge clk_i, negedge nrst_i) begin
464
      if(nrst_i == 1'b0)
465
        interrupt_pending_reg_set_r <= #1 5'h0 ;
466
      else
467
        interrupt_pending_reg_set_r <= #1 interrupt_pending_reg_set_w ;
468
   end
469
   assign receiver_data_available_reset = interrupt_pending_reg_set_r[1] & ~interrupt_pending_reg_set_w[1] ;
470
 
471
   always_ff @(posedge clk_i, negedge nrst_i) begin
472
      if(nrst_i == 1'b0)
473
        u_reg.interrupt_pending_reg <= #1 5'h00 ;
474
      else if(interrupt_pending_reg_set != 0)
475
        u_reg.interrupt_pending_reg <= #1 u_reg.interrupt_pending_reg | interrupt_pending_reg_set ;
476
      else if(interrupt_pending_reg_reset != 0)
477
        u_reg.interrupt_pending_reg <= #1 u_reg.interrupt_pending_reg & ~(interrupt_pending_reg_reset) ;
478
      else
479
        u_reg.interrupt_pending_reg <= #1 u_reg.interrupt_pending_reg ;
480
   end
481
 
482
endmodule
483
 
484
/// END OF FILE ///

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.