[HARMAN] 세미콘 아카데미/SystemVerilog

[Harman 세미콘 아카데미] Day_58(System Verilog)

uiop1716 2025. 4. 25. 09:48

FIFO (First In First Out) : 선입 선출   ex) Queue

LIFO (Last In First Out) : 후입 선출   ex) Stack 

 

FIFO가 없다면 APB_BUS Interface의 register에 계속 덮어쓰며 값이 사라지게 됩니다. 그래서, FIFO를 사용하여 순차적으로 APB_Master에 값을 보내도록 합니다. 

FIFO를 이용하여 통신 / buffer의 기능과 CDC(Clock Domain Crossing)역할을 합니다.

CDC란? 두개의 다른 Domain 회로의 다른 Clock으로 직접적인 연결이 불가하여, DualPort FIFO를 사이에 두어 Clock에 상관 없이 임시적으로 Data를 저장, 불러오기를 하여 데이터를 주고 받을 수 있습니다. 

FIFO 기능

 

어떻게 보면, FIFO는 Master와 Slave 사이에 존재하는 공유 메모리를 활용한다 라고 생각을 해도 무방합니다.

FIFIO의 Queue는 Memory의 Back(tail)에서 값을 입력(puh)하고 Front(head)에서 값을 출력(pop)합니다.

Memory의 주소에 Read나 Write할 순서를 정하여 동작을 실행해야 합니다. 동작의 순서를 알아야 뭐가 먼저 들어왔는지 알 수 있기 때문에, 이를 확인하기 위한 포인터를 만들어 줍니다. 이 포인터는, Read / Write에 대한 동작의 순서를 가리키고 또다른 Memory에 저장되어 있습니다.

FIFO(Queue)

 

 

FIFO 내부로 Data를 Write할 때, FIFO Register에 wdata 값을 wr_en 신호에 맞춰 동작합니다. Register가 꽉 차서 wdata를 못 받을 경우에는 full 신호를 내보내어 더이상 값이 못들어 오도록 합니다. 그리하여 full 신호는 ~wr_en으로 설계할 것입니다.

또한, FIFO Data를 Read할 때, FIFO Register에서 rdata를 rd_en 신호에 맞춰 read 합니다. Register가 empty 즉, 비어 있는 상태라면 출력할 값이 없기 때문에 read를 제한하는 empty 신호가 존재합니다.

 

** FIFO 회로의 특징 : RD/WR에 대한 Memoty Address가 없다. 

-> 입력/ 출력 순서대로 Memory Address가 내부 회로의 동작으로 자동 증가합니다.

FIFO Block

 

FIFO Pointer 관련 동작 조건 및 설명

 

0. 초기값

     - 아직 동작을 안하므로, rd_ptr의 주소와 wr_ptr의 주소는 동일하다.  = Memory 공간은 비어있다.

     -> rp_ptr = 0, wr_ptr = 0

     -> full = 0, empty = 1;

 

//write

기본 조건 : full = 0일 때 입력 가능

1.  'A' Push : wr_ptr값인 주소에 'A' Data Write

                  -> 종료 후, wr_ptr 1 증가

                  -> full = 0, empty = 0;

2.  'B' Push : wr_ptr값인 주소에 'B' Data Write

                  -> 종료 후, wr_ptr 1 증가

                  -> full = 0, empty = 0;

3.  'C' Push : wr_ptr값인 주소에 'C' Data Write

                  -> 종료 후, wr_ptr 1 증가

                  -> full = 0, empty = 0;

4.  'D' Push : wr_ptr값인 주소에 'A' Data Write

                  -> 종료 후, wr_ptr이 0으로 초기화

                  -> 조건 : wr_ptr이 rd_ptr과 다시 동일해 지면 full = 1;

                  -> full = 1, empty = 0; 

 

// read 

기본 조건 : empty가 0일때 출력 가능

5. pop  ->  'A'  출력 : rd_ptr값인 주소에 'A' Data Read

                  -> 종료 후, rd_ptr 1 증가

                  -> full = 0, empty = 0;

6. pop  ->  'B'  출력 : rd_ptr값인 주소에 'A' Data Read

                  -> 종료 후, rd_ptr 1 증가

                  -> full = 0, empty = 0;

7. pop  ->  'C'  출력 : rd_ptr값인 주소에 'A' Data Read

                  -> 종료 후, rd_ptr 1 증가

                  -> full = 0, empty = 0;

8. pop  ->  'D'  출력 : rd_ptr값인 주소에 'A' Data Read

                  -> 종료 후, rd_ptr 1 증가

                  -> 조건 : rd_ptr이 wr_ptr과 동일해지면 empty = 1;

                  -> full = 0, empty = 1;

waveform 설명

 

아래의 그림은 RAM과 FIFO의 연결과 동작을 나타낸 그림입니다.

FIFO Blockdiagram

 

RAM & FIFO Schematic

 

 

코드 : 

https://github.com/Heeju99/Code_Verilog_SystemVerilog/tree/main/workspace/250424_FIFO_re/250424_FIFO_re.srcs/sources_1/imports/new

 

Code_Verilog_SystemVerilog/workspace/250424_FIFO_re/250424_FIFO_re.srcs/sources_1/imports/new at main · Heeju99/Code_Verilog_Sy

Contribute to Heeju99/Code_Verilog_SystemVerilog development by creating an account on GitHub.

github.com

Testbench Code

 

결과:

순차적으로 RAM의 0,1,2,3 Register File에 1,2,3,4의 값을 순차적으로 Write하고, Read 하는 동작을 수행.

Clock에 맞춰 wr_en의 신호가 들어오면 0,1,2,3의 Register File에 wdata 값들이 저장되고 모두 저장하면 Full이 High가 됩니다.

또한, rd_en의 신호가 들어오며 1,2,3,4의 값들을 순차적으로 Read하여 값들을 rdata로 출력하고 모두 출력하면 empty가 High가 되면서 RegisterFile이 비었음을 나타내고 추후의 read 동작을 막습니다.

Simulation Result

 

 

그리고, 이를 UVM을 통해 Random값에 대한 Test를 진행해 보겠습니다. 

여태껏 사용하던 UVM 프레임워크를 가져와, transaction, reference model 등을 위주로 바꿔 만들면 됩니다.

 

먼저, Clocking block을 만들어 줍니다. Interface에 값을 보내거나 받는 class인 driver와 monitor의 경우, clk에 맞춰 값을 보내거나 받으면 두 값이 동시에 입/출력 될 수 있습니다. 그리하여 값의 혼동을 막기 위해 모든 input output 신호에 대해 #1 delay를 주어 input/ output signal timing을 정의합니다.

또한, modport를 통해 clocking 구문을 가져와, 모듈 내 Port에 대한 방향을 정의해 줍니다.

Clocking Block
Interface 내 방향이 없는 신호들을 modport를 통해 정의

 

 

코드 :

https://github.com/Heeju99/Code_Verilog_SystemVerilog/tree/main/workspace/250425_APB_FIFO_again/250425_APB_FIFO_again.srcs/sources_1/imports/Desktop/new

 

Code_Verilog_SystemVerilog/workspace/250425_APB_FIFO_again/250425_APB_FIFO_again.srcs/sources_1/imports/Desktop/new at main · H

Contribute to Heeju99/Code_Verilog_SystemVerilog development by creating an account on GitHub.

github.com

 

 

결과 : 

wr_en이 High가 되면  임의의 wdata값을 쓰고, rd_en이 High가 되면 값을 read합니다. Write 모드일 경우, register에 저장된 값과, 저장하려는 값이 같은지 확인하고, Read 모드일 경우에는 출력되는 rdata와 저장되어있는 값을 비교하여 socreboard에 값을 출력합니다. RAM 내부에 값이 차면 Full 이라는 말을 display하고 비어있으면 Empty를 display합니다. 

TCI Console 결과