많은 비디오 애플리케이션에서 이미지를 자연스럽게 처리하고 섬세한 에지 디테일을 유지하기 위해 양방향 필터링(Bilateral filtering)이 사용되고 있다. 이 글에서는 첨단 CCTV(Closed-Circuit Television) 시스템 내에 양방향 필터가 초기 소프트웨어 모델에서부터 C-to-FPGA 툴을 사용하는 실제 하드웨어 상에 어떻게 구현되고 처리되는지 설명하고자 한다.
글│Ed Trexel, 수석 애플리케이션 엔지니어, Impulse Accelerated Technologies
Dov Stamler, 하드웨어 엔지니어, Vigilant Technology
많은 비디오 애플리케이션에서 이미지를 자연스럽게 처리하고 섬세한 에지 디테일을 유지하기 위해 양방향 필터링(Bilateral Filtering)이 사용되고 있다.
또한 일부 애플리케이션에서는 비디오 선처리 중 발생하는 랜덤 노이즈를 감소시키고 실시간 비디오 환경에서 비디오 압축 효율을 향상시키기 위해 양방향 필터를 사용하고 있다.
지능형 IP 감시 및 보안 솔루션을 공급하고 있는 비질란트 테크놀로지(Vigi-lant Technology)는 현재 공항, 정부청사, 금융기관, 교정시설, 카지노, 도심 등에 보급되어 있는 수많은 카메라에 이러한 솔루션을 제공하고 있다. 이 글에서는 첨단 CCTV(Closed-Circuit Television) 시스템 내에 양방향 필터가 초기 소프트웨어 모델에서부터 C-to-FPGA 툴을 사용하는 실제 하드웨어 상에 어떻게 구현되고 처리되는지 설명하고자 한다.
우리는 검증된 C-언어 모델로 시작해, C-to-hardware 툴과 반복적인 설계 방법을 사용해 하드웨어를 구현했다. 신속하게 프로토타입을 개발하고 알고리즘을 실험할 수 있도록 우리는 디버깅 및 소프트웨어/하드웨어 설계 분석을 위해 범용의 익숙한 C-언어 툴을 사용했다.
반복적인 하드웨어 레벨 테스트는 소프트웨어에서 하드웨어로 변환하기 위해 매우 중요한 부분이다. 우리는 FPGA 임베디드 소프트웨어 테스트 벤치를 이용해 이 테스트를 했다.
이를 위해 자일링스 버텍스-4 (VirtexTM-4) FX 디바이스의 임베디드 프로세서의 여러 기능들을 사용해 이미지 필터링 알고리즘의 하드웨어-인-루프(Hardware-In-The Loop) 임베디드 테스트를 하였다.
양방향 필터링
양방향 필터는 여러 다른 핵심 이미지 알고리즘을 구현할 때 사용한다. 이 필터는 다음과 같이 동작한다: 각 픽셀의 새로운 값은 다음 방정식을 사용해 해당 픽셀 주변의 픽셀을 이용해 계산된다:
여기서 각 계수는 다음과 같이 계산된다:
새로운 계수(New coefficient)
다시 계산된 픽셀과 주변 픽셀들은 3x3 매트릭스 형태의 입력 벡터로 나타난다. 이 입력벡터는 9바이트 펼쳐진 후 9바이트가 동시에 필터로 전달된다. 각 입력벡터로부터 필터는 출력벡터라는 1바이트 크기의 Center 픽셀을 만들어 낸다.
이 출력 픽셀을 계산하는 핵심적인 알고리즘이 비질란트 테크놀로지 양방향 필터의 핵심이다. 그림 1은 입력과 출력 벡터를 요약한 것이다.
C-언어 모델로 시작하기
비질란트 테크놀로지는 양방향 노이즈 필터를 만들기 위해 플로팅 포인트 연산방법을 사용하여 C로 작성하였다. 우리는 최적화를 위한 첫번째 작업으로 Impulse C에 내장된 매크로를 사용하여 모든 연산을 unsigned fixed point로 바꿨다.
최적화의 두번째 레벨로서 C code내에 있는 loop의 숫자를 최소화시키기 위해 C code를 다시 구성하였고 모든 필터 I/O에 데이터 핸들링을 단순화시키기 위해 버퍼 스트림을 사용하였다. 우리는 임펄스 C 내에서 제공되는 스트리밍 관련 인터페이스 기능을 사용해 I/O를 정의했다. 어떤 경우 데이터 타이밍의 의존성을 줄이고 병렬 계산을 위해 배열 대신 독립변수를 사용하였다. 계수를 더할 때 생기는 선형적인 의존성과 다중 접근방식도 고려되었다. 이렇게 C code를 직접 수정할 때는 매크로를 사용하여 비교적 깔금하고 이식성이 좋도록 하였다.
코드가 최적화되고 하드웨어 생성을 위해 변경됨에 따라 우리는 원안 및 수정된 C 코드 모두에 대해 표준 C 디버거(Borland C++ 빌더 툴의 일부)를 사용하여 연산 검증 및 애플리케이션의 전반적인 기능을 검토했다. 개발과정 전반에 걸쳐 우리는 다양한 CCTV 시나리오를 통해 실제 비디오 클립을 이용한 실시간 확인을 수행했다. 그림 2는 임펄스 C 스트리밍 인터페이스와 자일링스 ML410 개발 보드를 이용해 양방향 필터의 노이즈 감소를 어떻게 구현하고 테스트했는지를 보여주고 있다.
애플리케이션의 소프트웨어 측면(하드웨어 레벨 테스트를 위해 사용된 Power-PCTM 405 프로세서의 경우)에서 임펄스 C 기능들은 데이터 스트림을 오픈하거나 폐쇄시키며, 스트림 상에 데이터를 읽거나 쓰게 한다. 그리고 필요할 경우, 결과에 대한 상태 메시지나 폴(Poll)을 전송한다. 버텍스-4 FX 디바이스의 경우, 읽기 및 쓰기 스트림은 싱글 트랜잭션에서 128bit의 데이터를 전송할 수 있는 고성능 소프트웨어-투-하드웨어 시리얼 인터페이스를 제공하는 APU(Auxiliary Peripheral Unit) 인터페이스의 장점을 구현할 수 있다.
FPGA 하드웨어 생성 및 테스트
Sequantial 하게 처리되는 C code로부터 하드웨어를 생성할 때는 ImpulseC는 낮은 단계의 병렬성을 추출할 수 있다. C code에서 루푸와 같은 구조는 처리속도를 증가시키기 위해 Unrolling 시키거나 Pipeline화 시킨다.
이러한 컴파일러 최적화는 애플리케이션 개발자들의 개발시간을 획기적으로 단축시켜 준다.
임펄스 C 컴파일러는 하드웨어를 생성할 때 VHDL이나 Verilog 코드를 만들며 자일링스 ISETM 소프트웨어를 사용해 synthesis 된다. 프로세서 측면에서 볼 때는 ImpulseC 컴파일러는 마이크로 블레이즈나 ppc405가 사용할 수 있는 Run-Tim Library를 만든다.
반복적인 하드웨어-레벨 유닛 테스트는 이 프로젝트에서 중요한 부분이다. 임베디드 PowerPC는 테스트 제너레이터로서 이 프로세서를 사용하여 빠르게 필터를 실행할 수 있도록 한다. 이 방법을 사용하여 데이터의 정확성을 검증할 수 있을 뿐만 아니라 필터 성능과 처리량을 직접 측정할 수 있다.
사실 임베디드 PowerPC를 사용한 전반적인 C-언어 테스트 방법은 비디오 데이터와 관련된 더욱 신속한 하드웨어 동작속도 테스트 방법인 HDL 시뮬레이션보다 더욱 실질적인 검증이 가능하다.
이러한 프로세스에서 XPS(Xilinx Platform Studio) 툴이 매우 중요하다는 것을 알 수 있다. XPS는 자일링스 ML-410 보드를 위한 보드 지원 패키지를 포함하고 있으며, 이를 통해 임베디드 PowerPC를 테스트 제너레이터로 셋업하거나 버텍스-4 FX APU 인터페이스를 통해 하드웨어 필터와 통신할 수 있다.
임펄스 툴은 XPS 하드웨어 및 소프트웨어 기능을 이출할 수 있으며, 이를 통해 생성된 양방향 필터 하드웨어로부터 APU 연결 커스텀 주변기기 개발을 매우 쉽게 처리할 수 있다.
ISE 툴은 사이즈 및 클럭 속도 성능에 대한 자료를 제공하며, ML410 보드는 하드웨어에서 생성된 필터가 적절하게 동작하는지 최종적인 결정을 내릴 수 있도록 도와준다.
개발기간 동안 HDL 시뮬레이션을 통해 생성된 HDL 코드의 동작여부 자체를 판단하는데도 사용하지만 보다 중요한 점은 클럭마다 동작하는 동작상태를 점검해 C code로 보다 최적화할 수 있는 점을 찾는데 HDL 시뮬레이션을 이용할 수 있다는 것이다.
HDL 시뮬레이션은 Pipeline이 심하게 구현된 하드웨어를 그 가치가 축소되지만 Sequential 블록을 분석하거나 생성된 HDL 코드의 상태를 분석하는데 매우 유용하다.
Impulse C는 C code는 병렬성을 비주얼화 시키고 생성된 하드웨어에 대응되는 C code를 보여주는 양방향 최적화를 할 수 있다. 이 최적화 기법을 사용하면 앞에서 HDL 시뮬레이션을 통해 분석된 결과는 바로 C code에 반영될 수 있다.
반복적인 최적화
초기 최적화 되지 않은 하드웨어 프로토타입을 가지고 제한된 로직조건하에서 주어진 타이밍을 맞추기 위해 최적화 작업을 시작하였다.
기존에 비슷한 필터를 손으로 최적화 시켰던 경험과 로직크기 및 실시간 영상 요구조건을 고려할 때 Vigilant는 약 100개의 슬라이와 초당 60개의 프레임을 처리하는 것을 목표로 하였다. 먼저 2개의 병렬처리 프로세서 내부에 있는 Critical Loop를 개선함으로 알고리즘의 재구성을 시작하였다. 이 방법은 143Mhz라는 비교적 높은 클럭을 구현할 것 처럼 보였지만 연속적이지 않은 파이프라인 구조 때문에 구현할 수 없었다.
이런 현상은 가장 느린 파이프라인 구조를 가진 프로세서에 의해 발생하게 된다. 따라서 시스템 레벨상에 두개의 프로세서가 병렬로 동작하더라도 주어진 픽셀 레이트를 만족시킬 수 없게 된다.
추가적인 분석작업이 진행된 후, 우리는 메인 필터링 루프를 위한 싱글 파이프라인 프로세스 적용을 포함한 여러 C 코드에 대한 수정을 가했다. 일련의 최적화 작업의 결과로 목표한 슬라이스 수와 단지 27MHz의 FPGA 클럭 속도(BT.601 포맷으로 받은 D1 비디오 스트림의 입력 클록 속도)로 15ms(초당 66프레임) 이상의 싱글 프레임 속도를 지원하는 필터를 구현할 수 있었다. 이 결과는 표 1에 정리되어 있다.
이번 사례에서 보여진 서로 다른 성능 결과는 FPGA에 사용하는 적절한 C 프로그래밍 기법이 얼마나 중요한지 새삼 깨닫게 한다. 비록 C-to-FPGA 툴이 복잡한 알고리즘을 하드웨어로 전화하는데 필요한 개발시간을 획기적으로 감소시켜 준다 하더라도 매우 주의깊게 이러한 툴을 적용해야 한다. 아마도 여러분은 수작업으로 구현한 HDL과 비교할 만한 결과를 얻기 위해서는 반복적인 최적화 방법을 사용해야 할 것이다. 다행스럽게도 이러한 기법들은 기본적인 경험과 기술을 가진 임베디드 소프트웨어 개발자라면 충분히 수행할 수 있다.
결론
소프트웨어-투-하드웨어 설계 툴은 복잡한 FPGA 알고리즘을 개발하고 빠르게 프로토타입을 구현하는데 있어 매우 중요한 역할을 수행한다. 그러나 수작업 HDL과 비교할만한 성능을 얻기 위해서는 일정한 수준의 수동 최적화 작업 또한 필요하다. 양방향 설계 및 최적화 툴과 결합된 반복적 설계 방법은 복잡한 대규모 임베디드 설계 및 고성능 컴퓨팅 애플리케이션을 관리하는데 효과적이다.
<자료제공: 월간 반도체네트워크 2007년 08월호>