어떻게 하면 잘 검증할 것인가??

VerilogHDL로 하드웨어 배우고 설계해봤는데 자동으로 검증 어떻게??

  1. Test 환경 구성

image.png

  1. Testbench 시나리오

    1. 초기화

    2. 리셋

    3. Send (UART Tx를 Start)

    4. Tx신호를 receive

image.png

receive는 (1/9600) /2 초에 읽으면 됨

send는 최소 10개의 bit 즉 1/960초 이상의 주기를 가지고 자동으로 쏴주면 됨.

function과 task의 차이? function은 시간 제어가 안됨!!

image.png

`timescale 1ns / 1ps

module tb_uart_tx ();

    parameter MS = 1_000_000;
    parameter TX_DELAY = (100_000_000 / 9600) * 10 * 10;
    parameter BAUD_RATE = 9600;
    parameter CLOCK_PERIOD_NS = 10;
    parameter BITPERCLOCK = 1 % BAUD_RATE;
    parameter BIT_PERIOD = BITPERCLOCK * CLOCK_PERIOD_NS;

    reg clk, rst, tx_start;
    reg [7:0] tx_data;
    wire tx, tx_busy;

    // verification variable
    reg [7:0] expected_data;  // 비교하기 위해서 저장해놓을 변수
    reg [7:0] receive_data;  // tx로 받은거 lsb부터 채워 넣을 것임
    integer bit_count;

    uart_top dut (
        .clk(clk),
        .rst(rst),
        .tx_start(tx_start),
        .tx_data(tx_data),
        .tx(tx),
        .tx_busy(tx_busy)
    );

    always #5 clk = ~clk;

    initial begin
        #0 clk = 0;
        rst = 1;
        tx_start = 0;
        tx_data = 8'h33;
        #10 rst = 0;
        #10 tx_start = 1;
        #(5 * MS) tx_start = 0;
        #(TX_DELAY);
        $stop;

        // verification process
        $display("UART TX testbench started");
        $display("BAUD Rate      : %d", BAUD_RATE);
        $display("Clock per Bits : %.20f", BITPERCLOCK);
        $display("Bit period     : %.20f", BIT_PERIOD);

        // test task
        single_uart_byte_test(8'h41);
        $stop;
    end

    // for verification
    task single_uart_byte_test(input [7:0] send_data);
        fork 
            sender(send_data);
            receive_uart();
        join
    endtask

    // gen uart tx start
    task sender(input [7:0] send_data);
        begin
            expected_data = send_data;
            tx_data       = send_data;
            @(negedge clk);
            tx_start = 1'b1;
            #(5*MS);
            //@(negedge clk);
            tx_start = 1'b0;

            @(negedge tx_busy);
        end
    endtask

    // receive for verification
    task receive_uart();
        begin
            receive_data = 0;
            @(negedge tx);

            #(TX_DELAY/20);

            // start bit pass/fail
            if (tx) begin
                $display("Fail Start bit");
            end

            // received data bit
            for (bit_count = 0; bit_count < 8; bit_count = bit_count + 1) begin
                #(TX_DELAY/10);
                receive_data[bit_count] = tx;
            end            
            
            if(!tx) begin
                $display("Fail Stop bit");
            end

            #(TX_DELAY/20);

            //pass/fail tx data
            if (expected_data == receive_data) begin
                $display("Pass : Data matched : received data %2x", receive_data);
            end else begin
                $display("Fail : Data mismatch : received data %2x", receive_data);
            end
        end
    endtask
endmodule