`resetall
`timescale 1ns / 1ps
`default_nettype none

module simple_spi #
(
    parameter integer AXI_ADDR_WIDTH	= 32,
    parameter integer AXI_DATA_WIDTH	= 32    
)
(
    input  wire         clk,
    input  wire         reset,
   
    // AXI4L Config Interface
    axi4l_intf.slave    ctrl_if,

    output wire [31:0]  ss,
    inout  wire         mosi,
	input  wire         miso,
	output wire         sck
);

// ------------------------------
// AXIL Decode
// ------------------------------
wire [AXI_ADDR_WIDTH-1 : 0]		raddr;
wire [AXI_ADDR_WIDTH-1 : 0]		waddr;
wire 						    rden;
wire 						    wren;
wire [AXI_DATA_WIDTH-1 : 0]		wdata;
reg [AXI_DATA_WIDTH-1 : 0]		rdata;


axil_slave 
# (
	.DATA_WIDTH(AXI_DATA_WIDTH),
	.ADDR_WIDTH(AXI_ADDR_WIDTH)
) axil_slave_i 
(
	// AXIL Slave
	.S_AXI_ACLK(ctrl_if.clk),
	.S_AXI_ARESETN(ctrl_if.resetn),
	.S_AXI_AWADDR(ctrl_if.awaddr),
	.S_AXI_AWPROT(ctrl_if.awprot),
	.S_AXI_AWVALID(ctrl_if.awvalid),
	.S_AXI_AWREADY(ctrl_if.awready),
	.S_AXI_WDATA(ctrl_if.wdata),
	.S_AXI_WSTRB(ctrl_if.wstrb),
	.S_AXI_WVALID(ctrl_if.wvalid),
	.S_AXI_WREADY(ctrl_if.wready),
	.S_AXI_BRESP(ctrl_if.bresp),
	.S_AXI_BVALID(ctrl_if.bvalid),
	.S_AXI_BREADY(ctrl_if.bready),
	.S_AXI_ARADDR(ctrl_if.araddr),
	.S_AXI_ARPROT(ctrl_if.arprot),
	.S_AXI_ARVALID(ctrl_if.arvalid),
	.S_AXI_ARREADY(ctrl_if.arready),
	.S_AXI_RDATA(ctrl_if.rdata),
	.S_AXI_RRESP(ctrl_if.rresp),
	.S_AXI_RVALID(ctrl_if.rvalid),
	.S_AXI_RREADY(ctrl_if.rready),	
	
	.raddr(raddr),
	.waddr(waddr),
	.wren(wren),
	.rden(rden),
	.wdata(wdata),
	.rdata(rdata)
);

// ------------------------------
// Config Registers
// ------------------------------
reg [31:0]  clk_div;
reg [7:0]   data; 
reg [31:0]  ss; 
reg [24:0]  pwm_pulsewidth; 

always @ (posedge clk) begin
    if (reset) begin
        scratch <= 0;
    end else if (wren && waddr[11:0] == 'h004) begin
        scratch <= wdata;
    end
end

always @ (posedge clk) begin
    if (reset) begin
        gpo_reg <= 0;
    end else if (wren && waddr[11:0] == 'h008) begin
        gpo_reg <= wdata;
    end
end

always @ (posedge clk) begin
    if (reset) begin
        pwm_period <= 1500000;
    end else if (wren && waddr[11:0] == 'h010) begin
        pwm_period <= wdata;
    end
end

always @ (posedge clk) begin
    if (reset) begin
        pwm_pulsewidth <= 500000;
    end else if (wren && waddr[11:0] == 'h014) begin
        pwm_pulsewidth <= wdata;
    end
end

always @ (posedge clk) begin
    if (rden) begin
        if (raddr[11:0] == 'h000)
            rdata <= 'h12345678;
        if (raddr[11:0] == 'h004)
            rdata <= scratch;
        if (raddr[11:0] == 'h008)
            rdata <= gpo_reg;        
        if (raddr[11:0] == 'h00C)
            rdata <= gpi;                                 
    end
end

assign gpo = gpo_reg;

// ------------------------------
// Fan PWM
// ------------------------------
reg [24:0]  pwm_cnt; 
reg pwm_out;

assign fan_pwm = pwm_out;

always @ (posedge clk) begin
	if (pwm_cnt < pwm_period) begin
		pwm_cnt <= pwm_cnt + 1;
	end else begin
		pwm_cnt <= 0;
	end

	if (pwm_cnt < pwm_pulsewidth) begin
		pwm_out <= 1'bz;
	end else begin
		pwm_out <= 1'b0;
	end

end



endmodule


`resetall