../src/lowrisc_ip_uart_0.1/rtl/uart_core.sv Cov: 100%

   1: // Copyright lowRISC contributors.
   2: // Licensed under the Apache License, Version 2.0, see LICENSE for details.
   3: // SPDX-License-Identifier: Apache-2.0
   4: //
   5: // Description: UART core module
   6: //
   7: 
   8: module uart_core (
   9:   input                  clk_i,
  10:   input                  rst_ni,
  11: 
  12:   input  uart_reg_pkg::uart_reg2hw_t reg2hw,
  13:   output uart_reg_pkg::uart_hw2reg_t hw2reg,
  14: 
  15:   input                  rx,
  16:   output logic           tx,
  17: 
  18:   output logic           intr_tx_watermark_o,
  19:   output logic           intr_rx_watermark_o,
  20:   output logic           intr_tx_empty_o,
  21:   output logic           intr_rx_overflow_o,
  22:   output logic           intr_rx_frame_err_o,
  23:   output logic           intr_rx_break_err_o,
  24:   output logic           intr_rx_timeout_o,
  25:   output logic           intr_rx_parity_err_o
  26: );
  27: 
  28:   import uart_reg_pkg::*;
  29: 
  30:   logic   [15:0]  rx_val_q;
  31:   logic   [7:0]   uart_rdata;
  32:   logic           tick_baud_x16, rx_tick_baud;
  33:   logic   [5:0]   tx_fifo_depth, rx_fifo_depth;
  34:   logic   [5:0]   rx_fifo_depth_prev_q;
  35:   logic   [23:0]  rx_timeout_count_d, rx_timeout_count_q, uart_rxto_val;
  36:   logic           rx_fifo_depth_changed, uart_rxto_en;
  37:   logic           tx_enable, rx_enable;
  38:   logic           sys_loopback, line_loopback, rxnf_enable;
  39:   logic           uart_fifo_rxrst, uart_fifo_txrst;
  40:   logic   [2:0]   uart_fifo_rxilvl;
  41:   logic   [1:0]   uart_fifo_txilvl;
  42:   logic           ovrd_tx_en, ovrd_tx_val;
  43:   logic   [7:0]   tx_fifo_data;
  44:   logic           tx_fifo_rready, tx_fifo_rvalid;
  45:   logic           tx_fifo_wready, tx_uart_idle;
  46:   logic           tx_out;
  47:   logic           tx_out_q;
  48:   logic   [7:0]   rx_fifo_data;
  49:   logic           rx_valid, rx_fifo_wvalid, rx_fifo_rvalid;
  50:   logic           rx_fifo_wready, rx_uart_idle;
  51:   logic           rx_sync;
  52:   logic           rx_in;
  53:   logic           break_err;
  54:   logic   [4:0]   allzero_cnt_d, allzero_cnt_q;
  55:   logic           allzero_err, not_allzero_char;
  56:   logic           event_tx_watermark, event_rx_watermark, event_tx_empty, event_rx_overflow;
  57:   logic           event_rx_frame_err, event_rx_break_err, event_rx_timeout, event_rx_parity_err;
  58:   logic           tx_watermark_d, tx_watermark_prev_q;
  59:   logic           rx_watermark_d, rx_watermark_prev_q;
  60:   logic           tx_uart_idle_q;
  61: 
  62:   assign tx_enable        = reg2hw.ctrl.tx.q;
  63:   assign rx_enable        = reg2hw.ctrl.rx.q;
  64:   assign rxnf_enable      = reg2hw.ctrl.nf.q;
  65:   assign sys_loopback     = reg2hw.ctrl.slpbk.q;
  66:   assign line_loopback    = reg2hw.ctrl.llpbk.q;
  67: 
  68:   assign uart_fifo_rxrst  = reg2hw.fifo_ctrl.rxrst.q & reg2hw.fifo_ctrl.rxrst.qe;
  69:   assign uart_fifo_txrst  = reg2hw.fifo_ctrl.txrst.q & reg2hw.fifo_ctrl.txrst.qe;
  70:   assign uart_fifo_rxilvl = reg2hw.fifo_ctrl.rxilvl.q;
  71:   assign uart_fifo_txilvl = reg2hw.fifo_ctrl.txilvl.q;
  72: 
  73:   assign ovrd_tx_en       = reg2hw.ovrd.txen.q;
  74:   assign ovrd_tx_val      = reg2hw.ovrd.txval.q;
  75: 
  76:   typedef enum logic {
  77:     BRK_CHK,
  78:     BRK_WAIT
  79:   } break_st_e ;
  80: 
  81:   break_st_e break_st_q;
  82: 
  83:   assign not_allzero_char = rx_valid & (~event_rx_frame_err | (rx_fifo_data != 8'h0));
  84:   assign allzero_err = event_rx_frame_err & (rx_fifo_data == 8'h0);
  85: 
  86: 
  87:   assign allzero_cnt_d = (break_st_q == BRK_WAIT || not_allzero_char) ? 5'h0 :
  88:                           //allzero_cnt_q[4] never be 1b without break_st_q as BRK_WAIT
  89:                           //allzero_cnt_q[4] ? allzero_cnt_q :
  90:                           allzero_err ? allzero_cnt_q + 5'd1 :
  91:                           allzero_cnt_q;
  92: 
  93:   always_ff @(posedge clk_i or negedge rst_ni) begin
  94:     if (!rst_ni)        allzero_cnt_q <= '0;
  95:     else if (rx_enable) allzero_cnt_q <= allzero_cnt_d;
  96:   end
  97: 
  98:   // break_err edges in same cycle as event_rx_frame_err edges ; that way the
  99:   // reset-on-read works the same way for break and frame error interrupts.
 100: 
 101:   always_comb begin
 102:     unique case (reg2hw.ctrl.rxblvl.q)
 103:       2'h0:    break_err = allzero_cnt_d >= 5'd2;
 104:       2'h1:    break_err = allzero_cnt_d >= 5'd4;
 105:       2'h2:    break_err = allzero_cnt_d >= 5'd8;
 106:       default: break_err = allzero_cnt_d >= 5'd16;
 107:     endcase
 108:   end
 109: 
 110:   always_ff @(posedge clk_i or negedge rst_ni) begin
 111:     if (!rst_ni) break_st_q <= BRK_CHK;
 112:     else begin
 113:       unique case (break_st_q)
 114:         BRK_CHK: begin
 115:           if (event_rx_break_err) break_st_q <= BRK_WAIT;
 116:         end
 117: 
 118:         BRK_WAIT: begin
 119:           if (rx_in) break_st_q <= BRK_CHK;
 120:         end
 121: 
 122:         default: begin
 123:           break_st_q <= BRK_CHK;
 124:         end
 125:       endcase
 126:     end
 127:   end
 128: 
 129:   assign hw2reg.val.d  = rx_val_q;
 130: 
 131:   assign hw2reg.rdata.d = uart_rdata;
 132: 
 133:   assign hw2reg.status.rxempty.d     = ~rx_fifo_rvalid;
 134:   assign hw2reg.status.rxidle.d      = rx_uart_idle;
 135:   assign hw2reg.status.txidle.d      = tx_uart_idle & ~tx_fifo_rvalid;
 136:   assign hw2reg.status.txempty.d     = ~tx_fifo_rvalid;
 137:   assign hw2reg.status.rxfull.d      = ~rx_fifo_wready;
 138:   assign hw2reg.status.txfull.d      = ~tx_fifo_wready;
 139: 
 140:   assign hw2reg.fifo_status.txlvl.d  = tx_fifo_depth;
 141:   assign hw2reg.fifo_status.rxlvl.d  = rx_fifo_depth;
 142: 
 143:   // resets are self-clearing, so need to update FIFO_CTRL
 144:   assign hw2reg.fifo_ctrl.rxilvl.de = 1'b0;
 145:   assign hw2reg.fifo_ctrl.rxilvl.d  = 3'h0;
 146:   assign hw2reg.fifo_ctrl.txilvl.de = 1'b0;
 147:   assign hw2reg.fifo_ctrl.txilvl.d  = 2'h0;
 148: 
 149:   //              NCO 16x Baud Generator
 150:   // output clock rate is:
 151:   //      Fin * (NCO/2**16)
 152:   // So, with a 16 bit accumulator, the output clock is
 153:   //      Fin * (NCO/65536)
 154:   logic   [16:0]     nco_sum_q; // extra bit to get the carry
 155: 
 156:   always_ff @(posedge clk_i or negedge rst_ni) begin
 157:     if (!rst_ni) begin
 158:       nco_sum_q <= 17'h0;
 159:     end else if (tx_enable || rx_enable) begin
 160:       nco_sum_q <= {1'b0,nco_sum_q[15:0]} + {1'b0,reg2hw.ctrl.nco.q};
 161:     end
 162:   end
 163: 
 164:   assign tick_baud_x16 = nco_sum_q[16];
 165: 
 166:   //////////////
 167:   // TX Logic //
 168:   //////////////
 169: 
 170:   assign tx_fifo_rready = tx_uart_idle & tx_fifo_rvalid & tx_enable;
 171: 
 172:   prim_fifo_sync #(
 173:     .Width(8),
 174:     .Pass (1'b0),
 175:     .Depth(32)
 176:   ) u_uart_txfifo (
 177:     .clk_i,
 178:     .rst_ni,
 179:     .clr_i  (uart_fifo_txrst),
 180:     .wvalid (reg2hw.wdata.qe),
 181:     .wready (tx_fifo_wready),
 182:     .wdata  (reg2hw.wdata.q),
 183:     .depth  (tx_fifo_depth),
 184:     .rvalid (tx_fifo_rvalid),
 185:     .rready (tx_fifo_rready),
 186:     .rdata  (tx_fifo_data)
 187:   );
 188: 
 189:   uart_tx uart_tx (
 190:     .clk_i,
 191:     .rst_ni,
 192:     .tx_enable,
 193:     .tick_baud_x16,
 194:     .parity_enable  (reg2hw.ctrl.parity_en.q),
 195:     .wr             (tx_fifo_rready),
 196:     .wr_parity      ((^tx_fifo_data) ^ reg2hw.ctrl.parity_odd.q),
 197:     .wr_data        (tx_fifo_data),
 198:     .idle           (tx_uart_idle),
 199:     .tx             (tx_out)
 200:   );
 201: 
 202:   assign tx = line_loopback ? rx : tx_out_q ;
 203:   always_ff @(posedge clk_i or negedge rst_ni) begin
 204:     if (!rst_ni) begin
 205:       tx_out_q <= 1'b1;
 206:     end else if (ovrd_tx_en) begin
 207:       tx_out_q <= ovrd_tx_val ;
 208:     end else if (sys_loopback) begin
 209:       tx_out_q <= 1'b1;
 210:     end else begin
 211:       tx_out_q <= tx_out;
 212:     end
 213:   end
 214: 
 215:   //////////////
 216:   // RX Logic //
 217:   //////////////
 218: 
 219:   //      sync the incoming data
 220:   prim_flop_2sync #(
 221:     .Width(1),
 222:     .ResetValue(1)
 223:   ) sync_rx (
 224:     .clk_i,
 225:     .rst_ni,
 226:     .d(rx),
 227:     .q(rx_sync)
 228:   );
 229: 
 230:   // Based on: en.wikipedia.org/wiki/Repetition_code mentions the use of a majority filter
 231:   // in UART to ignore brief noise spikes
 232:   logic   rx_sync_q1, rx_sync_q2, rx_in_mx, rx_in_maj;
 233: 
 234:   always_ff @(posedge clk_i or negedge rst_ni) begin
 235:     if (!rst_ni) begin
 236:       rx_sync_q1 <= 1'b1;
 237:       rx_sync_q2 <= 1'b1;
 238:     end else begin
 239:       rx_sync_q1 <= rx_sync;
 240:       rx_sync_q2 <= rx_sync_q1;
 241:     end
 242:   end
 243: 
 244:   assign rx_in_maj = (rx_sync    & rx_sync_q1) |
 245:                      (rx_sync    & rx_sync_q2) |
 246:                      (rx_sync_q1 & rx_sync_q2);
 247:   assign rx_in_mx  = rxnf_enable ? rx_in_maj : rx_sync;
 248: 
 249:   assign rx_in =  sys_loopback ? tx_out   :
 250:                   line_loopback ? 1'b1 :
 251:                   rx_in_mx;
 252: 
 253:   uart_rx uart_rx (
 254:     .clk_i,
 255:     .rst_ni,
 256:     .rx_enable,
 257:     .tick_baud_x16,
 258:     .parity_enable  (reg2hw.ctrl.parity_en.q),
 259:     .parity_odd     (reg2hw.ctrl.parity_odd.q),
 260:     .tick_baud      (rx_tick_baud),
 261:     .rx_valid,
 262:     .rx_data        (rx_fifo_data),
 263:     .idle           (rx_uart_idle),
 264:     .frame_err      (event_rx_frame_err),
 265:     .rx             (rx_in),
 266:     .rx_parity_err  (event_rx_parity_err)
 267:   );
 268: 
 269:   assign rx_fifo_wvalid = rx_valid & ~event_rx_frame_err & ~event_rx_parity_err;
 270: 
 271:   prim_fifo_sync #(
 272:     .Width (8),
 273:     .Pass  (1'b0),
 274:     .Depth (32)
 275:   ) u_uart_rxfifo (
 276:     .clk_i,
 277:     .rst_ni,
 278:     .clr_i  (uart_fifo_rxrst),
 279:     .wvalid (rx_fifo_wvalid),
 280:     .wready (rx_fifo_wready),
 281:     .wdata  (rx_fifo_data),
 282:     .depth  (rx_fifo_depth),
 283:     .rvalid (rx_fifo_rvalid),
 284:     .rready (reg2hw.rdata.re),
 285:     .rdata  (uart_rdata)
 286:   );
 287: 
 288:   always_ff @(posedge clk_i or negedge rst_ni) begin
 289:     if (!rst_ni)            rx_val_q <= 16'h0;
 290:     else if (tick_baud_x16) rx_val_q <= {rx_val_q[14:0], rx_in};
 291:   end
 292: 
 293:   ////////////////////////
 294:   // Interrupt & Status //
 295:   ////////////////////////
 296: 
 297:   always_comb begin
 298:     unique case(uart_fifo_txilvl)
 299:       2'h0:    tx_watermark_d = (tx_fifo_depth < 6'd2);
 300:       2'h1:    tx_watermark_d = (tx_fifo_depth < 6'd4);
 301:       2'h2:    tx_watermark_d = (tx_fifo_depth < 6'd8);
 302:       default: tx_watermark_d = (tx_fifo_depth < 6'd16);
 303:     endcase
 304:   end
 305: 
 306:   assign event_tx_watermark = tx_watermark_d & ~tx_watermark_prev_q;
 307: 
 308:   // The empty condition handling is a bit different.
 309:   // If empty rising conditions were detected directly, then every first write of a burst
 310:   // would trigger an empty.  This is due to the fact that the uart_tx fsm immediately
 311:   // withdraws the content and asserts "empty".
 312:   // To guard against this false trigger, empty is qualified with idle to extend the window
 313:   // in which software has an opportunity to deposit new data.
 314:   // However, if software deposit speed is TOO slow, this would still be an issue.
 315:   //
 316:   // The alternative software fix is to disable tx_enable until it has a chance to
 317:   // burst in the desired amount of data.
 318:   assign event_tx_empty     = ~tx_fifo_rvalid & ~tx_uart_idle_q & tx_uart_idle;
 319: 
 320:   always_ff @(posedge clk_i or negedge rst_ni) begin
 321:     if (!rst_ni) begin
 322:       tx_watermark_prev_q  <= 1'b1; // by default watermark condition is true
 323:       rx_watermark_prev_q  <= 1'b0; // by default watermark condition is false
 324:       tx_uart_idle_q       <= 1'b1;
 325:     end else begin
 326:       tx_watermark_prev_q  <= tx_watermark_d;
 327:       rx_watermark_prev_q  <= rx_watermark_d;
 328:       tx_uart_idle_q       <= tx_uart_idle;
 329:     end
 330:   end
 331: 
 332:   always_comb begin
 333:     unique case(uart_fifo_rxilvl)
 334:       3'h0:    rx_watermark_d = (rx_fifo_depth >= 6'd1);
 335:       3'h1:    rx_watermark_d = (rx_fifo_depth >= 6'd4);
 336:       3'h2:    rx_watermark_d = (rx_fifo_depth >= 6'd8);
 337:       3'h3:    rx_watermark_d = (rx_fifo_depth >= 6'd16);
 338:       3'h4:    rx_watermark_d = (rx_fifo_depth >= 6'd30);
 339:       default: rx_watermark_d = 1'b0;
 340:     endcase
 341:   end
 342: 
 343:   assign event_rx_watermark = rx_watermark_d & ~rx_watermark_prev_q;
 344: 
 345:   // rx timeout interrupt
 346:   assign uart_rxto_en  = reg2hw.timeout_ctrl.en.q;
 347:   assign uart_rxto_val = reg2hw.timeout_ctrl.val.q;
 348: 
 349:   assign rx_fifo_depth_changed = (rx_fifo_depth != rx_fifo_depth_prev_q);
 350: 
 351:   assign rx_timeout_count_d =
 352:               // don't count if timeout feature not enabled ;
 353:               // will never reach timeout val + lower power
 354:               (uart_rxto_en == 1'b0)              ? 24'd0 :
 355:               // reset count if timeout interrupt is set
 356:               event_rx_timeout                    ? 24'd0 :
 357:               // reset count upon change in fifo level: covers both read and receiving a new byte
 358:               rx_fifo_depth_changed               ? 24'd0 :
 359:               // reset count if no bytes are pending
 360:               (rx_fifo_depth == 5'd0)             ? 24'd0 :
 361:               // stop the count at timeout value (this will set the interrupt)
 362:               //   Removed below line as when the timeout reaches the value,
 363:               //   event occured, and timeout value reset to 0h.
 364:               //(rx_timeout_count_q == uart_rxto_val) ? rx_timeout_count_q :
 365:               // increment if at rx baud tick
 366:               rx_tick_baud                        ? (rx_timeout_count_q + 24'd1) :
 367:               rx_timeout_count_q;
 368: 
 369:   assign event_rx_timeout = (rx_timeout_count_q == uart_rxto_val) & uart_rxto_en;
 370: 
 371:   always_ff @(posedge clk_i or negedge rst_ni) begin
 372:     if (!rst_ni) begin
 373:       rx_timeout_count_q   <= 24'd0;
 374:       rx_fifo_depth_prev_q <= 6'd0;
 375:     end else begin
 376:       rx_timeout_count_q    <= rx_timeout_count_d;
 377:       rx_fifo_depth_prev_q  <= rx_fifo_depth;
 378:     end
 379:   end
 380: 
 381:   assign event_rx_overflow  = rx_fifo_wvalid & ~rx_fifo_wready;
 382:   assign event_rx_break_err = break_err & (break_st_q == BRK_CHK);
 383: 
 384:   // instantiate interrupt hardware primitives
 385: 
 386:   prim_intr_hw #(.Width(1)) intr_hw_tx_watermark (
 387:     .event_intr_i           (event_tx_watermark),
 388:     .reg2hw_intr_enable_q_i (reg2hw.intr_enable.tx_watermark.q),
 389:     .reg2hw_intr_test_q_i   (reg2hw.intr_test.tx_watermark.q),
 390:     .reg2hw_intr_test_qe_i  (reg2hw.intr_test.tx_watermark.qe),
 391:     .reg2hw_intr_state_q_i  (reg2hw.intr_state.tx_watermark.q),
 392:     .hw2reg_intr_state_de_o (hw2reg.intr_state.tx_watermark.de),
 393:     .hw2reg_intr_state_d_o  (hw2reg.intr_state.tx_watermark.d),
 394:     .intr_o                 (intr_tx_watermark_o)
 395:   );
 396: 
 397:   prim_intr_hw #(.Width(1)) intr_hw_rx_watermark (
 398:     .event_intr_i           (event_rx_watermark),
 399:     .reg2hw_intr_enable_q_i (reg2hw.intr_enable.rx_watermark.q),
 400:     .reg2hw_intr_test_q_i   (reg2hw.intr_test.rx_watermark.q),
 401:     .reg2hw_intr_test_qe_i  (reg2hw.intr_test.rx_watermark.qe),
 402:     .reg2hw_intr_state_q_i  (reg2hw.intr_state.rx_watermark.q),
 403:     .hw2reg_intr_state_de_o (hw2reg.intr_state.rx_watermark.de),
 404:     .hw2reg_intr_state_d_o  (hw2reg.intr_state.rx_watermark.d),
 405:     .intr_o                 (intr_rx_watermark_o)
 406:   );
 407: 
 408:   prim_intr_hw #(.Width(1)) intr_hw_tx_empty (
 409:     .event_intr_i           (event_tx_empty),
 410:     .reg2hw_intr_enable_q_i (reg2hw.intr_enable.tx_empty.q),
 411:     .reg2hw_intr_test_q_i   (reg2hw.intr_test.tx_empty.q),
 412:     .reg2hw_intr_test_qe_i  (reg2hw.intr_test.tx_empty.qe),
 413:     .reg2hw_intr_state_q_i  (reg2hw.intr_state.tx_empty.q),
 414:     .hw2reg_intr_state_de_o (hw2reg.intr_state.tx_empty.de),
 415:     .hw2reg_intr_state_d_o  (hw2reg.intr_state.tx_empty.d),
 416:     .intr_o                 (intr_tx_empty_o)
 417:   );
 418: 
 419:   prim_intr_hw #(.Width(1)) intr_hw_rx_overflow (
 420:     .event_intr_i           (event_rx_overflow),
 421:     .reg2hw_intr_enable_q_i (reg2hw.intr_enable.rx_overflow.q),
 422:     .reg2hw_intr_test_q_i   (reg2hw.intr_test.rx_overflow.q),
 423:     .reg2hw_intr_test_qe_i  (reg2hw.intr_test.rx_overflow.qe),
 424:     .reg2hw_intr_state_q_i  (reg2hw.intr_state.rx_overflow.q),
 425:     .hw2reg_intr_state_de_o (hw2reg.intr_state.rx_overflow.de),
 426:     .hw2reg_intr_state_d_o  (hw2reg.intr_state.rx_overflow.d),
 427:     .intr_o                 (intr_rx_overflow_o)
 428:   );
 429: 
 430:   prim_intr_hw #(.Width(1)) intr_hw_rx_frame_err (
 431:     .event_intr_i           (event_rx_frame_err),
 432:     .reg2hw_intr_enable_q_i (reg2hw.intr_enable.rx_frame_err.q),
 433:     .reg2hw_intr_test_q_i   (reg2hw.intr_test.rx_frame_err.q),
 434:     .reg2hw_intr_test_qe_i  (reg2hw.intr_test.rx_frame_err.qe),
 435:     .reg2hw_intr_state_q_i  (reg2hw.intr_state.rx_frame_err.q),
 436:     .hw2reg_intr_state_de_o (hw2reg.intr_state.rx_frame_err.de),
 437:     .hw2reg_intr_state_d_o  (hw2reg.intr_state.rx_frame_err.d),
 438:     .intr_o                 (intr_rx_frame_err_o)
 439:   );
 440: 
 441:   prim_intr_hw #(.Width(1)) intr_hw_rx_break_err (
 442:     .event_intr_i           (event_rx_break_err),
 443:     .reg2hw_intr_enable_q_i (reg2hw.intr_enable.rx_break_err.q),
 444:     .reg2hw_intr_test_q_i   (reg2hw.intr_test.rx_break_err.q),
 445:     .reg2hw_intr_test_qe_i  (reg2hw.intr_test.rx_break_err.qe),
 446:     .reg2hw_intr_state_q_i  (reg2hw.intr_state.rx_break_err.q),
 447:     .hw2reg_intr_state_de_o (hw2reg.intr_state.rx_break_err.de),
 448:     .hw2reg_intr_state_d_o  (hw2reg.intr_state.rx_break_err.d),
 449:     .intr_o                 (intr_rx_break_err_o)
 450:   );
 451: 
 452:   prim_intr_hw #(.Width(1)) intr_hw_rx_timeout (
 453:     .event_intr_i           (event_rx_timeout),
 454:     .reg2hw_intr_enable_q_i (reg2hw.intr_enable.rx_timeout.q),
 455:     .reg2hw_intr_test_q_i   (reg2hw.intr_test.rx_timeout.q),
 456:     .reg2hw_intr_test_qe_i  (reg2hw.intr_test.rx_timeout.qe),
 457:     .reg2hw_intr_state_q_i  (reg2hw.intr_state.rx_timeout.q),
 458:     .hw2reg_intr_state_de_o (hw2reg.intr_state.rx_timeout.de),
 459:     .hw2reg_intr_state_d_o  (hw2reg.intr_state.rx_timeout.d),
 460:     .intr_o                 (intr_rx_timeout_o)
 461:   );
 462: 
 463:   prim_intr_hw #(.Width(1)) intr_hw_rx_parity_err (
 464:     .event_intr_i           (event_rx_parity_err),
 465:     .reg2hw_intr_enable_q_i (reg2hw.intr_enable.rx_parity_err.q),
 466:     .reg2hw_intr_test_q_i   (reg2hw.intr_test.rx_parity_err.q),
 467:     .reg2hw_intr_test_qe_i  (reg2hw.intr_test.rx_parity_err.qe),
 468:     .reg2hw_intr_state_q_i  (reg2hw.intr_state.rx_parity_err.q),
 469:     .hw2reg_intr_state_de_o (hw2reg.intr_state.rx_parity_err.de),
 470:     .hw2reg_intr_state_d_o  (hw2reg.intr_state.rx_parity_err.d),
 471:     .intr_o                 (intr_rx_parity_err_o)
 472:   );
 473: 
 474: endmodule
 475: