Verilog/기본모듈 및 이론

Day 9 - Systemveril

onthejobtrain 2024. 6. 19. 23:56

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 신호 입력

인터페이스

변수들

https://wikidocs.net/170319 

 

01.02.02 Data Types

[TOC] ## Lexical Conventions SystemVerilog의 주요 Lexical Conventions는 아래와 같습니다. 대부분 Verilog의 규칙을 그…

wikidocs.net

위 사이트에 UVM에 대한 자세한 설명 및 예시가 있어 공부하기 좋다.

C언어와 비슷하고 Logic 이라는 변수는 wire 와 reg를 다 커버가능하다.

 

DUT

순차회로 → 더 안정적

fork join → thread랑 비슷하게 작동함

systemverilog로 만든 testbench의 최종 구조

과제

더보기

`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