In spite of many errors that still need fixing, this is a major advance
over the previous commit. All verilog modules are in place more or less
as intended, with various functions such as the housekeeping SPI placed
on user area pads, with the ability to switch to user control from the
configuration. The pad control bits are local to the pads and loaded
via serial shift register, so that there are not hundreds of control wires
feeding into the user space. The user has three basic controls over each
pad: in, out, and outenb. Two timer/counters and an SPI master have been
added to the SoC. The SPI master shares I/O with the housekeeping SPI, so
that all housekeeping SPI registers can be accessed from the SoC directly.
diff --git a/verilog/rtl/gpio_control_block.v b/verilog/rtl/gpio_control_block.v
index 1575841..2325b39 100644
--- a/verilog/rtl/gpio_control_block.v
+++ b/verilog/rtl/gpio_control_block.v
@@ -31,7 +31,21 @@
*/
module gpio_control_block #(
- parameter PAD_CTRL_BITS = 13
+ parameter PAD_CTRL_BITS = 13,
+ // Parameterized initial startup state of the pad.
+ // The default parameters if unspecified is for the pad to be
+ // an input with no pull-up or pull-down, so that it is disconnected
+ // from the outside world.
+ parameter HOLD_INIT = 1'b0,
+ parameter SLOW_INIT = 1'b0,
+ parameter TRIP_INIT = 1'b0,
+ parameter IB_INIT = 1'b0,
+ parameter IENB_INIT = 1'b0,
+ parameter OENB_INIT = 1'b1,
+ parameter DM_INIT = 3'b001,
+ parameter AENA_INIT = 1'b0,
+ parameter ASEL_INIT = 1'b0,
+ parameter APOL_INIT = 1'b0
) (
// Management Soc-facing signals
input resetn, // Global reset
@@ -45,7 +59,7 @@
// User-facing signals
input user_gpio_out, // User space to pad
- input user_gpio_outenb, // Output enable (user)
+ input user_gpio_oeb, // Output enable (user)
output user_gpio_in, // Pad to user space
// Pad-facing signals (Pad GPIOv2)
@@ -58,7 +72,7 @@
output pad_gpio_ana_sel,
output pad_gpio_ana_pol,
output [2:0] pad_gpio_dm,
- output pad_gpio_outenb,
+ output pad_gpio_oeb,
output pad_gpio_out,
input pad_gpio_in
);
@@ -67,15 +81,14 @@
localparam MGMT_EN = 0;
localparam OEB = 1;
localparam HLDH = 2;
- localparam ENH = 3;
- localparam INP_DIS = 4;
- localparam MOD_SEL = 5;
- localparam AN_EN = 6;
- localparam AN_SEL = 7;
- localparam AN_POL = 8;
- localparam SLOW = 9;
- localparam TRIP = 10;
- localparam DM = 11;
+ localparam INP_DIS = 2;
+ localparam MOD_SEL = 4;
+ localparam AN_EN = 5;
+ localparam AN_SEL = 6;
+ localparam AN_POL = 7;
+ localparam SLOW = 8;
+ localparam TRIP = 9;
+ localparam DM = 10;
/* Internally registered signals */
reg mgmt_ena; // Enable management SoC to access pad
@@ -129,17 +142,17 @@
always @(posedge load_data or posedge int_reset) begin
if (int_reset == 1'b1) begin
/* Initial state on reset: Pad set to management input */
- mgmt_ena <= 1'b0;
- gpio_holdover <= 1'b0; // All signals latched in hold mode
- gpio_slow_sel <= 1'b0; // Fast slew rate
- gpio_vtrip_sel <= 1'b0; // CMOS mode
- gpio_ib_mode_sel <= 1'b0; // CMOS mode
- gpio_inenb <= 1'b0; // Input enabled
- gpio_outenb <= 1'b1; // Output disabled
- gpio_dm <= 3'b001; // Configured as input only
- gpio_ana_en <= 1'b0; // Digital enabled
- gpio_ana_sel <= 1'b0; // Don't-care when gpio_ana_en = 0
- gpio_ana_pol <= 1'b0; // Don't-care when gpio_ana_en = 0
+ mgmt_ena <= 1'b1; // Management SoC has control over all I/O
+ gpio_holdover <= HOLD_INIT; // All signals latched in hold mode
+ gpio_slow_sel <= SLOW_INIT; // Fast slew rate
+ gpio_vtrip_sel <= TRIP_INIT; // CMOS mode
+ gpio_ib_mode_sel <= IB_INIT; // CMOS mode
+ gpio_inenb <= IENB_INIT; // Input enabled
+ gpio_outenb <= OENB_INIT; // Output disabled
+ gpio_dm <= DM_INIT; // Configured as input only
+ gpio_ana_en <= AENA_INIT; // Digital enabled
+ gpio_ana_sel <= ASEL_INIT; // Don't-care when gpio_ana_en = 0
+ gpio_ana_pol <= APOL_INIT; // Don't-care when gpio_ana_en = 0
end else begin
/* Load data */
mgmt_ena <= shift_register[MGMT_EN];
@@ -177,18 +190,23 @@
/* set the pullup or pulldown condition, the pad output bit must */
/* be set to the opposite state of dm[0]. */
/* dm[0] = 0 is pull-down; dm[0] = 1 is pull-up. */
- /* Otherwise, the output
+ /* */
+ /* This is done for management control only, since the management */
+ /* control has only 1 inout signal for both input and output, and */
+ /* cannot set the output and read the input simultaneously. The */
+ /* user has control over both lines and only needs to be told what */
+ /* to set the output line to, to enable a pullup or pulldown. */
- assign pad_gpio_out = (mgmt_ena) ? mgmt_gpio_io :
- (((gpio_dm[2:1] == 2'b01) && (gpio_inenb == 1'b0)) ?
- ~gpio_dm[0] : user_gpio_out);
+ assign pad_gpio_out = (mgmt_ena) ?
+ (((gpio_dm[2:1] == 2'b01) && (gpio_inenb == 1'b0)) ?
+ ~gpio_dm[0] : mgmt_gpio_io) : user_gpio_out;
/* When under user control, gpio_outenb = 1 means that the pad is */
/* configured as input, and the user outenb is unused. Otherwise, */
/* the pad outenb signal is controlled by the user. */
assign pad_gpio_outenb = (mgmt_ena) ? gpio_outenb :
- ((gpio_outenb == 1) ? 1'b1 : user_gpio_outenb);
+ ((gpio_outenb == 1) ? 1'b1 : user_gpio_oeb);
/* User gpio_in is grounded when the management controls the pad */
assign user_gpio_in = (mgmt_ena) ? 1'b0 : pad_gpio_in;