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: