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/mprj_ctrl.v b/verilog/rtl/mprj_ctrl.v
index 8970c41..cb67ac4 100644
--- a/verilog/rtl/mprj_ctrl.v
+++ b/verilog/rtl/mprj_ctrl.v
@@ -25,7 +25,10 @@
     output serial_data_out,
 
     // Read/write data to each GPIO pad from management SoC
-    inout [IO_PADS-1:0] mgmt_gpio_io
+    input [IO_PADS-1:0] mgmt_gpio_in,
+    output [IO_PADS-1:0] mgmt_gpio_out,
+    output [IO_PADS-1:0] mgmt_gpio_outz,
+    output [IO_PADS-1:0] mgmt_gpio_oeb		// Only JTAG and SDO connected
 );
     wire resetn;
     wire valid;
@@ -58,7 +61,11 @@
 	.serial_clock(serial_clock),
 	.serial_resetn(serial_resetn),
 	.serial_data_out(serial_data_out),
-	.mgmt_gpio_io(mgmt_gpio_io)
+	// .mgmt_gpio_io(mgmt_gpio_io)
+	.mgmt_gpio_in(mgmt_gpio_in),
+	.mgmt_gpio_out(mgmt_gpio_out),
+	.mgmt_gpio_outz(mgmt_gpio_outz),
+	.mgmt_gpio_oeb(mgmt_gpio_oeb)
     );
 
 endmodule
@@ -70,7 +77,7 @@
     parameter CONFIG = 8'h 08,
     parameter IO_PADS = 32,
     parameter PWR_PADS = 32,
-    parameter IO_CTRL_BITS = 14,
+    parameter IO_CTRL_BITS = 13,
     parameter PWR_CTRL_BITS = 1
 )(
     input clk,
@@ -86,26 +93,35 @@
     output serial_clock,
     output serial_resetn,
     output serial_data_out,
-    inout [IO_PADS-1:0] mgmt_gpio_io
+    // inout [IO_PADS-1:0] mgmt_gpio_io
+    input  [IO_PADS-1:0] mgmt_gpio_in,
+    output [IO_PADS-1:0] mgmt_gpio_out,
+    output [IO_PADS-1:0] mgmt_gpio_outz,
+    output [IO_PADS-1:0] mgmt_gpio_oeb
 );
 
-`define START	2'b00
-`define XBYTE	2'b01
-`define LOAD	2'b10
+`define IDLE	2'b00
+`define START	2'b01
+`define XBYTE	2'b10
+`define LOAD	2'b11
 
     localparam IO_BASE_ADR = (BASE_ADR | CONFIG);
     localparam PWR_BASE_ADR = (BASE_ADR | CONFIG) + IO_PADS*4;
-    localparam OEB = 1;			// Offset of OEB in shift register block.
+    localparam OEB = 1;			// Offset of output enable in shift register.
+    localparam INP_DIS = 3;		// Offset of input disable in shift register. 
 
     reg [IO_CTRL_BITS-1:0] io_ctrl [IO_PADS-1:0];  // I/O control, 1 word per gpio pad
     reg [PWR_CTRL_BITS-1:0] pwr_ctrl [PWR_PADS-1:0];// Power control, 1 word per power pad
-    reg [IO_PADS-1:0] mgmt_gpio_out;	// I/O read/write data, 1 bit per gpio pad
+    reg [IO_PADS-1:0] mgmt_gpio_out; // I/O write data, 1 bit per gpio pad
+    wire [IO_PADS-1:0] mgmt_gpio_outz;	 // I/O write data output when input disabled
+    wire [IO_PADS-1:0] mgmt_gpio_oeb;
     reg xfer_ctrl;			// Transfer control (1 bit)
 
     wire [IO_PADS-1:0] io_ctrl_sel;	// wishbone selects
     wire [PWR_PADS-1:0] pwr_ctrl_sel;
     wire io_data_sel;
     wire xfer_sel;
+    wire [IO_PADS-1:0] mgmt_gpio_in;
 
     assign xfer_sel = (iomem_addr[7:0] == XFER);
     assign io_data_sel = (iomem_addr[7:0] == DATA); 
@@ -114,14 +130,18 @@
     // if OEB = 0 then mgmt_gpio_out --> mgmt_gpio_io;  if OEB = 1 then
     // mgmt_gpio_io --> mgmt_gpio_in.  mgmt_gpio_in is always a copy of mgmt_gpio_io.
 
-    assign mgmt_gpio_in = mgmt_gpio_io;
+    // assign mgmt_gpio_in = mgmt_gpio_io;
 
     genvar i;
     generate
         for (i=0; i<IO_PADS; i=i+1) begin
             assign io_ctrl_sel[i] = (iomem_addr[7:0] == (IO_BASE_ADR[7:0] + i*4)); 
-            assign mgmt_gpio_io[i] = (io_ctrl[0][i] + OEB == 1'b0) ?
-				mgmt_gpio_out[i] : 1'bz;
+	    // OEB is both tranferred by serial chain and output;  that way
+	    // each pad can selectively choose whether to have a dedicated
+	    // signal for OEB, or to use it as a static configuration bit.
+    	    assign mgmt_gpio_oeb[i] = io_ctrl[OEB][i];
+    	    assign mgmt_gpio_outz[i] = (io_ctrl[INP_DIS][i] == 1'b1) ?
+			mgmt_gpio_out[i] : 1'bz;
         end
     endgenerate
 
@@ -145,8 +165,9 @@
 
 		if (io_data_sel) begin
 		    iomem_rdata <= mgmt_gpio_in;
-		    mgmt_gpio_out <= 'd0;
-		    if (iomem_wstrb[0]) mgmt_gpio_out[IO_PADS-1:0] <= iomem_wdata[IO_PADS-1:0];
+		    if (iomem_wstrb[0]) begin
+			mgmt_gpio_out[IO_PADS-1:0] <= iomem_wdata[IO_PADS-1:0];
+		    end
 
 		end else if (xfer_sel) begin
 		    iomem_rdata <= {31'd0, xfer_ctrl};
@@ -162,7 +183,9 @@
                 if (!resetn) begin
 		    // NOTE:  This needs to be set to the specific bit sequence
 		    // that initializes every I/O pad to the appropriate state on
-		    // startup.
+		    // startup, to match the startup state at each pad.  Otherwise
+		    // surprises happen if not all pad configurations are applied
+		    // from the program code, and a transfer is initiated.
                     io_ctrl[i] <= 'd0;
                 end else begin
                     if (iomem_valid && !iomem_ready && iomem_addr[31:8] == BASE_ADR[31:8]) begin
@@ -213,7 +236,7 @@
     always @(posedge clk or negedge resetn) begin
 	if (resetn == 1'b0) begin
 
-	    xfer_state <= `START;
+	    xfer_state <= `IDLE;
 	    xfer_count <= 4'd0;
 	    pad_count  <= 6'd0;
 	    serial_resetn <= 1'b0;
@@ -222,7 +245,13 @@
 
 	end else begin
 
-	    if (xfer_state == `START) begin
+	    if (xfer_state == `IDLE) begin
+	    	serial_resetn <= 1'b0;
+		serial_clock <= 1'b0;
+		if (xfer_ctrl == 1'b1) begin
+		    xfer_state <= `START;
+		end
+	    end else if (xfer_state == `START) begin
 	    	serial_resetn <= 1'b1;
 		serial_clock <= 1'b0;
 	    	xfer_count <= 6'd0;
@@ -266,7 +295,7 @@
 		end else if (xfer_count == 4'd3) begin
 		    serial_resetn <= 1'b1;
 		    serial_clock <= 1'b0;
-		    xfer_state <= `START;
+		    xfer_state <= `IDLE;
 		end
 	    end	
 	end