일단 UVM을 이용한 완성된 검증코드가 없어서
https://m.blog.naver.com/PostView.naver?blogId=nepenthes1&logNo=223483499976&navType=by
이 분의 코드를 가져와서 사용한다.
이 글은 개인 공부 기록이고 이분이 생각보다 정리를 잘 해놓으셨으니, 위 글을 읽어도 좋다.
이 글은 개인 공부 기록이므로 틀린 내용이 있을 수 있습니다.
그리고 자주 수정 될 수 있습니다.
일단 개념과 용어부터 정리한다.
=검증
내부 구조와 상관 없이 입력 값을 넣었을 때 나온 출력이 예상한 값과 같으면 검증이 끝났다고 판단한다.
이때 반복문으로 여러번 테스트 하면 좋고
같은 데이터가 아닌 다른 데이터로 테스트 하면 더 좋다.
그리고 연속된 데이터가 아닌 임의의 데이터를 입력하면 가장 좋다.
이를 정리하면
이런 랜덤 데이터 입력에 따른 출력을 비교하여 일정 횟수 돌려봤을 때 문제가 없는지 확인하는 방법이 UVM이다.
정확한 정의는 아니지만, 대충 이런 느낌이다. 이는 주요한 검증 방식 중 하나다.
이때 이런 랜덤 데이터 생성, 여러번 돌리기 위한 입출력 제어, 출력과 예상값 비교, 해당 내용의 출력 등을
미리 정의된 라이브러리 내부의 클래스를 상속받아 일정한 양식에 맞춰서 코드를 작성하고 검증하는 것이 UVM이다.
=클래스 내부 구조
클래스 -> 여러 함수와 변수의 묶음, 서로 관련 된 것만 묶어 놓았다고 생각하면 됨
function new() -> 클래스 개념이 도입된 언어에서 클래스를 복사해서 나만의 객체, 인스턴스 를 생성할 때,
처음 실행되어 객체를 초기화 하는 함수, 주로 상위 , 부모 클래스의 객체의 초기화를 위해서 사용.
task 실제 클래스 생성시 초기화 후 동작
function 이름을 가져서 이름으로 실행 가능, 항상 실행되는 것이 아닌, 오직 (객체).(함수)의 형태로 실행된다.
아마 UVM에서 이런 함수로 미리 이름을 만들어 놓아서 구성한 것으로 보인다.
= 개념
Unified Verification Methodology, UVM -> 검증 방법론중 하나, Accellera사에서 만들고 오픈소스로 공개
이를 통해 아무나 사용 가능해지면서 범용적으로 사용됨
DUT(Device Under Test) -> 검증 할 모듈
transaction -> 시뮬레이션을 위해 생성해서 DUT 모듈에 입출력하는 랜덤 입출력 데이터의 묶음을 트랜젝션으로 부른다.
x+y=z라고 하면 input x,y, output z 이 3가지를 묶어서 트랜젝션이라 부른다.
인터페이스는 이를 묶어서 사용하는 입출력 포트를 의미한다면,
트랜젝션은 돌아다니는 데이터의 개념
= 주요 블럭의 이름과 기능
interface -> 테스트 할 모듈의 입출력을 따로 묶어둔 것
이를 통해서 입력 신호를 한번에 처리한다.
uvm_sequence_item -> 검증을 위한 DUT모듈에 입력할 신호 생성을 위한 클래스
데이터 형식을 지정한다.
여기서는 신호에 입력되는 랜덤 값의 범위등을 설정 가능
이 신호는 랜덤 신호를 사용할 것이에요. 범위는 이정도에요. 정도의 기능
검증 과정에서는 딱 이 입출력 신호를 보기 때문에, 데이터 생성, 생성 데이터 전달, 출력 데이터 정리하는 곳으로 전달할때 등
많은 곳에서 이 클래스의 객체를 생성해서 해당 데이터를 저장한다. 이 과정에서 항상 같은 데이터 형식을 사용한다.
uvm_sequence -> uvm_sequence_item에서 만든 클래스를 불러와서 실제로 랜덤 데이터를 생성하는 기능
virtual을 통해 매번 새로 불러와서 매 검증 횟수마다 새로운 랜덤 값을 입력한다.
uvm_driver ->sequence_item 클래스를 상속 받고 인터페이스도 매번 새로 받아와서 sequence_item 객체에서 저장된 랜덤 생성된 값을 인터페이스에 넘겨주는 클래스
먼저 클래스 핸들러를 만들고
build_phase에서 핸들러에 실제 객체를 연결하고
run_phase 에서 실제로 객체의 랜덤 값을 인터페이스에 넘겨준다.
uvm_monitor -> 검증 과정에서 인터페이스를 통해 DUT 에 들어가고 나온 트랜젝션이란 데이터를
Scoreboard란 출력 결과와 예상 결과를 비교하는 곳으로 전달해주는 클래스
Scoreboard와 연결을 위한 uvm_analysis_port를 생성한다.
build_phase 여기서는 sequence_item 객체를 생성해서 DUT의 출력인 인터페이스에서 나온 값을 저장하고
Scoreboard로 전달할 출력 포트를 설정한다.
run_phase 에서 이 값을 다시 Scoreboard로 보낸다.
uvm_scoreboard -> uvm_monitor에서 전달 받은 값을 바탕으로 출력과 예상 값 비교를 실행한다.
여기서는 write란 함수를 이용했는데 이름이 정해진 것인지는 모르겠다.
uvm_agent -> monitor, driver, sequencer(sequence 아님) 객체를 생성하고 driver의 포트를 sequencer의 포트에 연결한다.
정확한 기능은 모르겠다. 다만 합쳐주는 과정인 것 같다.
Sequencer는 인터페이스와 드라이버 사이에서 중재하는 역할이라고 들었는데 정확히 모른다.
build_phase와
connect_phase가 있다.
여기서 잠시 구조를 정리하면
Driver - interface, seq_item이 있어서 입력을 연결해주고
Monitor - interface, seq_item이 있어서 입출력 값을 저장하고 이를 Scoreboard에 전달한다.
Sequencer - Driver랑 연결되어서 어딘가로 간다?
uvm_env -> 환경이라 부르는 부분이다. 스코어 보드와 에이전트를 부른다.이후 모니터의 값을 스코어보드에 연결한다.
딱 이게 전부다.
여기에
send,
recv,
uvm_analysis_port #(seq_item) send,
uvm_analysis_imp #(seq_item, adder_scoreboard) recv;
등의 표현이 있는데 이를 정리해야 좀더 자세한 구조를 이해할 수 있을 것 같다.
다시 구조 정리
ENV - Agent -------- |- Driver
| |- Monitor
| |- Sequencer
|- Scoreboard
uvm_test -> uvm_env와 uvm_sequence를 불러와서 검증 환경 설정을 불러오고, 랜덤 생성 값을 불러온다.
build_phase
객체 초기화 -> 여기서 신호 생성 구조 및 스코어 보드를 통한 UVM 출력 환경이 미리 설정 된다.
run_phase
phase 시작 -> Sequence에서 랜덤 신호 생성 후, Sequencer로 전달? -> phase 종료?
아마 여기가 실제로 검증 데이터 넣고 출력 나오는 부분으로 보인다.
여기서 랜덤 데이터 생성 하면 미리 만들어진 검증 환경에 들어가서 출력이 Scoreboard로 나오고
phase가 종료되면 랜덤 값도 사라지는 것으로 보인다.
결국 env는 미리 만들어진 회로고,
sequence는 랜덤 신호 생성으로 생성 되는 순간 회로에 전원공급 하듯 바로 전달되서 UVM에서 바로바로 결과를 출력하고
phase 종료시 sequence출력이 끝나면서 입력이 끊기면서 초기화 되는 듯 하다.
module tb_Adder(); -> 테스트 벤치 모듈
결국 이것도 SystemVerilog로 동작하니 테스트 벤치를 작성해야 동작한다.
먼저 인터페이스 불러오고, 테스트 클래스 불러온다.
이후 검증할 모듈 불러오고, initial로 테스트 클래스 불러와서 객체를 만들고,
uvm_config_db에서 인터페이스를 설정한다. 정확한 문법은 찾아봐야 된다.
이후 run_test();로 run_phase가 실행되는 것으로 보인다.
이를 그림으로 정리하고 각 모듈별로 올렸다.
정확하지는 않지만, 다음과 같다.
일단 이런 구조다.
Sequence에서 시작해서 랜덤 신호가 생성되면 이게 Sequencer로 연결되고
Sequecner에서 드라이버로 신호를 보내면
Interface를 통해 DUT 에 input 신호가 들어가고 output 신호가 생기면
이를 monitor에서 읽어가서 Scoreboard에 올린다.
그러면 예상 값과 비교해서 Scoreboard에서 판정후 해당 내용을
UVM info 나 UVM fatal 등의 메세지를 띄워준다.
대충 확인한 것이라 정확하지 않은 부분이 있으니 하나씩 보강하려 한다.
생각보다 ChatGPT가 이런 코드를 잘 알아서 주로 물어보려 한다.
아마 몇몇 부분은 내가 빼먹은 SystemVerilog 문법으로 보인다.
'과정 종료 후 개별 스터디 내용 > SystemVerilog, UVM' 카테고리의 다른 글
UVM 1, 2일차 - 자세한 내용 (0) | 2025.01.06 |
---|---|
SystemVerilog 검증 IDEC 강의 1일차 내용 요약 (2) | 2025.01.05 |
UVM 공부 시작 및 찾은 내용 정리 (1) | 2025.01.05 |
Vivado에서 UVM 사용하기 (0) | 2025.01.03 |