// 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 gpio_reg_top ( input logic clk_i, input logic rst_ni, // To HW output gpio_reg_pkg::gpio_reg2hw_t reg2hw, // Write input gpio_reg_pkg::gpio_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 gpio_reg_pkg::* ; localparam int AW = 5; 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 io_mode_we; logic [31:0] io_mode_qs; logic [31:0] io_mode_wd; logic int_mode_we; logic [31:0] int_mode_qs; logic [31:0] int_mode_wd; logic int_pending_we; logic [15:0] int_pending_qs; logic [15:0] int_pending_wd; logic data_we; logic [15:0] data_qs; logic [15:0] data_wd; logic filter_we; logic [15:0] filter_qs; logic [15:0] filter_wd; // Register instances // R[io_mode]: V(False) prim_subreg #( .DW (32), .SWACCESS("RW"), .RESVAL (32'h0) ) u_io_mode ( .clk_i (clk_i), .rst_ni (rst_ni), // from register interface .we (io_mode_we), .wd (io_mode_wd), // from internal hardware .de (1'b0), .d ('0), // to internal hardware .qe (), .q (reg2hw.io_mode.q), // to register interface (read) .qs (io_mode_qs) ); // R[int_mode]: V(False) prim_subreg #( .DW (32), .SWACCESS("RW"), .RESVAL (32'h0) ) u_int_mode ( .clk_i (clk_i), .rst_ni (rst_ni), // from register interface .we (int_mode_we), .wd (int_mode_wd), // from internal hardware .de (1'b0), .d ('0), // to internal hardware .qe (), .q (reg2hw.int_mode.q), // to register interface (read) .qs (int_mode_qs) ); // R[int_pending]: V(False) prim_subreg #( .DW (16), .SWACCESS("W1C"), .RESVAL (16'h0) ) u_int_pending ( .clk_i (clk_i), .rst_ni (rst_ni), // from register interface .we (int_pending_we), .wd (int_pending_wd), // from internal hardware .de (hw2reg.int_pending.de), .d (hw2reg.int_pending.d), // to internal hardware .qe (), .q (reg2hw.int_pending.q), // to register interface (read) .qs (int_pending_qs) ); // R[data]: V(False) prim_subreg #( .DW (16), .SWACCESS("RW"), .RESVAL (16'h0) ) u_data ( .clk_i (clk_i), .rst_ni (rst_ni), // from register interface .we (data_we), .wd (data_wd), // from internal hardware .de (hw2reg.data.de), .d (hw2reg.data.d), // to internal hardware .qe (), .q (reg2hw.data.q), // to register interface (read) .qs (data_qs) ); // R[filter]: V(False) prim_subreg #( .DW (16), .SWACCESS("RW"), .RESVAL (16'h0) ) u_filter ( .clk_i (clk_i), .rst_ni (rst_ni), // from register interface .we (filter_we), .wd (filter_wd), // from internal hardware .de (1'b0), .d ('0), // to internal hardware .qe (), .q (reg2hw.filter.q), // to register interface (read) .qs (filter_qs) ); logic [4:0] addr_hit; always_comb begin addr_hit = '0; addr_hit[0] = (reg_addr == GPIO_IO_MODE_OFFSET); addr_hit[1] = (reg_addr == GPIO_INT_MODE_OFFSET); addr_hit[2] = (reg_addr == GPIO_INT_PENDING_OFFSET); addr_hit[3] = (reg_addr == GPIO_DATA_OFFSET); addr_hit[4] = (reg_addr == GPIO_FILTER_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] & (|(GPIO_PERMIT[0] & ~reg_be))) | (addr_hit[1] & (|(GPIO_PERMIT[1] & ~reg_be))) | (addr_hit[2] & (|(GPIO_PERMIT[2] & ~reg_be))) | (addr_hit[3] & (|(GPIO_PERMIT[3] & ~reg_be))) | (addr_hit[4] & (|(GPIO_PERMIT[4] & ~reg_be))))); end assign io_mode_we = addr_hit[0] & reg_we & !reg_error; assign io_mode_wd = reg_wdata[31:0]; assign int_mode_we = addr_hit[1] & reg_we & !reg_error; assign int_mode_wd = reg_wdata[31:0]; assign int_pending_we = addr_hit[2] & reg_we & !reg_error; assign int_pending_wd = reg_wdata[15:0]; assign data_we = addr_hit[3] & reg_we & !reg_error; assign data_wd = reg_wdata[15:0]; assign filter_we = addr_hit[4] & reg_we & !reg_error; assign filter_wd = reg_wdata[15:0]; // Read data return always_comb begin reg_rdata_next = '0; unique case (1'b1) addr_hit[0]: begin reg_rdata_next[31:0] = io_mode_qs; end addr_hit[1]: begin reg_rdata_next[31:0] = int_mode_qs; end addr_hit[2]: begin reg_rdata_next[15:0] = int_pending_qs; end addr_hit[3]: begin reg_rdata_next[15:0] = data_qs; end addr_hit[4]: begin reg_rdata_next[15:0] = filter_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