blob: b28a02e80d9c2721c16a31f66820cc4478b8382c [file] [log] [blame]
Tim Edwards44bab472020-10-04 22:09:54 -04001/*
2 *---------------------------------------------------------------------
3 * 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.
11 *
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_block2 #(
30 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
45) (
46 // Management Soc-facing signals
47 input resetn, // Global reset
48 input serial_clock,
49
50 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)
53
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
60 input user_gpio_oeb, // Output enable (user)
61 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,
73 output pad_gpio_outenb,
74 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;
82 localparam ENH = 3;
83 localparam INP_DIS = 4;
84 localparam MOD_SEL = 5;
85 localparam AN_EN = 6;
86 localparam AN_SEL = 7;
87 localparam AN_POL = 8;
88 localparam SLOW = 9;
89 localparam TRIP = 10;
90 localparam DM = 11;
91
92 /* Internally registered signals */
93 reg mgmt_ena; // Enable management SoC to access pad
94 reg gpio_holdover;
95 reg gpio_slow_sel;
96 reg gpio_vtrip_sel;
97 reg gpio_inenb;
98 reg gpio_ib_mode_sel;
99 reg gpio_outenb;
100 reg [2:0] gpio_dm;
101 reg gpio_ana_en;
102 reg gpio_ana_sel;
103 reg gpio_ana_pol;
104
105 /* Derived output values */
106 wire pad_gpio_holdover;
107 wire pad_gpio_slow_sel;
108 wire pad_gpio_vtrip_sel;
109 wire pad_gpio_inenb;
110 wire pad_gpio_ib_mode_sel;
111 wire pad_gpio_ana_en;
112 wire pad_gpio_ana_sel;
113 wire pad_gpio_ana_pol;
114 wire [2:0] pad_gpio_dm;
115 wire pad_gpio_outenb;
116 wire pad_gpio_out;
117 wire pad_gpio_in;
118
119 /* Serial shift for the above (latched) values */
120 reg [PAD_CTRL_BITS-1:0] shift_register;
121
122 /* Utilize reset and clock to encode a load operation */
123 wire load_data;
124 wire int_reset;
125
126 /* Create internal reset and load signals from input reset and clock */
127 assign serial_data_out = shift_register[PAD_CTRL_BITS-1];
128 assign int_reset = (~resetn) & (~serial_clock);
129 assign load_data = (~resetn) & serial_clock;
130
131 always @(posedge serial_clock or posedge int_reset) begin
132 if (int_reset == 1'b1) begin
133 /* Clear shift register */
134 shift_register <= 'd0;
135 end else begin
136 /* Shift data in */
137 shift_register <= {shift_register[PAD_CTRL_BITS-2:0], serial_data_in};
138 end
139 end
140
141 always @(posedge load_data or posedge int_reset) begin
142 if (int_reset == 1'b1) begin
143 /* Initial state on reset: Pad set to management input */
144 mgmt_ena <= 1'b1; // Management SoC has control over all I/O
145 gpio_holdover <= HOLD_INIT; // All signals latched in hold mode
146 gpio_slow_sel <= SLOW_INIT; // Fast slew rate
147 gpio_vtrip_sel <= TRIP_INIT; // CMOS mode
148 gpio_ib_mode_sel <= IB_INIT; // CMOS mode
149 gpio_inenb <= IENB_INIT; // Input enabled
150 gpio_outenb <= OENB_INIT; // (unused placeholder)
151 gpio_dm <= DM_INIT; // Configured as input only
152 gpio_ana_en <= AENA_INIT; // Digital enabled
153 gpio_ana_sel <= ASEL_INIT; // Don't-care when gpio_ana_en = 0
154 gpio_ana_pol <= APOL_INIT; // Don't-care when gpio_ana_en = 0
155 end else begin
156 /* Load data */
157 mgmt_ena <= shift_register[MGMT_EN];
158 gpio_outenb <= shift_register[OEB];
159 gpio_holdover <= shift_register[HLDH];
160 gpio_inenb <= shift_register[INP_DIS];
161 gpio_ib_mode_sel <= shift_register[MOD_SEL];
162 gpio_ana_en <= shift_register[AN_EN];
163 gpio_ana_sel <= shift_register[AN_SEL];
164 gpio_ana_pol <= shift_register[AN_POL];
165 gpio_slow_sel <= shift_register[SLOW];
166 gpio_vtrip_sel <= shift_register[TRIP];
167 gpio_dm <= shift_register[DM+2:DM];
168
169 end
170 end
171
172 /* These pad configuration signals are static and do not change */
173 /* after setup. */
174
175 assign pad_gpio_holdover = gpio_holdover;
176 assign pad_gpio_slow_sel = gpio_slow_sel;
177 assign pad_gpio_vtrip_sel = gpio_vtrip_sel;
178 assign pad_gpio_ib_mode_sel = gpio_ib_mode_sel;
179 assign pad_gpio_ana_en = gpio_ana_en;
180 assign pad_gpio_ana_sel = gpio_ana_sel;
181 assign pad_gpio_ana_pol = gpio_ana_pol;
182 assign pad_gpio_dm = gpio_dm;
183 assign pad_gpio_inenb = gpio_inenb;
184
185 /* Implement pad control behavior depending on state of mgmt_ena */
186
187 assign pad_gpio_out = (mgmt_ena) ? mgmt_gpio_out : user_gpio_out;
188 assign pad_gpio_outenb = (mgmt_ena) ? mgmt_gpio_oeb : user_gpio_oeb;
189
190 assign user_gpio_in = (mgmt_ena) ? 1'b0 : pad_gpio_in;
191 assign mgmt_gpio_in = (mgmt_ena) ? pad_gpio_in : 1'b0;
192
193endmodule