01signal.com

Xillybus로 하는 간단한 데이터 수집

개요

Xillybus의 가장 흔한 사용 사례는 데이터 수집(data acquisition)입니다. 이 페이지에서는 FPGA에서 호스트로 데이터를 전송하는 작업을 어떻게 시작하는지 설명합니다.

FPGA 내부에서 Xillybus와의 상호 작용을 더 자세히 살펴보려면 Xillybus FPGA 설계자 가이드를 참조하십시오.

애플리케이션의 데이터 전송률이 높다면 Linux용 시작 가이드 또는 Microsoft Windows용 시작 가이드의 5장에 있는 지침도 읽어 보는 것이 좋습니다.

호스트 측

Xillybus가 어떻게 동작하는지 이해하려면 컴퓨터 쪽에서 시작하는 것이 가장 쉽습니다. 다음 명령을 사용하면 디스크의 파일로 데이터를 수집할 수 있습니다.

$ cat /dev/xillybus_read_32 > capture-file.dat

"cat"은 파일에서 모든 데이터를 읽어 표준 출력으로 쓰는 표준 Linux 명령입니다. 이 예제에서 입력은 일반 파일이 아니라 디바이스 파일입니다. 이 입력은 FPGA에서 도착하는 데이터 스트림으로 구성됩니다. 표준 출력이 리다이렉트되므로 이 데이터는 디스크의 파일에 기록됩니다.

이것은 억지로 꾸며 낸 예제가 아닙니다. 어떤 사용 시나리오에서는 이것이 Xillybus를 데이터 수집에 실질적으로 사용하는 올바른 방법입니다. 특정 양의 데이터를 얻으려면 "dd"를 쓰는 것이 더 나을 수도 있습니다. 더 자주 사용되는 방식은 전용 컴퓨터 프로그램이 디바이스 파일에서 데이터를 읽는 것입니다. 각 애플리케이션에는 데이터를 소비하는 선호 방식이 따로 있습니다.

따라서 어떤 프로그래밍 언어를 선호하든, Linux를 쓰든 Windows를 쓰든 상관없습니다. FPGA에서 데이터를 받는 컴퓨터 소프트웨어는 "cat"과 똑같이 파일을 열고 읽기만 하면 됩니다. 표준적인 파일 I/O(file I/O) 프로그래밍 기법을 소개하는 별도 페이지가 있습니다. Xillybus와 함께 사용하는 프로그래밍 기법에 대한 더 자세한 내용은 Linux 프로그래밍 가이드Windows 프로그래밍 가이드에서 찾을 수 있습니다.

데이터 수집을 위한 로직

이제 FPGA에서 어떤 일이 일어나는지 살펴보겠습니다. Xillybus IP 코어(IP core)와 애플리케이션 로직은 FIFO를 통해 서로 상호 작용합니다. 애플리케이션 로직이 FIFO에 데이터를 쓰면, Xillybus가 그 데이터가 호스트에 도달하도록 보장합니다. FIFO가 어떻게 동작하는지 익숙하지 않다면 이를 설명하는 별도 페이지가 있습니다.

Xillybus의 데모 번들(demo bundle)에는 xillydemo.v라는 파일이 들어 있습니다. 이것은 IP 코어와 인터페이스하는 Verilog 코드입니다. 데모 번들에는 VHDL 파일 xillydemo.vhd도 있습니다. 다만 아래 예제는 Verilog로 작성되어 있습니다.

Xillybus IP 코어의 인스턴스화(instantiation)는 xillydemo.v(또는 xillydemo.vhd) 안에서 이루어집니다. 아래는 위에서 사용한 "cat" 명령과 관련된 데이터 수집 예제의 핵심 부분입니다(나머지 부분은 생략했습니다).

   // Wires related to /dev/xillybus_read_32
   wire        user_r_read_32_rden;
   wire        user_r_read_32_empty;
   wire [31:0] user_r_read_32_data;
   wire        user_r_read_32_eof;
   wire        user_r_read_32_open;

[ ... ]

   xillybus xillybus_ins (
[ ... ]
			  // Ports related to /dev/xillybus_read_32
			  // FPGA to CPU signals:
			  .user_r_read_32_rden(user_r_read_32_rden),
			  .user_r_read_32_empty(user_r_read_32_empty),
			  .user_r_read_32_data(user_r_read_32_data),
			  .user_r_read_32_eof(user_r_read_32_eof),
			  .user_r_read_32_open(user_r_read_32_open),
[ ... ]
			  .bus_clk(bus_clk),
[ ... ]
			  );

IP 코어 포트의 의미는 Xillybus 로직 API 가이드에 자세히 설명되어 있습니다.

xillydemo.v에는 FIFO의 인스턴스화가 하나 들어 있습니다. 이 FIFO는 단일 클록 FIFO(single-clock FIFO)로서, 원래 Verilog 코드에서 보여 주는 루프백에 적합합니다. 데이터 수집 애플리케이션에는 듀얼 클록 FIFO(dual-clock FIFO)가 더 적합합니다. 데이터 수집 로직은 대개 자체 클록(clock)에 의존하기 때문입니다.

따라서 xillydemo.v를 다음과 같이 데이터 수집을 수행하는 모듈로 바꿀 수 있습니다. 단일 클록 FIFO(이름은 fifo_32x512)의 인스턴스화를 삭제하고 다음 코드로 대체하십시오.

   assign user_r_read_32_eof = 0;

   dualclock_fifo_32 fifo_32
     (
      .rd_clk(bus_clk),

      .rst(!user_r_read_32_open),
      .rd_en(user_r_read_32_rden),
      .dout(user_r_read_32_data),
      .empty(user_r_read_32_empty),

      .wr_clk(capture_clk),

      .wr_en(capture_en),
      .din(capture_data),
      .full(capture_full)
      );

듀얼 클록 FIFO

dualclock_fifo_32는 표준 듀얼 클록 FIFO입니다. 이것을 FPGA 개발 소프트웨어에서 IP 코어로 생성해야 합니다. 이 FIFO의 깊이는 512개 이상의 요소여야 합니다. FPGA 소프트웨어 간의 차이 때문에 포트 이름이 위에 표시된 것과 다를 수 있습니다. 그렇지만 FIFO 포트를 연결하는 방법은 쉽게 유추할 수 있을 것입니다.

다시 한 번 말하지만, FIFO 개념이 익숙하지 않다면 FIFO를 소개하는 페이지가 있습니다.

FIFO의 포트 몇 개(@rd_clk, @rd_en, @dout, @empty(비어 있음))는 Xillybus IP 코어에 직접 연결됩니다. 이 연결은 데모 번들에서 했던 것과 정확히 같게 이루어진다는 점에 유의하십시오. IP 코어는 이 네 신호를 사용해 FIFO에서 데이터를 가져옵니다. IP 코어에 이 포트들을 연결하는 방법은 언제나 이것이 올바른 방식입니다.

@rd_clk가 @bus_clk에 연결된 것도 주목하십시오. @bus_clk 신호는 Xillybus IP 코어에서 나옵니다. 즉, IP 코어가 FIFO의 한쪽에서 사용되는 클록을 결정합니다.

@rst와 관련해서는, 이것이 !user_r_read_32_open에 연결된 것을 확인하십시오. @user_r_read_32_open은 호스트에서 해당 디바이스 파일이 열려 있을 때만 high가 됩니다. 결과적으로 파일이 열려 있지 않으면 FIFO는 리셋됩니다. 따라서 호스트가 디바이스 파일을 열 때 FIFO는 empty(비어 있음) 상태가 됩니다. 만약 이전 세션의 잔여 데이터가 FIFO 저장 공간에 남아 있었다면, 디바이스 파일이 닫힐 때 그 데이터는 삭제되었기 때문입니다.

이런 동작은 데이터 소스에서 일반적으로 기대하는 바입니다. 그러나 디바이스 파일이 닫혀도 FIFO의 데이터를 유지하고 싶다면 @rst에 다른 신호를 연결하십시오. 또는 @rst를 low로 고정해도 됩니다.

이 예제에서 @user_r_read_32_eof는 데모 번들에서와 마찬가지로 0입니다. 이 신호는 호스트로 파일 끝(end-of-file)을 보내는 데 사용할 수 있습니다. 자세한 내용은 API 가이드에 나와 있습니다.

애플리케이션 로직과의 인터페이스

데이터 수집 애플리케이션에는 항상 호스트로 보낼 데이터를 만드는 일종의 애플리케이션 로직이 있습니다. 이 부분은 애플리케이션마다 다르므로 이 논의와는 무관합니다. 우리는 이 데이터를 호스트로 보내는 부분에 초점을 맞추겠습니다.

이 부분은 놀라울 정도로 쉽습니다. 애플리케이션 로직은 이 데이터를 FIFO에 쓰기만 하면 됩니다. FIFO에 쓰인 데이터는 호스트의 컴퓨터 프로그램에 연속적인 데이터 스트림으로 도달합니다.

따라서 애플리케이션 로직은 FIFO에 쓰는 표준 규칙을 사용합니다. 위 예제에서는 @capture_clk, @capture_en, @capture_data, @capture_full로 표시됩니다. 이 로직은 데이터를 @capture_data에 놓고 @capture_en을 제어해 FIFO에 올바르게 쓰기만 하면 됩니다. 애플리케이션 로직은 FIFO에 쓸 때 자체 클록을 사용한다는 점에 유의하십시오.

데이터 흐름

다음은 애플리케이션 로직에서 호스트의 사용자 애플리케이션 프로그램까지의 데이터 흐름을 나타낸 간소화된 블록 다이어그램입니다.

Simplified data flow diagram for data acquisition with Xillybus

이 블록 다이어그램에서는 두 가지 기술적 세부 사항이 생략되었습니다. PCIe 블록과 커널 드라이버가 표시되지 않았는데, 이들은 사용자가 인식하는 데이터 흐름과는 무관하기 때문입니다. Xillybus를 올바르게 사용하는 방법은 이러한 세부 사항을 잊고 애플리케이션 로직과 애플리케이션 소프트웨어에 집중하는 것입니다.

데이터를 패킷(packet)으로 묶을 필요가 없습니다. 애플리케이션 로직과 컴퓨터 사이의 통신 채널은 연속적인 스트림입니다. IP 코어와 드라이버는 데이터 흐름이 다른 스트림 프로토콜, 예를 들어 Linux에서 프로그램 사이의 파이프(pipe)처럼 동작하도록 보장합니다. 비슷한 동작을 하는 또 다른 프로토콜로는 TCP/IP가 있습니다. 다시 말해, FIFO에 얼마나 많은 데이터를 쓰는지는 중요하지 않습니다. 이 데이터는 곧 호스트의 사용자 애플리케이션 프로그램에 도달합니다.

데이터를 패킷으로 구성하고 IP 코어의 DMA 버퍼 크기를 그 패킷 크기에 맞추는 것은 흔한 실수입니다. 이렇게 해서 얻을 이점은 없습니다. 데이터가 일정한 크기의 패킷으로 전송되는 경우에도 IP 코어를 그 크기에 맞출 필요가 없습니다.

그런데 FIFO가 full(가득 참) 상태가 되면 어떻게 되나요?

FIFO의 기본 규칙 중 하나는 @full(가득 참) 포트가 high일 때 @wr_en은 low여야 한다는 것입니다. 쉽게 말해, full(가득 참) 상태인 FIFO에 쓰지 말라는 뜻입니다. 그런 일이 발생하면 어떻게 될까요? 이런 상황을 처리하려면 애플리케이션 로직이 상당히 복잡해집니다.

간단히 답하면, FIFO는 절대 full(가득 참) 상태가 되어서는 안 됩니다. 정상적인 동작 조건에서는 이것이 능동적으로 방지됩니다. IP 코어가 FIFO에서 데이터를 읽어 호스트의 RAM으로 복사하는데, 이 작업이 FIFO가 차오르는 것을 막을 만큼 빠르게 일어납니다. 대개 FIFO의 깊이는 512개 데이터 요소보다 깊을 필요가 없습니다.

하지만 애플리케이션 로직이 FIFO에 너무 빨리 쓰면 FIFO가 full(가득 참) 상태가 될 수 있습니다. 즉, 애플리케이션 로직의 평균 데이터 전송률이 IP 코어의 한계(각 유형의 IP 코어에 대해 명시된 값)를 초과하면 IP 코어가 FIFO에서 데이터를 충분히 빨리 읽지 못하게 됩니다.

또 다른 가능성은 사용자 애플리케이션 소프트웨어(예: 위 예제의 "cat")가 디바이스 파일에서 데이터를 충분히 빨리 읽지 못하는 경우입니다. 그러면 호스트의 RAM 버퍼가 가득 차게 되고, 이 역시 IP 코어가 FIFO에서 데이터를 읽지 못하게 합니다(IP 코어가 데이터를 쓸 곳이 없기 때문입니다). 결과적으로 오버플로(overflow)가 발생합니다. 사용자 애플리케이션 소프트웨어가 잘못 작성되었기 때문일 수도 있고, 운영 체제와 관련된 다른 이유가 있을 수도 있습니다. 이에 대해서는 아래에서 더 논의합니다.

호스트의 RAM 버퍼 크기는 Xillybus IP 코어에 따라 달라집니다. 예를 들어 xillybus_read_32와 xillybus_write_32의 경우 이 크기는 4MB입니다(데모 번들에 포함된 IP 코어 기준). IP Core Factory에서는 훨씬 더 큰 버퍼를 요청하는 커스텀 IP 코어(custom IP core)를 만들 수도 있습니다.

결론적으로, 오버플로를 막는 것은 IP 코어의 파라미터를 올바르게 선택하는 문제입니다. 무엇보다 IP 코어가 데이터 전송률을 처리할 수 있어야 합니다. 그에 더해 호스트의 RAM 버퍼가 충분히 커야 합니다. 그래야 사용자 애플리케이션 프로그램이 디바이스 파일에서 데이터를 읽지 않는 동안에도 데이터 흐름이 계속 이어질 수 있습니다.

그런데도 FIFO가 full(가득 참) 상태가 된다면, 대개 시스템 설계에 실수가 있는 것입니다. 오버플로의 흔한 원인은 컴퓨터가 해당 데이터 전송률을 처리할 수 있는 능력을 과대평가하는 것입니다.

특히 데이터가 위의 "cat" 명령처럼 디스크의 파일로 기록되는 경우, 최대 데이터 전송률은 생각보다 낮을 수 있습니다. 그 이유는 운영 체제가 대개 큰 디스크 캐시(수 기가바이트일 수도 있음)를 가지고 있기 때문입니다. 디스크 캐시보다 작은 양의 데이터로 디스크 전송 속도를 측정하면 결과가 지나치게 낙관적일 수 있습니다. 운영 체제가 실제로 디스크에 쓰기를 마치기 전에 마친 척하기 때문입니다. 실제로는 데이터가 캐시까지만 도달하고, 실제 디스크 쓰기는 나중에 이루어집니다. 이런 실수는 더 많은 양의 데이터를 처리할 때에만 드러납니다.

CPU 시간 박탈

안타깝게도 오버플로의 가능성은 피할 수 없습니다. 운영 체제(Linux 또는 Windows)는 사용자 공간(user-space) 프로세스의 CPU 사용을 무기한 중단할 수 있습니다. 다시 말해, 데이터를 읽는 컴퓨터 프로그램이 일정 시간 동안 갑자기 멈췄다가 다시 정상 동작을 재개할 수 있습니다. 이 시간에는 아무런 제한이 없습니다. 실시간 운영 체제가 아닌 운영 체제라면 이렇게 프로세스를 임의로 일시 정지시키는 것이 허용됩니다.

그럼에도 불구하고 이런 운영 체제에서 데이터 수집은 여전히 가능합니다. 오랜 시간 동안의 CPU 박탈은 일반적으로 좋지 않은 특성으로 간주되기 때문입니다. 따라서 이런 일시 정지는 대개 짧습니다.

이 일시 정지 동안에도 IP 코어는 호스트의 RAM 버퍼를 계속 채웁니다(DMA 덕분에 프로세서의 개입이 필요하지 않습니다). 컴퓨터 프로그램이 CPU를 되찾으면 쌓여 있던 모든 데이터를 빠르게 소비할 수 있습니다. 대개 10ms의 일시 정지를 보완할 수 있는 RAM 버퍼면 충분합니다. 다만 IP Core Factory에서 커스텀 IP 코어를 만들 때 훨씬 더 큰 버퍼를 요청할 수도 있습니다.

하지만 여전히 일시 정지가 너무 길어질 가능성은 있습니다. 그러면 RAM 버퍼가 가득 차고, 결국 FPGA의 FIFO도 full(가득 참) 상태가 됩니다. 이 오버플로의 결과로 데이터가 손실됩니다. 이런 일은 절대 일어나서는 안 되며, 아마 실제로도 일어나지 않을 것입니다. 그런데 만약 일어난다면?

오버플로 감지

제안하는 해결책은 FIFO가 full(가득 참) 상태가 되면 데이터 스트림을 끝내는 것입니다. 로직은 연속된 데이터의 마지막 요소 바로 뒤에 EOF(end-of-file)를 호스트로 보냅니다. 이제 호스트가 위에서 제안한 대로 "cat" 명령으로 데이터를 소비하는 경우를 생각해 보겠습니다.

$ cat /dev/xillybus_read_32 > capture-file.dat

정상적인 경우 이 명령은 CTRL-C로 중단할 때까지 계속 실행됩니다. 그러나 FPGA에서 FIFO가 full(가득 참) 상태가 되면, 이 명령은 일반 파일 복사를 마친 것처럼 정상적으로 종료됩니다. 출력 파일에는 FIFO가 full(가득 참) 상태가 되기 전에 수집된 모든 데이터가 들어 있습니다.

이 방법을 요약하면, capture-file.dat에 기록된 모든 데이터는 오류가 없고 연속적임이 보장됩니다. CPU 일시 정지 때문에 데이터 수집 시스템이 연속성을 유지하지 못한다면, 결과는 더 짧은 출력 파일이 됩니다. 그러나 파일의 내용은 신뢰할 수 있습니다.

이 해결책을 구현하려면 dualclock_fifo_32의 인스턴스화를 다음 코드로 교체하십시오.

   eof_fifo fifo_32
     (
      .rd_clk(bus_clk),

      .rst(!user_r_read_32_open),
      .rd_en(user_r_read_32_rden),
      .dout(user_r_read_32_data),
      .empty(user_r_read_32_empty),

      .wr_clk(capture_clk),

      .wr_en(capture_en),
      .din(capture_data),
      .full(),
      .eof(user_r_read_32_eof)
      );

eof_fifo의 정의는 별도 페이지에 나와 있습니다.

@user_r_read_32_eof가 이 FIFO의 @eof 포트에 연결된 것에 주목하십시오. 이것은 필요할 때 로직이 호스트로 EOF를 보내는 방식입니다. 또한 이 FIFO의 @full(가득 참) 포트에는 아무것도 연결되지 않은 것도 확인하십시오. 이 신호를 더 이상 모니터링할 필요가 없습니다. FIFO가 full(가득 참)이 되면 그것에 대해 할 수 있는 일이 많지 않습니다. EOF 메커니즘은 모든 유효한 데이터가 소비된 뒤에 호스트가 데이터 흐름을 다시 시작하도록 보장합니다.

데이터 재생

반대 방향은 어떨까요? 다음과 같은 것은 어떨까요?

$ cat playback-data.dat > /dev/xillybus_write_32

이것도 같은 원리로 동작합니다. "cat" 명령은 디스크의 파일을 읽어 디바이스 파일에 씁니다. FPGA에서는 IP 코어가 이 데이터를 FIFO에 씁니다. 애플리케이션 로직은 FIFO에서 데이터를 읽습니다. 방향만 반대일 뿐 동일한 개념입니다.

다음은 호스트의 사용자 애플리케이션 프로그램에서 애플리케이션 로직까지의 데이터 흐름을 나타낸 간소화된 블록 다이어그램입니다.

Simplified data flow diagram for data playback with Xillybus

데이터 수집과 마찬가지로 데이터 손실 위험은 없습니다. IP 코어는 FIFO가 full(가득 참) 상태일 때 FIFO에 쓰지 않습니다. 결과적으로 호스트 RAM의 버퍼도 가득 찰 수 있습니다. 이 경우 호스트의 사용자 애플리케이션 프로그램은 애플리케이션 로직이 FIFO에서 데이터를 충분히 읽을 때까지 잠들며(sleep) 대기합니다.

데이터 수집과 또 다른 공통점은, 사용자 애플리케이션 프로그램이 충분히 빠르게 데이터를 계속 쓰는 한 FIFO가 empty(비어 있음) 상태가 되지 않는다는 것입니다. 이를 보장하려면 앞서 설명한 것과 같은 고려 사항이 적용됩니다. IP 코어의 사양과 사용자 애플리케이션 프로그램이 모두 요구되는 데이터 전송률을 지원해야 합니다.

이 조건이 충족되면 애플리케이션 로직은 데이터가 필요할 때 FIFO에서 데이터를 소비할 수 있습니다. 언더플로(underflow)는 절대 발생하지 않아야 합니다.

비동기 스트림과 동기 스트림

이 주제는 앞의 내용과 직접적인 관련은 없지만, 그래도 간단히 짚고 넘어갈 가치가 있습니다.

데이터 수집 애플리케이션에서 가장 중요한 목표는 연속적인 데이터 흐름을 유지하는 것입니다. 따라서 IP 코어는 FIFO에서 호스트의 RAM 버퍼로 데이터를 가능한 한 빨리 옮깁니다. 호스트의 사용자 애플리케이션 프로그램이 그 순간 데이터를 요청하고 있는지(read() 함수 호출 등을 통해)는 중요하지 않습니다. 디바이스 파일이 열려 있고 FIFO에 데이터가 있는 한 데이터 흐름은 계속됩니다.

이것은 호스트가 FPGA로부터의 데이터 흐름을 제어할 방법이 없다는 뜻입니다(디바이스 파일을 열고 닫거나 애플리케이션 고유의 해결책을 쓰는 경우는 제외). 하지만 대부분의 실제 데이터 수집 애플리케이션에서는 데이터 흐름을 제어할 필요가 없습니다. 디바이스 파일을 여는 것만으로 데이터 흐름이 시작되어도 괜찮습니다. 각 데이터 요소가 FIFO에서 읽힌 정확한 시점은 중요하지 않습니다.

이렇게 동작하는 디바이스 파일을 Xillybus 용어로 비동기 스트림(asynchronous stream)이라고 합니다.

그러나 다른 애플리케이션에서는 데이터가 수집된 시점이 중요합니다. 예를 들어 FPGA의 애플리케이션 로직이 FIFO의 데이터 대신 상태 레지스터의 내용을 보낼 수도 있습니다. 데모 번들에서는 xillybus_mem_8이라는 디바이스 파일로 이 기능을 보여 줍니다. 이 경우 FPGA에서 데이터가 수집되는 시점을 제어하는 것이 매우 중요합니다. 호스트가 디바이스 파일을 읽어 그 순간의 상태 정보를 얻는 것이지, 알 수 없는 과거 시점의 상태를 얻는 것이 아니기 때문입니다.

Xillybus에는 이런 용도를 위한 동기 스트림(synchronous stream)이 있습니다. IP 코어는 항상 FPGA에서 가능한 한 적은 양의 데이터를 수집합니다. 즉, IP 코어는 호스트의 read() 함수 호출 등에 응답해서만 데이터를 수집합니다. 따라서 호스트가 FPGA에서 데이터를 수집하는 시점을 제어합니다.

동기 스트림의 단점은 데이터 흐름에 일시 정지가 생긴다는 것입니다. 이러한 일시 정지의 가장 큰 문제는 데이터 흐름이 잠시 멈추면 FPGA의 FIFO가 full(가득 참) 상태가 될 수 있다는 점입니다. 또한 이런 일시 정지는 데이터 흐름의 효율을 떨어뜨리므로 최대 데이터 전송률도 낮아집니다. 그렇지만 이 두 단점은 데이터 수집 애플리케이션에만 해당됩니다. 그런 애플리케이션은 어차피 비동기 스트림을 사용해야 합니다.

반대 방향의 디바이스 파일에서도 비동기 스트림과 동기 스트림 사이에 차이가 있습니다. 이 방향에서의 차이는 write() 함수 호출의 반환에 있습니다. 비동기 스트림에서는 write()가 데이터를 RAM 버퍼에 쓴 즉시 반환됩니다. 따라서 대부분의 경우 write()는 전혀 잠들지 않습니다. 반면 동기 스트림에서는 write()가 데이터가 FPGA에 전달될 때까지 대기합니다. 이것은 통신 채널을 명령을 보내는 데 사용할 때 중요합니다. 하지만 이것 역시 데이터 수집 애플리케이션에는 좋지 않습니다.

데모 번들에서 /dev/xillybus_mem_8만 동기 스트림입니다. 나머지 네 개의 디바이스 파일은 비동기 스트림입니다.

IP Core Factory에서 동기 스트림과 비동기 스트림 중 무엇을 쓸지는 애플리케이션 선택("use" 드롭다운 메뉴)에 따라 달라집니다. 예를 들어 "Data acquisition / playback"을 선택하면 도구가 비동기 스트림을 만들어 냅니다. "Command and status"를 선택하면 동기 스트림이 생성됩니다. "Autoset internals"를 끄면 이 항목을 직접 선택할 수도 있습니다.

비동기 스트림과 동기 스트림에 대한 자세한 내용은 Linux 프로그래밍 가이드(또는 Windows 프로그래밍 가이드)의 2장을 참조하십시오. IP Core Factory에 대해서는 커스텀 Xillybus IP 코어 정의하기 가이드를 참조하십시오.

요약

Xillybus를 사용하면 간단하면서도 실제로 동작하는 데이터 수집 시스템을 쉽고 빠르게 만들 수 있습니다. 애플리케이션 소프트웨어는 표준 Linux 명령("cat")을 사용하는 것으로 충분합니다. FPGA 쪽에서 Xillybus IP 코어와의 상호 작용은 FIFO에 데이터를 쓰는 것뿐입니다.

Xillybus로 수집한 데이터는 오류가 없고 연속적임이 보장됩니다. 그러나 운영 체제의 특성상 오버플로가 절대 발생하지 않으리라는 보장은 없습니다. 이것이 불가피하므로, 오버플로가 발생하면 이를 확실히 감지하는 것이 최선의 접근 방식입니다. Xillybus는 호스트로 EOF를 보내는 방식으로 이를 위한 간단한 메커니즘을 제공합니다.

이 페이지는 영어 원문을 기계 번역한 것입니다. 의문이 드는 부분이 있으면 원문을 참조하시기 바랍니다.
Copyright © 2021-2026. All rights reserved. (dcc38493)