blob: f011e38511c4f2efa9047ef3ce848f03f45683b0 [file] [log] [blame]
agorararmard6c766a82020-12-10 18:13:12 +02001// SPDX-FileCopyrightText: 2020 Efabless Corporation
agorararmarde5780bf2020-12-09 21:27:56 +00002//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
agorararmardafa96ea2020-12-09 23:37:31 +020014// SPDX-License-Identifier: Apache-2.0
agorararmarde5780bf2020-12-09 21:27:56 +000015
Matt Venn08cd6eb2020-11-16 12:01:14 +010016`default_nettype none
Tim Edwards04ba17f2020-10-02 22:27:50 -040017/*
18 *---------------------------------------------------------------------
Tim Edwards251e0df2020-10-05 11:02:12 -040019 * See gpio_control_block for description. This module is like
20 * gpio_contro_block except that it has an additional two management-
21 * Soc-facing pins, which are the out_enb line and the output line.
22 * If the chip is configured for output with the oeb control
23 * register = 1, then the oeb line is controlled by the additional
24 * signal from the management SoC. If the oeb control register = 0,
25 * then the output is disabled completely. The "io" line is input
26 * only in this module.
Tim Edwards04ba17f2020-10-02 22:27:50 -040027 *
28 *---------------------------------------------------------------------
29 */
30
31/*
32 *---------------------------------------------------------------------
33 *
34 * This module instantiates a shift register chain that passes through
35 * each gpio cell. These are connected end-to-end around the padframe
36 * periphery. The purpose is to avoid a massive number of control
37 * wires between the digital core and I/O, passing through the user area.
38 *
39 * See mprj_ctrl.v for the module that registers the data for each
40 * I/O and drives the input to the shift register.
41 *
42 *---------------------------------------------------------------------
43 */
44
45module gpio_control_block #(
Tim Edwards44bab472020-10-04 22:09:54 -040046 parameter PAD_CTRL_BITS = 13,
47 // Parameterized initial startup state of the pad.
48 // The default parameters if unspecified is for the pad to be
49 // an input with no pull-up or pull-down, so that it is disconnected
50 // from the outside world.
51 parameter HOLD_INIT = 1'b0,
52 parameter SLOW_INIT = 1'b0,
53 parameter TRIP_INIT = 1'b0,
54 parameter IB_INIT = 1'b0,
55 parameter IENB_INIT = 1'b0,
manarabdelaty589a5282020-12-05 01:06:48 +020056 parameter OENB_INIT = `OENB_INIT,
57 parameter DM_INIT = `DM_INIT,
Tim Edwards44bab472020-10-04 22:09:54 -040058 parameter AENA_INIT = 1'b0,
59 parameter ASEL_INIT = 1'b0,
60 parameter APOL_INIT = 1'b0
Tim Edwards04ba17f2020-10-02 22:27:50 -040061) (
Manar61dce922020-11-10 19:26:28 +020062 `ifdef USE_POWER_PINS
Tim Edwards53d92182020-10-11 21:47:40 -040063 inout vccd,
64 inout vssd,
65 inout vccd1,
66 inout vssd1,
67 `endif
68
Tim Edwards04ba17f2020-10-02 22:27:50 -040069 // Management Soc-facing signals
70 input resetn, // Global reset
71 input serial_clock,
72
Tim Edwards251e0df2020-10-05 11:02:12 -040073 output mgmt_gpio_in, // Management from pad (input only)
74 input mgmt_gpio_out, // Management to pad (output only)
75 input mgmt_gpio_oeb, // Management to pad (output only)
Tim Edwards04ba17f2020-10-02 22:27:50 -040076
77 // Serial data chain for pad configuration
78 input serial_data_in,
79 output serial_data_out,
80
81 // User-facing signals
82 input user_gpio_out, // User space to pad
Tim Edwards44bab472020-10-04 22:09:54 -040083 input user_gpio_oeb, // Output enable (user)
Tim Edwards04ba17f2020-10-02 22:27:50 -040084 output user_gpio_in, // Pad to user space
85
86 // Pad-facing signals (Pad GPIOv2)
87 output pad_gpio_holdover,
88 output pad_gpio_slow_sel,
89 output pad_gpio_vtrip_sel,
90 output pad_gpio_inenb,
91 output pad_gpio_ib_mode_sel,
92 output pad_gpio_ana_en,
93 output pad_gpio_ana_sel,
94 output pad_gpio_ana_pol,
95 output [2:0] pad_gpio_dm,
Tim Edwards251e0df2020-10-05 11:02:12 -040096 output pad_gpio_outenb,
Tim Edwards04ba17f2020-10-02 22:27:50 -040097 output pad_gpio_out,
Ahmed Ghazyd0dcdcf2020-12-15 22:00:25 +020098 input pad_gpio_in,
99
100 // to provide a way to automatically disable/enable output
101 // from the outside with needing a conb cell
102 output one,
103 output zero
Tim Edwards04ba17f2020-10-02 22:27:50 -0400104);
105
106 /* Parameters defining the bit offset of each function in the chain */
107 localparam MGMT_EN = 0;
108 localparam OEB = 1;
109 localparam HLDH = 2;
Tim Edwards251e0df2020-10-05 11:02:12 -0400110 localparam INP_DIS = 3;
Tim Edwards44bab472020-10-04 22:09:54 -0400111 localparam MOD_SEL = 4;
112 localparam AN_EN = 5;
113 localparam AN_SEL = 6;
114 localparam AN_POL = 7;
115 localparam SLOW = 8;
116 localparam TRIP = 9;
117 localparam DM = 10;
Tim Edwards04ba17f2020-10-02 22:27:50 -0400118
119 /* Internally registered signals */
120 reg mgmt_ena; // Enable management SoC to access pad
121 reg gpio_holdover;
122 reg gpio_slow_sel;
123 reg gpio_vtrip_sel;
124 reg gpio_inenb;
125 reg gpio_ib_mode_sel;
126 reg gpio_outenb;
127 reg [2:0] gpio_dm;
128 reg gpio_ana_en;
129 reg gpio_ana_sel;
130 reg gpio_ana_pol;
131
132 /* Derived output values */
133 wire pad_gpio_holdover;
134 wire pad_gpio_slow_sel;
135 wire pad_gpio_vtrip_sel;
136 wire pad_gpio_inenb;
137 wire pad_gpio_ib_mode_sel;
138 wire pad_gpio_ana_en;
139 wire pad_gpio_ana_sel;
140 wire pad_gpio_ana_pol;
141 wire [2:0] pad_gpio_dm;
142 wire pad_gpio_outenb;
143 wire pad_gpio_out;
144 wire pad_gpio_in;
Ahmed Ghazyd0dcdcf2020-12-15 22:00:25 +0200145 wire one;
146 wire zero;
Tim Edwards04ba17f2020-10-02 22:27:50 -0400147
Tim Edwards53d92182020-10-11 21:47:40 -0400148 wire user_gpio_in;
149 wire gpio_in_unbuf;
Tim Edwards581068f2020-11-19 12:45:25 -0500150 wire gpio_logic1;
Tim Edwards53d92182020-10-11 21:47:40 -0400151
Tim Edwards04ba17f2020-10-02 22:27:50 -0400152 /* Serial shift for the above (latched) values */
153 reg [PAD_CTRL_BITS-1:0] shift_register;
154
155 /* Utilize reset and clock to encode a load operation */
156 wire load_data;
157 wire int_reset;
158
159 /* Create internal reset and load signals from input reset and clock */
160 assign serial_data_out = shift_register[PAD_CTRL_BITS-1];
161 assign int_reset = (~resetn) & (~serial_clock);
162 assign load_data = (~resetn) & serial_clock;
163
164 always @(posedge serial_clock or posedge int_reset) begin
165 if (int_reset == 1'b1) begin
166 /* Clear shift register */
167 shift_register <= 'd0;
168 end else begin
169 /* Shift data in */
170 shift_register <= {shift_register[PAD_CTRL_BITS-2:0], serial_data_in};
171 end
172 end
173
174 always @(posedge load_data or posedge int_reset) begin
175 if (int_reset == 1'b1) begin
176 /* Initial state on reset: Pad set to management input */
Tim Edwards44bab472020-10-04 22:09:54 -0400177 mgmt_ena <= 1'b1; // Management SoC has control over all I/O
178 gpio_holdover <= HOLD_INIT; // All signals latched in hold mode
179 gpio_slow_sel <= SLOW_INIT; // Fast slew rate
180 gpio_vtrip_sel <= TRIP_INIT; // CMOS mode
181 gpio_ib_mode_sel <= IB_INIT; // CMOS mode
182 gpio_inenb <= IENB_INIT; // Input enabled
Tim Edwards251e0df2020-10-05 11:02:12 -0400183 gpio_outenb <= OENB_INIT; // (unused placeholder)
Tim Edwards44bab472020-10-04 22:09:54 -0400184 gpio_dm <= DM_INIT; // Configured as input only
185 gpio_ana_en <= AENA_INIT; // Digital enabled
186 gpio_ana_sel <= ASEL_INIT; // Don't-care when gpio_ana_en = 0
187 gpio_ana_pol <= APOL_INIT; // Don't-care when gpio_ana_en = 0
Tim Edwards04ba17f2020-10-02 22:27:50 -0400188 end else begin
189 /* Load data */
190 mgmt_ena <= shift_register[MGMT_EN];
191 gpio_outenb <= shift_register[OEB];
192 gpio_holdover <= shift_register[HLDH];
193 gpio_inenb <= shift_register[INP_DIS];
194 gpio_ib_mode_sel <= shift_register[MOD_SEL];
195 gpio_ana_en <= shift_register[AN_EN];
196 gpio_ana_sel <= shift_register[AN_SEL];
197 gpio_ana_pol <= shift_register[AN_POL];
198 gpio_slow_sel <= shift_register[SLOW];
199 gpio_vtrip_sel <= shift_register[TRIP];
200 gpio_dm <= shift_register[DM+2:DM];
201
202 end
203 end
204
205 /* These pad configuration signals are static and do not change */
206 /* after setup. */
207
208 assign pad_gpio_holdover = gpio_holdover;
209 assign pad_gpio_slow_sel = gpio_slow_sel;
210 assign pad_gpio_vtrip_sel = gpio_vtrip_sel;
211 assign pad_gpio_ib_mode_sel = gpio_ib_mode_sel;
212 assign pad_gpio_ana_en = gpio_ana_en;
213 assign pad_gpio_ana_sel = gpio_ana_sel;
214 assign pad_gpio_ana_pol = gpio_ana_pol;
215 assign pad_gpio_dm = gpio_dm;
216 assign pad_gpio_inenb = gpio_inenb;
217
218 /* Implement pad control behavior depending on state of mgmt_ena */
219
Tim Edwards33f5f6f2020-12-15 11:38:13 -0500220// assign gpio_in_unbuf = (mgmt_ena) ? 1'b0 : pad_gpio_in;
221// assign mgmt_gpio_in = (mgmt_ena) ? ((gpio_inenb == 1'b0) ?
222// pad_gpio_in : 1'bz) : 1'b0;
223
224 assign gpio_in_unbuf = pad_gpio_in;
225 assign mgmt_gpio_in = (gpio_inenb == 1'b0) ? pad_gpio_in : 1'bz;
Tim Edwards89f09242020-10-05 15:17:34 -0400226
227 assign pad_gpio_outenb = (mgmt_ena) ? ((mgmt_gpio_oeb == 1'b1) ? gpio_outenb :
228 1'b0) : user_gpio_oeb;
229 assign pad_gpio_out = (mgmt_ena) ?
230 ((mgmt_gpio_oeb == 1'b1) ?
231 ((gpio_dm[2:1] == 2'b01) ? ~gpio_dm[0] : mgmt_gpio_out) :
232 mgmt_gpio_out) :
233 user_gpio_out;
234
Tim Edwards53d92182020-10-11 21:47:40 -0400235 /* Buffer user_gpio_in with an enable that is set by the user domain vccd */
236
237 sky130_fd_sc_hd__conb_1 gpio_logic_high (
Ahmed Ghazy64c17e82020-11-18 20:17:26 +0200238`ifdef USE_POWER_PINS
Tim Edwards53d92182020-10-11 21:47:40 -0400239 .VPWR(vccd1),
240 .VGND(vssd1),
241 .VPB(vccd1),
242 .VNB(vssd1),
Ahmed Ghazy64c17e82020-11-18 20:17:26 +0200243`endif
Tim Edwards53d92182020-10-11 21:47:40 -0400244 .HI(gpio_logic1),
245 .LO()
246 );
247
248 sky130_fd_sc_hd__einvp_8 gpio_in_buf (
Ahmed Ghazy64c17e82020-11-18 20:17:26 +0200249`ifdef USE_POWER_PINS
Tim Edwards53d92182020-10-11 21:47:40 -0400250 .VPWR(vccd),
251 .VGND(vssd),
252 .VPB(vccd),
253 .VNB(vssd),
Ahmed Ghazy64c17e82020-11-18 20:17:26 +0200254`endif
Tim Edwards53d92182020-10-11 21:47:40 -0400255 .Z(user_gpio_in),
256 .A(~gpio_in_unbuf),
257 .TE(gpio_logic1)
258 );
Tim Edwards04ba17f2020-10-02 22:27:50 -0400259
Ahmed Ghazyd0dcdcf2020-12-15 22:00:25 +0200260 sky130_fd_sc_hd__conb_1 const_source (
261`ifdef USE_POWER_PINS
262 .VPWR(vccd),
263 .VGND(vssd),
264 .VPB(vccd),
265 .VNB(vssd),
266`endif
267 .HI(one),
268 .LO(zero)
269 );
270
Tim Edwards04ba17f2020-10-02 22:27:50 -0400271endmodule
Tim Edwards581068f2020-11-19 12:45:25 -0500272`default_nettype wire