#// 
#// -------------------------------------------------------------
#//    Copyright 2010 Cadence.
#//    Copyright 2011 Mentor Graphics Corporation
#//    All Rights Reserved Worldwide
#// 
#//    Licensed under the Apache License, Version 2.0 (the
#//    "License"); you may not use this file except in
#//    compliance with the License.  You may obtain a copy of
#//    the License at
#// 
#//        http://www.apache.org/licenses/LICENSE-2.0
#// 
#//    Unless required by applicable law or agreed to in
#//    writing, software distributed under the License is
#//    distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
#//    CONDITIONS OF ANY KIND, either express or implied.  See
#//    the License for the specific language governing
#//    permissions and limitations under the License.
#// -------------------------------------------------------------
#//
#
#//
#// TITLE: HDL Paths Checking Test Sequence
#//
#
#//
#// class: uvm_reg_mem_hdl_paths_seq
#//
#// Verify the correctness of HDL paths specified for registers and memories.
#//
#// This sequence is be used to check that the specified backdoor paths
#// are indeed accessible by the simulator.
#// By default, the check is performed for the default design abstraction.
#// If the simulation contains multiple models of the DUT,
#// HDL paths for multiple design abstractions can be checked.
#// 
#// If a path is not accessible by the simulator, it cannot be used for 
#// read/write backdoor accesses. In that case a warning is produced. 
#// A simulator may have finer-grained access permissions such as separate 
#// read or write permissions.
#// These extra access permissions are NOT checked.
#//
#// The test is performed in zero time and
#// does not require any reads/writes to/from the DUT.
#//
#
#class uvm_reg_mem_hdl_paths_seq extends uvm_reg_sequence #(uvm_sequence #(uvm_reg_item));
#    // Variable: abstractions
#    // If set, check the HDL paths for the specified design abstractions.
#    // If empty, check the HDL path for the default design abstraction,
#    // as specified with <uvm_reg_block::set_default_hdl_path()>
#    string abstractions[$];
#    
#    `uvm_object_utils_begin(uvm_reg_mem_hdl_paths_seq)
#        `uvm_field_queue_string(abstractions, UVM_DEFAULT)
#    `uvm_object_utils_end
#    
#    function new(string name="uvm_reg_mem_hdl_paths_seq");
#        super.new(name);
#    endfunction
#
#    virtual task body();
#
#        if (model == null) begin
#            uvm_report_error("uvm_reg_mem_hdl_paths_seq", "Register model handle is null");
#            return;
#        end
#
#       `uvm_info("uvm_reg_mem_hdl_paths_seq",
#                 {"checking HDL paths for all registers/memories in ",
#                  model.get_full_name()}, UVM_LOW);
#
#       if (abstractions.size() == 0)
#          do_block(model, "");
#       else begin
#          foreach (abstractions[i])
#             do_block(model, abstractions[i]);
#       end
#
#        `uvm_info("uvm_reg_mem_hdl_paths_seq", "HDL path validation completed ",UVM_LOW);
#        
#    endtask: body
#
#
#    // Any additional steps required to reset the block
#    // and make it accessible
#    virtual task reset_blk(uvm_reg_block blk);
#    endtask
#
#
#    protected virtual function void do_block(uvm_reg_block blk,
#                                             string        kind);
#        uvm_reg       regs[$];
#        uvm_mem       mems[$];
#
#       `uvm_info("uvm_reg_mem_hdl_paths_seq",
#                 {"Validating HDL paths in ", blk.get_full_name(),
#                  " for ", (kind == "") ? "default" : kind,
#                  " design abstraction"}, UVM_MEDIUM) 
#
#       // Iterate over all registers, checking accesses
#       blk.get_registers(regs, UVM_NO_HIER);
#       foreach (regs[i]) 
#          check_reg(regs[i], kind);
#       
#       blk.get_memories(mems, UVM_NO_HIER);
#       foreach (mems[i]) 
#          check_mem(mems[i], kind);
#    
#       begin
#          uvm_reg_block blks[$];
#          
#          blk.get_blocks(blks);
#          foreach (blks[i]) begin
#             do_block(blks[i], kind);
#          end
#       end
#    endfunction: do_block
#    
#
#    protected virtual function void check_reg(uvm_reg r,
#                                              string kind);
#        uvm_hdl_path_concat paths[$];
#
#	// avoid calling get_full_hdl_path when the register has not path for this abstraction kind
#	if(!r.has_hdl_path(kind))
#		return;
#
#        r.get_full_hdl_path(paths, kind);
#        if (paths.size() == 0) return;
#
#        foreach(paths[p]) begin
#            uvm_hdl_path_concat path=paths[p];
#            foreach (path.slices[j]) begin
#                string p_ = path.slices[j].path;
#                uvm_reg_data_t d;
#                if (!uvm_hdl_read(p_,d))
#                    `uvm_error("uvm_reg_mem_hdl_paths_seq",
#                               $sformatf("HDL path \"%s\" for register \"%s\" is not readable",
#                                         p_, r.get_full_name()));
#                if (!uvm_hdl_check_path(p_))
#                    `uvm_error("uvm_reg_mem_hdl_paths_seq",
#                               $sformatf("HDL path \"%s\" for register \"%s\" is not accessible",
#                                         p_, r.get_full_name()));
#            end
#        end
#    endfunction
# 
#
#    protected virtual function void check_mem(uvm_mem m,
#                                              string kind);
#        uvm_hdl_path_concat paths[$];
#
#	// avoid calling get_full_hdl_path when the register has not path for this abstraction kind
#	if(!m.has_hdl_path(kind))
#		return;
#
#        m.get_full_hdl_path(paths, kind);
#        if (paths.size() == 0) return;
#
#        foreach(paths[p]) begin
#            uvm_hdl_path_concat path=paths[p];
#            foreach (path.slices[j]) 
#            begin
#                string p_ = path.slices[j].path;
#                if(!uvm_hdl_check_path(p_))
#                    `uvm_error("uvm_reg_mem_hdl_paths_seq",
#                               $sformatf("HDL path \"%s\" for memory \"%s\" is not accessible",
#                                         p_, m.get_full_name()));
#            end
#        end
#    endfunction 
#endclass: uvm_reg_mem_hdl_paths_seq
