LabVIEW FPGA로 디지털 통신 인터페이스 개발하기

개요

지원되지 않거나 사용자 정의된 디지털 통신 프로토콜을 통해 테스트 어플리케이션을 개발하는 엔지니어는 LabVIEW FPGA 모듈을 사용하여 FPGA 기반 R 시리즈 재구성가능한 I/O 하드웨어에서 다양한 통신 인터페이스를 신속하게 구현하거나 프로토타핑할 수 있습니다. ASIC와 같은 사용자 하드웨어를 설계하고 빌드하거나 FPGA에서 실행할 VHDL 코드를 작성하는 것과 달리, LabVIEW FPGA Module 사용하면 특수 개발 도구가 필요하지 않고도 새로운 기능을 쉽게 테스트하고 디버깅할 수 있습니다.

내용

LabVIEW FPGA

자동차, 항공 및 기타 산업 분야에서 테스트 시스템을 개발할 때 일반적으로 필요한 것은 테스트 시스템과 다른 디바이스 간의 디지털 통신을 위한 인터페이스를 개발하거나 구현하는 것입니다. 이러한 디바이스에는 다른 테스트 시스템 또는 컴퓨터, 인스트루먼트, DUT, ECU와 같은 하위 레벨 시스템 구성요소 등이 포함됩니다.

새로운 테스트 시스템을 개발할 때에는 어플리케이션 개발 도구를 위한 사용하기 쉬운 드라이버가 포함된 디지털 통신 프로토콜을 위해 준비된 인터페이스가 필요합니다. 그러나 대부분의 경우 이것은 현실이 아닙니다. 외부 디바이스와 통신할 보드나 다른 인터페이스를 개발해야 하는 경우도 있습니다. ASIC을 직접 설계하는 극단적인 방법으로 사용자 정의 하드웨어를 개발하거나, 최소한 기성 부품을 기반으로 새 보드를 납땜하여 제작할 수 있습니다. 그러나 재구성가능한 I/O 하드웨어와 LabVIEW FPGA 모듈을 사용하면 LabVIEW와 그래픽 프로그래밍 도구만을 사용하여 사용자 하드웨어를 설계할 수 있습니다. 사용자 정의된 하드웨어 디자인은 재구성가능한 I/O 하드웨어의 FPGA에 로드되어 필요에 맞게 사용자 정의된 인터페이스 보드를 생성합니다.

LabVIEW FPGA Module을 사용하여 사용자 정의 인터페이스 보드에서 다양한 통신 프로토콜을 구현하는 방법을 설명합니다. 이러한 기술은 플러그인 PCI 및 PXI 재구성 가능 I/O 카드 (R 시리즈)와 견고한 산업용 인클로저를 제공하는 CompactRIO 플랫폼 모두에 적용됩니다.

디지털 통신 프로토콜

테스트 시스템에는 RS-232 및 GPIB와 같은 매우 일반적인 인터페이스에서 개별 제조업체 및 어플리케이션 개발자가 구현하는 맞춤형 프로토콜에 이르기까지 다양한 통신 프로토콜이 사용됩니다. 일반적이지만 널리 알려지지 않은 인터페이스에는 SPI(Serial Peripheral Interface) 및 I2C(Inter-Integrated Circuit)가 포함되며, 이는 전자 장치와 시스템 간 통신에 사용됩니다. 이러한 프로토콜은 어플리케이션에서 일반적으로 사용되지만, 다양한 플랫폼 및 소프트웨어 환경에서 사용할 수 있는 통신 인터페이스가 지원하는 것은 아닙니다. 이러한 요구를 위해 LabVIEW FPGA 및 재구성가능한 I/O 플랫폼은 비용 효율적인 솔루션을 제공하는 이상적인 도구입니다.

디지털 통신 프로토콜은 해당 어플리케이션 영역 또는 산업에 따라 그룹화될 수 있으며, 프로토콜 자체의 특성과 기술적 스펙에 따라 그룹화될 수 있습니다. 다음 섹션에서는 각 프로토콜의 기술적 세부사항과 특성에 대해 자세히 설명하고 이를 구현하기 위해 LabVIEW를 사용하는 방법을 설명합니다. 애플리케이션 및 업계에서 다음은 LabVIEW FPGA를 사용하여 해결된 통신 인터페이스를 포함하는 범주 및 샘플 프로토콜의 기본 세트입니다.

컴포넌트/IC 통신
  • 전자 설계: SPI, I2C, JTAG, PS/2, ...
시스템 통신
  •   항공우주: MIL-STD-1553, ARINC-429, ...
  •   자동차: CAN, MOST, KWP, 1939, ...
텔레커뮤니케이션
  • 위성 및 항공우주 통신: PCM/텔메트리
가전
  •   디지털 오디오: S/PDIF, I2S
사용자 정의
  • 디바이스별 구현

프로토콜 분류

디지털 통신 프로토콜은 기술적 정의와 요구사항에 따라 분류할 수 있습니다. 이 어플리케이션 독립적인 프로토콜 관찰 방식은 사용 중인 개발 도구를 사용하여 최적의 구현을 선택하는데 중요한 세부사항에 초점을 맞출 수 있도록 도와줍니다. 이 문서의 나머지 부분에서는 이러한 분류 기준과 FPGA에서 여러 프로토콜 그룹이 구현되는 방법에 대해 설명합니다.

대부분의 디지털 통신 인터페이스는 발신자와 수신자 사이의 데이터 신호 개수에 따라 시리얼과 병렬의 두 가지 매우 일반적인 항목 중 하나로 분류됩니다. 데이터가 단일 데이터 라인에서 전송되는 경우, 모든 데이터 비트가 순차적으로 또는 직렬로 전송되기 때문에 시리얼 데이터 링크입니다. 병렬 데이터 링크에는 하나 이상의 데이터 라인이 있고 8개 데이터 라인의 배수가 있는 경우가 많습니다. 데이터는 병렬로 전송되며, 일반적으로 한 번에 하나의 바이트 또는 워드를 사용합니다. 전통적으로 시리얼(예: RS-232) 및 병렬(예: GPIB) 통신 링크는 같은 클럭 속도에서 더 높은 데이터 전송 속도를 제공하는 병렬 통신 링크와 함께 사용됩니다. 단일 데이터 라인에서 가능한 비트 속도가 메가비트 및 기가비트 범위로 증가함에 따라 시리얼 링크는 케이블 연결뿐만 아니라 인터페이스 구성요소(예: 라인 드라이버)의 비용과 케이블 연결 비용을 절감하는 보다 경제적인 솔루션을 제공하기 때문에 시장에서 훨씬 널리 사용되고 있습니다. 시리얼 및 병렬 통신 인터페이스에는 클럭 및 트리거링뿐만 아니라 컨트롤 및 명령 통신에 사용되는 추가적인 신호 라인이 있을 수 있습니다.

물리적 통신 인터페이스의 두 번째 기본 분류는 디지털 신호 라인에 사용되는 전압 레벨과 접지 참조입니다. 데이터 비트와 기타 정보는 신호 라인의 다양한 전압 레벨에 의해 전달되지만, 서로 다른 타입의 인터페이스에서 사용되는 전압 레벨에는 상당한 차이가 있을 수 있습니다. 단일 종단형 디지털 신호에서, 신호 라인의 전압 레벨은 공통 접지 참조를 기준으로 측정됩니다. 차동 디지털 신호는 두 개의 참조되지 않은 신호로 구성되며 두 신호 라인 사이의 전압 레벨은 신호 값을 나타냅니다. 차동 신호는 신호 라인이 수집하는 노이즈에 더 면역적이며 일반적으로 장거리로 전송되는 신호에 사용될 수 있습니다. 디지털 통신에 사용되는 특정 전압 레벨은 TTL, CMOS, LVDS와 같은 표준에 의해 참조되며, FPGA의 프로토콜 구현에서는 처리되지 않습니다. 재구성가능한 I/O 하드웨어의 디지털 입력과 출력은 TTL/CMOS 호환 전압 레벨을 사용합니다. 다른 레벨이 필요한 경우, 신호 변환기를 인터페이스 하드웨어와 통신 링크 사이에 삽입해야 합니다.

신호 및 비트뱅잉

프로토콜을 분석하고 LabVIEW FPGA의 구현에 대해 생각할 때 프로토콜에서 사용되는 다양한 신호 라인과 각 신호의 목적을 식별해야 합니다. 프로토콜에 의해 사용되는 신호 라인의 개수는 LabVIEW 프로젝트에서 얼마나 많은 하드웨어 리소스를 구성해야 하는지 그리고 LabVIEW 다이어그램에서 얼마나 많은 디지털 라인을 사용할지 결정합니다. SPI (Serial Peripheral Interface) 프로토콜을 보여주는 다음 타이밍 다이어그램(그림 1)은 이 프로토콜을 구현할 때 관리해야 하는 세 개의 신호 라인의 사용을 보여줍니다.

1개의 데이터 라인으로 SPI 프로토콜의 간단한 타이밍 다이어그램

그림 1: 하나의 데이터 라인과 함께 SPI 프로토콜의 간단한 타이밍 다이어그램

구현을 시작할 때 타이밍 다이어그램을 대응하는 LabVIEW FPGA 코드로 변환하려면 디지털 라인을 켜고 끄는 것과 서로 다른 디지털 라인의 상태를 설정하는 동안 적절한 시간을 기다리는 것과 같은 두 가지가 있습니다. 디지털 프로토콜을 읽는 어플리케이션에서는 디지털 라인의 상태를 읽고 각 신호 라인의 전환 사이의 시간을 기록하는 작업을 수행합니다. 일반적으로 디지털 프로토콜을 출력하는 것은 구현하기 쉬우므로 먼저 이 문제를 해결해 보겠습니다.

클럭 신호

프로토콜을 분류하는데 사용하는 다음 기준 중 하나는 프로토콜이 사용하는 클럭 소스입니다. 두 가지 주요 항목은 동기화 프로토콜과 비동기화 프로토콜입니다. 동기화 프로토콜은 프로토콜에 특정한 타이밍 신호를 포함하고, 비동기화 프로토콜은 정의된 비트 속도를 사용하여 타이밍을 설정합니다.

동기화 프로토콜의 일반적인 예는 위의 타이밍 다이어그램에서 보이는 SPI 프로토콜입니다. 프로토콜에는 전용 클럭 신호가 포함되어 있어, 모든 수신자가 클럭 라인을 타임베이스로 사용하여 데이터 라인을 읽거나 쓸 수 있습니다. 가장 잘 알려진 비동기화 프로토콜은 여러 PC에서 사용되는 시리얼 (RS-232) 버스입니다. 시리얼 버스를 사용할 때, 통신 중인 디바이스의 보드레이트 (초당 비트)를 지정합니다. 보드레이트는 발신자와 수신자가 사용하여 동일한 속도로 데이터 신호를 업데이트하거나 읽습니다. 통신의 양쪽 끝에서 시간 소스가 정확히 같지 않기 때문에 비동기식 통신 데이터 패킷의 길이는 비트 비정렬을 방지하기 위해 제한됩니다. 비동기식 통신은 일정한 타이밍 차이를 허용하기 위해 자주 재동기화되어야 합니다. 반면, 동기식 통신 프로토콜은 모든 데이터 비트에서 동기화되므로 연속적으로 통신할 수 있습니다.

클럭 신호를 동기화 프로토콜의 일부로 구현할 때, FPGA 클럭을 사용하여 프로토콜의 타임베이스를 결정하고 이에 따라 클럭 신호를 업데이트합니다.

LabVIEW FPGA 다이어그램에서 10 us (100 kHz) 클럭 신호 생성

그림 2: 10 us (100 kHz) 클럭 신호를 생성하는 LabVIEW FPGA 다이어그램

비동기화 프로토콜에서는 별도의 클럭 신호가 생성되지 않지만, FPGA 클럭과 정의된 보 전송속도를 사용하여 데이터 신호를 언제 업데이트하거나 읽을지 결정합니다. 

LabVIEW FPGA 다이어그램에서 데이터 라인을 4800 보로 업데이트

그림 3: LabVIEW FPGA 다이어그램에서 데이터 라인을 4800 보로 업데이트
(8333 FPGA 클럭 사이클 = 208.3 us = 1/4800 Hz)

인코딩/디코딩 - 펄스 코드 변조

클럭 신호 또는 타이밍 스펙에 의해 지정된 속도에 따라 데이터는 데이터 신호에서 인코딩되거나 데이터 신호에서 읽은 후 디코딩됩니다.  데이터를 여러 다른 포맷으로 인코딩할 수 있습니다. 가장 일반적인 방법은 하나 또는 여러 개의 데이터 신호 상태로 데이터 비트의 값을 나타내는 것입니다. 이 일반적인 인코딩 방법의 클래스는 PCM (Pulse Code Modulation)이라고 합니다.

데이터 비트가 데이터 신호의 단일 상태로 나타나는 PCM 메소드의 부분을 NRZ (Non-Return to Zero)라고 합니다. 예를 들어, 하이 데이터 신호는 '1' 비트를 나타내고, 로우 데이터 신호는 '0' 비트를 나타냅니다. 이 방법은 데이터 신호의 레벨이 데이터 비트를 나타내기 때문에 NRZ-L이라고 부릅니다. RS-232와 같은 일부 프로토콜에서, 이 로직은 하이 상태가 '0'을 나타내고, 로우 상태가 '1'을 나타내는 반대로 되었습니다. 이것을 NRZ-I (역)이라고 합니다. 추가적인 NRZ 서브타입은 NRZ-M (마크) 및 NRZ-S (스페이스)입니다. 여기서 '1' 데이터 비트 값은 데이터 신호의 변화(NRZ-M)로 나타나거나 '0'은 데이터 신호의 변화(NRZ-S)로 나타납니다.

NRZ (Non-Return to Zero) 인코딩 방법

그림 4: NRZ (Non-Return to Zero) 인코딩 방법

펄스 코드 변조는 클럭 신호와 데이터 신호를 하나의 데이터 라인으로 결합하는 다른 인코딩 방식을 포함합니다. 각 비트는 데이터 신호의 여러 상태로 나타납니다. 이는 양상 인코딩이라고 하며, 일반적인 맨체스터 인코딩 방식은 양상 인코딩의 한 타입입니다.

다른 고급 인코딩 방식에는 다양한 형태의 펄스 폭 인코딩이 포함됩니다. 일반적으로 사용되는 펄스 폭 변조(PWM) 방법은 아날로그 값을 상수 주파수 펄스 트레인의 변화하는 펄스 폭으로 직접 변환합니다. 펄스 폭 인코딩의 다른 형태는 두 개의 서로 다른 펄스 폭을 사용하여 기존의 비트 시퀀스에서 '0'와 '1' 비트를 나타냅니다.

 

LabVIEW FPGA 구현

이제 공통 프로토콜을 설명하는 기본 분류가 있기 때문에 LabVIEW FPGA에서 프로토콜을 구현하는 방법을 살펴볼 수 있습니다. LabVIEW FPGA에서 프로토콜을 구현하려면 일반적으로 타이밍 다이어그램을 통해서 시작하여 서로 다른 신호 라인의 상태 변화와 이러한 변화 사이의 타이밍을 대응하는 LabVIEW 함수와 구조로 변환합니다. 디지털 라인의 각 상태 변경은 FPGA I/O 노드를 사용하여 구현되고, 타이밍은 LabVIEW FPGA 타이밍 함수(루프 타이머 및 기다림)를 사용하여 구현됩니다. 여러 번 반복되는 타이밍 다이어그램의 단계는 For 또는 While 루프를 사용하여 구현됩니다. 보다 광범위한 프로토콜의 경우, 함수와 구조의 그룹이 SubVI에 캡슐화되어 코드를 재사용하고 코드를 보다 모듈화하고 관리하기 쉽도록 할 수 있습니다.

SPI 출력

첫 번째 예로 위의 그림 1과 같은 SPI 타이밍 다이어그램을 구현합니다. SPI 프로토콜을 사용하는 통신은 두 디바이스 사이에 전송되는 데이터의 패킷으로 구성됩니다. SPI 통신에서는 칩 선택 신호와 클럭 신호를 컨트롤하는 마스터 디바이스가 있습니다. 마스터에서 각 슬레이브로 전용 ChipSelect 신호 라인과 모든 디바이스에 대한 공통 데이터 라인이 있는 하나 이상의 슬레이브 디바이스가 있을 수 있습니다. 어플리케이션이 마스터와 슬레이브 사이의 양방향 통신을 포함하는 경우, 일반적으로 두 개의 데이터 라인이 사용됩니다. 이 두 라인은 마스터 출력 슬레이브 입력(MOSI)과 마스터 출력 슬레이브 출력(MISO)이라고 합니다. 이 예제에서는 하나의 데이터 라인에만 집중합니다.

두 장치 간의 SPI 통신을 위한 연결 다이어그램

그림 5: 두 디바이스 간의 SPI 통신을 위한 와이어링 다이어그램

패킷 전송은 항상 주소가 지정된 슬레이브 디바이스의 칩선택 라인을 지정하여 마스터 디바이스가 시작합니다. 일반적으로 칩선택 라인은 활성 로우이기 때문에 시스템이 유휴 상태이면 하이 상태로 유지되며, 마스터가 로우로 전송을 시작하도록 만듭니다. 칩 선택 신호가 지정된 후, 마스터는 데이터 라인을 업데이트한 후 클럭 라인을 토글하여 각 데이터 비트를 슬레이브에 전달합니다. 데이터 패킷의 내용은 어플리케이션에 따라 다르며 개발자와 디바이스 설계자의 정의에 따릅니다.

대응하는 LabVIEW FPGA 다이어그램(아래 그림 6 참조)에서 각 데이터 전송은 '쓰기' 불리언 컨트롤을 설정하여 시작됩니다. 이렇게 하면 참 케이스가 실행됩니다. 초기에 디지털 출력을 로우로 설정하여 ChipSelect 라인(SPI CS*)을 지정합니다. 동시에 데이터 값 '데이터 출력'이 상응하는 비트 시퀀스(불리언 배열)로 변환됩니다. 1 마이크로초 (1us) 기다림 함수는 슬레이브 디바이스가 다음 데이터 비트를 받을 준비가 되도록 시간을 제공합니다. 그런 다음 For 루프에서 데이터 라인을 업데이트하고 클럭 라인을 토글하는 시퀀스가 16번 반복됩니다. 불리언 배열의 각 비트는 데이터 라인(SPI DOUT)에 출력되고, 그 다음에 클럭 라인(SPI SCLK)이 하이로 설정되고 로우로 설정됩니다. [루프 타이머] 함수는 루프가 2 us 간격으로 실행되도록 하며, [기다림] 함수는 클럭 신호의 하이 위상 길이를 1 us로 제어하여 500 kHz 50% 듀티 사이클 클럭 신호를 생성합니다. 16 비트가 모두 생성된 후, 칩 선택과 데이터 라인은 유휴 상태로 되돌아가고 5us 최소 유휴 시간 기다림 함수가 삽입됩니다. 이제 FPGA는 다음 쓰기 명령을 받을 준비가 되었습니다.

LabVIEW FPGA 다이어그램의 간단한 SPI 출력 구현

그림 6: 간단한 SPI 출력 구현의 LabVIEW FPGA 다이어그램

사용 중인 SPI 디바이스와 어플리케이션의 사양에 따라, 전송할 데이터 비트 수, 클럭 신호의 주파수 등과 같은 통신 파라미터를 다이어그램에서 조절하거나 LabVIEW FPGA VI의 프런트패널에 있는 컨트롤을 사용하여 동적으로 제어할 수 있습니다.

필요한 경우, 출력 활성화 FPGA I/O 메소드 설정 노드를 사용하여 어플리케이션에서 사용되는 각 디지털 라인의 방향을 프로그램적으로 설정할 수 있습니다(그림 7 참조).

LabVIEW FPGA 디지털 라인의 초기화

그림 7: LabVIEW FPGA 디지털 라인의 초기화

SPI 입력

프로토콜의 입력 부분을 구현하는 것은 프로토콜을 감지하고 처리할 때 코드가 더 유연해져야 하기 때문에 몇 가지 고유한 문제를 초래할 수 있습니다. 디지털 출력 라인을 업데이트하고 적절한 지연을 삽입하는 대신, 코드는 서로 다른 디지털 라인의 상태를 모니터하고 필요한 경우 신호 라인의 특정 전환 사이의 시간을 측정합니다.

다음 예제는 이전 SPI 출력 예제와 대응하는 기본 SPI 입력 구현을 보여줍니다. 유휴 상태인 동안 FPGA는 칩선택 라인을 모니터하고 하강 에지를 감지합니다. 하강 에지에 따라 클럭 라인을 모니터하기 시작합니다. 클럭 신호의 각 16 개의 상승 에지에서, FPGA는 데이터 신호를 읽고 미리 할당된 불리언 배열에 비트 값을 저장합니다. 데이터 패킷의 끝에서 16 클럭 사이클 후, 불리언 배열은 정수 데이터 값으로 변환되고 VI의 프런트패널에서 사용할 수 있습니다.

간단한 SPI 입력 구현의 LabVIEW FPGA 다이어그램

그림 8: 간단한 SPI 입력 구현의 LabVIEW FPGA 다이어그램

SPI 프로토콜의 특성 때문에 이 예제는 모든 타이밍이 프로토콜의 에지에 의해 직접 컨트롤되기 때문에 시간 측정을 할 필요가 없습니다.

구현 고려사항

이 섹션에서는 LabVIEW FPGA를 사용하여 디지털 통신 프로토콜을 개발할 때 고려해야 할 추가적인 주제를 다룹니다.

오픈 컬렉터/오픈 드레인 신호 라인

위의 SPI 예에서 각 신호 라인은 하나의 디바이스에서만 구동됩니다. 그러나, 많은 프로토콜에서 신호 라인은 버스 또는 통신의 상태에 따라 하나 이상의 디바이스에 의해 구동되거나 컨트롤될 수 있습니다. 이렇게 하면 여러 디바이스가 버스에서 전송을 시작하거나 같은 데이터 라인을 사용하여 데이터를 전송하고 수신할 수 있습니다. 일반적으로 이는 오픈 컬렉터/오픈 드레인 회로를 사용하여 이루어집니다. 이 설정에서 디바이스는 신호 라인을 로우로 구동하거나 구동할 수 있지만, 라인을 하이로 설정하거나 라인을 구동하지 않을 때 신호 라인이 플로팅하도록 합니다. 신호 라인에 연결된 각 디바이스뿐만 아니라, 연결된 디바이스가 신호 로우를 구동하지 않는 경우, 신호 라인에는 설정된 전압에 대한 풀업 저항이 있습니다. 이 설정을 사용하면 모든 디바이스가 서로 다른 디바이스 사이에 전압 충돌을 일으키지 않고 로우 라인을 구동할 수 있습니다. 이러한 신호는 일반적으로 활성 로우로 정의되며, 이는 버스가 유휴 상태일 때 라인이 하이 상태이고 디바이스가 로우로 라인을 가져서 신호를 지정한다는 것을 의미합니다. 활성 로우 신호는 이전 예제에서 사용된 ChipSelect* (SPI CS*) 신호의 경우와 같이 신호 이름 뒤에 있는 막대나 별표로 표시되는 경우가 많습니다.

LabVIEW FPGA에서 오픈 컬렉터 신호를 구현하려면 디지털 라인의 방향을 제어하여 라인을 로우로 구동하고 플로팅하도록 합니다. LabVIEW FPGA에서는 I/O 메소드 노드를 사용하여 디지털 출력 라인을 활성화 또는 비활성화합니다. 라인이 비활성화되어 있는 동안, FPGA는 디지털 라인을 구동하지 않고 하이로 플로팅하도록 허용합니다. 활성화된 라인을 로우로 구동하려면, 출력 데이터를 거짓으로 설정합니다. 출력 데이터는 라인이 라인을 구동하거나 플로팅으로 설정되었는지에 관계없이 그 값을 유지하는 소프트웨어 레지스터입니다.

다음 그림은 I2C (Inter-Integrated Circuit) 프로토콜을 위한 LabVIEW FPGA의 오픈 컬렉터 구성의 예를 보여줍니다. I2C는 SPI와 유사한 애플리케이션에서 EEPROM, ADC, DAC 등과 같은 여러 종류의 통합 회로와 통신하는 데 사용됩니다. I2C 버스는 클럭과 데이터라는 두 개의 신호 라인만 가지고 있으며 각각 개방형 컬렉터 라인입니다. 통신에 적합한 수신자를 선택하려면, 발신자는 먼저 수신 디바이스를 지정하는 고유한 디바이스 주소를 전송합니다.

오픈 컬렉터 통신을 위한 VI를 초기화하려면 두 신호 라인(SCL과 SDA)이 비활성화되어 버스를 유휴 상태로 만듭니다. 각 신호의 출력 데이터는 거짓으로 설정되어 있습니다. 이 시점부터 각 라인의 상태는 [출력 활성화 설정] 메소드를 사용하여 라인을 활성화하고 로우로 구동하거나 비활성화하고 하이로 플로팅하도록 컨트롤됩니다.

그림 9: 오픈 컬렉터 통신을 위한 두 개의 디지털 라인 구성

I2C 버스에서 전송을 시작하려면, 발신자는 데이터 라인(SDA) 로우를 구동한 다음 클럭 라인(SCL) 로우를 구동하여 시작 조건을 전송합니다.

그림 10: 버스에서 I2C 시작 조건 구현

I2C 버스에서 데이터 비트를 전송하려면(그림 11 참조), 발신자는 데이터 라인(1번째 프레임)을 업데이트한 다음 클럭 라인 하이(2 프레임)과 로우(4번째 프레임)를 토글합니다.

I2C 프로토콜에서 각 데이터 바이트(8비트)를 전송한 후, 이전 바이트의 성공적인 수신을 수신 디바이스가 인식할 수 있도록 통신에 여분의 클럭 사이클이 삽입됩니다. 이를 위해 수신기는 9번째 클럭 사이클 동안 데이터 라인을 로우로 만듭니다. 본 예제의 발신자 측에서는 하이 데이터 비트를 보내고 클럭 주기 동안 데이터 라인(3번째 프레임)의 실제 상태를 확인하여 이를 구현합니다. 발신자가 데이터 라인을 하이로 플로팅하도록 하더라도, 수신자가 데이터 라인을 로우로 풀어 마지막 데이터 바이트를 인식하기 때문에 실제 데이터 값은 로우여야 합니다.

그림 11: I2C 버스에서 데이터 비트 전송

OSI 참조 모델

 

OSI (Open Systems Interconnection) 참조 모델은 통신 프로토콜을 사용하는 어플리케이션을 포함한 통신 프로토콜의 다양한 논리 계층을 나타냅니다. 프로토콜과 네트워크의 다양한 측면을 보다 잘 정의하고 이해하는데 사용됩니다.

그림 12:  OSI 참조 모델

레이어 1은 캐리어를 통해 데이터를 전송할 수 있는 전기적 및 기계적 세부사항을 다루는 물리 계층입니다. 단순 비동기화 패킷은 이 레벨에서 작동합니다.

레이어 2는 NRZ 및 동기화를 초과하는 변조뿐만 아니라 비트 및 바이트 레벨 데이터의 기본 정의를 제공합니다.

다음 두 개의 레이어는 주소 지정, 데이터 패킷 정의, 에러 확인 등을 다룹니다.

FPGA의 예에서 볼 수 있듯이, FPGA는 전기 레벨의 각 디지털 입력 및 출력 라인에 직접 인터페이스하여 L1 물리 계층에서 작동합니다. 이는 LabVIEW FPGA에서 디지털 통신 프로토콜의 개발자로서 프로토콜 및 애플리케이션에 대한 참조 모델의 모든 계층에 대해 책임을 지는 것을 의미합니다. 보다 간단한 프로토콜의 경우, 프로토콜 계층 위에 인터페이스를 추가하여 어플리케이션이 FPGA와 상호작용하고 프로토콜을 사용할 수 있도록 하기 위해 지금까지 사용한 것보다 조금 더 많은 프로그래밍이 필요합니다. 그러나 고급 프로토콜의 경우, 버스 레벨 에러 감지 및 핸들링, 패킷 빌드 및 분석, 여러 타입의 패킷 핸들링 등과 같은 중간 프로토콜 레이어를 제공하는 프로그래밍이 훨씬 더 필요할 수 있습니다.

타이밍 및 해상도

이미 본 것처럼, 타이밍은 프로토콜 구현을 개발하는데 매우 중요한 역할을 합니다. 데이터와 클럭 라인을 정확한 간격으로 업데이트해야 합니다. 프로토콜을 디코딩하는 동안 이와 같은 간격을 정확하게 측정하는 것이 중요합니다. FPGA의 타이밍 동작을 염두에 두어 통신 프로토콜을 개발해야 구현이 프로토콜의 요구사항과 스펙을 충족할 수 있습니다.

FPGA는 베이스 클럭 주파수에서 작동하며 모든 타이밍 함수는 같은 클럭 속도를 기반으로 합니다. LabVIEW FPGA의 경우 기본 FPGA 클럭 주파수는 40 MHz이며, 각 클럭 사이클과 시간 단위는 25 나노초(ns)입니다. LabVIEW FPGA에서는 타이밍 함수의 시간 간격을 밀리초, 마이크로초, 틱 단위로 지정할 수 있습니다. 각 Tick은 1개의 클럭 사이클 또는 25 ns에 해당합니다. 이는 지연 또는 루프 반복 시간을 지정할 때 가장 높은 분해능이 25 ns임을 의미합니다. 이것은 매우 정확하게 들리지만, 역방향을 사용하여 생성 가능한 주파수를 결정하면 더 높은 속도에서 그 효과를 볼 수 있습니다.

디지털 라인에 대해 1 MHz의 업데이트 속도를 생성하려면, [루프 타이머] 함수를 40 ticks로 설정할 수 있습니다.

1 MHz => 1 us = 1000 ns
Tick당 1000 ns / 25 ns = 40 ticks

1.25 MHz의 업데이트 속도를 원하는 경우

1.25 MHz =>0.8 us = 800 ns
tick당 800 ns / 25 ns = 32 ticks

1.25 MHz의 경우, 32 ticks의 지연을 사용합니다. 1.1 MHz의 업데이트 속도를 원하는 경우

1.1 MHz => 0.9091 us = 909.1 ns
Tick당 909.1 ns / 25 ns = 36.36 ticks

특정한 부분 클럭 사이클을 선택할 수 없으므로, 지연이 900 ns이고 주파수가 1.111 MHz인 36개의 클럭 사이클을 선택해야 합니다. 다음과 같은 낮은 주파수는 37 ticks 또는 1.081 MHz입니다. 따라서 40 MHz FPGA 클럭을 사용하면 디지털 라인을 1.081 MHz 또는 1.111 MHz로 업데이트할 수 있지만, 그 사이에는 업데이트할 수 없습니다.

LabVIEW 프로젝트의 FPGA 속성과 클럭 리소스를 사용하여 FPGA 베이스 클럭 주파수를 80 MHz 또는 120 MHz로 변경할 수 있습니다. 이렇게 하면 FPGA의 주파수가 높아지고 타이밍 함수의 타이밍 분해능이 향상됩니다. 그러나 클럭 주파수가 높을수록 FPGA VI 다이어그램에서 사용할 수 있고 FPGA용으로 컴파일할 수 있는 복잡성이 줄어듭니다.

Timed 프로토콜을 구현하려면 FPGA의 타이밍 분해능이 프로토콜과 어플리케이션의 필요에 적합한지 결정해야 합니다. 이는 이전 계산에서 보이는 것처럼 프로토콜을 생성하는데 필요한 타이밍에 특히 중요합니다. 프로토콜 읽기 및 디코딩의 경우, 프로토콜의 가장 높은 업데이트 속도보다 높은 속도로 신호 라인을 읽을 수 있는 경우가 많습니다. 안전하려면 업데이트 속도보다 적어도 두 배 빠른 속도로 신호를 샘플링할 수 있어야 합니다.

프로토콜에 포함된 데이터를 디코딩하기 위해 입력 신호에서 시간 측정이 필요한 경우, 프로토콜을 정확하게 디코딩하는데 필요한 타이밍 분해능을 결정하기 위해 추가적인 계산을 수행해야 합니다.

상태 머신

상태 머신은 디지털 통신 프로토콜의 인코딩 또는 디코딩을 구현하는데 유용한 기법입니다. LabVIEW에서는 While 루프와 Case 구조를 사용하여 각 상태를 나타내기 위해 상태 머신을 쉽게 구현할 수 있습니다. 

상태 머신은 타이밍 다이어그램을 별도의 단계로 분해하고 LabVIEW FPGA 다이어그램에서 각 단계를 별도의 상태로 변환할 수 있기 때문에 통신 프로토콜의 개발에 도움이 됩니다. 이렇게 하면 각 프로그램 단계를 절연시키고 구현의 어떤 부분에서도 프로그래밍의 복잡성을 줄일 수 있습니다. 또한 프로토콜 실행의 어느 곳에서든 특수 에러 핸들링 상태로 이동할 수 있도록 하여 에러 및 예외 핸들링과 같은 일반적인 작업을 단순화합니다. 때때로 프로토콜 스펙은 상태 머신으로 작성되며, 이를 직접 LabVIEW 상태 다이어그램으로 변환할 수 있습니다.

그림 1의 SPI 타이밍 다이어그램에서 다음 단계는 타이밍 다이어그램을 상태 머신으로 분할하는 방법입니다.

  • 칩선택을 낮게 설정
  • 데이터 설정 (0)
  • 클럭 하이 설정
  • 클럭 낮게 설정
  • 데이터 설정 (1)
  • 클럭 하이 설정
  • 클럭 낮게 설정
  • (비트 2-15에서 데이터와 클럭을 반복)
  • 칩선택을 높게 설정

각 데이터 비트마다 반복되는 5 단계가 있지만, 5 단계는 고유합니다. 원래 For 루프에서 이러한 반복 단계를 구현했습니다. 상태 머신에서 각 5단계에 대해 고유한 상태를 생성한 후 이를 실행합니다. 데이터 라인을 업데이트하고 클럭 라인을 토글하는 세 가지 반복 단계의 경우, 상태 머신이 마지막 단계로 넘어가기 전에 이 시퀀스를 16번 반복하도록 설정합니다. LabVIEW 상태 머신에서 이는 While 루프의 시프트 레지스터에 있는 카운터를 사용하여 구현됩니다.

단일 사이클 Timed 루프 사용

상태 머신 아키텍처의 또 다른 장점은 LabVIEW FPGA 단일 사이클 Timed 루프(SCTL) 내에서 프로토콜 구현을 구현할 수 있다는 것입니다. SCTL은 LV FPGA 다이어그램의 실행 속도를 향상시켜 루프의 각 사이클이 한 클럭 사이클로 실행되도록 합니다. 이렇게 하면 신호 라인을 FPGA 베이스 클럭 주파수로 업데이트할 수 있습니다. 또한 SCTL은 코드 생성을 최적화하여 FPGA의 코드가 더 효율적이고 FPGA 고유 재산을 더 적게 사용하도록 합니다. 그러나, SCTL 내부에서 구현되는 코드에는 몇 가지 제한이 있습니다. 예를 들어, SCTL 반복마다 각 신호 라인에 한 번만 접근할 수 있습니다. 그러므로 상태 머신의 상태를 정의하여 상태 당 각 신호 라인을 한 번만 읽거나 업데이트해야 합니다.

다음 다이어그램(그림 13)은 SCTL 내부의 상태 머신을 사용하는 SPI 출력 프로토콜의 구현을 보여줍니다. 유휴 상태는 쓰기 명령이 다음 데이터 패킷의 출력을 시작할 때까지 기다립니다. 또한 출력 작업의 데이터 값을 불리언 배열로 변환합니다. 다음 단계에서 CSS 설정은 ChipSelect 라인을 지정합니다. 그 후 데이터 비트 출력을 시작합니다. 리셋 클럭에서 다음 비트 값으로 데이터 라인을 업데이트하고 클럭 신호를 리셋합니다. 셋 클럭에서 수신기가 데이터 신호를 읽도록 트리거하는 클럭 신호를 설정합니다. 이 두 가지 상태에서 시프트 레지스터의 카운터를 증가시킵니다. 시프트 레지스터는 데이터 라인에 보낼 불리언 배열로부터 적절한 데이터 값을 선택합니다. 16비트를 출력하면 모든 신호 라인을 버스 유휴 상태로 리셋하는 리셋 CS 상태로 전환합니다. 거기서 우리는 다시 유휴 상태로 돌아가서 다음 쓰기 명령을 기다립니다.

그림 13: 단일 사이클 Timed 루프에서 SPI 출력 구현

양상 변조

양상 인코딩 또는 변조는 여러 다른 프로토콜에서 사용되는 매우 일반적인 데이터 인코딩 타입입니다. 데이터 신호와 클럭 신호를 하나의 신호 라인으로 결합하여 케이블 연결 필요를 줄이고 케이블 연결 거리가 길어지는 동안 데이터 무결성을 크게 향상시킵니다.