[Zynq FIR IP 개발 #6]

YOUNGWOONG HAN·2026년 5월 6일

Zynq 구조 이해

① PS(C코드): 멀티톤 신호 합성
       ↓
② PS: DDR에 입력 배열 저장
       ↓
③ DMA MM2S: DDR → AXI-Stream → FIR S_AXIS (입력)
       ↓
④ FIR IP: 필터링 + 데시메이션 (M=2)
       ↓
⑤ DMA S2MM: FIR M_AXIS → AXI-Stream → DDR (출력 배열 저장)
       ↓
⑥ PS(C코드): DDR에서 결과 읽기 → UART 출력

DMA는 채널이 2개

  • MM2S (Memory-Mapped to Stream): DDR → FIR 방향
  • S2MM (Stream to Memory-Mapped): FIR → DDR 방향

생성하려는 block design

bd_fir_dma: custom fir ip와 PS ip, DMA ip를 붙인 block design

Block Design: bd_fir_dma
├── ZYNQ7 Processing System   ← IP 1
├── AXI DMA                   ← IP 2
└── fir_decimator_n43_axis    ← IP 3 (우리 것)
#IP 이름출처역할
1ZYNQ7 Processing SystemXilinx 기본 제공ARM 코어 + DDR + HP0 포트
2AXI Direct Memory AccessXilinx 기본 제공DDR ↔ AXI-Stream 브리지
3fir_decimator_n43_axis우리가 만든 RTLFIR 필터 + 데시메이터

Vivado가 "Run Connection Automation" 시 자동으로 추가하는 IP 2개:

#IP 이름역할
4Processor System ResetPS 리셋 신호 동기화
5AXI SmartConnectPS GP0 → DMA AXI-Lite 연결 중계

1. Vivado Block Design 생성

GUI에서 IP들을 배치하고 연결하는 것:

  • Zynq PS7 IP — ARM 코어, HP0 포트 활성화
  • AXI DMA IP — DDR ↔ AXI-Stream 브리지
  • Custom FIR IP (fir_decimator_n43_axis) — 커스텀 IP로 패키징해서 삽입

연결:

AXI DMA MM2S → (AXI-Stream) → FIR S_AXIS (입력)
AXI DMA S2MM ← (AXI-Stream) ← FIR M_AXIS (출력)
AXI DMA ↔ PS7 HP0 (DDR 직접 접근)

2. 비트스트림 생성 + XSA 내보내기

Block Design → Synthesize → Implement → Generate Bitstream → Export Hardware (.xsa)

Vivado GUI로 Block Design 완성하기

진행 순서
1. 새 프로젝트 생성 (Board: Zybo Z7-20)
2. Create Block Design
3. IP 추가: ZYNQ7 Processing System
4. IP 추가: AXI DMA
5. IP 추가: 우리 FIR (커스텀 IP 패키징 먼저 필요)
6. Create HDL Wrapper
7. Generate Bitstream
8. Export Hardware

1. 새 프로젝트 생성

  1. Create Project 클릭
  2. Project name: fir_decimator_trans_n43
  3. Project location: 원하는 경로 설정
  4. Project type: RTL Project
    Sources 추가할 때 RTL 파일들 넣기:
    • rtl/transposed_form/n43/fir_decimator_n43_axis.v ← 최상위 top
    • rtl/transposed_form/decimator_m2_phase0.v
    • rtl/transposed_form/n43/fir_decimator_n43.v
    • rtl/transposed_form/n43/fir_n43.v
  5. constraint file은 포함하지 말기! 나는 실수로 포함시킴
  6. Default Part에서 Board 탭 → Zybo Z7-20 선택
  7. finish

2. Create Block Design

Module Reference 방식

Vivado 좌측 Flow Navigator에서:

  1. IP INTEGRATORCreate Block Design 클릭
  2. Design name: bd_fir_dma

3. IP 추가: ZYNQ7 Processing System

  1. 캔버스 우클릭 → Add IP → 검색창에 zynq 입력 → ZYNQ7 Processing System 더블클릭

  2. PS 설정하기
    블록 더블클릭 이후 수정할 두 가지 항목 확인

1. 포트 활성화
PS-PL ConfigurationHP Slave AXI InterfaceS AXI HP0 Interface 체크

  • HP0: PL(DMA)이 PS(CPU)의 DDR에 접근하는 유일한 경로, 기본 비활성화이므로 활성화 해주기

2. 클럭 확인
Clock ConfigurationPL Fabric ClocksFCLK_CLK0 가 100MHz인지 확인

4. IP 추가: AXI DMA

  1. 캔버스 우클릭 → Add IP → 검색창에 axi dma 입력 → AXI Direct Memory Access 더블클릭
  2. DMA 설정하기

블록 더블클릭 이후 확인/수정할 항목 확인

상단

항목설명
Enable Scatter Gather Engine해제 ✓Simple DMA 모드. 디스크립터 체인 불필요
Enable Micro DMA해제기능 제한된 경량 DMA. 해당 없음
Enable Multi Channel Support비활성해당 없음
Enable Control/Status Stream비활성해당 없음
Width of Buffer Length Register14 bits최대 전송 크기 2¹⁴ = 16KB. 4117샘플 × 2bytes ≈ 8KB이므로 충분
Address Width32 bitsZynq-7000은 32비트 주소 체계. 맞음

Read Channel (MM2S) — DDR → FIR 방향

항목설명
Number of Channels1채널 하나면 충분
Memory Map Data Width32DDR(HP0) 쪽 버스 폭. 32비트 표준
Stream Data Width16FIR s_axis_tdata 폭과 일치
Max Burst Size16DDR 읽기 시 한 번에 16 beat. 기본값으로 충분
Allow Unaligned Transfers해제16비트 샘플은 정렬 보장됨

Write Channel (S2MM) — FIR → DDR 방향

항목설명
Number of Channels1채널 하나면 충분
Memory Map Data Width32 (AUTO)DDR 쪽 버스 폭. 동일
Stream Data Width16 (MANUAL)FIR m_axis_tdata 폭과 일치
Max Burst Size16DDR 쓰기 시 한 번에 16 beat
Allow Unaligned Transfers해제정렬 보장됨

하단

항목설명
Enable Single AXI4 Data InterfaceAUTO/해제MM2S와 S2MM이 DDR 포트를 각각 따로 씀. 동시 읽기+쓰기 가능

5. IP 추가: Custom FIR

  1. 캔버스 우클릭 → Add Modulefir_decimator_n43_axis 선택

  2. 캔버스 상단 초록색 배너 "Run Connection Automation" 클릭

  3. 모든 항목 체크 : Vivado가 SmartConnect, Processor System Reset을 자동 생성하고 연결합니다

6. 자동 생성된 IP:AXI Interconnect

"Run Connection Automation"으로 자동 생성된 AXI Direct Memory Access 더블클릭

  • Number of Slave Interfaces → 2

7. FIR 모듈 수동 연결

포트 연결 요약:

PS GP0 → SmartConnect → DMA S_AXI_LITE     (PS가 DMA 제어)
DMA M_AXI_MM2S → PS HP0                    (DMA가 DDR 읽기)
DMA M_AXI_S2MM → PS HP0                    (DMA가 DDR 쓰기)
DMA M_AXIS_MM2S → FIR S_AXIS               (DDR → FIR)
FIR M_AXIS → DMA S_AXIS_S2MM               (FIR → DDR)

첫 번째: aclk 연결

FIR 블록의 aclk 포트 → PS 블록의 FCLK_CLK0 포트로 드래그

두 번째: aresetn 연결

FIR 블록의 aresetn 포트 → rst_ps7_0_100M 블록의 peripheral_aresetn 포트로 드래그

aresetn : FIR IP의 active-low 리셋 포트

세 번째: DMA → FIR 입력 연결

axi_dma_0 블록의 M_AXIS_MM2S 포트 → FIR 블록의 s_axis 포트로 드래그

네 번째: FIR → DMA 출력 연결

FIR 블록의 m_axis 포트 → axi_dma_0 블록의 S_AXIS_S2MM 포트로 드래그

다섯 번째: Run Block Automation 클릭
상단 녹색 배너의 Run Block Automation 클릭

여섯 번째: 검증하기
단축키 F6를 눌러 Validate Design 진행

Digilent 보드 파일을 쓰는 Zybo 설계에서는 항상 뜨는 경고라고 합니다. 실제 DDR 동작에 문제 없다고 합니다.

8. Create HDL Wrapper

Sources 탭에서 Block Design 파일(bd_fir_dma) 우클릭 → Create HDL WrapperLet Vivado manage wrapper and auto-update 선택

9. Generate Bitstream

SynthesisImplementationGenerate Bitstream

error 1

비트스트림 생성 실패

error 1 해결

로그 첫 줄:synth_design -top fir_decimator_n43_axis

두 가지 문제가 동시에 존재했다.

문제 1: 합성 Top 모듈 오설정

합성 Top 모듈이 bd_fir_dma_wrapper가 아닌 fir_decimator_n43_axis로 설정되어 있었다.
이는 Block Design 생성 이전에 FIR IP 단독 검증을 위해 fir_decimator_n43_axis를 Top으로 설정해 두었던 상태가 그대로 남아 있었기 때문이다. Block Design Wrapper가 아닌 FIR 모듈 단독으로 합성을 시도하니 DMA, PS 등 나머지 연결이 전혀 없는 불완전한 설계가 합성 대상이 되었다.

→ Sources 패널에서 bd_fir_dma_wrapper를 우클릭 → Set as Top으로 변경

문제 2: 불필요한 XDC 파일 활성화

로그에서 zybo_n43.xdc가 포함되어 있었다. 이 XDC 파일은 FIR IP를 단독으로 합성할 때 사용하던 핀 제약 파일로, fir_decimator_n43_axis의 포트를 물리 핀에 직접 매핑하는 내용이 담겨
있었다. Block Design 기반 설계에서는 FIR 포트가 내부적으로 DMA에 연결되므로 물리 핀 매핑이 필요 없는데, 이 XDC가 여전히 활성화되어 있어 잘못된 핀 제약이 적용되고 있었다.

→ Sources 패널 → Constraints 폴더 → zybo_n43.xdc 우클릭 → Disable File

두 문제를 모두 수정한 뒤 다시 시도했다.

9-1. Generate Bitstream 다시 시도

드디어 성공

IMPLEMENTATIONOpen Implemented DesignReport Timing Summary

  • WNS = +1.332ns — Step 4의 +0.278ns보다 오히려 더 여유가 생겼음
  • TNS = 0.000ns (타이밍 위반 없음)
  • Failing Endpoints = 0

10. Export Hardware

FileExportExport HardwareInclude bitstream 체크
지정한 디렉토리에 xsa 파일을 export하는 과정입니다.
XSA (Xilinx Support Archive):
Vivado가 만드는 하드웨어 설명 패키지 파일

11. TCL 스크립트 추출

Block Design은 Vivado 프로젝트 파일(.xpr) 안에만 존재합니다. 프로젝트가 유실되거나 다른 환경에서 재현해야 할 때를 대비해 write_bd_tcl로 Block Design 전체를 TCL 파일로 추출해 레포에 보관합니다.

추출 명령어

Block Design이 열린 상태에서 Vivado TCL Console에서 실행:

write_bd_tcl -force /home/young/dev/10_zynq-fir-decimation-ip/vivado/bd_fir_dma.tcl

추출 결과: /home/young/dev/10_zynq-fir-decimation-ip/vivado 디렉토리안에 bd_fir_dma.tcl 스크립트 저장

포함 내용

write_bd_tcl이 추출하는 정보:

  • 모든 IP 정보 (버전 포함: processing_system7:5.5, axi_dma:7.1 등)
  • IP 파라미터 설정 전체 (stream width=16 등)
  • 모든 배선 연결 (AXI, AXI-Stream, 클럭, 리셋)
  • 주소 할당 (assign_bd_address)
  • 마지막에 validate_bd_design 자동 호출

재현 방법

다른 머신에서 Block Design을 재현하려면:

  1. Vivado 2024.2 + Zybo Z7-20 보드 파일 설치
  2. RTL 소스 4개가 포함된 Vivado 프로젝트 생성 (1 참고)
  3. Vivado TCL Console에서:
source vivado/bd_fir_dma.tcl

RTL 소스 없이 sourcing하면 fir_decimator_n43_axis 모듈을 찾지 못해 실패한다.

error 정리

합성 Top 오설정 + XDC 충돌 — 합성 Top이 bd_fir_dma_wrapper가 아닌 fir_decimator_n43_axis로 남아 있었고, 단독 합성용 zybo_n43.xdc가 활성화되어 잘못된 핀 제약이 적용됨 → Top 모듈 변경 및 XDC 비활성화

마무리하며

Validate Design 성공과 비트스트림 생성 성공은 다르다는 걸 이번 작업에서 체감했습니다. Vivado가 "연결에 문제없다"고 판정해도, 합성 Top이 잘못 설정되어 있거나 프로젝트 초기에 넣어둔 XDC 파일이 남아있으면 비트스트림 단계에서 막힙니다. 에러 메세지를 읽고 원인을 역추적하는 과정이 번거롭긴 했지만, 덕분에 Block Design의 외부 포트 개념과 Vivado 프로젝트 상태 관리 방식을 제대로 이해하게 됐습니다. 다음 단계는 생성된 .xsa를 Vitis에서 열어 DMA를 제어하는 C 코드를 작성하는 것입니다.

profile
electronic engineering student

0개의 댓글