/****************************************************************************
    +-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+
    |F|u|n|c|t|i|o|n|a|l| |V|e|r|i|f|i|c|a|t|i|o|n| |o|f| |H|a|r|d|w|a|r|e|
    +-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+

    FILE            apb_test_top.sv

    DESCRIPTION     top module
                    - connects DUT and interface
                    - generates clk and reset
                    - runs UVM test

 ****************************************************************************/

`ifndef APB_TEST_TOP_SV
`define APB_TEST_TOP_SV

/**
 * Module: apb_test_top
 */
module apb_test_top;

    import uvm_pkg::*;            // import the UVM library
    `include "uvm_macros.svh"     // Include the UVM macros

    import apb_pkg::*;            // import the APB pkg
    
    `include "apb_test_lib.sv"
    
    `include "dut.sv"

    logic clock;
    logic reset;

    // interface
    apb_if apb_vif(clock, reset);
    
    // DUT
    dut #(  .ADDR_WIDTH(32),
            .RDATA_WIDTH(32),
            .WDATA_WIDTH(32),
            .SLV_NUM(15)
        ) dut_inst (
            .paddr   (apb_vif.paddr  ),
            .psel    (apb_vif.psel   ),
            .penable (apb_vif.penable),
            .pwrite  (apb_vif.pwrite ),
            .pwdata  (apb_vif.pwdata ),
            .pready  (apb_vif.pready ),
            .prdata  (apb_vif.prdata ),
            .pslverr (apb_vif.pslverr)            
        );

    // set interface in db; run UVM test
    initial begin
        uvm_config_db#(virtual apb_if)::set(null,"uvm_test_top.*","apb_if", apb_vif);
        run_test();
    end
    
    // initialize clock and reset
    initial begin
        clock <= 1'b0;
        reset <= 1'b0;
        #50 reset <= 1'b1;
    end

    // generate clock
    always #5 clock = ~clock;    

endmodule : apb_test_top

`endif

