|  | // Copyright lowRISC contributors. | 
|  | // Licensed under the Apache License, Version 2.0, see LICENSE for details. | 
|  | // SPDX-License-Identifier: Apache-2.0 | 
|  | // | 
|  | // This it the padctrl portion that has to be placed into the toplevel. | 
|  | // It basically just wraps the regfile and outputs the configuration bits | 
|  | // to be consumed on the chiplevel. | 
|  | // | 
|  |  | 
|  | `include "prim_assert.sv" | 
|  |  | 
|  | module padctrl import padctrl_reg_pkg::*; ( | 
|  | input                                  clk_i, | 
|  | input                                  rst_ni, | 
|  | // Bus Interface (device) | 
|  | input  tlul_pkg::tl_h2d_t              tl_i, | 
|  | output tlul_pkg::tl_d2h_t              tl_o, | 
|  | // pad attributes to chip level instance | 
|  | output logic[NMioPads-1:0][AttrDw-1:0] mio_attr_o, | 
|  | output logic[NDioPads-1:0][AttrDw-1:0] dio_attr_o | 
|  | ); | 
|  |  | 
|  | ///////////// | 
|  | // Regfile // | 
|  | ///////////// | 
|  |  | 
|  | padctrl_reg2hw_t reg2hw; | 
|  | padctrl_hw2reg_t hw2reg; | 
|  |  | 
|  | padctrl_reg_top u_reg ( | 
|  | .clk_i  , | 
|  | .rst_ni , | 
|  | .tl_i   , | 
|  | .tl_o   , | 
|  | .reg2hw , | 
|  | .hw2reg , | 
|  | .devmode_i(1'b1) | 
|  | ); | 
|  |  | 
|  | //////////////// | 
|  | // HWEXT Regs // | 
|  | //////////////// | 
|  |  | 
|  | logic [NDioPads-1:0][AttrDw-1:0] dio_attr_q; | 
|  | logic [NMioPads-1:0][AttrDw-1:0] mio_attr_q; | 
|  |  | 
|  | always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs | 
|  | if (!rst_ni) begin | 
|  | dio_attr_q <= '0; | 
|  | mio_attr_q <= '0; | 
|  | end else begin | 
|  | // dedicated pads | 
|  | for (int kk = 0; kk < NDioPads; kk++) begin | 
|  | if (reg2hw.dio_pads[kk].qe) begin | 
|  | dio_attr_q[kk] <= reg2hw.dio_pads[kk].q; | 
|  | end | 
|  | end | 
|  | // muxed pads | 
|  | for (int kk = 0; kk < NMioPads; kk++) begin | 
|  | if (reg2hw.mio_pads[kk].qe) begin | 
|  | mio_attr_q[kk] <= reg2hw.mio_pads[kk].q; | 
|  | end | 
|  | end | 
|  | end | 
|  | end | 
|  |  | 
|  | //////////////////////// | 
|  | // Connect attributes // | 
|  | //////////////////////// | 
|  |  | 
|  | // Note that these are not real pad instances. We only query the supported attributes here | 
|  | for (genvar k = 0; k < NDioPads; k++) begin : gen_dio_attr | 
|  | logic [AttrDw-1:0] warl_mask; | 
|  |  | 
|  | prim_generic_pad_wrapper #( | 
|  | .AttrDw   ( AttrDw        ), | 
|  | .WarlOnly ( 1'b1          ) // this prevents instantiation of pad logic | 
|  | ) i_prim_generic_pad_wrapper ( | 
|  | .inout_io (               ), | 
|  | .in_o     (               ), | 
|  | .ie_i     ( 1'b0          ), | 
|  | .out_i    ( 1'b0          ), | 
|  | .oe_i     ( 1'b0          ), | 
|  | .attr_i   ( '0            ), | 
|  | .warl_o   ( warl_mask     ) | 
|  | ); | 
|  |  | 
|  | assign dio_attr_o[k]        = dio_attr_q[k] & warl_mask; | 
|  | assign hw2reg.dio_pads[k].d = dio_attr_q[k] & warl_mask; | 
|  | end | 
|  |  | 
|  | for (genvar k = 0; k < NMioPads; k++) begin : gen_mio_attr | 
|  | logic [AttrDw-1:0] warl_mask; | 
|  |  | 
|  | prim_generic_pad_wrapper #( | 
|  | .AttrDw   ( AttrDw        ), | 
|  | .WarlOnly ( 1'b1          ) // this prevents instantiation of pad logic | 
|  | ) i_prim_generic_pad_wrapper ( | 
|  | .inout_io (               ), | 
|  | .in_o     (               ), | 
|  | .ie_i     ( 1'b0          ), | 
|  | .out_i    ( 1'b0          ), | 
|  | .oe_i     ( 1'b0          ), | 
|  | .attr_i   ( '0            ), | 
|  | .warl_o   ( warl_mask     ) | 
|  | ); | 
|  |  | 
|  | assign mio_attr_o[k]        = mio_attr_q[k] & warl_mask; | 
|  | assign hw2reg.mio_pads[k].d = mio_attr_q[k] & warl_mask; | 
|  | end | 
|  |  | 
|  | //////////////// | 
|  | // Assertions // | 
|  | //////////////// | 
|  |  | 
|  | `ASSERT_KNOWN(TlDValidKnownO_A, tl_o.d_valid) | 
|  | `ASSERT_KNOWN(TlAReadyKnownO_A, tl_o.a_ready) | 
|  | `ASSERT_KNOWN(MioKnownO_A, mio_attr_o) | 
|  | `ASSERT_KNOWN(DioKnownO_A, dio_attr_o) | 
|  |  | 
|  | endmodule : padctrl |