UVM(Universal Verification Methodology) 반도체 검증 알고지즘 방법 중 하나이다.
나중에 더욱 자세하게 배울 것 이다.
https://seon77.tistory.com/entry/UVMUniversal-Verification-Methodology-개요
UVM(Universal Verification Methodology) 개요
UVM은 검증 환경과 VIP(Verification IP)를 재사용하여 빠른 개발을 가능하게 하는 표준 검증 방법론이다. UVM을 활용하면 다른 팀들과 테스트벤치의 균일성, 호환성, 유지 관리의 유연성/용이성을 보장
seon77.tistory.com
위 블로그를 참고해보면 좋다.
Systemverilog
<SystemVerilog TestBench 구조도>
generator : Data 생성
Transaction : test를 위한 Data 묶음
driver : Data를 H/W 신호 변형 , 소프트웨어를 하드웨어 신호로 변경 해주는 것
monitor : DUT출력신호를 Data로 변경
scoreboard : 생성 Data와 모니터의 Data를 비교 Pass, Fail 판단
UVM형식으로 Systemverilog로 testbench를 만드는 것 이다.
System Verilog
- 검증용으로 왜 SystemVerilog를 사용할까?Class → 객체지향언어 - 3대기능 (캡슐화, 추상화, 상속화,다형성)상속: 재사용성 -새로운기능을 만들 때 기존에 만들어 놓은 것을 사용하는것.다형성: 같은객체를 다르게 정의 할 수 있다. (상속개념 + 포인터 + 변수)
- 확장성: 기존 기능, 기본 기능 + 새로운 기능.
- 캡슐화: 목적기능을 위한 변수 함수들을 묶어 놓은 것
- Randomized Stimulus → 임의값으로 DUT 신호 입력
인터페이스
변수들
01.02.02 Data Types
[TOC] ## Lexical Conventions SystemVerilog의 주요 Lexical Conventions는 아래와 같습니다. 대부분 Verilog의 규칙을 그…
wikidocs.net
위 사이트에 UVM에 대한 자세한 설명 및 예시가 있어 공부하기 좋다.
C언어와 비슷하고 Logic 이라는 변수는 wire 와 reg를 다 커버가능하다.
DUT
순차회로 → 더 안정적
fork join → thread랑 비슷하게 작동함
과제
`timescale 1ns / 1ps
interface reg_intf;
logic clk;
logic reset;
logic [15:0] a_in;
logic [15:0] a_out;
endinterface //reg_intf
class transaction;
rand logic [15:0] a_in;
logic [15:0] a_out;
task display(string name);
$display("[%s] a_in: %d , a_out: %d", name, a_in, a_out);
endtask
endclass
class generator;
transaction tr;
mailbox #(transaction) gen2drv_mbox;
event genNextEvent;
function new();
tr = new();
endfunction //new()
task run();
repeat (1000) begin
assert (tr.randomize())
else $error("tr.randomize() error !");
gen2drv_mbox.put(tr);
tr.display("GEN");
@(genNextEvent);
end
endtask //
endclass //generator
class driver;
virtual reg_intf reg_if;
mailbox #(transaction) gen2drv_mbox;
transaction tr;
event monNextEvent;
function new(virtual reg_intf reg_if);
this.reg_if = reg_if;
endfunction
task reset();
reg_if.a_in <= 0;
reg_if.a_out <= 0;
reg_if.reset <= 1'b1;
repeat (5) @(reg_if.clk);
reg_if.reset <= 1'b0;
endtask
task run();
forever begin
gen2drv_mbox.get(tr);
reg_if.a_in <= tr.a_in;
reg_if.a_out <= tr.a_out;
@(posedge reg_if.clk);
@(posedge reg_if.clk);
@(posedge reg_if.clk);
tr.display("DRV");
->monNextEvent;
end
endtask
endclass
class monitor;
virtual reg_intf reg_if;
mailbox #(transaction) mon2scb_mbox;
transaction tr;
event monNextEvent;
function new(virtual reg_intf reg_if);
this.reg_if = reg_if;
tr = new();
endfunction
task run();
forever begin
@(monNextEvent);
tr.a_in = reg_if.a_in;
tr.a_out = reg_if.a_out;
mon2scb_mbox.put(tr);
tr.display("MON");
end
endtask
endclass
class scoreboard;
mailbox #(transaction) mon2scb_mbox;
transaction tr;
int total_cnt, pass_cnt, fail_cnt;
event genNextEvent;
task run();
forever begin
mon2scb_mbox.get(tr);
tr.display("SCB");
if (tr.a_in == tr.a_out) begin
$display("--> PASS ! %d == %d", tr.a_in, tr.a_out);
pass_cnt++;
end else begin
$display("--> FAIL ! %d == %d", tr.a_in, tr.a_out);
fail_cnt++;
end
total_cnt++;
->genNextEvent;
end
endtask
endclass
module tb_register ();
reg_intf reg_interface ();
generator gen;
driver drv;
monitor mon;
scoreboard scb;
event genNextEvent;
event monNextEvent;
mailbox #(transaction) gen2drv_mbox;
mailbox #(transaction) mon2scb_mbox;
register dut (
.clk (reg_interface.clk),
.reset(reg_interface.reset),
.a_in (reg_interface.a_in),
.a_out(reg_interface.a_out)
);
always #5 reg_interface.clk = ~reg_interface.clk;
initial begin
reg_interface.clk = 1'b0;
reg_interface.reset = 1'b1;
end
initial begin
gen2drv_mbox = new();
mon2scb_mbox = new();
gen = new();
drv = new(reg_interface);
mon = new(reg_interface);
scb = new();
gen.genNextEvent = genNextEvent;
scb.genNextEvent = genNextEvent;
mon.monNextEvent = monNextEvent;
drv.monNextEvent = monNextEvent;
gen.gen2drv_mbox = gen2drv_mbox;
drv.gen2drv_mbox = gen2drv_mbox;
mon.mon2scb_mbox = mon2scb_mbox;
scb.mon2scb_mbox = mon2scb_mbox;
drv.reset();
fork
gen.run();
drv.run();
mon.run();
scb.run();
join_any
$display("===============================");
$display("== Final Report ==");
$display("===============================");
$display("Total Test : %d", scb.total_cnt);
$display("Pass Test : %d", scb.pass_cnt);
$display("Fail Test : %d", scb.fail_cnt);
$display("===============================");
$display("== test bench is finished! ==");
$display("===============================");
#10 $finish;
end
endmodule
'Verilog > 기본모듈 및 이론' 카테고리의 다른 글
Day 11 - UART(FIFO) (0) | 2024.06.20 |
---|---|
Day 10 - System Verilog(2) (0) | 2024.06.20 |
Day 8 - UART(ASM) (0) | 2024.06.19 |
Day 7 - UART_Rx (0) | 2024.06.19 |
Day 6 - FSM, UART_Tx (0) | 2024.06.17 |