System Verilog(FIFO)

Park SeungChan·2024년 5월 23일
0

Verilog

목록 보기
7/8

FIFO

FIFO(First In First Out)은 데이터를 저장하는 방식으로 처음 저장된 데이터를 제일 먼저 읽을 수 있는 구조로 만들어진다.

주로 read와 write의 속도가 다를 때 사용하며, 데이터의 순서를 보장하는 버퍼의 역할을 한다.

Push : 데이터를 write
Pop : 데이터를 read
Full : 더이상 write할 수 없다, Memory Full
Empty : 더이상 read할게 없다, Memory Empty

FIFO는 write를 위한 pointer와 read를 위한 pointer로 현재의 위치를 나타낸다.

초기에는 저장된 데이터가 없으므로 두 포인터는 같은 위치를 가리키며 Empty상태이다.
Push동작에서 두 포인터가 같아지면 데이터가 가득차는 Full상태이고, Pop동작에서 두 포인터가 같아지면 데이터가 비어있는 Empty상태이다.

FIFO설계 & SystemVerilog검증코드

`include "transaction.sv"

class scoreboard;
    transaction trans;
    mailbox #(transaction) mon2scb_mbox;
    event gen_next_event;

    int total_cnt, read_pass_cnt, read_fail_cnt, write_cnt, write_fail_cnt, empty_cnt;
    reg [7:0] scb_fifo[$:8];  // '$' is queue(fifo), ':8'이 없으면 무한대 값, golden reference
    reg [7:0] scb_fifo_data;

    function new(mailbox#(transaction) mon2scb_mbox, event gen_next_event);
        this.mon2scb_mbox   = mon2scb_mbox;
        this.gen_next_event = gen_next_event;

        total_cnt           = 0;
        read_pass_cnt       = 0;
        read_fail_cnt       = 0;
        write_cnt           = 0;
        write_fail_cnt      = 0;
        empty_cnt 			= 0;
    endfunction  //new()

    task run();
        forever begin
            mon2scb_mbox.get(trans);
            trans.display("SCB");
            if (trans.wr_en) begin
                if(!trans.full) begin
                    scb_fifo.push_back(trans.wdata);  // 뒤에서 입력
                    $display(" --> WRITE! fifo_data: %x, queue size: %d",
                             trans.wdata, scb_fifo.size());
                    write_cnt++;
                end else begin
                    $display(" --> WRITE_FAIL! fifo_data: %x, queue size: %d",
                             trans.wdata, scb_fifo.size());
                    write_fail_cnt++;
                end
            end else if (trans.rd_en) begin
                if(!trans.empty) begin
                    scb_fifo_data = scb_fifo.pop_front(); // 앞에서 출력하여 저장
                    if (scb_fifo_data == trans.rdata) begin
                        $display(" --> PASS! fifo_data %x == rdata %x, que size: %d",
                            scb_fifo_data, trans.rdata, scb_fifo.size());
                        read_pass_cnt++;
                    end else begin
                        $display(" --> FAIL! fifo_data %x != rdata %x, que size: %d",
                            scb_fifo_data, trans.rdata, scb_fifo.size());
                        read_fail_cnt++;
                    end
                end else begin
                    $display(" --> EMPTY! fifo_data %x , rdata %x, que size: %d",
                        scb_fifo_data, trans.rdata, scb_fifo.size());
                    empty_cnt++;
                end
            end
            total_cnt++;
            ->gen_next_event;
        end
    endtask
endclass  //scoreboard
reg [7:0] scb_fifo[$:8];

소프트웨어적으로 scoreboard에 fifo를 만들어주고 하드웨어 FIFO동작에따라 "push_back , pop_front"와 같은 구문으로 stimulus를 저장해 Golden Data와 DUT의 출력을 비교하여 검증을 수행한다.

UART-FIFO

설계한 UART와 FIFO를 연결해 PC에서 보드로 받는 RX신호를 다시 roofback하여 보드에서 PC로 transmit하는 테스트를 진행한다.

  1. 구성은 trasmitter와 receiver 각각에 대한 FIFO를 만든다.

  2. rx_fifo는 receiver의 done신호에 의해 데이터가 write되며, rx_empty의 not신호를 데이터를 read하는데 사용한다.

  3. tx_fifo는 rx_fifo의 rx_data를 그대로 roofback하고, rx_empty의 not신호를 데이터를 write하는데 사용한다. 그리고 tx_empty신호를 transmitter의 start신호로 주어 데이터를 PC로 내보낸다.

UART_FIFO 전체코드

동작영상------

profile
RTL Circuit Design & Verification

0개의 댓글

관련 채용 정보