Phase(단계)는 시뮬레이션의 진행을 체계적으로 관리하기 위해 사용됩니다. UVM Phase는 테스트벤치의 동작을 구조화하고, 특정 작업을 순차적으로 수행하도록 돕는 역할을 합니다. 이는 복잡한 테스트 환경에서 동기화 문제를 줄이고, 코드의 재사용성과 가독성을 높이기 위해 설계되었습니다. -GPT-
UVM의 모든 component
(driver, agent 등)들은 uvm_component
라는 Class
에서 파생됩니다. 또한 시뮬레이션할 때, 모든 component
들이 동기화되어 각 단계에 따라 순차적으로 작동합니다. 우리는 이것을 synchronizing mechanism을 따른다고 합니다. 그리고 이러한 동기화를 가능하게 해주는 것이 phase 라는 컨셉입니다.
일반적인 Verilog는 Static한 module
이나 container
로 이루어져 있습니다. 모든 모듈은 시뮬레이션을 시작할 때 생성되며, 도중에 모듈이 생성되거나 component
가 호출되지 않습니다(구조가 변하지 않습니다). 즉, Verilog 테스트벤치는 기능이 제한적이며 확장성이 없습니다. 하지만 SystemVerilog는 OOP(객체 지향 프로그래밍) 기능의 도입으로 게임 전체를 변화시킵니다.
uvm component
를 말함. uvm component
는 모두 class의 type을 가짐)를 만들 수 있습니다. component
가 아직 초기화되지 않은 상태에서 호출되면 잘못된 테스트벤치 출력이 발생할 수 있습니다. 또는 아직 호출되지 않은 component
를 사용하여 하면 오류가 발생합니다.component
간의 동기화가 핵심 요구 사항입니다.
사진 출처: Chipverify
Phase를 크게 3단계로 구분합니다.
1. Build time phase
2. Run time phase
3. Clean-Up phase
더 자세하게 보면 다음 표와 같습니다.
Phase Category | UVM Phase Name | Method Type | Description |
---|---|---|---|
Build | build_phase | function | 테스트벤치 component를 만들고 인스턴스를 create하는 데 사용됩니다. |
connect_phase | function | TLM 포트를 통해 서로 다른 테스트벤치 component를 연결하는 데 사용됩니다. | |
end_of_elaboration_phase | function | UVM 토폴로지 및 connect 후 수행해야 하는 기타 기능을 display하는 데 사용됩니다. | |
start_of_simulation_phase | function | Initial run-time configuration을 셋팅하거나 토폴로지를 display하는 데 사용됩니다. | |
Run | run_phase | task | 실제 시뮬레이션은 이 UVM 단계에서 이루어지며, 다른 UVM run_phase와 병렬로 실행됩니다. |
Clean | extract_phase | function | Scoreboard에서 예상 데이터를 추출하고 계산하기 위해 사용됩니다. |
check_phase | function | Used to perform scoreboard tasks that check for errors between expected and actual values from design | |
report_phase | function | Checker의 결과를 display하거나, 다른 test objectives를 요약하는 데 사용됩니다. | |
final_phase | function | 일반적으로 시뮬레이션을 종료하기 전에 마지막 순간에 해야하는 작업이 있다면, 해당 작업을 수행하는 데 사용됩니다. |
agent
내부에 driver
와 monitor
가 있다고 하면 agent
의 build phase 먼저 실행됩니다. 상위 component가 있어야 하위 component가 생성될 수 있기 때문입니다.Agent
class agent extends uvm_agent;
`uvm_component_utils(agent)
function new(string name="agent", uvm_component parent=null);
super.new(name, parent);
endfunction
driver d0; // Driver handle
monitor m0; // Monitor handle
uvm_sequencer #(Item) s0; // Sequencer Handle
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
s0 = uvm_sequencer#(Item)::type_id::create("s0", this);
d0 = driver::type_id::create("d0", this);
m0 = monitor::type_id::create("m0", this);
endfunction
...
Agent
의 build_phase
까지만 작성해보았습니다. Agent
의 하위 component
들을 create
하는 phase입니다.Monitor
class monitor extends uvm_monitor;
...
...
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
if (!uvm_config_db#(virtual des_if)::get(this, "", "des_vif", vif))
`uvm_fatal("MON", "Could not get vif")
mon_analysis_port = new ("mon_analysis_port", this);
endfunction
...
Monitor의 build_phase입니다.
이렇게 하위 component를 create하는 것 뿐만 아니라, virtual interface를 get하거나 필요한 TLM ports들을 생성할 수도 있습니다.
pre
, post
가 붙은 phase도 있으며,추후 알게되는 개념들이 있다면 더 자세하게 작성하여 추가하겠습니다.
더 자세한 내용은 제가 참고한 https://wikidocs.net/170348, https://www.chipverify.com/uvm/uvm-phases 사이트를 참고하셔도 좋을 것 같습니다!
읽어주셔서 감사합니다!
댓글, 지적, 하트와 댓글 부탁드립니다~><