// Copyright lowRISC contributors. // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 // // Register Top module auto-generated by `reggen` module uart_reg_top ( input logic clk_i, input logic rst_ni, // To HW output uart_reg_pkg::uart_reg2hw_t reg2hw, // Write input uart_reg_pkg::uart_hw2reg_t hw2reg, // Read input logic reg_we, input logic reg_re, input logic [31:0] reg_wdata, input logic [ 3:0] reg_be, input logic [31:0] reg_addr, output logic [31:0] reg_rdata ); import uart_reg_pkg::* ; localparam int AW = 4; localparam int DW = 32; localparam int DBW = DW/8; // Byte Width logic reg_error; logic addrmiss, wr_err; logic [DW-1:0] reg_rdata_next; assign reg_rdata = reg_rdata_next; assign reg_error = wr_err; // Define SW related signals // Format: __{wd|we|qs} // or _{wd|we|qs} if field == 1 or 0 logic ctrl_we; logic ctrl_tx_en_qs; logic ctrl_tx_en_wd; logic ctrl_rx_en_qs; logic ctrl_rx_en_wd; logic ctrl_tx_fifo_empty_int_en_qs; logic ctrl_tx_fifo_empty_int_en_wd; logic ctrl_rx_fifo_not_empty_int_en_qs; logic ctrl_rx_fifo_not_empty_int_en_wd; logic ctrl_tx_fifo_rst_wd; logic ctrl_rx_fifo_rst_wd; logic [15:0] ctrl_baud_div_qs; logic [15:0] ctrl_baud_div_wd; logic status_re; logic status_txfull_qs; logic status_rxfull_qs; logic status_txempty_qs; logic status_rxempty_qs; logic status_txidle_qs; logic status_rxidle_qs; logic txdata_we; logic [7:0] txdata_wd; logic rxdata_re; logic [7:0] rxdata_qs; // Register instances // R[ctrl]: V(False) // F[tx_en]: 0:0 prim_subreg #( .DW (1), .SWACCESS("RW"), .RESVAL (1'h0) ) u_ctrl_tx_en ( .clk_i (clk_i), .rst_ni (rst_ni), // from register interface .we (ctrl_we), .wd (ctrl_tx_en_wd), // from internal hardware .de (1'b0), .d ('0), // to internal hardware .qe (reg2hw.ctrl.tx_en.qe), .q (reg2hw.ctrl.tx_en.q), // to register interface (read) .qs (ctrl_tx_en_qs) ); // F[rx_en]: 1:1 prim_subreg #( .DW (1), .SWACCESS("RW"), .RESVAL (1'h0) ) u_ctrl_rx_en ( .clk_i (clk_i), .rst_ni (rst_ni), // from register interface .we (ctrl_we), .wd (ctrl_rx_en_wd), // from internal hardware .de (1'b0), .d ('0), // to internal hardware .qe (reg2hw.ctrl.rx_en.qe), .q (reg2hw.ctrl.rx_en.q), // to register interface (read) .qs (ctrl_rx_en_qs) ); // F[tx_fifo_empty_int_en]: 2:2 prim_subreg #( .DW (1), .SWACCESS("RW"), .RESVAL (1'h0) ) u_ctrl_tx_fifo_empty_int_en ( .clk_i (clk_i), .rst_ni (rst_ni), // from register interface .we (ctrl_we), .wd (ctrl_tx_fifo_empty_int_en_wd), // from internal hardware .de (1'b0), .d ('0), // to internal hardware .qe (reg2hw.ctrl.tx_fifo_empty_int_en.qe), .q (reg2hw.ctrl.tx_fifo_empty_int_en.q), // to register interface (read) .qs (ctrl_tx_fifo_empty_int_en_qs) ); // F[rx_fifo_not_empty_int_en]: 3:3 prim_subreg #( .DW (1), .SWACCESS("RW"), .RESVAL (1'h0) ) u_ctrl_rx_fifo_not_empty_int_en ( .clk_i (clk_i), .rst_ni (rst_ni), // from register interface .we (ctrl_we), .wd (ctrl_rx_fifo_not_empty_int_en_wd), // from internal hardware .de (1'b0), .d ('0), // to internal hardware .qe (reg2hw.ctrl.rx_fifo_not_empty_int_en.qe), .q (reg2hw.ctrl.rx_fifo_not_empty_int_en.q), // to register interface (read) .qs (ctrl_rx_fifo_not_empty_int_en_qs) ); // F[tx_fifo_rst]: 4:4 prim_subreg #( .DW (1), .SWACCESS("W1C"), .RESVAL (1'h0) ) u_ctrl_tx_fifo_rst ( .clk_i (clk_i), .rst_ni (rst_ni), // from register interface .we (ctrl_we), .wd (ctrl_tx_fifo_rst_wd), // from internal hardware .de (1'b0), .d ('0), // to internal hardware .qe (reg2hw.ctrl.tx_fifo_rst.qe), .q (reg2hw.ctrl.tx_fifo_rst.q), // to register interface (read) .qs () ); // F[rx_fifo_rst]: 5:5 prim_subreg #( .DW (1), .SWACCESS("W1C"), .RESVAL (1'h0) ) u_ctrl_rx_fifo_rst ( .clk_i (clk_i), .rst_ni (rst_ni), // from register interface .we (ctrl_we), .wd (ctrl_rx_fifo_rst_wd), // from internal hardware .de (1'b0), .d ('0), // to internal hardware .qe (reg2hw.ctrl.rx_fifo_rst.qe), .q (reg2hw.ctrl.rx_fifo_rst.q), // to register interface (read) .qs () ); // F[baud_div]: 31:16 prim_subreg #( .DW (16), .SWACCESS("RW"), .RESVAL (16'hd9) ) u_ctrl_baud_div ( .clk_i (clk_i), .rst_ni (rst_ni), // from register interface .we (ctrl_we), .wd (ctrl_baud_div_wd), // from internal hardware .de (1'b0), .d ('0), // to internal hardware .qe (reg2hw.ctrl.baud_div.qe), .q (reg2hw.ctrl.baud_div.q), // to register interface (read) .qs (ctrl_baud_div_qs) ); // R[status]: V(True) // F[txfull]: 0:0 prim_subreg_ext #( .DW (1) ) u_status_txfull ( .re (status_re), .we (1'b0), .wd ('0), .d (hw2reg.status.txfull.d), .qre (reg2hw.status.txfull.re), .qe (), .q (reg2hw.status.txfull.q), .qs (status_txfull_qs) ); // F[rxfull]: 1:1 prim_subreg_ext #( .DW (1) ) u_status_rxfull ( .re (status_re), .we (1'b0), .wd ('0), .d (hw2reg.status.rxfull.d), .qre (reg2hw.status.rxfull.re), .qe (), .q (reg2hw.status.rxfull.q), .qs (status_rxfull_qs) ); // F[txempty]: 2:2 prim_subreg_ext #( .DW (1) ) u_status_txempty ( .re (status_re), .we (1'b0), .wd ('0), .d (hw2reg.status.txempty.d), .qre (reg2hw.status.txempty.re), .qe (), .q (reg2hw.status.txempty.q), .qs (status_txempty_qs) ); // F[rxempty]: 3:3 prim_subreg_ext #( .DW (1) ) u_status_rxempty ( .re (status_re), .we (1'b0), .wd ('0), .d (hw2reg.status.rxempty.d), .qre (reg2hw.status.rxempty.re), .qe (), .q (reg2hw.status.rxempty.q), .qs (status_rxempty_qs) ); // F[txidle]: 4:4 prim_subreg_ext #( .DW (1) ) u_status_txidle ( .re (status_re), .we (1'b0), .wd ('0), .d (hw2reg.status.txidle.d), .qre (reg2hw.status.txidle.re), .qe (), .q (reg2hw.status.txidle.q), .qs (status_txidle_qs) ); // F[rxidle]: 5:5 prim_subreg_ext #( .DW (1) ) u_status_rxidle ( .re (status_re), .we (1'b0), .wd ('0), .d (hw2reg.status.rxidle.d), .qre (reg2hw.status.rxidle.re), .qe (), .q (reg2hw.status.rxidle.q), .qs (status_rxidle_qs) ); // R[txdata]: V(False) prim_subreg #( .DW (8), .SWACCESS("WO"), .RESVAL (8'h0) ) u_txdata ( .clk_i (clk_i), .rst_ni (rst_ni), // from register interface .we (txdata_we), .wd (txdata_wd), // from internal hardware .de (1'b0), .d ('0), // to internal hardware .qe (reg2hw.txdata.qe), .q (reg2hw.txdata.q), // to register interface (read) .qs () ); // R[rxdata]: V(True) prim_subreg_ext #( .DW (8) ) u_rxdata ( .re (rxdata_re), .we (1'b0), .wd ('0), .d (hw2reg.rxdata.d), .qre (reg2hw.rxdata.re), .qe (), .q (reg2hw.rxdata.q), .qs (rxdata_qs) ); logic [3:0] addr_hit; always_comb begin addr_hit = '0; addr_hit[0] = (reg_addr == UART_CTRL_OFFSET); addr_hit[1] = (reg_addr == UART_STATUS_OFFSET); addr_hit[2] = (reg_addr == UART_TXDATA_OFFSET); addr_hit[3] = (reg_addr == UART_RXDATA_OFFSET); end assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ; // Check sub-word write is permitted always_comb begin wr_err = (reg_we & ((addr_hit[0] & (|(UART_PERMIT[0] & ~reg_be))) | (addr_hit[1] & (|(UART_PERMIT[1] & ~reg_be))) | (addr_hit[2] & (|(UART_PERMIT[2] & ~reg_be))) | (addr_hit[3] & (|(UART_PERMIT[3] & ~reg_be))))); end assign ctrl_we = addr_hit[0] & reg_we & !reg_error; assign ctrl_tx_en_wd = reg_wdata[0]; assign ctrl_rx_en_wd = reg_wdata[1]; assign ctrl_tx_fifo_empty_int_en_wd = reg_wdata[2]; assign ctrl_rx_fifo_not_empty_int_en_wd = reg_wdata[3]; assign ctrl_tx_fifo_rst_wd = reg_wdata[4]; assign ctrl_rx_fifo_rst_wd = reg_wdata[5]; assign ctrl_baud_div_wd = reg_wdata[31:16]; assign status_re = addr_hit[1] & reg_re & !reg_error; assign txdata_we = addr_hit[2] & reg_we & !reg_error; assign txdata_wd = reg_wdata[7:0]; assign rxdata_re = addr_hit[3] & reg_re & !reg_error; // Read data return always_comb begin reg_rdata_next = '0; unique case (1'b1) addr_hit[0]: begin reg_rdata_next[0] = ctrl_tx_en_qs; reg_rdata_next[1] = ctrl_rx_en_qs; reg_rdata_next[2] = ctrl_tx_fifo_empty_int_en_qs; reg_rdata_next[3] = ctrl_rx_fifo_not_empty_int_en_qs; reg_rdata_next[4] = '0; reg_rdata_next[5] = '0; reg_rdata_next[31:16] = ctrl_baud_div_qs; end addr_hit[1]: begin reg_rdata_next[0] = status_txfull_qs; reg_rdata_next[1] = status_rxfull_qs; reg_rdata_next[2] = status_txempty_qs; reg_rdata_next[3] = status_rxempty_qs; reg_rdata_next[4] = status_txidle_qs; reg_rdata_next[5] = status_rxidle_qs; end addr_hit[2]: begin reg_rdata_next[7:0] = '0; end addr_hit[3]: begin reg_rdata_next[7:0] = rxdata_qs; end default: begin reg_rdata_next = '1; end endcase end // Unused signal tieoff // wdata / byte enable are not always fully used // add a blanket unused statement to handle lint waivers logic unused_wdata; logic unused_be; assign unused_wdata = ^reg_wdata; assign unused_be = ^reg_be; endmodule