//
// GPIO controller for picorv32
//
// Little endian.
// Increasing numeric significance with increasing memory addresses known as "little-endian".
//
`include "inc/timescale.vh"

module gpio (
	     // Bus interface
	     input wire 	clk,
	     input wire 	resetn,
	     input wire 	enable,
	     input wire 	mem_valid,
	     output wire 	mem_ready,
	     input wire 	mem_instr,
	     input wire [3:0] 	mem_wstrb,
	     input wire [31:0] 	mem_wdata,
	     input wire [31:0] 	mem_addr,
	     output wire [31:0] mem_rdata,

	     // gpio interface
	     output reg [31:0] 	gpio
	     );

   reg [7:0] 			q;
   reg 				rdy;

   always @(posedge clk) begin
      if (!resetn) begin
         rdy <= 0;
         q <= 0;
         gpio <= 0;
      end else if (mem_valid & enable) begin
         if (mem_wstrb[0])
           gpio[7:0] <= mem_wdata[7:0];
         if (mem_wstrb[1])
           gpio[15:8] <= mem_wdata[15:8];
         if (mem_wstrb[2])
           gpio[23:16] <= mem_wdata[23:16];
         if (mem_wstrb[3])
           gpio[31:24] <= mem_wdata[31:24];
         rdy <= 1;
      end else begin
         rdy <= 0;
      end
      q <= gpio;
   end

   // Wire-OR'ed bus outputs.
   assign mem_rdata = enable ? q : 1'b0;
   assign mem_ready = enable ? rdy : 1'b0;

endmodule
