hw/ip/prim_generic/rtl/prim_generic_pad_wrapper.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: // Generic, technology independent pad wrapper. This is NOT synthesizable!
   6: 
   7: 
   8: module prim_generic_pad_wrapper #(
   9:   parameter int unsigned AttrDw = 6
  10: ) (
  11:   inout wire         inout_io, // bidirectional pad
  12:   output logic       in_o,     // input data
  13:   input              out_i,    // output data
  14:   input              oe_i,     // output enable
  15:   // additional attributes {drive strength, keeper, pull-up, pull-down, open-drain, invert}
  16:   input [AttrDw-1:0] attr_i
  17: );
  18: 
  19:   // get pad attributes
  20:   logic kp, pu, pd, od, inv;
  21:   typedef enum logic {STRONG_DRIVE = 1'b0, WEAK_DRIVE = 1'b1} drv_e;
  22:   drv_e drv;
  23:   assign {drv, kp, pu, pd, od, inv} = attr_i[5:0];
  24: 
  25:   // input inversion
  26:   assign in_o     = inv ^ inout_io;
  27: 
  28:   // virtual open drain emulation
  29:   logic oe, out;
  30:   assign out      = out_i ^ inv;
  31:   assign oe       = oe_i & ((od & ~out) | ~od);
  32: 
  33: // driving strength attributes are not supported by verilator
  34: `ifdef VERILATOR
  35:   assign inout_io = (oe) ? out : 1'bz;
  36: `else
  37:   // different driver types
  38:   assign (strong0, strong1) inout_io = (oe && drv == STRONG_DRIVE) ? out : 1'bz;
  39:   assign (pull0, pull1)     inout_io = (oe && drv == WEAK_DRIVE)   ? out : 1'bz;
  40:   // pullup / pulldown termination
  41:   assign (highz0, weak1)    inout_io = pu;
  42:   assign (weak0, highz1)    inout_io = ~pd;
  43:   // fake trireg emulation
  44:   assign (weak0, weak1)     inout_io = (kp) ? inout_io : 1'bz;
  45: `endif
  46: 
  47:   // assertions
  48:   `ASSERT_INIT(AttrDwCheck_A, AttrDw >= 7)
  49: 
  50: endmodule : prim_generic_pad_wrapper
  51: