UVM: HDL Backdoor Access Support Routines - IKSciting
2020
post-template-default,single,single-post,postid-2020,single-format-standard,bridge-core-2.8.7,qodef-qi--no-touch,qi-addons-for-elementor-1.7.1,qode-page-transition-enabled,ajax_fade,page_not_loaded,,qode-title-hidden,qode_grid_1300,footer_responsive_adv,qode-content-sidebar-responsive,qode-theme-ver-27.1,qode-theme-bridge,qode_header_in_grid,wpb-js-composer js-comp-ver-6.6.0,vc_responsive,elementor-default,elementor-kit-838

HDL Backdoor Access Support Routines

간혹 검증을 진행하다 보면 DUT의 신호에 특정 값을 강제하기 위하여 Verilog/SystemVerilog의 force statement 또는 release statement를 사용해야 하는 경우가 있다. UVM에도 HDL backdoor access support routine라고 불리는 uvm_hdl_force function 또는 uvm_hdl_release function이 존재한다. Verilog/SystemVerilog에서 기본적으로 제공하는 forcerelease와 UVM에서 제공하는 uvm_hdl_forceuvm_hdl_release 사이에는 어떤 차이가 있으며 각각 어떤 목적으로 사용될 수 있는지 알아보자.

먼저 Verilog/SystemVerilog에서 제공하는 forcerelease statement의 syntax는 아래와 같다.

force top.dut.r = 32'hDEAD_BEEF;
release top.dut.r;

다음으로 UVM에서 제공하는 uvm_hdl_forceuvm_hdl_release function의 syntax는 아래와 같다.

uvm_hdl_force("top.dut.r", 32'hDEAD_BEEF);
uvm_hdl_release("top.dut.r");

Verilog/SystemVerilog의 forcerelease의 경우 compile-time에 path를 찾게 되고 만약 해당 path가 존재하지 않는다면 compile-time error로 출력된다. 반면, UVM의 많은 function이 그러하듯 uvm_hdl_forceuvm_hdl_release 역시 path를 string으로 전달 받고 해당 path를 run-time에 찾게 된다. 만약 path가 변수의 형태로 run-time에 dynamic하게 변경되어야 하는 특수한 경우라면 UVM function의 도움을 받을 수 있겠지만 일반적으로 그런 경우가 흔하지는 않다.

또 다른 차이는 forcerelease와 다르게 uvm_hdl_forceuvm_hdl_release는 0 또는 1의 값을 return 한다는 점이다. 만약 path에 대한 access가 성공적이면 1을 return 하지만, path가 잘못 기술되었거나 backdoor access를 위한 option이 적절히 적용되지 않았을 때는 0을 return 한다. 아래와 같이 항상 return 값을 check하여 UVM_ERROR 또는 UVM_FATAL로 출력하는 것이 좋다. 참고로 backdoor access를 위한 simulator option은 EDA vendor별로 상이하며 해당 access option 적용은 simulation speed에 영향을 줄 여지가 있다. 

if (!uvm_hdl_force("top.dut.r", 32'hDEAD_BEEF)) begin
    `uvm_fatal("top", "failed to force the signal")
end
if (!uvm_hdl_release("top.dut.r")) begin
    `uvm_fatal("top", "failed to release the signal")
end

이 외에도 uvm_hdl_check_pathuvm_hdl_deposituvm_hdl_force_timeuvm_hdl_release_and_readuvm_hdl_read와 같은 function이 존재한다. 참고로 UVM에서 제공하는 이러한 HDL backdoor access service routine은 DPI-C를 이용하는 방식이다. 즉, UVM에 대한 compilation 시 UVM_NO_DPI 또는 UVM_HDL_NO_DPI와 같은 text macro가 define 되면 안 된다는 뜻이다. 아래 UVM code를 참고하자.

//------------------------------------------------------------
//   Copyright 2007-2010 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: UVM HDL Backdoor Access support routines.
//
// These routines provide an interface to the DPI/PLI
// implementation of backdoor access used by registers.
//
// If you DON'T want to use the DPI HDL API, then compile your
// SystemVerilog code with the vlog switch
//:   vlog ... +define+UVM_HDL_NO_DPI ...
//


`ifndef UVM_HDL__SVH
`define UVM_HDL__SVH


`ifndef UVM_HDL_MAX_WIDTH
`define UVM_HDL_MAX_WIDTH 1024
`endif

/* 
 * VARIABLE: UVM_HDL_MAX_WIDTH
 * Sets the maximum size bit vector for backdoor access. 
 * This parameter will be looked up by the 
 * DPI-C code using:
 *   vpi_handle_by_name(
 *     "uvm_pkg::UVM_HDL_MAX_WIDTH", 0);
 */
parameter int UVM_HDL_MAX_WIDTH = `UVM_HDL_MAX_WIDTH;


typedef logic [UVM_HDL_MAX_WIDTH-1:0] uvm_hdl_data_t;

                            
`ifndef UVM_HDL_NO_DPI

  // Function: uvm_hdl_check_path
  //
  // Checks that the given HDL ~path~ exists. Returns 0 if NOT found, 1 otherwise.
  //
  import "DPI-C" context function int uvm_hdl_check_path(string path);


  // Function: uvm_hdl_deposit
  //
  // Sets the given HDL ~path~ to the specified ~value~.
  // Returns 1 if the call succeeded, 0 otherwise.
  //
  import "DPI-C" context function int uvm_hdl_deposit(string path, uvm_hdl_data_t value);


  // Function: uvm_hdl_force
  //
  // Forces the ~value~ on the given ~path~. Returns 1 if the call succeeded, 0 otherwise.
  //
  import "DPI-C" context function int uvm_hdl_force(string path, uvm_hdl_data_t value);


  // Function: uvm_hdl_force_time
  //
  // Forces the ~value~ on the given ~path~ for the specified amount of ~force_time~.
  // If ~force_time~ is 0, <uvm_hdl_deposit> is called.
  // Returns 1 if the call succeeded, 0 otherwise.
  //
  task uvm_hdl_force_time(string path, uvm_hdl_data_t value, time force_time=0);
    if (force_time == 0) begin
      void'(uvm_hdl_deposit(path, value));
      return;
    end
    if (!uvm_hdl_force(path, value))
      return;
    #force_time;
    void'(uvm_hdl_release_and_read(path, value));
  endtask


  // Function: uvm_hdl_release_and_read
  //
  // Releases a value previously set with <uvm_hdl_force>.
  // Returns 1 if the call succeeded, 0 otherwise. ~value~ is set to
  // the HDL value after the release. For 'reg', the value will still be
  // the forced value until it has bee procedurally reassigned. For 'wire',
  // the value will change immediately to the resolved value of its
  // continuous drivers, if any. If none, its value remains as forced until
  // the next direct assignment.
  //
  import "DPI-C" context function int uvm_hdl_release_and_read(string path, inout uvm_hdl_data_t value);


  // Function: uvm_hdl_release
  //
  // Releases a value previously set with <uvm_hdl_force>.
  // Returns 1 if the call succeeded, 0 otherwise.
  //
  import "DPI-C" context function int uvm_hdl_release(string path);


  // Function: uvm_hdl_read()
  //
  // Gets the value at the given ~path~.
  // Returns 1 if the call succeeded, 0 otherwise.
  //
  import "DPI-C" context function int uvm_hdl_read(string path, output uvm_hdl_data_t value);

`else

  function int uvm_hdl_check_path(string path);
    uvm_report_fatal("UVM_HDL_CHECK_PATH", 
      $sformatf("uvm_hdl DPI routines are compiled off. Recompile without +define+UVM_HDL_NO_DPI"));
    return 0;
  endfunction

  function int uvm_hdl_deposit(string path, uvm_hdl_data_t value);
    uvm_report_fatal("UVM_HDL_DEPOSIT", 
      $sformatf("uvm_hdl DPI routines are compiled off. Recompile without +define+UVM_HDL_NO_DPI"));
    return 0;
  endfunction

  function int uvm_hdl_force(string path, uvm_hdl_data_t value);
    uvm_report_fatal("UVM_HDL_FORCE", 
      $sformatf("uvm_hdl DPI routines are compiled off. Recompile without +define+UVM_HDL_NO_DPI"));
    return 0;
  endfunction

  task uvm_hdl_force_time(string path, uvm_hdl_data_t value, time force_time=0);
    uvm_report_fatal("UVM_HDL_FORCE_TIME", 
      $sformatf("uvm_hdl DPI routines are compiled off. Recompile without +define+UVM_HDL_NO_DPI"));
  endtask

  function int uvm_hdl_release(string path, output uvm_hdl_data_t value);
    uvm_report_fatal("UVM_HDL_RELEASE", 
      $sformatf("uvm_hdl DPI routines are compiled off. Recompile without +define+UVM_HDL_NO_DPI"));
    return 0;
  endfunction

  function int uvm_hdl_read(string path, output uvm_hdl_data_t value);
    uvm_report_fatal("UVM_HDL_READ", 
      $sformatf("uvm_hdl DPI routines are compiled off. Recompile without +define+UVM_HDL_NO_DPI"));
    return 0;
  endfunction

`endif


`endif

References

6 Comments
  • babyworm
    Posted at 12:20h, 17 September Reply

    보통은 force를 사용하고 있는데, uvm_hdl_force, uvm_hdl_release를 사용할 만한 상황이 존재하는지요? (혹은 장점이라던지요..)

    • IKS
      Posted at 12:22h, 17 September Reply

      일반적으로는 force, release로도 충분합니다.
      사실 개인적으로는 uvm_hdl_force, uvm_hdl_release를 업무에 적용해야 했던 경우는 없었습니다.
      하지만 본문에 언급한 것과 같이 만약에 force/release 하고자 하는 HDL path가 compile-time에 결정되지 않고 run-time 도중에 dynamic하게 변경되는 경우라면 uvm_hdl_force, uvm_hdl_release의 도움을 받을 수 있습니다.

  • minwoo
    Posted at 12:20h, 17 September Reply

    검증 엔지니어 쪽에서 종사중이신가요? 그쪽으로 하고 싶어 준비하는 초년생인데 여쭤보고 싶은게 몇개 있어서요. 감사합니다.

    • IKS
      Posted at 12:22h, 17 September Reply

      Contact 페이지를 통해 연락 주세요.

  • 이종원
    Posted at 12:21h, 17 September Reply

    UVM 관련 Posting 모두 정독했습니다. 좋은 내용들이 많네요 !!

    • IKS
      Posted at 12:23h, 17 September Reply

      감사합니다.

Post A Comment