blob: 8ccdfddee0a8c993877dab6250428dbf60c7bac8 [file] [log] [blame]
Matt Venn08cd6eb2020-11-16 12:01:14 +01001`default_nettype none
Tim Edwards04ba17f2020-10-02 22:27:50 -04002/*
3 *---------------------------------------------------------------------
Tim Edwards251e0df2020-10-05 11:02:12 -04004 * See gpio_control_block for description. This module is like
5 * gpio_contro_block except that it has an additional two management-
6 * Soc-facing pins, which are the out_enb line and the output line.
7 * If the chip is configured for output with the oeb control
8 * register = 1, then the oeb line is controlled by the additional
9 * signal from the management SoC. If the oeb control register = 0,
10 * then the output is disabled completely. The "io" line is input
11 * only in this module.
Tim Edwards04ba17f2020-10-02 22:27:50 -040012 *
13 *---------------------------------------------------------------------
14 */
15
16/*
17 *---------------------------------------------------------------------
18 *
19 * This module instantiates a shift register chain that passes through
20 * each gpio cell. These are connected end-to-end around the padframe
21 * periphery. The purpose is to avoid a massive number of control
22 * wires between the digital core and I/O, passing through the user area.
23 *
24 * See mprj_ctrl.v for the module that registers the data for each
25 * I/O and drives the input to the shift register.
26 *
27 *---------------------------------------------------------------------
28 */
29
30module gpio_control_block #(
Tim Edwards44bab472020-10-04 22:09:54 -040031 parameter PAD_CTRL_BITS = 13,
32 // Parameterized initial startup state of the pad.
33 // The default parameters if unspecified is for the pad to be
34 // an input with no pull-up or pull-down, so that it is disconnected
35 // from the outside world.
36 parameter HOLD_INIT = 1'b0,
37 parameter SLOW_INIT = 1'b0,
38 parameter TRIP_INIT = 1'b0,
39 parameter IB_INIT = 1'b0,
40 parameter IENB_INIT = 1'b0,
41 parameter OENB_INIT = 1'b1,
42 parameter DM_INIT = 3'b001,
43 parameter AENA_INIT = 1'b0,
44 parameter ASEL_INIT = 1'b0,
45 parameter APOL_INIT = 1'b0
Tim Edwards04ba17f2020-10-02 22:27:50 -040046) (
Manar61dce922020-11-10 19:26:28 +020047 `ifdef USE_POWER_PINS
Tim Edwards53d92182020-10-11 21:47:40 -040048 inout vccd,
49 inout vssd,
50 inout vccd1,
51 inout vssd1,
52 `endif
53
Tim Edwards04ba17f2020-10-02 22:27:50 -040054 // Management Soc-facing signals
55 input resetn, // Global reset
56 input serial_clock,
57
Tim Edwards251e0df2020-10-05 11:02:12 -040058 output mgmt_gpio_in, // Management from pad (input only)
59 input mgmt_gpio_out, // Management to pad (output only)
60 input mgmt_gpio_oeb, // Management to pad (output only)
Tim Edwards04ba17f2020-10-02 22:27:50 -040061
62 // Serial data chain for pad configuration
63 input serial_data_in,
64 output serial_data_out,
65
66 // User-facing signals
67 input user_gpio_out, // User space to pad
Tim Edwards44bab472020-10-04 22:09:54 -040068 input user_gpio_oeb, // Output enable (user)
Tim Edwards04ba17f2020-10-02 22:27:50 -040069 output user_gpio_in, // Pad to user space
70
71 // Pad-facing signals (Pad GPIOv2)
72 output pad_gpio_holdover,
73 output pad_gpio_slow_sel,
74 output pad_gpio_vtrip_sel,
75 output pad_gpio_inenb,
76 output pad_gpio_ib_mode_sel,
77 output pad_gpio_ana_en,
78 output pad_gpio_ana_sel,
79 output pad_gpio_ana_pol,
80 output [2:0] pad_gpio_dm,
Tim Edwards251e0df2020-10-05 11:02:12 -040081 output pad_gpio_outenb,
Tim Edwards04ba17f2020-10-02 22:27:50 -040082 output pad_gpio_out,
83 input pad_gpio_in
84);
85
86 /* Parameters defining the bit offset of each function in the chain */
87 localparam MGMT_EN = 0;
88 localparam OEB = 1;
89 localparam HLDH = 2;
Tim Edwards251e0df2020-10-05 11:02:12 -040090 localparam INP_DIS = 3;
Tim Edwards44bab472020-10-04 22:09:54 -040091 localparam MOD_SEL = 4;
92 localparam AN_EN = 5;
93 localparam AN_SEL = 6;
94 localparam AN_POL = 7;
95 localparam SLOW = 8;
96 localparam TRIP = 9;
97 localparam DM = 10;
Tim Edwards04ba17f2020-10-02 22:27:50 -040098
99 /* Internally registered signals */
100 reg mgmt_ena; // Enable management SoC to access pad
101 reg gpio_holdover;
102 reg gpio_slow_sel;
103 reg gpio_vtrip_sel;
104 reg gpio_inenb;
105 reg gpio_ib_mode_sel;
106 reg gpio_outenb;
107 reg [2:0] gpio_dm;
108 reg gpio_ana_en;
109 reg gpio_ana_sel;
110 reg gpio_ana_pol;
111
112 /* Derived output values */
113 wire pad_gpio_holdover;
114 wire pad_gpio_slow_sel;
115 wire pad_gpio_vtrip_sel;
116 wire pad_gpio_inenb;
117 wire pad_gpio_ib_mode_sel;
118 wire pad_gpio_ana_en;
119 wire pad_gpio_ana_sel;
120 wire pad_gpio_ana_pol;
121 wire [2:0] pad_gpio_dm;
122 wire pad_gpio_outenb;
123 wire pad_gpio_out;
124 wire pad_gpio_in;
125
Tim Edwards53d92182020-10-11 21:47:40 -0400126 wire user_gpio_in;
127 wire gpio_in_unbuf;
Tim Edwards581068f2020-11-19 12:45:25 -0500128 wire gpio_logic1;
Tim Edwards53d92182020-10-11 21:47:40 -0400129
Tim Edwards04ba17f2020-10-02 22:27:50 -0400130 /* Serial shift for the above (latched) values */
131 reg [PAD_CTRL_BITS-1:0] shift_register;
132
133 /* Utilize reset and clock to encode a load operation */
134 wire load_data;
135 wire int_reset;
136
137 /* Create internal reset and load signals from input reset and clock */
138 assign serial_data_out = shift_register[PAD_CTRL_BITS-1];
139 assign int_reset = (~resetn) & (~serial_clock);
140 assign load_data = (~resetn) & serial_clock;
141
142 always @(posedge serial_clock or posedge int_reset) begin
143 if (int_reset == 1'b1) begin
144 /* Clear shift register */
145 shift_register <= 'd0;
146 end else begin
147 /* Shift data in */
148 shift_register <= {shift_register[PAD_CTRL_BITS-2:0], serial_data_in};
149 end
150 end
151
152 always @(posedge load_data or posedge int_reset) begin
153 if (int_reset == 1'b1) begin
154 /* Initial state on reset: Pad set to management input */
Tim Edwards44bab472020-10-04 22:09:54 -0400155 mgmt_ena <= 1'b1; // Management SoC has control over all I/O
156 gpio_holdover <= HOLD_INIT; // All signals latched in hold mode
157 gpio_slow_sel <= SLOW_INIT; // Fast slew rate
158 gpio_vtrip_sel <= TRIP_INIT; // CMOS mode
159 gpio_ib_mode_sel <= IB_INIT; // CMOS mode
160 gpio_inenb <= IENB_INIT; // Input enabled
Tim Edwards251e0df2020-10-05 11:02:12 -0400161 gpio_outenb <= OENB_INIT; // (unused placeholder)
Tim Edwards44bab472020-10-04 22:09:54 -0400162 gpio_dm <= DM_INIT; // Configured as input only
163 gpio_ana_en <= AENA_INIT; // Digital enabled
164 gpio_ana_sel <= ASEL_INIT; // Don't-care when gpio_ana_en = 0
165 gpio_ana_pol <= APOL_INIT; // Don't-care when gpio_ana_en = 0
Tim Edwards04ba17f2020-10-02 22:27:50 -0400166 end else begin
167 /* Load data */
168 mgmt_ena <= shift_register[MGMT_EN];
169 gpio_outenb <= shift_register[OEB];
170 gpio_holdover <= shift_register[HLDH];
171 gpio_inenb <= shift_register[INP_DIS];
172 gpio_ib_mode_sel <= shift_register[MOD_SEL];
173 gpio_ana_en <= shift_register[AN_EN];
174 gpio_ana_sel <= shift_register[AN_SEL];
175 gpio_ana_pol <= shift_register[AN_POL];
176 gpio_slow_sel <= shift_register[SLOW];
177 gpio_vtrip_sel <= shift_register[TRIP];
178 gpio_dm <= shift_register[DM+2:DM];
179
180 end
181 end
182
183 /* These pad configuration signals are static and do not change */
184 /* after setup. */
185
186 assign pad_gpio_holdover = gpio_holdover;
187 assign pad_gpio_slow_sel = gpio_slow_sel;
188 assign pad_gpio_vtrip_sel = gpio_vtrip_sel;
189 assign pad_gpio_ib_mode_sel = gpio_ib_mode_sel;
190 assign pad_gpio_ana_en = gpio_ana_en;
191 assign pad_gpio_ana_sel = gpio_ana_sel;
192 assign pad_gpio_ana_pol = gpio_ana_pol;
193 assign pad_gpio_dm = gpio_dm;
194 assign pad_gpio_inenb = gpio_inenb;
195
196 /* Implement pad control behavior depending on state of mgmt_ena */
197
Tim Edwards53d92182020-10-11 21:47:40 -0400198 assign gpio_in_unbuf = (mgmt_ena) ? 1'b0 : pad_gpio_in;
Tim Edwards89f09242020-10-05 15:17:34 -0400199 assign mgmt_gpio_in = (mgmt_ena) ? ((gpio_inenb == 1'b0) ?
200 pad_gpio_in : 1'bz) : 1'b0;
201
202 assign pad_gpio_outenb = (mgmt_ena) ? ((mgmt_gpio_oeb == 1'b1) ? gpio_outenb :
203 1'b0) : user_gpio_oeb;
204 assign pad_gpio_out = (mgmt_ena) ?
205 ((mgmt_gpio_oeb == 1'b1) ?
206 ((gpio_dm[2:1] == 2'b01) ? ~gpio_dm[0] : mgmt_gpio_out) :
207 mgmt_gpio_out) :
208 user_gpio_out;
209
Tim Edwards53d92182020-10-11 21:47:40 -0400210 /* Buffer user_gpio_in with an enable that is set by the user domain vccd */
211
212 sky130_fd_sc_hd__conb_1 gpio_logic_high (
Ahmed Ghazy64c17e82020-11-18 20:17:26 +0200213`ifdef USE_POWER_PINS
Tim Edwards53d92182020-10-11 21:47:40 -0400214 .VPWR(vccd1),
215 .VGND(vssd1),
216 .VPB(vccd1),
217 .VNB(vssd1),
Ahmed Ghazy64c17e82020-11-18 20:17:26 +0200218`endif
Tim Edwards53d92182020-10-11 21:47:40 -0400219 .HI(gpio_logic1),
220 .LO()
221 );
222
223 sky130_fd_sc_hd__einvp_8 gpio_in_buf (
Ahmed Ghazy64c17e82020-11-18 20:17:26 +0200224`ifdef USE_POWER_PINS
Tim Edwards53d92182020-10-11 21:47:40 -0400225 .VPWR(vccd),
226 .VGND(vssd),
227 .VPB(vccd),
228 .VNB(vssd),
Ahmed Ghazy64c17e82020-11-18 20:17:26 +0200229`endif
Tim Edwards53d92182020-10-11 21:47:40 -0400230 .Z(user_gpio_in),
231 .A(~gpio_in_unbuf),
232 .TE(gpio_logic1)
233 );
Tim Edwards04ba17f2020-10-02 22:27:50 -0400234
235endmodule
Tim Edwards581068f2020-11-19 12:45:25 -0500236`default_nettype wire