module spi_sysctrl_wb_tb;

    reg wb_clk_i;
	reg wb_rst_i;

    reg wb_stb_i;
    reg wb_cyc_i;
	reg wb_we_i;
	reg [3:0] wb_sel_i;
	reg [31:0] wb_dat_i;
	reg [31:0] wb_adr_i;

	wire wb_ack_o;
	wire [31:0] wb_dat_o;

    wire [7:0] spi_ro_config; // (verify) wire input to the core not connected to HKSPI, what should it be connected to ? 
    wire [4:0] spi_ro_pll_div; 
    wire [2:0] spi_ro_pll_sel;
    wire spi_ro_xtal_ena;
    wire spi_ro_reg_ena; 
    wire [25:0] spi_ro_pll_trim;
    wire spi_ro_pll_dco_ena;
    wire [11:0] spi_ro_mfgr_id;
    wire [7:0] spi_ro_prod_id;
    wire [3:0] spi_ro_mask_rev;
    wire spi_ro_pll_bypass;
   
    // HKSPI
    reg RSTB;	    
    reg SCK;	   
    reg SDI;	    
    reg CSB;	    
    reg trap;
    reg [3:0] mask_rev_in;	

    wire SDO;	  
    wire sdo_enb;
    wire xtal_ena;
    wire reg_ena;
    wire pll_dco_ena;
    wire [25:0] pll_trim;
    wire [2:0] pll_sel;
    wire [4:0] pll_div;
    wire pll_bypass;
    wire irq;
    wire reset;
    wire RST;
    wire [11:0] mfgr_id;
    wire [7:0] prod_id;
    wire [3:0] mask_rev;

    initial begin
        wb_clk_i = 0; 
        wb_rst_i = 0;
        wb_stb_i = 0; 
        wb_cyc_i = 0;  
        wb_sel_i = 0;  
        wb_we_i  = 0;  
        wb_dat_i = 0; 
        wb_adr_i = 0; 
        CSB = 1;
        SCK = 0;
        SDI = 0;
        RSTB = 0; 
    end

    always #1 wb_clk_i = ~wb_clk_i;

    // System Control Default Register Addresses (Read-only reg)
    wire [31:0] spi_cfg         = uut.BASE_ADR | uut.SPI_CFG; // unused & reserved ? 
    wire [31:0] spi_ena         = uut.BASE_ADR | uut.SPI_ENA;
    wire [31:0] spi_pll_cfg     = uut.BASE_ADR | uut.SPI_PLL_CFG;
    wire [31:0] spi_mfgr_id     = uut.BASE_ADR | uut.SPI_MFGR_ID;
    wire [31:0] spi_prod_id     = uut.BASE_ADR | uut.SPI_PROD_ID;
    wire [31:0] spi_mask_rev    = uut.BASE_ADR | uut.SPI_MASK_REV;
    wire [31:0] spi_pll_bypass  = uut.BASE_ADR | uut.SPI_PLL_BYPASS;

    initial begin
        $dumpfile("spi_sysctrl_wb_tb.vcd");
        $dumpvars(0, spi_sysctrl_wb_tb);
        repeat (50) begin
            repeat (1000) @(posedge wb_clk_i);
        end
        $display("%c[1;31m",27);
        $display ("Monitor: Timeout, Test SPI System Control Failed");
        $display("%c[0m",27);
        $finish;
    end

    integer i;

    initial begin   
        // Reset Operation
        wb_rst_i = 1;
        RSTB = 0;       // active low reset
        #2;
        wb_rst_i = 0;
        RSTB = 1; 
        #2;

        // Read mask_rev register
        mask_rev_in = 4'hF;
        read(spi_mask_rev);
        if (wb_dat_o !== {28'd0, mask_rev_in}) begin
            $display("Error reading mask_rev reg");
            $finish;
        end

        // Read manufacture id register
        read(spi_mfgr_id);
        if (wb_dat_o !== {20'd0, 12'h456}) begin
            $display("Error reading manufacture id reg");
            $finish;
        end

        // Read product id register
        read(spi_prod_id);
        if (wb_dat_o !== {24'd0, 8'h05}) begin
            $display("Error reading product id reg");
            $finish;
        end

        // Read PLL-Bypass register
        read(spi_pll_bypass);
        if (wb_dat_o !== {31'd0, 1'b1}) begin
            $display("Error reading pll bypass id reg");
            $finish;
        end

        // Read PLL-Configuration register
        read(spi_pll_cfg);
        if (wb_dat_o !== {5'd0, spi_ro_pll_trim, spi_ro_pll_dco_ena}) begin
            $display("Error reading pll bypass id reg");
            $finish;
        end

        // Read SPI Enables register
        read(spi_ena);
        if (wb_dat_o !== {22'd0, spi_ro_pll_div, spi_ro_pll_sel, spi_ro_xtal_ena, spi_ro_reg_ena}) begin
            $display("Error reading pll bypass id reg");
            $finish;
        end                
        $display("Success!");
        $finish;
    end

    task read;
        input [32:0] addr;
        begin 
            @(posedge wb_clk_i) begin
                wb_stb_i = 1;
                wb_cyc_i = 1;
                wb_we_i = 0;
                wb_adr_i = addr;
                $display("Monitor: Read Cycle Started.");
            end
            // Wait for an ACK
            wait(wb_ack_o == 1);
            wait(wb_ack_o == 0);
            wb_cyc_i = 0;
            wb_stb_i = 0;
            $display("Monitor: Read Cycle Ended.");
        end
    endtask

    spi_sysctrl_wb uut(
        .wb_clk_i(wb_clk_i),
	    .wb_rst_i(wb_rst_i),

        .wb_stb_i(wb_stb_i),
	    .wb_cyc_i(wb_cyc_i),
	    .wb_sel_i(wb_sel_i),
	    .wb_we_i(wb_we_i),
	    .wb_dat_i(wb_dat_i),
	    .wb_adr_i(wb_adr_i), 
        .wb_ack_o(wb_ack_o),
	    .wb_dat_o(wb_dat_o),
        
        .spi_ro_config(spi_ro_config), // (verify) wire input to the core not connected to HKSPI, what should it be connected to ? 
        .spi_ro_pll_div(spi_ro_pll_div), 
        .spi_ro_pll_sel(spi_ro_pll_sel),
        .spi_ro_xtal_ena(spi_ro_xtal_ena),
        .spi_ro_reg_ena(spi_ro_reg_ena), 
    
        .spi_ro_pll_trim(spi_ro_pll_trim),
        .spi_ro_pll_dco_ena(spi_ro_pll_dco_ena),  

        .spi_ro_mfgr_id(spi_ro_mfgr_id),
        .spi_ro_prod_id(spi_ro_prod_id), 
        .spi_ro_mask_rev(spi_ro_mask_rev), 
        .pll_bypass(spi_ro_pll_bypass)
    );

    striVe_spi hkspi (
		.RSTB(RSTB),
		.SCK(SCK),
		.SDI(SDI),
		.CSB(CSB),

		.SDO(SDO),
		.sdo_enb(SDO_enb),
		.xtal_ena(spi_ro_xtal_ena),
		.reg_ena(spi_ro_reg_ena),
		.pll_dco_ena(spi_ro_pll_dco_ena),
		.pll_sel(spi_ro_pll_sel),
		.pll_div(spi_ro_pll_div),
		.pll_trim(spi_ro_pll_trim),
		.pll_bypass(spi_ro_pll_bypass),
		.irq(irq_spi),
		.RST(por),
		.reset(ext_reset),
		.trap(trap),
		.mfgr_id(spi_ro_mfgr_id),
		.prod_id(spi_ro_prod_id),
		.mask_rev_in(mask_rev_in),
		.mask_rev(spi_ro_mask_rev)
    );

endmodule