이 페이지는 timing에 대한 일련의 페이지 에 속합니다. 이전 페이지에서는 timing 계산에 대한 이론을 설명하고 clock period constraint에 대해 논의했으며 timing closure를 소개했습니다. 하지만 올바르게 설정하려고 했지만 timing 문제가 있는 경우에는 어떻게 해야 합니까? 이 페이지는 그 질문에 답하려고 시도합니다.
소개
이전 페이지 에서 나는 timing closure 문제를 해결하는 단일 방법이 없다는 것을 당신에게 확신시키려고 노력했습니다. critical path에 초점을 맞추는 것이 맞을 때도 있고 그렇지 않을 때도 있습니다. 도구 설정을 간단히 변경하여 문제를 쉽게 해결할 수 있는 경우도 있고 그보다 훨씬 어려운 경우도 있습니다. 문제의 근본 원인에 도달하기 위해 당신이 가진 모든 경험과 지혜를 활용하는 것 외에 다른 것은 없습니다. 체크리스트로 timing closure를 요약할 수 있는 방법은 없습니다.
그럼에도 불구하고 가능한 전략 목록을 갖는 것이 종종 도움이 됩니다. 그래서 이 페이지에서는 timing에 문제가 생겼을 때 생각해 볼 가치가 있는 몇 가지 주제를 모았습니다. 해결해야 할 특정 timing 문제가 있기 때문에 이 글을 읽는다면 이러한 아이디어 중 하나가 해결책으로 이어질 가능성이 있습니다. 그러나 귀하의 솔루션이 여기에 설명되어 있다고 기대하지 마십시오.
또한 이 일련의 페이지는 여기서 끝나지 않습니다. 동기 부여를 위해 다른 많은 주제보다 먼저 timing closure 에 대해 논의하기로 했습니다. 그러나 나중에 나오는 페이지의 정보도 관련이 있습니다.
같은 이유로 I/O timing constraints 에 대한 논의는 나중으로 미룬다. 당분간은 FPGA내부에서 시작하고 끝나는 paths 에 집중하고 있습니다.
따라서 timing closure와 관련하여 고려해야 할 몇 가지 아이디어가 있습니다.
아이디어 #1: logic design수정
이것은 항상 가장 덜 매력적인 솔루션입니다. 이는 특히 design이 이미 제대로 작동하는 것으로 알려진 경우에 해당됩니다. 작동하는 것을 변경하고 싶지 않습니다. 그러나 종종 문제의 근본적인 원인은 Verilog 코드가 필요한 성능에 대해 충분히 잘 작성되지 않았기 때문입니다. logic design 의 변화는 계속되는 어려움에 직면하는 대신 문제를 완전히 해결합니다.
빠른 logic 작성을 위한 몇 가지 제안이 이전 페이지 에 있습니다. 그리고 이것을 반복할 가치가 있습니다: 개발 과정에서 항상 timing을 염두에 두십시오. 처음부터 Verilog 코드를 제대로 작성하는 것보다 timing 문제를 해결하는 것이 훨씬 어렵습니다.
아이디어 #2: fan-out줄이기
net 의 fan-out가 높을 때 propagation delay은 두 가지 주요 이유 때문에 증가합니다.
- 물리적 와이어의 capacitance가 더 크기 때문에 logic state를 변경하려면 더 많은 전하가 필요합니다.
- 도구가 net의 모든 대상에 대해 delay이 낮은 routing을 찾는 것이 더 어려워집니다. 이러한 대상은 logic fabric에 흩어져 있는 logic elements 입니다. 따라서 대상이 많을수록 모든 nets가 낮은 delay을 갖도록 timing을 최적화하기가 더 어려워집니다.
design에 synchronous reset을 쓴다면 이 signal은 fan-out가 높을 가능성이 높다. 이 항목은 별도의 페이지 에서 설명합니다.
그러나 많은 logic elements 에 도달하는 모든 signal은 높은 fan-out로 인해 잠재적으로 timing 문제를 일으킬 수 있습니다. 때때로 이 높은 fan-out는 명백하고(예: clock enable signals) 때때로 높은 fan-out를 기대하기 쉽지 않습니다. FPGA tools는 일반적으로 가장 높은 fan-outs를 가진 nets를 나열하여 도움이 될 수 있습니다.
fan-out를 낮게 유지하는 두 가지 방법이 있습니다.
- FPGA tools는 fan-out에 한계가 있습니다. 이 한계에 도달하면 도구는 net의 소스인 register를 복제합니다. synthesis constraints덕분에 각 register 에 대한 이 한계 값을 변경할 수 있습니다. synthesizer의 매개변수를 변경하여 글로벌 한계를 변경할 수도 있습니다.
- Verilog 코드 편집: fan-out가 높은 register를 여러 registers로 명시적으로 복제합니다.
분명히 두 방법 모두 동일한 결과에 도달합니다. fan-out가 높은 register는 여러 registers로 복제됩니다. 따라서 이것이 도구에 의해 자동으로 수행될 수 있다면(첫 번째 방법 사용) 왜 수동으로 수행해야 합니까(두 번째 방법에서처럼)?
두 번째 방법은 더 많은 노력이 필요하지만 한 가지 중요한 이점이 있습니다. 합리적인 방식으로 register를 복제하는 것이 가능합니다. 목표는 fan-out를 줄이는 것만이 아니라는 점을 명심하십시오. 각 register 의 output이 logic fabric의 작은 영역에 배치된 logic elements 에 분산되는 것도 중요합니다. 그렇지 않으면 물리적 거리로 인해 결과가 routing delays 로 커집니다. 따라서 Verilog 코드가 fan-out를 염두에 두고 작성되면 logic elements간의 짧은 연결을 보장할 수 있습니다. 다른 페이지에서 synchronous reset signal 에 대해 설명합니다.
반면, FPGA tools가 registers를 복제하는 역할을 한다면, 그 결과는 그렇게 효율적이지 않을 수 있습니다. routing delay 의 개선은 각 복제된 register가 어떻게 사용되는지 결정하는 알고리즘에 따라 달라집니다. 결과의 품질은 어떤 FPGA tool이 사용되는지에 따라 달라집니다.
기본적으로 synthesizer가 정확히 동일하게 작동하는 두 개의 registers를 감지하면 이러한 registers는 자동으로 하나의 register로 병합됩니다. 따라서 Verilog 코드에서 register가 복제되면 synthesizer는 모든 복제본을 하나의 register로 대체합니다. 이는 이러한 동등한 registers가 다른 modules에 정의된 경우에도 종종 적용됩니다. 이러한 병합을 방지하려면 이 기능을 명시적으로 비활성화해야 합니다. 이를 수행하는 일반적인 방법은 synthesis attributes를 사용하는 것입니다(예: "dont_touch", "dont_merge" 또는 "keep").
아이디어 #3: floorplanning확인
기본적으로 logic fabric 에 logic elements를 배치하는 것은 FPGA tools (더 구체적으로는 placer)에 의해 자동으로 결정됩니다. 그러나 특정 logic elements를 FPGA의 특정 영역에 배치하도록 요청할 수 있습니다. 특정 logic element를 특정 위치에 배치하도록 요청할 수도 있습니다. 이러한 종류의 요청을 floorplanning 라고 합니다. 이러한 요청은 placement constraints에 의해 이루어지며, 이는 종종 timing constraints와 유사한 구문을 가진 Tcl commands 입니다.
대부분의 경우 placement constraints는 timing constraints를 달성하기 어렵게 만듭니다. 첫 번째 이유는 분명합니다. placer의 선택이 제한되면 결과는 제한이 없는 것보다 나쁠 수 있습니다. 그러나 이에 대한 보다 구체적인 이유는 다음과 같습니다.
- Floorplanning은 많은 logic을 FPGA의 작은 영역에 강제로 넣을 수 있습니다. 이로 인해 routing congestion이 발생할 수 있습니다. 해당 영역 내부의 logic elements 에는 평소보다 더 많은 routing이 필요합니다. 결과적으로 router는 최적이 아닌 리소스를 사용해야 합니다. 이로 인해 routing delay이 차선책이 되고 요구 사항을 충족하지 못할 수 있습니다.
- Placement constraints는 logic elements를 서로 가깝게 배치하는 것이 더 나을지라도 강제로 멀리 떨어지게 만들 수 있습니다. 따라서 routing delay을 줄이기 위해 placer가 logic elements를 이동하는 것이 방지됩니다.
- Floorplanning은 routing에 장애가 되는 영역을 만들 수 있습니다. 예를 들어 floorplanning이 logic elements로 밀집된 영역을 만들었다고 가정합니다. 다른 logic 의 routing은 이 혼잡한 영역에 들어가지 않도록 강제될 수 있습니다. 결과적으로 이 routing은 더 먼 거리를 이동해야 하므로 routing delay이 더 커집니다.
대부분의 designs에서는 floorplanning을 피하고 placer가 logic elements의 배치를 최적화할 수 있는 자유를 주는 것이 최선입니다. 그러나 placement constraints가 일반적으로 사용되는 경우가 있습니다. 예를 들면 다음과 같습니다.
- IP block은 생성하는 logic elements 용 placement constraints를 포함할 수 있습니다. 예를 들어 PCIe 인터페이스를 구현하는 IP는 종종 가장 중요한 구성 요소의 위치를 결정하는 placement constraints를 생성합니다. transceivers, PLLs 및 전용 PCIe hard IP. 이런 종류의 placement constraints는 일반적으로 필요하고 정확합니다.
- FPGA는 지역으로 나눌 수 있으므로 각 지역에는 특정 modules만 포함됩니다. 이것이 floorplanning의 원래 의미입니다. 이와 같이 FPGA를 분할하는 동기는 프로젝트의 여러 팀이 독립적으로 작업할 수 있도록 하기 위한 것일 수 있습니다.
- Partial Reconfiguration 는 작동하는 동안 bitstream을 FPGA 로 로드하여 FPGA 의 일부만 영향을 받도록 하는 기능입니다. 이것이 작동하려면 floorplanning이 필요합니다. FPGA는 새로운 bitstream이 도착했을 때 그대로 남아 있는 영역과 이 bitstream에 의해 업데이트된 영역으로 나뉩니다.
timing closure의 목적을 위해 문제의 잠재적 원인으로 placement constraints를 인식하는 것이 중요합니다. 특히 routing delays가 예상보다 큰 경우 근본 원인은 placer가 logic elements의 위치를 최적화하지 못하는 것일 수 있습니다. floorplanning은 배치가 제한된 logic elements 와 관련이 없는 paths 에 부정적인 영향을 미칠 수 있음을 기억하십시오.
아이디어 #4: timing constraints확인
timing constraints는 FPGA의 안정적인 작동에 매우 중요합니다. 따라서 프로젝트의 implementation 이전에 검증되어야 합니다. 그러나 때때로 timing constraints는 어쨌든 잘못된 것으로 판명됩니다. 실수는 timing closure 프로세스 중에 명백해질 수 있습니다. 이런 일이 발생해서는 안 되지만 발생하면 문제를 해결하는 것이 좋습니다.
timing constraints확인에 대한 전체 페이지가 있습니다. 여기서는 timing closure에서 문제를 일으킬 수 있는 두 가지 일반적인 실수에 대해서만 설명하겠습니다.
- unrelated clocks사이의 paths 에서 timing constraints를 불필요하게 시행합니다.
- asynchronous resets에서 timing constraints를 불필요하게 시행합니다.
먼저 unrelated clocks에 대해 알아보겠습니다. clock domain crossings 에 대한 주제는 이전에 이미 논의되었습니다 . timing constraints가 어떤 clocks가 related clocks 인지 아닌지를 반영하는 것이 중요한 몇 가지 이유가 있습니다. 가장 중요한 이유는 logic의 적절한 작동을 보장하기 위한 것이지만 timing closure 도 영향을 받습니다. 한 쌍의 clocks가 도구에 의해 불필요하게 related clocks 로 취급되면 이 두 clocks사이의 paths 에 timing 요구 사항이 불필요하게 적용됩니다. 결과적으로 도구는 이러한 노력이 실제로 필요한 paths를 희생시키면서 이러한 paths 에 대한 노력을 낭비합니다.
이 문제를 해결하는 timing constraint는 이 페이지의 뒷부분 에서 설명합니다.
asynchronous resets관련: 대부분의 경우 asynchronous reset에서 끝나는 path 에서 timing constraints를 적용해야 합니다. 그러나 때로는 이것이 필요하지 않습니다. 예를 들어, reset이 비활성으로 변경될 때 clock이 활성화되지 않는다는 보장이 있는 경우입니다. 또 다른 가능성은 asynchronous reset을 수신하는 flip-flop 에 clock domain crossing와 마찬가지로 timing violations에 대한 보호 메커니즘이 있는 경우입니다. 이러한 상황에서 timing 요구 사항을 충족하기 위한 도구의 노력은 무의미합니다.
이러한 종류의 문제로 인해 timing closure를 달성하기 어렵다는 사실을 깨닫는 것은 어려울 수 있습니다. 때때로 critical path는 불필요하게 related clocks로 취급되는 두 개의 clocks 와 아무 관련이 없습니다. asynchronous reset이 도구의 노력을 돌리면 인식하기가 훨씬 더 어렵습니다. 이런 상황에서 timing을 개선하기 위해 critical path 에 집중하려는 시도는 무의미할 수 있습니다.
물론 timing constraints는 다양한 방식으로 잘못될 수 있습니다. 여기에 설명된 상황은 하나의 가능성일 뿐입니다. 따라서 timing 의 문제는 timing constraints를 전반적으로 검토할 수 있는 좋은 기회가 될 수 있습니다.
아이디어 #5: 다시 시도하세요
place and route 프로세스는 logic elements를 logic fabric에 임의로 흩뿌리는 것으로 시작합니다. 그런 다음 도구는 반복적인 시도를 통해 timing을 개선하려고 시도합니다. 따라서 이 프로세스의 성공은 어느 정도의 운에 달려 있습니다. 이유에 대한 논리적 설명이 없는 경우에도 place and route 알고리즘의 약간 다른 동작이 더 나은 결과를 얻을 수 있습니다.
따라서 timing constraints가 실패하고 음수 slack이 상대적으로 작은 경우(전체 delay중 10-20% 정도) 다시 시도하면 충분할 수 있습니다. 그러나 implementation을 다시 실행하는 것만으로는 소용이 없을 것입니다. 대부분의 FPGA 소프트웨어는 동일한 input로 실행될 때 결과를 정확하게 반복하도록 설계되었습니다. 따라서 다시 실행하기 전에 무언가를 변경해야 합니다. 이 변경은 critical path와 관련이 없어도 됩니다. 요점은 이전 implementation의 정확한 반복을 피하는 것입니다.
예를 들어, Vivado 에서 각 run 에는 "strategy"라고 하는 attribute이 있습니다. 이름에서 알 수 있듯이, 이 attribute은 implementation동안 도구가 적용하는 전략을 제어합니다. 이 attribute을 변경하면 다음 implementation이 이전 implementation 와 동일하지 않게 됩니다. 또한 특정 logic design와 관련하여 다른 전략이 더 합리적일 수도 있습니다.
모든 FPGA tools는 implementation 프로세스의 매개변수를 수정하는 유사한 가능성을 제공합니다. design의 목표를 충족하기 위해 더 높은 수준의 노력을 요청하는 것이 종종 가능합니다. 때로는 더 높은 노력이 정말 필요하지만, 도구가 다른 작업을 수행하기 때문에 더 높은 수준의 노력을 요청하는 것이 도움이 되는 경우가 많습니다.
반복을 피하는 또 다른 방법은 Verilog 코드를 변경하는 것입니다. 다시 한 번, 변경 사항이 critical path와 관련될 필요는 없습니다. 때로는 이전 제품과 충분히 다른 implementation을 얻기 위해 register 의 이름을 변경하는 것으로 충분합니다.
이 아이디어는 극단으로 가져갈 수 있습니다. implementation을 여러 대의 컴퓨터에서 병렬로 실행하여 각 implementation 의 매개변수가 조금씩 다를 수 있습니다. 이것은 FPGA 의 가격이 중요할 때 의미가 있습니다. 이 시나리오에서는 더 저렴한 FPGA에서 timing constraints가 달성되도록 컴퓨터를 열심히 작동시키는 것이 좋습니다.
요약하면 이 방법은 대부분 운에 의존합니다. 기대치는 다음과 같아야 합니다. 도구가 때때로 timing constraints를 달성하지 못하는 경우에만 다시 시도하면 도움이 됩니다. 그러나 가능하면 다른 방법으로 timing을 개선하는 것이 항상 좋습니다.
아이디어 #6: FPGA가 꽉 찼습니까?
FPGA의 필 레벨이 약 70%에 도달하면 timing constraints 의 문제가 시작되는 것은 매우 일반적입니다. 이런 일이 발생하는 데는 세 가지 주요 이유가 있습니다.
- logic elements는 FPGA의 logic fabric에 더 밀집되어 있습니다. 따라서 timing을 개선할 수 있는 placer의 자유는 logic elements를 한 위치에서 다른 위치로 이동하는 것이 더 어렵기 때문에 더 제한적입니다. 이것은 더 큰 routing delays로 이어집니다.
- FPGA 의 배선량(routing resources)은 제한되어 있습니다. FPGA가 상대적으로 비어 있는 한 router는 logic elements사이에서 가장 적합한 경로를 선택할 수 있습니다. 더 많은 logic이 추가되면 최적이 아닌 선택은 더 큰 routing delays로 이어집니다.
- FPGA 의 특수 logic elements가 소진될 수 있습니다. 예를 들어 대부분의 FPGA 에는 block RAMs 와 산술 곱셈 전용 구성 요소가 있습니다. 이러한 리소스가 부족하면 도구는 간단한 logic elements (slices)로 필요한 기능을 구현합니다. 이것은 종종 많은 수의 logic levels로 이어지고 따라서 증가된 logic delay로 이어집니다. 특수 logic elements대신 slices를 사용하기 때문에 FPGA의 필 레벨도 예상보다 빠르게 증가하기 시작할 수 있습니다.
위에 주어진 세 가지 이유 중 세 번째 이유만이 해결책을 가지고 있습니다. 예를 들어 FPGA의 block RAMs 및 기타 유사한 리소스를 사용하는 logic을 수동으로 결정하는 것이 도움이 될 수 있습니다. 이 외에 전체 FPGA 에 대한 유일한 솔루션은 더 큰 것을 선택하는 것입니다. 그러나 이것이 항상 가능한 것은 아닙니다. 따라서 더 많은 logic이 추가될수록 timing closure가 더 단단해질 것이라고 예상하는 것이 중요합니다.
아이디어 #7: 다른 FPGA가 필요할까요?
때로는 FPGA가 작업에 적합하지 않다는 것을 인정할 수밖에 없습니다. 동일한 FPGA를 더 높은 speed grade와 함께 사용할 수 있는 경우 솔루션은 더 빠른 FPGA로 업그레이드하기로 결정하는 것일 수 있습니다. 이 결정은 물론 구매 비용을 증가시키지만 예상하지 못한 또 다른 결과를 초래할 수 있습니다. 더 높은 speed grade에 FPGAs가 부족할 수 있습니다. 이러한 더 빠른 FPGAs가 특정 시간에 풍부하더라도 일반적으로 더 빠른 FPGAs는 수요가 공급을 초과하면 가장 먼저 시장에서 사라집니다.
이것은 매우 자연스러운 일입니다. 더 빠른 FPGAs는 테스트를 더 잘 통과한 제품이며 더 느린 FPGAs대신 항상 사용할 수 있습니다. 때로는 제조업체가 더 빠른 FPGAs를 생산하지 못하고 때로는 함께 작동할 수 있는 모든 것을 구매하는 대규모 소비자가 있습니다.
따라서 오랫동안 생산을 목적으로 하는 제품을 작업하는 경우 항상 design 와 함께 사용할 수 있는 가장 낮은 speed grade를 선호하십시오. 돈이 문제가 아닌 경우에도 마찬가지입니다.
완전히 다른 유형의 업그레이드는 최신 FPGA 제품군에서 FPGA를 선택하는 것입니다. 또는 다른 공급업체의 FPGA를 선택할 수도 있습니다. 이러한 변화는 보다 과감하지만 프로젝트가 초기 단계에 있는 경우 고려해야 합니다. 우리 모두는 익숙한 도구와 구성 요소를 좋아하는 경향이 있습니다. 하지만 모든 것이 너무 익숙해지면 대안을 찾아보기에 좋은 때입니다.
그럼에도 불구하고, 경험이 풍부한 FPGA engineers는 최신의 완전히 새로운 FPGA 와 그 도구를 선택하는 것이 위험한 도박이라는 것을 알고 있습니다. 하지만 종종 현재의 FPGA선택보다 훨씬 나은 상당히 확립된 대안이 있습니다. 그런 상황에서는 컴포트 존을 벗어나 새로운 것을 시도하는 것이 낫습니다.
아이디어 #8: 온도 범위 줄이기
이 가능성을 거의 마지막에 두는 이유가 있습니다. 이것은 그들 모두의 추악한 솔루션입니다. 그러나 때로는 다른 선택이 없습니다.
기본적으로 도구의 timing constraints 강제 실행은 FPGA가 datasheet에 정의된 전체 온도 범위에서 안정적으로 작동하도록 보장합니다. 일부 FPGA tools는 프로젝트에 대해 다른 온도 범위를 선택할 수 있도록 합니다(예: Quartus 에는 이 목적을 위해 "MAX_CORE_JUNCTION_TEMP"라는 attribute이 있음). 이는 도구에 전체 온도 범위를 지원할 필요가 없음을 알리는 데 사용할 수 있습니다.
일반적으로 FPGAs 에서 logic elements 의 delays는 온도가 올라갈수록 증가합니다. 최대 온도가 감소하면 timing 계산에서 delays 의 값이 더 작아집니다. 이를 통해 도구는 tsetup 요구 사항을 보다 쉽게 달성할 수 있습니다. 때때로 이것은 도구가 timing constraints를 달성하도록 하는 유일한 방법입니다.
이 방법을 사용할 때의 위험을 이해하는 것이 중요합니다. 특히 junction temperature에 대해 이야기하고 있다는 점에 유의하십시오. 즉, 이것은 FPGA의 silicon 에 있는 온도입니다. 이것은 주변 온도가 아닙니다.
따라서 최대 온도가 85°C라고 해서 FPGA가 해당 온도의 오븐에서 작동한다는 의미는 아닙니다. 이 온도는 특히 FPGA에 heatsink이 없는 경우 실온(25°C)에서도 도달할 수 있습니다. junction 의 온도와 주변 온도 사이에는 항상 차이가 있습니다. 이 차이의 크기는 FPGA 및 냉각 솔루션의 전력 소비에 따라 다릅니다.
상용 제품에서 작업하는 경우 FPGA 의 주변 온도가 실온보다 훨씬 더 높을 수 있다는 점에 유의하십시오. 특히 FPGA가 공기 흐름이 좋지 않은 상자 안에 있으면 상자 내부 온도가 상자 외부 온도보다 훨씬 높아질 수 있습니다. 설상가상으로 대부분의 전자 제품은 0°C 와 40°C 사이의 온도에서 작동할 것으로 예상됩니다(대략 이 수치는 제품마다 다릅니다). 최종 제품이 가장 높은 온도에서 테스트되고 FPGA가 제품 인클로저 내부에 있을 때 junction의 온도는 얼마입니까? 그것이 물어볼 질문입니다. timing 계산은 해당 온도(또는 그 이상)를 기반으로 해야 합니다.
즉, timing constraints를 달성하기 위해 최대 온도를 낮추고 실험실에서 모든 것이 잘 작동한다면 그것은 아무 의미가 없습니다. timing constraints와 관련하여 FPGA design이 실험실에서 작동한다는 것은 항상 아무 의미가 없음을 기억하십시오. 그러나 최대 온도를 낮추는 것은 이와 관련하여 훨씬 더 나쁩니다. 무분별하게 온도 범위를 좁히면 실제 문제가 발생할 수 있습니다. 가장 높은 온도에서 이루어지는 생산 전 제품 최종 테스트는 실패할 수 있으며 온도 범위가 보정되면 timing constraints를 달성할 수 없습니다. 이 문제를 해결하는 유일한 방법은 처음부터 FPGA design을 다시 작성하는 것입니다.
따라서 timing closure를 위해 온도 범위를 변경하기 전에 안전한지 확인하십시오. 가능한 모든 작업 조건에서 junction 의 온도 범위를 엄격하게 평가하십시오.
implementation의 매개변수를 변경하여 기본값 이상으로 온도 범위를 확장하는 것은 불가능합니다. 도구의 기본 온도 범위는 항상 datasheet에 명시된 것과 동일합니다. 따라서 이 기본 온도 범위를 넘어서는 FPGA 의 안정적인 작동을 보장할 수 없습니다.
아이디어 #9: 정렬되지 않은 related clocks
이것은 다소 난해한 상황이며 이해하기 약간 어렵습니다. 그래서 이 주제를 마지막에 두었습니다.
정렬되지 않은 두 related clocks 사이에 clock domain crossing이 있다고 가정합니다. 즉, 두 개의 clocks는 동일한 reference clock에서 파생되지만 이러한 clocks간에는 clock skew를 제어할 수 있는 메커니즘이 없습니다.
결과적으로 도구가 이 두 clocks사이에서 paths 의 timing 요구 사항을 충족하기가 더 어려워집니다. 가능한 두 가지 유형의 어려움이 있습니다. ( tsetup 와 thold 는 앞에서 설명한 것을 기억하십시오.)
- clock skew로 인해 clock이 첫 번째 flip-flop 에 나중에 도착하는 경우: 따라서 다음 clock edge가 두 번째 flip-flop에 도달할 때까지 시간이 더 짧습니다. 따라서 tsetup 요구 사항을 충족하기가 더 어렵습니다.
- clock skew로 인해 clock이 첫 번째 flip-flop 보다 먼저 도착하는 경우: 따라서 첫 번째 flip-flop은 동일한 clock edge가 두 번째 flip-flop에 도달하기 전에 output을 업데이트합니다. 결과적으로 두 번째 flip-flop에서 thold 요구 사항을 위반할 수 있습니다. 도구는 path 의 routing을 인위적으로 길게 만들어 이를 방지합니다. 이로 인해 tsetup 요구 사항을 충족하지 못할 수 있습니다. 또한 routing 리소스의 낭비이기도 합니다.
이러한 어려움을 극복하기 위해 도구가 평소보다 더 열심히 작동해야 하는 경우 다른 paths를 최적화하는 비용이 발생할 수 있다는 점에 유의하는 것이 중요합니다.
그러나 정렬되지 않은 related clocks는 오류가 아니며 때로는 불가피합니다. 이 상황은 도구가 더 열심히 작동해야 함을 의미합니다. timing constraints가 달성되면 design에는 문제가 없습니다. 그러나 합리적인 노력으로 가능한 한 피해야 합니다.
위의 "아이디어 #5"에서 언급한 실수는 두 가지 실수가 도구를 불필요하게 힘들게 만들고 둘 다 clock domain crossing와 관련이 있음에도 불구하고 다릅니다.
related clocks가 정렬되지 않은 상황을 해결하는 가장 좋은 솔루션은 이러한 clocks를 정렬하는 것입니다. 이는 일반적으로 PLL을 추가하거나 기존 PLL에 clock output을 추가하여 수행됩니다. 목표는 문제의 두 clocks가 동일한 PLL의 outputs 라는 것입니다.
또 다른 가능한 솔루션은 clocks를 unrelated clocks로 취급하는 것입니다. 이를 위해서는 logic design 자체와 timing constraints의 변경이 필요합니다. 이것이 너무 어렵지 않다면 노력할 가치가 있습니다. 나중에 이 항목에 대해 자세히 설명합니다 .
이제 정렬되지 않은 related clocks 사이의 clock domain crossing 예를 살펴보겠습니다.
wire pll_clk;
reg [24:0] result;
reg [11:0] x, y, x1, y1;
clk_wiz_0 pll_i
(.clk_in1(clk),
.clk_out1(pll_clk));
always @(posedge clk)
begin
x1 <= x;
y1 <= y;
end
always @(posedge pll_clk)
result <= x1 * y1;
PLL (clk_wiz_0)가 있습니다. 이 PLL은 @clk을 reference clock로 사용하며 주파수는 250 MHz입니다. 이전 페이지 상단의 예에 표시된 것과 동일한 PLL 입니다. @pll_clk 의 주파수는 125 MHz입니다.
이 예제에서 중요한 부분은 두 related clocks (@clk 및 @pll_clk) 사이의 clock domain crossing 입니다. PLL은 @pll_clk 만 생성하므로 이 두 clocks는 정렬되지 않습니다. 따라서 paths 에서 @result 까지( @x1 및 @y1에서) clock skew가 있습니다. 이 clock skew에도 불구하고 clocks는 여전히 related clocks가 며 도구는 timing 요구 사항을 충족하려고 합니다.
@clk을 사용하는 유일한 이유가 250 MHz 주파수의 clock이 필요한 것이라면 올바른 솔루션은 PLL로 다른 clock을 생성하는 것입니다. reference clock와 동일한 주파수로 clock을 생산하는 것은 자원 낭비가 아닙니다. 반대로 이렇게 하면 도구의 노력이 많이 절약됩니다. 예에서와 같이 @clk을 직접 사용하는 좋은 이유는 단 하나뿐입니다. @clk을 사용하는 logic이 PLL이 사용 가능한 clocks를 생성하기 전에 작동해야 하는 경우.
Vivado 에서 생성된 timing report는 다음과 같습니다. 이 특정한 경우에는 tsetup 요구 사항에만 문제가 있었습니다.
Slack (VIOLATED) : -1.456ns (required time - arrival time) Source: x1_reg[7]/C (rising edge-triggered cell FDRE clocked by clk {rise@0.000ns fall@2.000ns period=4.000ns}) Destination: result_reg/DSP_OUTPUT_INST/ALU_OUT[10] (rising edge-triggered cell DSP_OUTPUT clocked by clk_out1_clk_wiz_0 {rise@0.000ns fall@4.000ns period=8.000ns}) Path Group: clk_out1_clk_wiz_0 Path Type: Setup (Max at Slow Process Corner) Requirement: 4.000ns (clk_out1_clk_wiz_0 rise@8.000ns - clk rise@4.000ns) Data Path Delay: 3.012ns (logic 2.677ns (88.878%) route 0.335ns (11.122%)) Logic Levels: 5 (DSP_A_B_DATA=1 DSP_ALU=1 DSP_M_DATA=1 DSP_MULTIPLIER=1 DSP_PREADD_DATA=1) Clock Path Skew: -2.192ns (DCD - SCD + CPR) Destination Clock Delay (DCD): 0.998ns = ( 8.998 - 8.000 ) Source Clock Delay (SCD): 3.202ns = ( 7.202 - 4.000 ) Clock Pessimism Removal (CPR): 0.012ns Clock Uncertainty: 0.148ns ((TSJ^2 + DJ^2)^1/2) / 2 + PE Total System Jitter (TSJ): 0.071ns Discrete Jitter (DJ): 0.103ns Phase Error (PE): 0.086ns Clock Net Delay (Source): 1.414ns (routing 0.002ns, distribution 1.412ns) Clock Net Delay (Destination): 1.184ns (routing 0.002ns, distribution 1.182ns) Clock Domain Crossing: Inter clock paths are considered valid unless explicitly excluded by timing constraints such as set_clock_groups or set_false_path. Location Delay type Incr(ns) Path(ns) Netlist Resource(s) ------------------------------------------------------------------- ------------------- (clock clk rise edge) 4.000 4.000 r AG12 0.000 4.000 r clk (IN) net (fo=0) 0.000 4.000 clk_IBUF_inst/I AG12 INBUF (Prop_INBUF_HRIO_PAD_O) 0.738 4.738 r clk_IBUF_inst/INBUF_INST/O net (fo=1, routed) 0.105 4.843 clk_IBUF_inst/OUT AG12 IBUFCTRL (Prop_IBUFCTRL_HRIO_I_O) 0.049 4.892 r clk_IBUF_inst/IBUFCTRL_INST/O net (fo=1, routed) 0.795 5.687 clk_IBUF BUFGCE_X1Y2 BUFGCE (Prop_BUFCE_BUFGCE_I_O) 0.101 5.788 r clk_IBUF_BUFG_inst/O X2Y0 (CLOCK_ROOT) net (fo=62, routed) 1.414 7.202 clk_IBUF_BUFGCE SLICE_X52Y45 FDRE r x1_reg[7]/C ------------------------------------------------------------------- ------------------- SLICE_X52Y45 FDRE (Prop_HFF_SLICEM_C_Q) 0.138 7.340 f x1_reg[7]/Q net (fo=1, routed) 0.335 7.675 result_reg/A[7] DSP48E2_X8Y18 DSP_A_B_DATA (Prop_DSP_A_B_DATA_DSP48E2_A[7]_A2_DATA[7]) 0.396 8.071 r result_reg/DSP_A_B_DATA_INST/A2_DATA[7] net (fo=1, routed) 0.000 8.071 result_reg/DSP_A_B_DATA.A2_DATA<7> DSP48E2_X8Y18 DSP_PREADD_DATA (Prop_DSP_PREADD_DATA_DSP48E2_A2_DATA[7]_A2A1[7]) 0.182 8.253 r result_reg/DSP_PREADD_DATA_INST/A2A1[7] net (fo=1, routed) 0.000 8.253 result_reg/DSP_PREADD_DATA.A2A1<7> DSP48E2_X8Y18 DSP_MULTIPLIER (Prop_DSP_MULTIPLIER_DSP48E2_A2A1[7]_U[10]) 0.994 9.247 f result_reg/DSP_MULTIPLIER_INST/U[10] net (fo=1, routed) 0.000 9.247 result_reg/DSP_MULTIPLIER.U<10> DSP48E2_X8Y18 DSP_M_DATA (Prop_DSP_M_DATA_DSP48E2_U[10]_U_DATA[10]) 0.164 9.411 r result_reg/DSP_M_DATA_INST/U_DATA[10] net (fo=1, routed) 0.000 9.411 result_reg/DSP_M_DATA.U_DATA<10> DSP48E2_X8Y18 DSP_ALU (Prop_DSP_ALU_DSP48E2_U_DATA[10]_ALU_OUT[10]) 0.803 10.214 r result_reg/DSP_ALU_INST/ALU_OUT[10] net (fo=1, routed) 0.000 10.214 result_reg/DSP_ALU.ALU_OUT<10> DSP48E2_X8Y18 DSP_OUTPUT r result_reg/DSP_OUTPUT_INST/ALU_OUT[10] ------------------------------------------------------------------- ------------------- (clock clk_out1_clk_wiz_0 rise edge) 8.000 8.000 r BUFGCE_X1Y2 BUFGCE 0.000 8.000 r clk_IBUF_BUFG_inst/O net (fo=62, routed) 1.078 9.078 pll_i/inst/clk_in1 MMCME3_ADV_X1Y0 MMCME3_ADV (Prop_MMCME3_ADV_CLKIN1_CLKOUT0) -1.777 7.301 r pll_i/inst/mmcme3_adv_inst/CLKOUT0 net (fo=1, routed) 0.422 7.723 pll_i/inst/clk_out1_clk_wiz_0 BUFGCE_X1Y0 BUFGCE (Prop_BUFCE_BUFGCE_I_O) 0.091 7.814 r pll_i/inst/clkout1_buf/O X2Y0 (CLOCK_ROOT) net (fo=6, routed) 1.184 8.998 result_reg/CLK DSP48E2_X8Y18 DSP_OUTPUT r result_reg/DSP_OUTPUT_INST/CLK clock pessimism 0.012 9.010 clock uncertainty -0.148 8.862 DSP48E2_X8Y18 DSP_OUTPUT (Setup_DSP_OUTPUT_DSP48E2_CLK_ALU_OUT[10]) -0.104 8.758 result_reg/DSP_OUTPUT_INST ------------------------------------------------------------------- required time 8.758 arrival time -10.214 ------------------------------------------------------------------- slack -1.456
이 report는 도구가 timing constraints를 달성하지 못했음을 보여줍니다. 표시된 path는 @clk의 rising edge 에서 4 ns로 시작하여 @pll_clk의 rising edge 에서 8 ns로 끝납니다. 문제는 clock 에서 input pin이 첫 번째 flip-flop의 clock input pin에 도달하는 데 걸리는 시간입니다. 3.2 ns. 따라서 이 clock edge 의 도착 시간은 7.2 ns입니다.
그러나 @pll_clk은 PLL에서 생성되므로 이 clock은 @clk의 input pin에 맞춰져 있습니다. 따라서 delay은 1.0 ns일 뿐입니다. 따라서 @pll_clk이 두 번째 flip-flop 에 도달하는 시간은 9.0 ns입니다. 따라서 data path 에 남은 시간은 9.0 – 7.2 = 1.8 ns 입니다(대략 clock uncertainty 등으로 인해). 이것은 지정된 산술 단위를 사용하더라도 산술 곱셈에 충분하지 않습니다. 따라서 timing 요구 사항을 충족할 수 없습니다.
따라서 이 예에서 clock skew때문에 clock이 첫 번째 flip-flop 에 늦게 도착합니다. 이로 인해 tsetup 요구 사항을 충족하지 못합니다.
이 문제는 @pll_clk의 정렬을 조작하여 해결할 수 있습니다. 예를 들어 PLL의 reference clock은 @clk을 배포하는 global clock buffer 의 output이 될 수 있습니다. 더 나은 정렬을 달성하기 위해 PLL 의 phase shift를 정의하는 것도 가능합니다. 그러나 이들은 최후의 수단으로만 사용해야 하는 솔루션입니다.
요약
다시 한 번 말하지만 이는 timing closure 문제를 해결하는 데 도움이 될 수 있는 몇 가지 아이디어에 불과합니다. 불행하게도 이런 종류의 문제를 해결하려면 그 이상이 필요할 수 있습니다. 사실 FPGAs 분야에서 timing closure와 관련이 없는 주제는 하나도 없습니다.
이미 언급했듯이 logic design을 처음부터 신중하게 작성하는 것이 가장 좋은 전략입니다. timing closure를 다루는 가장 좋은 방법은 timing closure를 피하는 것입니다.
지금까지 이 일련의 페이지에서는 timing에 대해 논의했지만 timing constraints에 대해서는 많이 언급하지 않았습니다. 이것은 곧 변경될 예정입니다 . 다음 페이지 부터 논의가 보다 기술적으로 진행됩니다.