blob: 681da94d51fdf19ceadc7476890c9da481e4d7e8 [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) (
Tim Edwards53d92182020-10-11 21:47:40 -040046 `ifdef LVS
47 inout vccd,
48 inout vssd,
49 inout vccd1,
50 inout vssd1,
51 `endif
52
Tim Edwards04ba17f2020-10-02 22:27:50 -040053 // Management Soc-facing signals
54 input resetn, // Global reset
55 input serial_clock,
56
Tim Edwards251e0df2020-10-05 11:02:12 -040057 output mgmt_gpio_in, // Management from pad (input only)
58 input mgmt_gpio_out, // Management to pad (output only)
59 input mgmt_gpio_oeb, // Management to pad (output only)
Tim Edwards04ba17f2020-10-02 22:27:50 -040060
61 // Serial data chain for pad configuration
62 input serial_data_in,
63 output serial_data_out,
64
65 // User-facing signals
66 input user_gpio_out, // User space to pad
Tim Edwards44bab472020-10-04 22:09:54 -040067 input user_gpio_oeb, // Output enable (user)
Tim Edwards04ba17f2020-10-02 22:27:50 -040068 output user_gpio_in, // Pad to user space
69
70 // Pad-facing signals (Pad GPIOv2)
71 output pad_gpio_holdover,
72 output pad_gpio_slow_sel,
73 output pad_gpio_vtrip_sel,
74 output pad_gpio_inenb,
75 output pad_gpio_ib_mode_sel,
76 output pad_gpio_ana_en,
77 output pad_gpio_ana_sel,
78 output pad_gpio_ana_pol,
79 output [2:0] pad_gpio_dm,
Tim Edwards251e0df2020-10-05 11:02:12 -040080 output pad_gpio_outenb,
Tim Edwards04ba17f2020-10-02 22:27:50 -040081 output pad_gpio_out,
82 input pad_gpio_in
83);
84
85 /* Parameters defining the bit offset of each function in the chain */
86 localparam MGMT_EN = 0;
87 localparam OEB = 1;
88 localparam HLDH = 2;
Tim Edwards251e0df2020-10-05 11:02:12 -040089 localparam INP_DIS = 3;
Tim Edwards44bab472020-10-04 22:09:54 -040090 localparam MOD_SEL = 4;
91 localparam AN_EN = 5;
92 localparam AN_SEL = 6;
93 localparam AN_POL = 7;
94 localparam SLOW = 8;
95 localparam TRIP = 9;
96 localparam DM = 10;
Tim Edwards04ba17f2020-10-02 22:27:50 -040097
98 /* Internally registered signals */
99 reg mgmt_ena; // Enable management SoC to access pad
100 reg gpio_holdover;
101 reg gpio_slow_sel;
102 reg gpio_vtrip_sel;
103 reg gpio_inenb;
104 reg gpio_ib_mode_sel;
105 reg gpio_outenb;
106 reg [2:0] gpio_dm;
107 reg gpio_ana_en;
108 reg gpio_ana_sel;
109 reg gpio_ana_pol;
110
111 /* Derived output values */
112 wire pad_gpio_holdover;
113 wire pad_gpio_slow_sel;
114 wire pad_gpio_vtrip_sel;
115 wire pad_gpio_inenb;
116 wire pad_gpio_ib_mode_sel;
117 wire pad_gpio_ana_en;
118 wire pad_gpio_ana_sel;
119 wire pad_gpio_ana_pol;
120 wire [2:0] pad_gpio_dm;
121 wire pad_gpio_outenb;
122 wire pad_gpio_out;
123 wire pad_gpio_in;
124
Tim Edwards53d92182020-10-11 21:47:40 -0400125 wire user_gpio_in;
126 wire gpio_in_unbuf;
127
Tim Edwards04ba17f2020-10-02 22:27:50 -0400128 /* Serial shift for the above (latched) values */
129 reg [PAD_CTRL_BITS-1:0] shift_register;
130
131 /* Utilize reset and clock to encode a load operation */
132 wire load_data;
133 wire int_reset;
134
135 /* Create internal reset and load signals from input reset and clock */
136 assign serial_data_out = shift_register[PAD_CTRL_BITS-1];
137 assign int_reset = (~resetn) & (~serial_clock);
138 assign load_data = (~resetn) & serial_clock;
139
140 always @(posedge serial_clock or posedge int_reset) begin
141 if (int_reset == 1'b1) begin
142 /* Clear shift register */
143 shift_register <= 'd0;
144 end else begin
145 /* Shift data in */
146 shift_register <= {shift_register[PAD_CTRL_BITS-2:0], serial_data_in};
147 end
148 end
149
150 always @(posedge load_data or posedge int_reset) begin
151 if (int_reset == 1'b1) begin
152 /* Initial state on reset: Pad set to management input */
Tim Edwards44bab472020-10-04 22:09:54 -0400153 mgmt_ena <= 1'b1; // Management SoC has control over all I/O
154 gpio_holdover <= HOLD_INIT; // All signals latched in hold mode
155 gpio_slow_sel <= SLOW_INIT; // Fast slew rate
156 gpio_vtrip_sel <= TRIP_INIT; // CMOS mode
157 gpio_ib_mode_sel <= IB_INIT; // CMOS mode
158 gpio_inenb <= IENB_INIT; // Input enabled
Tim Edwards251e0df2020-10-05 11:02:12 -0400159 gpio_outenb <= OENB_INIT; // (unused placeholder)
Tim Edwards44bab472020-10-04 22:09:54 -0400160 gpio_dm <= DM_INIT; // Configured as input only
161 gpio_ana_en <= AENA_INIT; // Digital enabled
162 gpio_ana_sel <= ASEL_INIT; // Don't-care when gpio_ana_en = 0
163 gpio_ana_pol <= APOL_INIT; // Don't-care when gpio_ana_en = 0
Tim Edwards04ba17f2020-10-02 22:27:50 -0400164 end else begin
165 /* Load data */
166 mgmt_ena <= shift_register[MGMT_EN];
167 gpio_outenb <= shift_register[OEB];
168 gpio_holdover <= shift_register[HLDH];
169 gpio_inenb <= shift_register[INP_DIS];
170 gpio_ib_mode_sel <= shift_register[MOD_SEL];
171 gpio_ana_en <= shift_register[AN_EN];
172 gpio_ana_sel <= shift_register[AN_SEL];
173 gpio_ana_pol <= shift_register[AN_POL];
174 gpio_slow_sel <= shift_register[SLOW];
175 gpio_vtrip_sel <= shift_register[TRIP];
176 gpio_dm <= shift_register[DM+2:DM];
177
178 end
179 end
180
181 /* These pad configuration signals are static and do not change */
182 /* after setup. */
183
184 assign pad_gpio_holdover = gpio_holdover;
185 assign pad_gpio_slow_sel = gpio_slow_sel;
186 assign pad_gpio_vtrip_sel = gpio_vtrip_sel;
187 assign pad_gpio_ib_mode_sel = gpio_ib_mode_sel;
188 assign pad_gpio_ana_en = gpio_ana_en;
189 assign pad_gpio_ana_sel = gpio_ana_sel;
190 assign pad_gpio_ana_pol = gpio_ana_pol;
191 assign pad_gpio_dm = gpio_dm;
192 assign pad_gpio_inenb = gpio_inenb;
193
194 /* Implement pad control behavior depending on state of mgmt_ena */
195
Tim Edwards53d92182020-10-11 21:47:40 -0400196 assign gpio_in_unbuf = (mgmt_ena) ? 1'b0 : pad_gpio_in;
Tim Edwards89f09242020-10-05 15:17:34 -0400197 assign mgmt_gpio_in = (mgmt_ena) ? ((gpio_inenb == 1'b0) ?
198 pad_gpio_in : 1'bz) : 1'b0;
199
200 assign pad_gpio_outenb = (mgmt_ena) ? ((mgmt_gpio_oeb == 1'b1) ? gpio_outenb :
201 1'b0) : user_gpio_oeb;
202 assign pad_gpio_out = (mgmt_ena) ?
203 ((mgmt_gpio_oeb == 1'b1) ?
204 ((gpio_dm[2:1] == 2'b01) ? ~gpio_dm[0] : mgmt_gpio_out) :
205 mgmt_gpio_out) :
206 user_gpio_out;
207
Tim Edwards53d92182020-10-11 21:47:40 -0400208 /* Buffer user_gpio_in with an enable that is set by the user domain vccd */
209
210 sky130_fd_sc_hd__conb_1 gpio_logic_high (
Tim Edwards53d92182020-10-11 21:47:40 -0400211 .VPWR(vccd1),
212 .VGND(vssd1),
213 .VPB(vccd1),
214 .VNB(vssd1),
Tim Edwards53d92182020-10-11 21:47:40 -0400215 .HI(gpio_logic1),
216 .LO()
217 );
218
219 sky130_fd_sc_hd__einvp_8 gpio_in_buf (
Tim Edwards53d92182020-10-11 21:47:40 -0400220 .VPWR(vccd),
221 .VGND(vssd),
222 .VPB(vccd),
223 .VNB(vssd),
Tim Edwards53d92182020-10-11 21:47:40 -0400224 .Z(user_gpio_in),
225 .A(~gpio_in_unbuf),
226 .TE(gpio_logic1)
227 );
Tim Edwards04ba17f2020-10-02 22:27:50 -0400228
229endmodule