module sysctrl #(
    parameter BASE_ADR = 32'h2300_0000,
    parameter PWRGOOD	   = 8'h00,
    parameter CLK_OUT      = 8'h04,
    parameter TRAP_OUT     = 8'h08,
    parameter IRQ_SRC      = 8'h0c
) (
    input clk,
    input resetn,
    
    input [31:0] iomem_addr,
    input iomem_valid,
    input [3:0] iomem_wstrb,
    input [31:0] iomem_wdata,
    output reg [31:0] iomem_rdata,
    output reg iomem_ready,

    input  usr1_vcc_pwrgood,
    input  usr2_vcc_pwrgood,
    input  usr1_vdd_pwrgood,
    input  usr2_vdd_pwrgood,
    output clk1_output_dest,
    output clk2_output_dest,
    output trap_output_dest,
    output irq_7_inputsrc,
    output irq_8_inputsrc
); 

    reg clk1_output_dest;
    reg clk2_output_dest;
    reg trap_output_dest;
    reg irq_7_inputsrc;
    reg irq_8_inputsrc;

    wire usr1_vcc_pwrgood;
    wire usr2_vcc_pwrgood;
    wire usr1_vdd_pwrgood;
    wire usr2_vdd_pwrgood;

    wire pwrgood_sel;
    wire clk_out_sel;
    wire trap_out_sel;
    wire irq_sel;

    assign pwrgood_sel  = (iomem_addr[7:0] == PWRGOOD);
    assign clk_out_sel  = (iomem_addr[7:0] == CLK_OUT);
    assign trap_out_sel = (iomem_addr[7:0] == TRAP_OUT);
    assign irq_sel  = (iomem_addr[7:0] == IRQ_SRC);

    always @(posedge clk) begin
        if (!resetn) begin
            clk1_output_dest <= 0;
            clk2_output_dest <= 0;
            trap_output_dest <= 0;
            irq_7_inputsrc <= 0;
            irq_8_inputsrc <= 0;
        end else begin
            iomem_ready <= 0;
            if (iomem_valid && !iomem_ready && iomem_addr[31:8] == BASE_ADR[31:8]) begin
                iomem_ready <= 1'b 1;
                
                if (pwrgood_sel) begin
                    iomem_rdata <= {28'd0, usr2_vdd_pwrgood, usr1_vdd_pwrgood,
				usr2_vcc_pwrgood, usr1_vcc_pwrgood};
		    // These are read-only bits;  no write behavior on wstrb.

                end else if (clk_out_sel) begin
                    iomem_rdata <= {30'd0, clk2_output_dest, clk1_output_dest};
                    if (iomem_wstrb[0]) begin
                        clk1_output_dest <= iomem_wdata[0];
                        clk2_output_dest <= iomem_wdata[1];
		    end

                end else if (trap_out_sel) begin
                    iomem_rdata <= {31'd0, trap_output_dest};
                    if (iomem_wstrb[0]) 
                        trap_output_dest <= iomem_wdata[0];

                end else if (irq_sel) begin
                    iomem_rdata <= {30'd0, irq_8_inputsrc, irq_7_inputsrc};
                    if (iomem_wstrb[0]) begin
                        irq_7_inputsrc <= iomem_wdata[0];
                        irq_8_inputsrc <= iomem_wdata[1];
		    end
                end
            end
        end
    end

endmodule