들어가며
이 페이지에서는 소스 동기식(source-synchronous) 데이터 입력을 다룹니다. 이 기법은 데이터 입력이, 외부 부품이 이 입력들과 함께 생성하는 클록에 동기화되는 방식을 말합니다.
이 방법은 흔히 외부 부품이 원래 그런 방식으로 동작하기 때문에 선택됩니다. 또 다른 좋은 이유로는 데이터의 소스가 FPGA 로부터 물리적으로 멀리 떨어져 있는 경우가 있습니다. FPGA 와 상대편 사이에 케이블이나 커넥터가 있는 경우도 해당됩니다. 예를 들어 픽셀 데이터를 보내는 디지털 카메라 같은 경우입니다.
소스 동기식 클록(source synchronous clock)의 잠재적 어려움은 그 클록이 항상 활성화되어 있지 않을 수 있다는 점입니다. 클록 신호는 헐거운 물리적 연결이나 과도한 노이즈의 영향도 받을 수 있습니다. 또한 클록의 주기가 일정하지 않거나 지터(jitter)가 지나치게 클 가능성도 있습니다. 이런 문제는 데이터, 따라서 클록도 함께, 그 소스가 마이크로프로세서의 I/O 주변 장치일 때 자주 발생합니다.
클록과 데이터의 관계 전반은 별도 페이지에서 다룬다는 점을 참고하시기 바랍니다.
불안정한 클록 다루기
소스 동기식 입력에서 가장 중요한 지침은 클록을 FPGA 내부의 논리 요소에 직접 연결하지 말아야 한다는 점입니다. 대신 FPGA 내부에서 사용하는 클록은 FPGA 내부의 PLL(위상 고정 루프, Phase-Locked Loop)이 생성한 깨끗한 클록이어야 합니다.
외부 클록을 FPGA 내부의 로직에 직접 연결하면 이상한 문제들이 발생할 수 있습니다. 나쁜 클록은 클록 문제처럼 보이지 않는 예상 밖의 동작을 만들어 냅니다. 과도한 지터와 글리치(glitch)는 설계가 안정적으로 동작하도록 보장하는 타이밍 요구사항을 위반할 수 있습니다. 그 결과 Verilog 코드로는 불가능한 상황을 포함해 사실상 어떤 일이든 일어날 수 있습니다. 따라서 문제를 FPGA 설계의 버그로 오인하기 쉽습니다.
클록 문제는 단지 클록 사이클이 손실되고 그 결과 일부 데이터가 빠질 뿐이라고 (잘못) 생각하는 것은 자연스러운 일입니다. 나쁜 클록이 다른 문제를 일으킬 때, 문제를 해결하려는 시도는 대개 설계에서 가장 관련이 있어 보이는 부분에 집중됩니다. 그렇게 시간을 낭비할 수 있습니다.
외부 클록을 로직 패브릭이 직접 사용할 수 있는 유일한 상황은 그 클록이 안정적이고 깨끗하다고 보장되는 경우입니다. FPGA 가 동작을 시작할 때 이 클록이 아직 안정적이지 않다면, 이 문제는 별도 처리가 필요합니다. 클록이 불안정한 동안에는 그 클록에 의존하는 로직에 리셋을 인가해야 합니다.
가능한 전략들
외부 클록에 동기화하는 방법은 크게 네 가지가 있습니다. 아래에서 특별한 순서 없이 설명합니다.
전략 #1: 01 신호 샘플링
이 전략은 소스 동기식 입력을 처리하는 가장 견고한 방법입니다. 외부 클록이 불안정하게 동작할 때, 01 신호 샘플링(01-signal sampling)은 다른 어떤 방법보다 분명한 이점을 가집니다. 다만 이 방법은 데이터 소스의 클록 주파수가 비교적 낮을 때만 유용합니다.
이 방법은 전용 페이지에서 별도로 설명합니다.
전략 #2: PLL 사용
이 전략에서는 외부 클록을 FPGA 의 PLL 입력에 연결합니다. 이 PLL 의 출력 클록을 논리 요소에 사용합니다. PLL 이 잠기지 않았을 때는 이 논리 요소들에 리셋 신호를 인가합니다. 이렇게 하면 논리 요소가 항상 안정적인 클록에 의존하게 됩니다. PLL 의 출력 클록이 불안정하면 리셋에 의해 논리 요소가 비활성화되기 때문입니다.
PLL 을 사용하면 외부 클록을 직접 연결하는 경우보다 타이밍 제약 조건을 달성하기도 쉬워집니다. PLL 이 클록 핀과 FPGA 내부 클록 사이의 지연을 보상해 주기 때문입니다.
하지만 외부 클록의 불완전함 때문에 PLL 출력에 과도한 지터가 생길 수 있습니다. PLL 의 잠금 검출기(lock detector)는 PLL 이 정상적으로 동작한다고 계속 알려 줄 수 있는데, 실제로 PLL 이 만들어 내는 클록은 비정상적으로 노이즈가 많을 수 있습니다. 이 상황에는 간단한 해결책이 없습니다. 한 가지 가능성은 PLL 출력에 의존하는 로직의 타이밍 제약 조건(timing constraints)을 변경하는 것입니다. 예를 들어 타이밍 제약 조건에서 클록 지터 값을, PLL 이 아마 초과하지 않을 값으로 늘려 놓을 수 있습니다. PLL 이 락을 잃으면 그 지터 값을 초과하게 될 것입니다.
이 전략은 시스템 동기 클록 방식(system synchronous clocking)과 유사한 점이 있습니다. 두 경우 모두 외부 클록을 PLL 에 연결하고 그 출력을 FPGA 내부에서 사용합니다. 따라서 타이밍 제약 조건도 시스템 동기 클록(system synchronous clock)과 같은 방식으로 작성합니다.
또한 PLL 은 보통 출력 클록을 시스템 동기 클록에 최적이 되도록 외부 클록과 정렬합니다. 소스 동기 클록(source synchronous clock)에 최적인 정렬은 여기와 약간 다를 수 있습니다. 두 경우 모두 클록들이 완벽하게 정렬되지는 않습니다. 그 대신 클록 에지 사이에 의도적인 작은 시간 차이가 있습니다. 이 시간 차이 덕분에 I/O 레지스터의 타이밍 요구사항을 충족하기가 쉬워집니다. 일부 PLL 은 소스 동기 클록에 맞춰 최적 성능이 되도록 클록을 정렬하게 설정할 수 있습니다.
이 전략은 여기서 소개한 다른 전략들과 비교할 때 구현이 가장 쉽습니다. 비교적 높은 클록 주파수에 적합합니다. 다만 I/O 가 지원할 수 있는 최대치에 가까운 주파수에서는 이 전략이 아마 동작하지 않을 것입니다.
전략 #3: 위상 이동
이 전략은 데이터 전송 속도가 FPGA 가 지원할 수 있는 최대치에 가까울 때 주로 선택됩니다.
이런 데이터 전송 속도에서는 타이밍 요구사항을 보장하는 일반적인 방법이 동작하지 않습니다. 타이밍 제약 조건을 달성하는 것이 불가능해집니다. 하지만 그렇다고 해도 데이터 신호를 안정적으로 샘플링하는 것은 여전히 가능합니다.
타이밍 제약 조건(timing constraints)으로는 계산을 통해 타이밍 요구사항을 보장하려고 합니다. 그런 계산에는 FPGA 제조 공정의 차이 등 몇 가지 불확실한 파라미터가 포함됩니다. 이런 파라미터들을 고려하면, 안정적인 샘플링을 보장하는 타이밍 해가 계산으로는 나오지 않습니다. 데이터 전송 속도가 매우 높으면 이런 불확실성에 쓸 타이밍 여유가 없습니다.
하지만 특정 FPGA 칩 하나에 대해서는 이런 파라미터들이 일정합니다. 따라서 FPGA 가 동작하는 동안 올바른 타이밍을 탐색하면 됩니다. 실제로는 FPGA 내부의 상태 머신(state machine)이 데이터 클록과 샘플링 시점 사이의 지연을 조절합니다. 계산에 의존하는 대신, 적응형 메커니즘으로 최적의 타이밍을 찾는 것입니다. 이 메커니즘을 위상 이동(phase shifting)이라고 합니다.
이 전략은 DDR SDRAM 메모리의 데이터 신호와 함께 자주 사용됩니다. 이 응용에서는 항상 가능한 한 높은 데이터 전송 속도를 달성하는 것이 목표이므로, I/O 포트의 성능을 한계까지 사용합니다. 따라서 데이터 입력을 안정적으로 샘플링하려면 위상 이동이 유일한 방법입니다. DDR 메모리 초기화가 끝나면 메모리에 특별한 데이터 시퀀스를 씁니다. 메모리로 가는 데이터 신호는 소스 동기식 출력(source-synchronous outputs)이므로 타이밍에 어려움이 없습니다. 그런 다음 FPGA 는 DDR 메모리의 같은 부분을 반복해서 읽습니다. 상태 머신이 샘플링 지연을 조금씩 바꾸면서 최적의 타이밍을 찾습니다. 예상되는 입력 데이터는 앞서 써 넣은 것과 같은 시퀀스이므로 미리 알고 있습니다. 따라서 상태 머신은 데이터가 얼마나 안정적인지 쉽게 판단할 수 있고, 최적의 지연도 찾을 수 있습니다.
이 메커니즘의 흥미로운 특징은 DDR 칩이 공급하는 데이터 클록을 무시할 수 있다는 점입니다. DDR 메모리는 FPGA 가 생성하는 클록에 동기화됩니다. 이 클록은 DDR 메모리가 받는 소스 동기식 출력(source-synchronous outputs)의 일부입니다. 따라서 소스 동기식 입력의 데이터 클록 주파수는 FPGA 가 생성하는 클록 주파수와 정확히 같다고 보장됩니다. 그러므로 위상 이동 메커니즘은 데이터와 함께 들어오는 클록 대신 내부 클록에 의존할 수 있습니다. 두 클록 사이에 알 수 없는 지연이 있어도 문제가 되지 않습니다. 상태 머신은 그 지연과 무관하게 최적의 타이밍을 찾기 때문입니다.
실제로 DDR 메모리의 경우에도 이 메커니즘을 구현할 때 보통 이렇게 합니다. DDR 메모리에는 소스 동기식 클록, 즉 데이터 스트로브(data strobe)가 있음에도 불구하고, 일반적인 위상 이동 구현은 이 신호를 무시합니다. 그 이유는 스트로브와 정렬되는 것보다 데이터 신호가 안정적으로 도착하는 것이 더 중요하기 때문입니다.
따라서 위상 이동을 사용하면 데이터 클록이 필요 없어질 수 있습니다. 그 대신 내부 클록의 주파수가 데이터 전송 속도와 정확히 같다고 보장된다면 내부 클록에 의존하면 됩니다.
이 전략에서 타이밍 제약 조건의 목적은 일반 IOB 레지스터의 경우와 같습니다.
전략 #4: 클록 직접 사용
이 전략은 겉보기에는 가장 단순해 보입니다. 외부 클록을 FPGA 내부의 플립플롭에 직접 연결하는 것입니다. 대략 다음과 같습니다.
module top (
input data_clk,
input [7:0] data
);
reg [7:0] data_samp;
always @(posedge data_clk)
begin
data_samp <= data;
[ ... ]
end
위에서 언급했듯이 이 전략은 보통 좋지 않습니다. 가장 큰 이유는 @data_clk 에 글리치가 생기면, 이 클록에 의존하는 모든 로직이 예측할 수 없는 상태가 되기 때문입니다.
외부 클록이 깨끗하고 안정적이라고 보장된다면, 이렇게 외부 클록을 사용하는 것이 합리적일 수 있습니다. 하지만 그런 보장이 있어도 클록 핀에서 플립플롭까지의 지연 때문에 타이밍 요구사항을 달성하기 어려울 수 있습니다. 일부 FPGA 는 이 지연을 줄이기 위한 특수 클록 리소스를 갖추고 있습니다. 이 리소스를 사용하려면 전용 클록 입력 핀을 쓰고, I/O 포트를 FPGA 의 특정 영역으로 제한해야 할 수도 있습니다.
클록을 직접 사용할 때 타이밍 제약 조건은 시스템 동기 클록(system synchronous clock)과 같은 방식으로 작성합니다.
이 전략에 대한 단순한 대안은 위에서 제안한 대로 PLL 을 사용하는 것입니다. 데이터 클록이 안정적이지 않다면 01 신호 샘플링을 고려해야 합니다.
요약
이 페이지에서 01 신호 샘플링을 첫 번째로 소개하고, 그 전략을 별도 페이지에서 설명한 것은 우연이 아닙니다. 데이터 전송 속도가 이 방법이 처리할 수 있는 범위를 넘지 않는다면, 이 방법이 가장 권장되기 때문입니다.
다른 전략을 고려한다면 데이터 클록의 안정성에 주의를 기울이는 것이 중요합니다. 클록이 허용된 동작 범위, 즉 클록 주기와 최대 지터의 규격에서 벗어나면, 관련 로직이 영구적이고 복구 불가능한 오동작을 일으킬 수 있습니다. 로직을 정상 동작으로 되돌릴 수 있는 방법은 리셋뿐입니다.
PLL 로 안정적인 클록을 생성하면 상황이 크게 개선됩니다. PLL 의 잠금 검출기가 잠겼다고 알려 주는 한 PLL 의 출력은 신뢰할 수 있습니다. 그렇지 않은 경우에는 이 로직에 리셋을 인가해야 합니다.
