../src/lowrisc_ip_padctrl_component_0.1/rtl/padctrl.sv Cov: 91.1%

   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: // This it the padctrl portion that has to be placed into the toplevel.
   6: // It basically just wraps the regfile and outputs the configuration bits
   7: // to be consumed on the chiplevel.
   8: //
   9: 
  10: `include "prim_assert.sv"
  11: 
  12: `ifndef PRIM_DEFAULT_IMPL
  13:   `define PRIM_DEFAULT_IMPL prim_pkg::ImplGeneric
  14: `endif
  15: 
  16: module padctrl import padctrl_reg_pkg::*; #(
  17:   parameter prim_pkg::impl_e Impl = `PRIM_DEFAULT_IMPL
  18: ) (
  19:   input                                  clk_i,
  20:   input                                  rst_ni,
  21:   // Bus Interface (device)
  22:   input  tlul_pkg::tl_h2d_t              tl_i,
  23:   output tlul_pkg::tl_d2h_t              tl_o,
  24:   // pad attributes to chip level instance
  25:   output logic[NMioPads-1:0][AttrDw-1:0] mio_attr_o,
  26:   output logic[NDioPads-1:0][AttrDw-1:0] dio_attr_o
  27: );
  28: 
  29:   //////////////////
  30:   // WARL Control //
  31:   //////////////////
  32: 
  33:   // This controls the WARL'ness of the CSRs
  34:   // needs to be in line with the corresponding
  35:   // prim_pad_wrapper implementation
  36:   logic [AttrDw-1:0] warl_mask;
  37:   if (Impl == prim_pkg::ImplGeneric) begin : gen_generic
  38:     // all attributes supported
  39:     assign warl_mask = AttrDw'(6'h3F);
  40:   end else if (Impl == prim_pkg::ImplXilinx) begin : gen_xilinx
  41:     // only OD and INV supported
  42:     assign warl_mask = AttrDw'(2'h3);
  43:   end else begin : gen_others
  44:     // all attributes supported
  45:     assign warl_mask = AttrDw'(6'h3F);
  46:   end
  47: 
  48:   /////////////
  49:   // Regfile //
  50:   /////////////
  51: 
  52:   padctrl_reg2hw_t reg2hw;
  53:   padctrl_hw2reg_t hw2reg;
  54: 
  55:   padctrl_reg_top i_reg_top (
  56:     .clk_i  ,
  57:     .rst_ni ,
  58:     .tl_i   ,
  59:     .tl_o   ,
  60:     .reg2hw ,
  61:     .hw2reg ,
  62:     .devmode_i(1'b1)
  63:   );
  64: 
  65:   ////////////////
  66:   // HWEXT Regs //
  67:   ////////////////
  68: 
  69:   logic [NDioPads-1:0][AttrDw-1:0] dio_attr_q;
  70:   logic [NMioPads-1:0][AttrDw-1:0] mio_attr_q;
  71: 
  72:   always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
  73:     if (!rst_ni) begin
  74:       dio_attr_q <= '0;
  75:       mio_attr_q <= '0;
  76:     end else begin
  77:       // dedicated pads
  78:       for (int kk = 0; kk < NDioPads; kk++) begin
  79:         if (reg2hw.dio_pads[kk].qe) begin
  80:           dio_attr_q[kk] <= reg2hw.dio_pads[kk].q;
  81:         end
  82:       end
  83:       // muxed pads
  84:       for (int kk = 0; kk < NMioPads; kk++) begin
  85:         if (reg2hw.mio_pads[kk].qe) begin
  86:           mio_attr_q[kk] <= reg2hw.mio_pads[kk].q;
  87:         end
  88:       end
  89:     end
  90:   end
  91: 
  92:   ////////////////////////
  93:   // Connect attributes //
  94:   ////////////////////////
  95: 
  96:   // using the warl_mask here instead instead of in the register assignment above
  97:   // avoids lint errors. the unused registers can be removed automatically by most tools.
  98:   for (genvar k = 0; k < NDioPads; k++) begin : gen_dio_attr
  99:     assign dio_attr_o[k]        = dio_attr_q[k] & warl_mask;
 100:     assign hw2reg.dio_pads[k].d = dio_attr_q[k] & warl_mask;
 101:   end
 102: 
 103:   for (genvar k = 0; k < NMioPads; k++) begin : gen_mio_attr
 104:     assign mio_attr_o[k]        = mio_attr_q[k] & warl_mask;
 105:     assign hw2reg.mio_pads[k].d = mio_attr_q[k] & warl_mask;
 106:   end
 107: 
 108:   ////////////////
 109:   // Assertions //
 110:   ////////////////
 111: 
 112:   `ASSERT_KNOWN(TlDValidKnownO_A, tl_o.d_valid)
 113:   `ASSERT_KNOWN(TlAReadyKnownO_A, tl_o.a_ready)
 114:   `ASSERT_KNOWN(MioKnownO_A, mio_attr_o)
 115:   `ASSERT_KNOWN(DioKnownO_A, dio_attr_o)
 116: 
 117: endmodule : padctrl
 118: