개요
프로젝트 기간
2025.08.27 ~ 2025.09.05
AMBA BUS 개요
- BUS : CPU나 Memory, I/O 장치 간의 Data / 신호 교환을 위한 통로
- AHB (Advanced High-Performance Bus)
- 여러 개의 Master가 여러 개의 Slave에 연결되어 있는 구조
- Burst transfer를 통한 파이프라인 구조 가능
- 고속 데이터 전송 가능
- APB (Advanced Peripheral Bus)
- 최소한의 전력 소모와 시스템의 복잡도를 줄인 저가형 인터페이스
- 파이프라인 형태가 아님 (AHB보다 전송 속도가 느림)
- 구현이 매우 단순
AXI4 Protocol 개요
- Point-to-Point : AMBA BUS와는 다르게 BUS 개념이 아닌 protocol의 개념
- 장점 : 동시 통신이 가능. (write와 read의 분리 사용이 가능)
- 단점 : wire 수가 많아짐 (Area 증가)
개발 환경
- 사용 언어 : SystemVerilog, C
- Tool : Vivado, Vitis, draw.io
- editor : VS Code
AMBA APB-BUS 상세 설계
APB-BUS Signal
Blockdiagram
FSM
APB-BUS Peripheral Blockdiagram
AMBA APB-BUS 시뮬레이션 및 검증
APB-BUS RAM (UVM 기반 systemverilog 검증)
- Write값을 랜덤으로 생성 (0 or 1) 즉, 무작위로 읽거나 쓰는 동작 수행
- read 동작 수행 시 ref_mem에 저장되어 있는 값을 ref_rdata에 저장해둠
- ref_rdata값과 실제 RAM에서 read한 값이 일치하면 pass
- 만약, 내가 접근한 메모리 주소에 값이 없다면 x 값을 읽어옴
- 이 때, ref_rdata도 동일 주소에서 값이 없을 경우 x 값을 읽어옴. 따라서, 이 두 결과가 동일하면 pass
- 총 100000회 동작 수행. write 동작 : 49828회, read & 비교 동작 : 50172회
- 모든 경우 pass (fail 0건)
APB-BUS Peripheral 검증
GPIO test
- GPO test : CR[1:0] = 1, ODR[1:0] = 1로 설정. GPO[1:0] 핀에 1 1이 출력되는지 확인
- GPI test : 입력 벡터 gpi = 8'b1100_0000을 넣고, CR[7:6] = 1로 입력 활성화. h1000_2004의 idr값을 읽음
FND_Controller test
- en = 1로 설정, fnd_data = 14'd1000로 설정
- fndFont에서 1(f9), 0(c0), 0(c0), 0(c0)이 반복되서 출력되는 것을 확인. 즉, 1000이 fnd로 display
UART test
- sr[1:0] = 1 1 을 넣어서, tx, rx enable
- tx_Data에 8'b0011_1010을 넣어주고 tx 값 확인
- rx에 1 0 1 0 1 0 1 0을 104us의 주기로 강제로 넣어주고 rx_data [7:0] 값 확인
- rx_Done이 뜨면 rx_done에 해당하는 slv_reg[4]에 1을 띄워줌. CPU가 rx_data를 읽을 때, slv_reg[4]를 0으로 내림
AXI4-Lite 상세 설계
AXI4-Lite Signal
- AW, W, B, AR, R은 채널의 개념. 각 채널은 단방향이고 분리. 즉, 이론상 같은 시간에 read, write 가능
- transfer는 신호 하나를 의미
- transaction은 한 채널의 주고 받는 신호들을 의미
AXI4-Lite protocol 통신 방식
- 모든 채널에 VALID, READY handshake가 존재
- Source에서 Destination으로 보낼 때, VALID 신호를 HIGH로 같이 보내줌
- Destination 쪽에서 잘 받았으면, Source 쪽으로 Ready 신호를 High로 전송
AXI4-Lite protocol Blockdiagram
AXI4-Lite protocol FSM
AXI4-Lite RTL Design
- MicroBlaze CPU IP 사용
- MicroBlaze는 200MHz clk을 사용하므로 이를 clock wizard를 통해 clk을 100MHz로 바꿔줌
- AXI4_Lite Peripheral IP 사용
AXI4-Lite 시뮬레이션 및 검증
Vitis를 통한 검증
- Vitis : 내장형 Arm 프로세서에서 실행되는 호스트 애플리케이션 개발을 위한 독립형 내장형 소프트웨어 개발 패키지
- AXI4-Lite의 GPIO, FND Peripheral test를 위해 간단한 C code 작성
- GPIO는 Basys 3 보드의 LED와 연결하여 0.1초 간격으로 깜빡거림
- FND는 0.1초마다 증가하는 counter값을 출력
동작 영상
트러블 슈팅
1. GPIO Load/Write 오류
- 문제 상황 : GPIO 주변 장치에 접근할 때, 기대한 값 대신 X value가 찍힘
- 원인 분석 : APB Protocol에서 레지스터 접근이 word 단위 (4 Byte 정렬)로 이루어져야 함
- 해결 방법 :
PADDR[3:2]로 수정 하여 4 Byte 단위 레지스터에 정확히 매핑되도록 함
2. UVM 기반 systemverilog RAM 검증 시 X value fail
- 문제 상황 : 실제 동작은 정상임에도 불구하고 FAIL (Dismatched Data) 메시지가 발생
- 원인 분석 : == 연산자는 x (unknown), z (high-impedance) 값을 동등 비교하지 못함. 즉, x == x라도 FALSE가 되어 FAIL 발생
- 해결 방법 :
=== 연산자를 사용하여 0/1 뿐만 아니라 x value도 동일하게 취급하여 비교 가능
3. Uart Peripheral에서 rx 동작 오류
- 문제 상황 : Simulation에서는 rx_done이 잘 뜨지만, 머신 코드에 올렸을 때, Loop Back 응답 x
- 원인 분석 : Uart 모듈 자체에서 rx_done은 1 tick (10ns)을 내보냄. 처음 설계 구조에서는 rx_done, tx_done, tx_busy 자체를 slv_reg0에 넣어둠. 따라서, CPU가 rx_done 한 tick을 감지하지 못하면, 다시 PC로 Tx하는 동작 수행 X
- 해결 방법 : 따라서, rx_done 신호를 받을 때, 한 tick을 그대로 받는 것이 아니라 slv_reg0[4]에 1을 계속 저장해둠. CPU가 rx_data값을 읽었을 때, slv_reg0[4]를 다시 0으로 내려주는 방식으로 동작
결론 및 고찰
느낀점
- RV32I CPU에 APB Bus를 붙이고, 주변 장치들을 직접 설계, 연동하면서 실제 MCU와 유사한 시스템을 구축해 봄.
- APB Bus를 이용하여 메모리 맵 기반의 주변 장치 제어 구조를 구현함으로써, 임베디드 시스템에서 CPU와 주변 장치가 어떻게 상호작용하는지 이해할 수 있었음.
- 단순히 CPU와 메모리를 연결하는 수준을 넘어, 하드웨어와 소프트웨어가 메모리 맵을 통해 통합되는 방식을 직접 경험.
확장 가능성
- Peripheral 확장 : HC-SR04, DHT11 등 다양한 센서 확장.
- UART + FIFO : UART에 FIFO를 추가하여 더 큰 데이터 전송 및 버퍼링 기능 제공