blob: 5d3adb12af8ed0efff4abe1ed732c8f711bebe53 [file] [log] [blame]
Tim Edwards04ba17f2020-10-02 22:27:50 -04001/*
2 *---------------------------------------------------------------------
Tim Edwards251e0df2020-10-05 11:02:12 -04003 * See gpio_control_block for description. This module is like
4 * gpio_contro_block except that it has an additional two management-
5 * Soc-facing pins, which are the out_enb line and the output line.
6 * If the chip is configured for output with the oeb control
7 * register = 1, then the oeb line is controlled by the additional
8 * signal from the management SoC. If the oeb control register = 0,
9 * then the output is disabled completely. The "io" line is input
10 * only in this module.
Tim Edwards04ba17f2020-10-02 22:27:50 -040011 *
12 *---------------------------------------------------------------------
13 */
14
15/*
16 *---------------------------------------------------------------------
17 *
18 * This module instantiates a shift register chain that passes through
19 * each gpio cell. These are connected end-to-end around the padframe
20 * periphery. The purpose is to avoid a massive number of control
21 * wires between the digital core and I/O, passing through the user area.
22 *
23 * See mprj_ctrl.v for the module that registers the data for each
24 * I/O and drives the input to the shift register.
25 *
26 *---------------------------------------------------------------------
27 */
28
29module gpio_control_block #(
Tim Edwards44bab472020-10-04 22:09:54 -040030 parameter PAD_CTRL_BITS = 13,
31 // Parameterized initial startup state of the pad.
32 // The default parameters if unspecified is for the pad to be
33 // an input with no pull-up or pull-down, so that it is disconnected
34 // from the outside world.
35 parameter HOLD_INIT = 1'b0,
36 parameter SLOW_INIT = 1'b0,
37 parameter TRIP_INIT = 1'b0,
38 parameter IB_INIT = 1'b0,
39 parameter IENB_INIT = 1'b0,
40 parameter OENB_INIT = 1'b1,
41 parameter DM_INIT = 3'b001,
42 parameter AENA_INIT = 1'b0,
43 parameter ASEL_INIT = 1'b0,
44 parameter APOL_INIT = 1'b0
Tim Edwards04ba17f2020-10-02 22:27:50 -040045) (
46 // Management Soc-facing signals
47 input resetn, // Global reset
48 input serial_clock,
49
Tim Edwards251e0df2020-10-05 11:02:12 -040050 output mgmt_gpio_in, // Management from pad (input only)
51 input mgmt_gpio_out, // Management to pad (output only)
52 input mgmt_gpio_oeb, // Management to pad (output only)
Tim Edwards04ba17f2020-10-02 22:27:50 -040053
54 // Serial data chain for pad configuration
55 input serial_data_in,
56 output serial_data_out,
57
58 // User-facing signals
59 input user_gpio_out, // User space to pad
Tim Edwards44bab472020-10-04 22:09:54 -040060 input user_gpio_oeb, // Output enable (user)
Tim Edwards04ba17f2020-10-02 22:27:50 -040061 output user_gpio_in, // Pad to user space
62
63 // Pad-facing signals (Pad GPIOv2)
64 output pad_gpio_holdover,
65 output pad_gpio_slow_sel,
66 output pad_gpio_vtrip_sel,
67 output pad_gpio_inenb,
68 output pad_gpio_ib_mode_sel,
69 output pad_gpio_ana_en,
70 output pad_gpio_ana_sel,
71 output pad_gpio_ana_pol,
72 output [2:0] pad_gpio_dm,
Tim Edwards251e0df2020-10-05 11:02:12 -040073 output pad_gpio_outenb,
Tim Edwards04ba17f2020-10-02 22:27:50 -040074 output pad_gpio_out,
75 input pad_gpio_in
76);
77
78 /* Parameters defining the bit offset of each function in the chain */
79 localparam MGMT_EN = 0;
80 localparam OEB = 1;
81 localparam HLDH = 2;
Tim Edwards251e0df2020-10-05 11:02:12 -040082 localparam INP_DIS = 3;
Tim Edwards44bab472020-10-04 22:09:54 -040083 localparam MOD_SEL = 4;
84 localparam AN_EN = 5;
85 localparam AN_SEL = 6;
86 localparam AN_POL = 7;
87 localparam SLOW = 8;
88 localparam TRIP = 9;
89 localparam DM = 10;
Tim Edwards04ba17f2020-10-02 22:27:50 -040090
91 /* Internally registered signals */
92 reg mgmt_ena; // Enable management SoC to access pad
93 reg gpio_holdover;
94 reg gpio_slow_sel;
95 reg gpio_vtrip_sel;
96 reg gpio_inenb;
97 reg gpio_ib_mode_sel;
98 reg gpio_outenb;
99 reg [2:0] gpio_dm;
100 reg gpio_ana_en;
101 reg gpio_ana_sel;
102 reg gpio_ana_pol;
103
104 /* Derived output values */
105 wire pad_gpio_holdover;
106 wire pad_gpio_slow_sel;
107 wire pad_gpio_vtrip_sel;
108 wire pad_gpio_inenb;
109 wire pad_gpio_ib_mode_sel;
110 wire pad_gpio_ana_en;
111 wire pad_gpio_ana_sel;
112 wire pad_gpio_ana_pol;
113 wire [2:0] pad_gpio_dm;
114 wire pad_gpio_outenb;
115 wire pad_gpio_out;
116 wire pad_gpio_in;
117
118 /* Serial shift for the above (latched) values */
119 reg [PAD_CTRL_BITS-1:0] shift_register;
120
121 /* Utilize reset and clock to encode a load operation */
122 wire load_data;
123 wire int_reset;
124
125 /* Create internal reset and load signals from input reset and clock */
126 assign serial_data_out = shift_register[PAD_CTRL_BITS-1];
127 assign int_reset = (~resetn) & (~serial_clock);
128 assign load_data = (~resetn) & serial_clock;
129
130 always @(posedge serial_clock or posedge int_reset) begin
131 if (int_reset == 1'b1) begin
132 /* Clear shift register */
133 shift_register <= 'd0;
134 end else begin
135 /* Shift data in */
136 shift_register <= {shift_register[PAD_CTRL_BITS-2:0], serial_data_in};
137 end
138 end
139
140 always @(posedge load_data or posedge int_reset) begin
141 if (int_reset == 1'b1) begin
142 /* Initial state on reset: Pad set to management input */
Tim Edwards44bab472020-10-04 22:09:54 -0400143 mgmt_ena <= 1'b1; // Management SoC has control over all I/O
144 gpio_holdover <= HOLD_INIT; // All signals latched in hold mode
145 gpio_slow_sel <= SLOW_INIT; // Fast slew rate
146 gpio_vtrip_sel <= TRIP_INIT; // CMOS mode
147 gpio_ib_mode_sel <= IB_INIT; // CMOS mode
148 gpio_inenb <= IENB_INIT; // Input enabled
Tim Edwards251e0df2020-10-05 11:02:12 -0400149 gpio_outenb <= OENB_INIT; // (unused placeholder)
Tim Edwards44bab472020-10-04 22:09:54 -0400150 gpio_dm <= DM_INIT; // Configured as input only
151 gpio_ana_en <= AENA_INIT; // Digital enabled
152 gpio_ana_sel <= ASEL_INIT; // Don't-care when gpio_ana_en = 0
153 gpio_ana_pol <= APOL_INIT; // Don't-care when gpio_ana_en = 0
Tim Edwards04ba17f2020-10-02 22:27:50 -0400154 end else begin
155 /* Load data */
156 mgmt_ena <= shift_register[MGMT_EN];
157 gpio_outenb <= shift_register[OEB];
158 gpio_holdover <= shift_register[HLDH];
159 gpio_inenb <= shift_register[INP_DIS];
160 gpio_ib_mode_sel <= shift_register[MOD_SEL];
161 gpio_ana_en <= shift_register[AN_EN];
162 gpio_ana_sel <= shift_register[AN_SEL];
163 gpio_ana_pol <= shift_register[AN_POL];
164 gpio_slow_sel <= shift_register[SLOW];
165 gpio_vtrip_sel <= shift_register[TRIP];
166 gpio_dm <= shift_register[DM+2:DM];
167
168 end
169 end
170
171 /* These pad configuration signals are static and do not change */
172 /* after setup. */
173
174 assign pad_gpio_holdover = gpio_holdover;
175 assign pad_gpio_slow_sel = gpio_slow_sel;
176 assign pad_gpio_vtrip_sel = gpio_vtrip_sel;
177 assign pad_gpio_ib_mode_sel = gpio_ib_mode_sel;
178 assign pad_gpio_ana_en = gpio_ana_en;
179 assign pad_gpio_ana_sel = gpio_ana_sel;
180 assign pad_gpio_ana_pol = gpio_ana_pol;
181 assign pad_gpio_dm = gpio_dm;
182 assign pad_gpio_inenb = gpio_inenb;
183
184 /* Implement pad control behavior depending on state of mgmt_ena */
185
Tim Edwards251e0df2020-10-05 11:02:12 -0400186 assign pad_gpio_out = (mgmt_ena) ? mgmt_gpio_out : user_gpio_out;
187 assign pad_gpio_outenb = (mgmt_ena) ? mgmt_gpio_oeb : user_gpio_oeb;
Tim Edwards04ba17f2020-10-02 22:27:50 -0400188
Tim Edwards251e0df2020-10-05 11:02:12 -0400189 assign user_gpio_in = (mgmt_ena) ? 1'b0 : pad_gpio_in;
190 assign mgmt_gpio_in = (mgmt_ena) ? pad_gpio_in : 1'b0;
Tim Edwards04ba17f2020-10-02 22:27:50 -0400191
192endmodule