Zynq SoC Training – ADC/DAC and Digital Audio Processing

Acknowledgement (Korean)
아래의 글은 Ali Aljaani가 운영하는 블로그인 embedded centric의 “Zynq SoC Training”을 번역한 문서입니다. 한글 번역 및 공개를 허용한 Ali Aljaani에게 감사의 말을 전합니다.

Acknowledgement (English)
This post is a translated version of “Zynq SoC training” in embedded centric. Thank you Ali Aljaani for allowing me to translate nice posts. I’m Taekyung Heo, and I translated this post into Korean.

Contact information (Author)
Ali Aljaani’s blog: http://embeddedcentric.com/
Ali Aljaani’s mail: alialjaani@embeddedcentric.com
Ali Aljaani’s LinkedIn: https://www.linkedin.com/in/ali-aljaani-a7130099
Ali Aljaani’s github: https://github.com/ama142


이번 실습에서는 Analog-to-Digital 변환기, Digital-to-Analog 변환기 (DAC), 샘플링, 그리고 양자화 기초에 대해 학습할 것이다. ZedBoard에 탑재된 ADAU1761 오디오 코덱 칩 (coder-decoder)을 사용해 오디오 처리를 할 것이다. Codec은 I2C 버스를 통해 설정되며, 그 방법에 대해서는 이번 실습에서 자세히 다룰 것이다. Codec에 있는 두 개의 ADC를 사용해 스테레오 오디오 (우측 채널 + 좌측 채널)를 48KHz로 샘플링하는 어플리케이션을 개발할 것이다. 샘플링된 오디오는 I2S 표준 오디오 버스를 통해 Zynq 칩으로 보내져 처리된다. Zynq 칩의 NCO(Numerically Controlled Oscillator)는 정해진 주기를 갖고 사인파를 만들어내는 것에 사용된다. 이 사인파는 받아진 오디오 샘플에 중첩된다. 수정된 오디오 샘플 (칩으로 받아져 온 오디오 샘플 + 사인파 샘플)은 I2S 버스를 통해 DAC 변환기로 전달되고, 칩의 출력 포트에 연결된 스피커 또는 이어폰으로 재생된다. I2S 표준 오디오 버스 또한 이번 실습에서 자세히 다룰 것이다.

lab-8-design-flow


Lab 8 Design Flow


lab8-block-diagram


Lab8 Block Diagram


lab8-board-interface


Lab8 Board Interface


오디오 신호는 아날로그 신호이며, 임베디드 시스템에서 디지털 신호로 변환되어야 한다. 다음의 그림은 오디오 신호의 예제를 보여준다.
sample-of-an-audio-signal


Sample of an audio signal


Analog-to-Digital 변환기 (ADC)는 오디오 신호를 디지털화한다. Nyquist theorem에 따라, 오디오 ADC의 샘플링 주기는 적어도 오디오 신호 최대 주파수의 두 배 이상이 되어야 한다 (22Khz). 따라서, 샘플링 주기는 적어도 44Khz는 되어야 한다. 오디오 신호를 디지털화 한 다음에는 이를 디지털 시스템(DSP, 마이크로프로세서, 또는 마이크로컨트롤러)에서 처리해야 한다. 이 처리는 어플리케이션의 특성에 따라 그 복잡도가 다양하다. 음성 인식과 같이 복잡할 수도 있고, 필터링 또는 믹싱과 같이 단순할 수도 있다. 이렇게 처리한 오디오를 다시 내보내려면, digital-to-analog 변환기 (DAC)가 필요하다. DAC 변환기는 디지털 신호 값들을 아날로그 신호로 변환해, 스피커에 재생할 수 있도록 해준다.
typical-digital-audio-processing-system


Typical Digital Audio Processing System


ZedBoard에는 오디오 처리를 위한 ADAU1761 Codec (coder-decoder)이 있다. 이는 두 개의 24-bit ADC와 두 개의 24-bit DAC를 가지며, 샘플링 주기는 8Khz에서 96Khz까지 설정할 수 있다.

이번 실습에서는 Codec에 있는 두 개의 ADC를 사용해 스테레오 아날로그 오디오(우측 채널 + 좌측 채널)를 48Khz로 샘플링하고, 이렇게 디지털화된 샘플들은 I2S 표준 오디오 버스를 사용해 Zynq 칩으로 보내져 처리된다 (The Zynq Book에 있는 zed_audio_ctrl IP core를 사용해 I2S 인터페이스를 구현한다). Zynq 칩에서는 NCO(Numerically Controlled Oscillator – 마찬가지로 the Zynq Book에서 가져옴)을 사용해 정해진 주기로 사인파를 샘플링한다. 이러한 사인파의 샘플들은 오디오를 통해 받아진 샘플 위에 덮어쓰여진다. 그리고 스위치를 사용해 이를 조작할 수 있다. 수정된 오디오 샘플들 (받아온 오디오 샘플 + 생성한 사인파 샘플)은 I2S 버스를 사용해 Codec의 DAC 변환기로 보내져 스피커 또는 이어폰으로 재생된다 (녹색 플러그). 입력 아날로그 오디오 신호는 마이크에를 사용해 주어도 되고, 데스크탑 또는 노트북의 오디오 출력 신호를 주어도 된다 (파란색 플러그).

codec-adau1761-interface


ADAU1761 Codec Interface


사용하는 오디오 케이블은 스테레오 케이블이어야 한다.

connection-diagram-for-standard-stereo-audio-cable


Connection diagram for standard stereo audio cable


입력 오디오에 중첩되는 사인파의 주파수는 ZedBoard에 부착된 여덟 개의 스위치로 설정할 수 있다. 스위치 상태의 이진 값에 해당하는 값을 LED를 통해 시각적으로 확인할 수 있다. ADAU1761 Codec을 사용하기 위해서는, 우선 설정부터 해야 한다. 설정은 I2C 버스를 사용해 명령어를 보냄으로써 할 수 있다. 이것이 I2C 컨트롤러가 Zynq 칩의 PS-side에 있는 이유이다. Codec은 외부 클럭 공급을 필요로 하며, PS의 FCLK_CLK1을 10Mhz로 설정하여 Codec에 제공할 수 있다.

배경 지식
A. ADAU1761 Codec
Analog Devices가 생상한 ADAU1761은 다목적의 오디오 칩이다. 음원 재생, 녹음, 처리에 다양하게 사용될 수 있다. 이 칩은 두 개의 24-bit 오디오 ADC와 두 개의 24-bit DAC 변환기를 갖고 있으며, 완전히 독립적이며 자율적인 Sigma DSP 코어도 갖고 있다. 샘플링 비율은 8Khz에서 96Khz까지 지원한다. 샘플링 주파수는 외부에서 주어지는 마스터 클럭에 의해 구동되는 PLL 이 생성한다 (이 실습에서 우리는 PS의 FCLK_CLK1의 10Mhz를 사용한다). 잡히고 전송된 디지털 오디오는 칩의 데이터 포트에서 읽고 쓸 수 있으며, 데이터 포트는 I2S 표준 오디오 규격을 따른다.

adau1761-codec-block-diagram


ADAU1761 Codec Block Diagram


adau1761-codec-detailed-block-diagram


ADAU1761 Codec Detailed Block Diagram

데이터 포트와 더불어, Codec은 제어 포트를 갖고 있다. 칩의 사용 이전에, 제어 포트를 먼저 설정해야 한다. 설정은 I2S와 호환되는 제어 포트에 명령어를 전송함으로써 할 수 있다. 제어 포트는 필수적으로 칩의 제어 레지스터에 접근을 제공해야 한다. 칩에는 67개의 제어 레지스터가 있으며, 이 67개 레지스터의 주소들은 0x4000에서 0x40FA에 걸쳐있다. 이 레지스터 집합에 쓰기 연산을 수행함으로써 신호 증폭, 믹싱, 칩 내부 모듈의 스위칭, 샘플링 주파수의 결정 등을 할 수 있다. 예를 들어, 레지스터 R19 (주소 0x4019)에 이진수 0x0000011을 씀으로써 두 개의 ADC 모두를 활성화할 수 있다.

r19-control-register-inside-the-adau1716-codec


R19 Control Register inside the ADAU1716 Codec


다른 예를 들자면, 레지스터 R61 (주소 0x40F5)에 0값을 씀으로써 Codec의 DSP Core를 비활성화 할 수 있다.
r61-control-register-inside-the-adau1716-codec

R61 Control Register inside the ADAU1716 Codec

B. I2C Bus
I2C 버스를 사용해 제어 레지스터에 값을 씀으로써 Codec을 설정할 수 있다. I2C 버스의 직렬 데이터 (SDA) 라인은 I2C 마스터 컨트롤러 (Zynq)와 직렬 클럭(SCL)으로 구동 중인 Codec 사이에 명령어를 전송하는 역할을 한다. ADAU1761 Codec은 항상 버스에서 슬레이브로 동작한다. 따라서 데이터 전송을 시작할 수 없다. I2C 슬레이브 장치는 고유한 7-bits 주소로 구분할 수 있다. Bits[6:2]는 ADAU1761에 대한 주소이며, (01110)2를 갖는다. 반면에 Bits[1:0]은 ADDR1ADDR0의 레벨로 결정된다. 이 값들은 시스템 블록 다이어그램에 정의되어 있으며, 이 둘 모두 0으로 되어 있다. 따라서 Bits[1:0]=(00)2이다. 따라서 Codec을 위한 주소는 (0111000)2 또는 (0x38)이다.

처음에 Codec은 idle 상태에 있으며, SDASCL, 그리고 특정 주소를 보며 시작 조건을 확인한다. I2C 마스터(Zynq 칩)는 시작 조건을 구성하며 데이터 전송을 시작한다. SCL을 높게 유지하면서 SDA 신호를 high에서 low로 전이시킨다. 이 동작 이후에 따라오는 데이터는 주소와 데이터 스트림이다. Codec은 다음 MSB 8 비트를 (7-bit 주소와 R/W 비트) 이동시킨다. Codec은 아홉 개의 클럭 동안 전송되는 주소와 응답 (acknowledges)을 확인한다. 아홉 번째 비트는 acknowledge 비트이며, 이를 사용해 마스터는 Codec이 작동 및 실행 중이라는 것을 알 수 있다. 이 이후에 I2C 마스터는 제어 레지스터의 상위 주소를 Codec에 전송한다. Codec은 아홉 번째 클럭에서 데이터 라인을 낮게 함으로써 데이터를 받았음을 알린다. 그 다음에는 쓰고자 하는 레지스터의 낮은 하위 주소를 Codec에 전송한다. 앞서와 마찬가지 방식으로 Codec이 데이터를 받았음을 알린다. 마지막으로 제어 레지스터에 쓰일 데이터가 전송되고, Codec은 이를 받았음을 아홉 번째 클럭에 알린다. 이것이 단일 워드 쓰기 연산이다. 이는 마스터가 정지 조건을 지정함으로써 종료된다. 아래의 그림은 단일 워드 쓰기 연산을 보여준다. 아홉 번째 펄스마다 Codec은 SDA를 낮게 함으로써 acknowledge를 생성한다. 제어 레지스터에 바이트를 쓰기 위해서는, 실제로는 네 바이트를 전송해야 한다.

1. Byte1: ADAU1761에 대한 I2C 주소 (0x38)
2. Byte2: 제어 레지스터의 상위 주소 일부 바이트
3. Byte3: 제어 레지스터의 하위 주소 일부 바이트
4. Byte4: 제어 레지스터에 쓰고자 하는 데이터

single-word-i2c-write-operation


Single-word I2C write operation


single-word-i2c-write-operation-digital-waveform


Single-word I2C write operation digital waveform


DSP 코어 예제로 돌아가자. DSP 코어는 61번 레지스터 (주소 0x40F5)와 연관되어 있다. 스위치 비활성화 명령어를 전송하기 위해서는 네 개의 바이트를 I2C 버스를 통해 전송해야 한다. 첫 번째 바이트는 칩 주소 (0x3B)이고, 두 번째 바이트는 상위 주소 바이트(0x40), 그 다음으로 하위 주소 바이트 (0xF5), 마지막 바이트는 (0x00)이다.

C. I2S Bus
I2S (Inter-IC Sound)는 디지털 시스템에서 오디오 데이터를 전송하기 위한 사실상의 표준이다. I2S 프로토콜에서 전송되는 신호들은 두 개의 클럭과 직렬 오디오 데이터 입출력이다:

1. The Left-Right clock (LRCLK).
2. Bit clock (BCLK).
3. Serial audio data in/out lines (SDATA_ADC)과 (SDATA_DAC).

i2s-protocol1


Inter-IC Sound (I2S) Protocol


Left-Right 클럭 (LRCLK)는 오디오 시스템의 샘플링 비율을 확인하고, 두 개의 채널 프레임을 확인하기 위해 사용된다. Left/Right 클럭 신호는 항상 오디오 샘플링 비율과 같아야 한다. 이보다 높거나 낮은 클럭을 사용해 좌측과 우측 채널 데이터를 분리한다. Bit clock (BCLK)은 때로 직렬 클럭이라고도 불리며, 오디오 포트에서 오디오 데이터 비트를 이동시키기 위해 사용된다. Bit clock의 최저 주파수는 시스템 오디오 샘플링 비율과 오디오 워드 길이와 직접적으로 연관되어 있다. 오디오 데이터는 좌측, 우측의 두 개의 채널로 이루어져 있다. 그리고 Left/Right 클럭은 반드시 오디오 샘플링 비율과 같아야 한다. 따라서 bit 클럭의 최저 주파수는 적어도 (오디오 샘플링 비율 X 오디오 워드 길이)는 되어야 한다. 직렬 오디오 데이터 입출력(SDATA) 라인은 오디오 데이터를 전송하며, ADC 또는 DAC의 데이터를 전송하는데 사용된다.

오디오 데이터를 전송하는데 사용되는 업계 표준은 24-bit 크기의 고정 소수점 2의 보수이다. 오디오 데이터는 항상 Most Significant Bit(MSB)와 함께 전송된다. 고정 소수점은 A.B 표기법을 따른다. A는 소수점까지의 비트 수이고, B는 소수점 이후의 비트 수이다. ADAU1761은 ADC와 DAC 모두에 고정소수점 1.23을 사용하고 있다.

1-23-fixed-point-data-format


1.23 Fixed Point Data Format


1-23-fixed-point-data-format-notation


1.23 Fixed Point Data Format Notation


D. Numerically Controlled Oscillator (the Zynq Book Team)
NCO는 특정 주파수(가청 주파수)의 사인파를 생성하기 위해 사용된다. NCO는 정확한 시점에 구동되도록 하기 위해 AXI 코어의 형태로 하드웨어에 들어가 있다. 두 개의 구동 함수를 사용해서 코어를 동작시킬 수 있다:

XNco_SetStep_size_v() // 사인파의 주파수를 설정한다.
XNco_GetSine_sample_v() // 특정 주파수로 사인파를 샘플링한다.

코어에 의해 반환된 데이터는 오디오에 적합한 데이터이다. 내부적으로 코어는 사인파 값에 대한 데이터 표를 갖고 있다. 표를 이루는 데이터는 4096개이며, 고정 소수점 데이터이다.

look-up-table-for-a-sine-wave


Look Up Table for a sine wave

목표
1. 오디오와 같은 아날로그 신호를 처리하기 위한 디지털 및 아날로그 컴포넌트에 대해 학습
2. ADAU1761 오디오 코덱의 아키텍쳐 이해
3. Inter-Integrated Circuit(I2C) 인터페이스 프로토콜에 대해 학습하고, 이를 사용해 외부 칩과 통신하는 방법 이해
4. Inter-IC Sound(I2S0 인터페이스 프로토콜에 대해 학습하고, 이를 사용해 오디오 데이터를 교환하는 방법 이해
5. 오디오 데이터가 저장되고 처리되는 형식 학습
6. 간단한 디지털 오디어 처리 어플리케이션 개발

실습 단계
A. GitHub에서 zed_audio_ctrlxilinx_com_hls_nco_1_0 IP 코어를 다운로드하기
두 개의 IP 컨트롤러를 내 GitHub 페이지에서 다운로드한다 (GitHub에서 다운로드 하는 방법에 대해 익숙하지 않다면, 두 번째 실습의 실습 단계 A를 참고하라). 다운로드한 IP들은 압축되어 있으며, 사용하기 위해서는 압축 해제해야 한다.

1. zed_audio_ctrl IP 컨트롤러는 ADAU1761 Codec과 I2S 프로토콜을 사용해 데이터를 교환한다.
2. xilinx_com_hls_nco_1_0 IP 컨트롤러는 설정된 주파수로 사인파를 생성한다.

이 IP 컨트롤러들은 the Zynq book 팀에서 개발했다 (Louise Crockett, Ross Elliot, Martin Enderwitz, Bob Stewart, David Northcote). 이 IP 컨트롤러들을 공백을 포함하지 않는 경로에 위치하도록 압축을 풀어 준비한다. “C:\ip_cores”과 같은 디렉토리가 좋다.

extract-the-ip-cores


Extract the IP Cores


B. Vivado에서 프로젝트를 생성하고 target board로 ZedBoard 선택
실습 1의 실습 단계 A의 다섯 단계를 동일하게 수행한다. 단, 프로젝트 이름은 “lab8″로 한다.

C. IP integrator를 사용해 임베디드 프로세서 프로젝트 생성
실습 1의 실습 단계 B의 네 단계를 동일하게 수행한다.

D. ZYNQ7 Processing System 설정
1. 녹색 정보 바에서 Run Block Automation을 클릭한다. Run Block Automation 창에서 모든 옵션을 기본으로 두고 OK를 클릭한다.

run-block-automation-leave-default-options


Run Block Automation-Leave default settings


이제 PS는 다음과 같이 보인다. Note: 기본으로 활성화된 모든 컴포넌트가 이번 실습에서 필요한 것은 아니다. 예를 들어, Ethernet, USB 그리고 타이머는 필요하지 않다. 하지만 실습 단계를 줄이고자 이를 그대로 두었으며, 이를 비활성화해도 좋다.
zynq7-processing-system-after-running-block-automation-with-default-settings


ZYNQ7 Processing System after running Block Automation with default settings


2. ZYNQ7 Processing System을 더블 클릭하여 Re-customize IP 창을 연다. MIO Configuration에서 I2C 1 controller를 활성화한다.
mio-configuration-enable-i2c


MIO Configuration – Enable I2C 1


3. Clock Configuration 페이지에서 PL Fabric Clocks를 확장하고, FCLK_CLK1을 활성화하고 그 값을 10Mhz로 설정한다.
mio-configuration-enable-fclk_clk1-and-set-to-10mhz


MIO Configuration – Enable FCLK_CLK1 and set to 10Mhz


이 클럭을 사용해 ADAU1761 Codec을 구동한다. OK를 클릭해 Re-customize IP 창을 닫는다. 이제 PS는 다음과 같이 보여야 한다:
zynq7-processing-system-after-enable-i2c-and-fclk_clk1


ZYNQ7 Processing System after enable I2C 1 and FCLK_CLK1


4. IIC_1 포트로 마우스를 올려 연필 모양이 되도록 한다. 우클릭한 뒤 Make External을 클릭한다.
make-iic_1-port-external


Make IIC_1 Port External


5. 네 번째 단계를 FCLK_CLK1에 대해 반복한다. 이제 PS는 다음과 같은 모습을 보여야 한다:
zynq7-processing-system-after-making-iic_1-and-fclk_clk1-external


ZYNQ7 Processing System after making IIC_1 and FCLK_CLK1 external


E. zed_audio_ctrlxilinx_com_hls_nco_1_0 IP를 Vivado IP Repository에 더하기
Vivado에서 Flow Navigator에서 Project Settings를 클릭한다. IP를 클릭하고 IP Repositories에서 녹색 더하기 심볼을 클릭한다. 탐색기 창이 뜰 것이고, 여기에서 앞서 압축 해제한 IP가 있는 경로인 “C:\ip_cores”를 선택한다.
project-settings-window3


Project Settings Window


browsing-to-the-location-where-the-ips-are-saved


Browsing to the location where the IPs are saved


이제 Vivado는 해당 디렉토리에 있는 새로운 IP들을 감지한다. Apply를 클릭하고 OK를 클릭한다.
ip-repository-after-refering-to-the-location-where-the-ips-are-saved


IP Repository after refering to the location where the IPs are saved


이로써 현재 디렉토리의 IP 레포지토리에 zed_audio_ctrlxilinx_com_hls_nco_1_0를 추가했다. 그 다음으로 이제 블록 디자인에 이를 추가하고 Zynq processing system에 연결하면 된다.

F. zed_audio_ctrl과 NCO IP들을 설계에 추가하고 연결하기
1. 다이어그램 창에서 아무 곳이나 우클릭한 뒤, Add IP를 선택한다. 그리고 탐색 창에서 “nco”를 입력한 뒤 “Nco”를 클릭해 이를 추가한다.

add-nco-ip-core


Add NCO IP Core


2. 좌측 상단 바에 Designer Assistance를 사용할 수 있음을 확인할 수 있다. Run Connection Automation을 클릭한다. Run Connection Automation창이 뜨면 모든 옵션을 기본으로 두고 OK를 선택한다.
3. 단계 1, 2를 zed_audio_ctrl에 대해 수행한다.
4. 다이어그램 창의 임의의 지점을 선택한 뒤, Regenerate layout을 클릭한다. 블록 다이어그램이 다음과 같이 바뀔 것이다:
block-diagram-after-adding-and-connecting-zed_audio_ctrl-and-xilinx_com_hls_nco_1_0-ip-cores


Block Diagram after adding and connecting zed_audio_ctrl and xilinx_com_hls_nco_1_0 IPs


5. zed_audio_ctrlBCLK 포트에 마우스를 올려 연필 모양으로 바뀌도록 한다. 우클릭한 뒤, Make External을 선택한다 (대신에 Ctrl+T 키를 눌러도 된다).
6. 5번 단계를 LRCLK, SDATA_O, SDATA_I에 대해서도 같은 방식으로 진행한다. 블록 다이어그램은 다음과 같은 모양을 보일 것이다:
defining-external-ports-for-the-zed_audio_ctrl


Define external ports for zed_audio_ctrl


이 포트들은 ADAU1761 오디오 Codec과 연결될 것이다.

G. 이중 채널 모드의 GPIO IP 코어 추가
1. Add IP 버튼을 클릭한다. IP catalog에서, AXI GPIO을 더블 클릭해 추가한다. 탐색 창에서 “gpio”를 검색한다.

addinggpio


Add GPIO


2. GPIO는 두 개의 채널을 설정할 것이다. 한 개는 LED를 위한 것이고, 다른 한 개는 스위치를 위한 것이다. 이렇게 하는 것이 두 개의 독립적인 GPIO를 사용하는 것보다 더 적은 면적을 소모한다 (첫 번째 실습에서는 두 개의 독립적인 GPIO 사용함). GPIO 블록을 더블 클릭하여 Re-customize IP 창을 연다. Board 탭에서 IP interface GPIO(channel 1)을 led_8bits로 설정하고, GPIO2 (channel 2)를 sws_8bits으로 설정한다. OK를 클릭해 Re-customize IP 창을 나간다.
configure-dual-channels-gpio


Configure dual channels GPIO


3. 다이어그램 뷰어의 우측 상단에 Designer Assistance를 사용할 수 있음을 확인할 수 있다. Run Connection Automation를 클릭하고, All Automation(세 개 모두 선택)를 선택한 뒤 OK를 클릭한다.
run-connection-automation-gpio-dual-channels


Run Connection Automation- GPIO dual channels


create-port


Create Port


H. ADAU1761의 I2C 주소 하위 비트 bits[1:0]에 값 할당
1. 다이어그램 창에서 빈 공간을 우클릭한 뒤, Create Port를 선택한다.
2. Create Port 창에서 다음과 같이 인자를 입력한다.
create-port-window


Create Port Window


3. 다이어그램 창에서 아무 빈 공간을 우클릭한 뒤, Add IP를 선택한다. 탐색창에 “cons”를 입력한다. Constant를 더블 클릭해 설계에 추가한다. Constant IP 코어는 “ADDRESS[1:0]” 포트에 0값을 준다.
constant-ip-core


Constant IP core


4. Constant IP 코어를 더블 클릭해서 Re-customize IP 창을 연다. 그리고 다음과 같이 값을 설정한다.
constant-ip-core-configuration


Constant IP core configuration


5. 마우스를 사용해 Constant의 “dout[1:0]” 포트를 “Address[1:0]” 포트에 연결한다.
6. 다이어그램 창의 임의의 빈 지점을 우클릭한 뒤 Regenerate layout을 선택한다. 블록 다이어그램은 다음과 같이 보일 것이다:
complete-hardware-design-lab8


Block Diagram after adding all needed IP cores for lab8

I. 물리적인 제약 추가
1. Flow Navigator 창의 Project Manager 섹션에서 Add Sources를 클릭한다.

add-sources3


Add Sources


2. Add Sources 대화창이 열릴 것이다. Add or Create Constraints를 선택한다.

add-or-create-constraints


Add or Create constraints


3. Next를 클릭한 뒤, Create File을 선택한다.
create-a-new-constraint-file


Create a new constraint file


다음 창에서 File type으로 XDC을 선택한 뒤, File name으로는 adc_dac_audio를 입력한다.
name-new-constraints-file-adc_dac_audio


Name new constraints file: adc_dac_audio


OK를 클릭한 뒤, 다음 창에서 Finish를 클릭해 대화 상자를 닫는다. Sources 탭에서 Constraints 그룹을 확장한 뒤, 새롭게 생성된 adc_dac_audio.xdc파일을 연다.
sources-pane-with-adc_dac_audio-selected


Sources pane with adc_dac_audio selected


다음의 제약 파일을 추가한다. 또는 내 GitHub 페이지에서 adc_dac_audio.xdc를 다운받아도 된다.

# ZedBoard Audio Codec Constraints
set_property PACKAGE_PIN AA6 [get_ports BCLK]
set_property IOSTANDARD LVCMOS33 [get_ports BCLK]

set_property PACKAGE_PIN Y6 [get_ports LRCLK]
set_property IOSTANDARD LVCMOS33 [get_ports LRCLK]

set_property PACKAGE_PIN AA7 [get_ports SDATA_I]
set_property IOSTANDARD LVCMOS33 [get_ports SDATA_I]

set_property PACKAGE_PIN Y8 [get_ports SDATA_O]
set_property IOSTANDARD LVCMOS33 [get_ports SDATA_O]

#MCLK
set_property PACKAGE_PIN AB2 [get_ports FCLK_CLK1]
set_property IOSTANDARD LVCMOS33 [get_ports FCLK_CLK1]

set_property PACKAGE_PIN AB4 [get_ports iic_1_scl_io]
set_property IOSTANDARD LVCMOS33 [get_ports iic_1_scl_io]

set_property PACKAGE_PIN AB5 [get_ports iic_1_sda_io]
set_property IOSTANDARD LVCMOS33 [get_ports iic_1_sda_io]

set_property PACKAGE_PIN AB1 [get_ports {ADDRESS[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ADDRESS[0]}]

set_property PACKAGE_PIN Y5 [get_ports {ADDRESS[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ADDRESS[1]}]

이 파일을 저장한다. 이로써 모든 포트들이 ADAU1761 오디오 Codec에 연결되었다.

J. Bitstream 생성
1. Sources 창에서 system.bd를 우클릭한 뒤, Create HDL Wrapper를 선택해 블록 다이어그램으로부터 Verilog 파일을 생성한다. 다음 메시지가 뜨면 Let Vivado manage wrapper and auto-update를 선택한다. system_wrapper.v가 디자인 창 계층의 최상단에 생성된 것을 확인할 수 있다.

create-hdl-wrapper1


Create HDL Wrapper


2. Flow Navigator창의 Program and Debug 섹션에서 Generate Bitstream을 클릭한다. 지금까지의 변경을 저장할 것이냐는 대화창이 뜨면 Save를 클릭한다.
generating-bitstream1


Generating Bitstream


Bitstream 생성에는 컴퓨터의 성능에 따라 다소 시간이 걸릴 것이다. Bitstream의 생성이 끝난 뒤에는 대화 상자에서 View Reports를 선택한 뒤, OK를 클릭한다.

K. 하드웨어 디자인을 SDK에 내보내기
1. File > Export > Export Hardware를 클릭한다. Include bitstream을 체크하도록 한다.

export-hardware-to-sdk


Export Hardware to SDK


2. File>Launch SDK를 클릭한다. SDK 창이 뜰 것이고, 설계와 관련된 파일이 SDK에 내보내졌다는 알림이 뜰 것이다.

L. SDK에서 작업하기
1. SDK에서 File > New > Application Project를 클릭한다.
2. 다음 창에서 인자 값을 다음과 같이 입력한다.

new-standalone-c-project-e28093-audio_test


New Standalone C Project – audio_test


다음 창에서 Empty Application을 선택하고 Finish를 클릭한다. 이는 BSP와 관련 드라이버를 컴파일할 것이다.

3. audio_test 프로젝트 디렉토리를 확장하고, src 디렉토리를 우클릭해 New->Source File 을 선택한다.

new-c-source-file-e28093-lab8


New C Source File – lab8.c


4. 다음 창이 뜨면 source file 이름으로 “lab8.c”를 입력하고 Finish를 클릭한다. 이로써 src 디렉토리에 빈 C 파일이 생성될 것이다.
lab8-c-empty-source-file-created-in-sdk


lab8.c empty source file created in SDK


5. audio_test 프로젝트 디렉토리를 확장한 뒤, src 디렉토리를 우클릭해 New->Header File을 선택한다.
6. 다음 창이 뜨면 header file 이름으로 “audio.h”를 입력하고 Finish를 클릭한다. 이로써 src 디렉토리에 빈 헤더 파일이 생성될 것이다.
audio-h-empty-header-file-created-in-sdk


audio.h empty header file created in SDK


7. SDK의 lab8.c 편집 창에 lab8.c의 내용을 붙여넣는다 (내 GitHub 페이지에서 다운로드할 수 있다). 마찬가지 방식으로 audio.h의 내용도 audio.h의 편집창에 붙여넣는다 (내 GitHub 페이지에서 다운로드할 수 있다).

M. Bitstream을 다운로드하고 어플리케이션을 실행하기
1. Xilinx Tools-> Program FPGA를 선택해 Bitstream을 다운로드한다 (수 초 소요).

program-fpga


Downloading Bitstream to the PL


2. audio_test 프로젝트 디렉토리를 선택한 뒤-> Run As-> Launch on Hardware (GDB)를 클릭해 audio_test 어플리케이션을 ARM 프로세서에서 실행한다.
run-applicaton-on-hardware


Run application on ARM processor


다운로드가 완료된 뒤, Line out(green plug)에 연결된 스피커 또는 이어폰을 연결하고 스위치를 끄고 켬으로써 다른 톤의 사인파를 들을 수 있다. Line in(blue plug)에 데스크탑 또는 노트북의 음성 신호를 입력하면, 사인파와 섞여진 오디오 신호를 들을 수 있다.
3-5mm-jack-lead-male-to-male-stereo


3.5mm jack male-to-male-stereo cable


ADAU1761 Codec이 Line in으로 들어오는 아날로그 음성 신호를 디지털로 변환해, I2S 버스를 통해 Zynq 칩으로 전달한다. Zynq 칩은 오디오 데이터를 받아서 어떤 작업도 할 수 있다 (이 실습에서는 단순히 사인파만 더했다). 수정된 오디오는 다시 I2S 버스를 통해 ADAU1761로 전달된다. ADAU1761 Codec의 DAC 변환기는 원본 음성과 사인파를 더한 것을 아날로그 신호로 변환한다. DAC 출력은 스피커 또는 이어폰으로 전달된다. 데모 영상을 확인하자:


이로써 여덟 번째 실습인 ADC/DAC and Digital Audio Processing을 마친다. 이번 실습에 대한 해답은 여기에 있다.


Advertisements
Tagged with: , , , , , , , , , , , , , , , , ,
Posted in FPGA

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

누적 방문자 수
  • 98,779 hits
%d bloggers like this: