이 페이지는 timing에 대한 일련의 페이지 에 속합니다. 이전 페이지에서는 timing 계산에 대한 이론을 설명하고 여러 timing constraints를 작성하는 방법을 보여주고 timing closure의 원리에 대해 논의했습니다. 이 페이지에서는 clock domains와 관련된 timing constraints를 정의하는 방법을 설명합니다.
소개
특정 logic elements를 찾는 방법과 paths를 정의하는 방법에 대한 지식을 갖추고 이제 이 지식을 활용하는 timing constraints를 살펴보겠습니다.
가장 먼저 살펴볼 것은 timing constraints 와 clock domains의 관계입니다. 이 두 가지 주제는 밀접하게 관련되어 있으며 다른 하나를 포함하지 않고 둘 중 하나를 논의하는 것은 불가능합니다. 따라서 이 주제가 생소한 경우 clock domains에 대한 이 일련의 페이지 를 읽어 보시기 바랍니다. 무엇보다도 이것은 아래에서 사용할 용어를 이해하는 데 필요합니다.
logic은 clocks간의 관계를 정의합니다.
Verilog 코드의 이 예를 살펴보겠습니다.
module top(
input clk,
input foo,
output reg bar_reg,
output reg baz
);
reg foo_reg;
reg bar;
reg baz_metaguard;
wire pll_clk_8, pll_clk_6;
clk_wiz_1 pll_i
(.clk_in1(clk),
.clk_out1(pll_clk_8),
.clk_out2(pll_clk_6));
always @(posedge pll_clk_8)
foo_reg <= foo;
always @(posedge pll_clk_6)
begin
bar <= !foo_reg;
bar_reg <= bar;
end
always @(posedge clk)
begin
baz_metaguard <= bar;
baz <= baz_metaguard;
end
이것은 이전에 본 PLL의 예와 거의 동일합니다. 차이점은 새로운 clock domain crossing이 있다는 것입니다. @bar 의 값은 metastability guard를 통해 @baz 로 복사됩니다.
따라서 이 예에는 두 가지 유형의 clock domain crossings가 있습니다.
- @foo_reg 에서 @bar로, 두 related clocks 사이( metastability guard없음).
- @bar 에서 @baz로, 두 unrelated clocks 사이(@baz_metaguard는 metastability guard임).
clock domain crossing의 유형을 결정하기 위해 한 가지 기준만 살펴보았습니다. metastability guard의 유무. logic이 unrelated clocks를 예상하는 경우 필요한 안전 메커니즘을 사용합니다. 따라서 다른 것은 중요하지 않습니다. clocks사이에서 paths 에 timing requirements를 확보하는 것이 가능하다고 하더라도, 이렇게 할 이유가 없습니다.
그 반대: logic이 related clocks를 예상하는 경우 timing violations에 대한 보호 기능이 없습니다. 따라서 이러한 clocks사이의 모든 paths 에서 timing 요구 사항을 충족해야 합니다.
결론적으로, logic은 항상 어떤 clocks가 related clocks가 고 어떤 clocks가 아닌지에 대한 가정을 합니다. 이러한 가정은 보호 메커니즘의 존재 또는 부재에 반영됩니다. 하지만 이러한 가정이 실현되도록 하는 것은 FPGA tools 입니다. 특히, 이 도구는 timing 요구 사항이 related clocks사이의 paths 에서 충족되도록 합니다.
따라서 도구가 clocks에 대한 logic의 가정을 알고 있는지 확인해야 합니다.
위의 예에서 도구는 @pll_clk_6 및 @clk에 대한 logic의 기대치를 알 수 있는 방법이 없습니다. logic은 이것이 related clocks 라고 가정할 수 있고 그 반대라고 가정할 수 있습니다. 실제로 related clocks사이에서 path를 시연하기 위해 이전에 비슷한 예 ("아이디어 #9" 참조)를 사용했습니다. 위의 예에서 이 두 clocks는 unrelated clocks로 취급됩니다.
이 도구는 @baz_metaguard라는 이름에서 지능적인 추측을 할 수 있습니다. 아마도 metastability guard 의 일반적인 구조가 힌트를 제공할 수 있을 것입니다. 그러나 그것만으로는 그렇게 중요한 문제에 대한 결정을 내리기에 충분하지 않습니다.
clocks에 대한 도구 설명
지금까지의 예에는 timing constraint가 하나만 있었습니다.
create_clock -period 4.000 -name clk [get_ports clk]
가장 먼저 떠오르는 질문은 도구가 기본적으로 @pll_clk_6 에서 @clk 로 clock domain crossing을 처리하는 방법입니다. 이것이 유일한 timing constraint인 경우 도구가 @bar 와 @baz_metaguard사이의 path 에서 무엇이든 시행합니까?
답은 어떤 FPGA tool을 사용하느냐에 따라 달라집니다. 사실상 모든 FPGA tools가 @pll_clk_6 와 @pll_clk_8을 related clocks로 간주하더라도 다른 쌍의 clocks에서는 어떻게 되는지 명확하지 않습니다. 이 도구는 일반적으로 모든 clocks를 기본적으로 related clocks 로 처리하지만, 그것에 의존하는 것은 안전하지 않습니다.
많은 FPGA tools가 set_clock_groups command를 지원합니다. 이것은 clocks간의 관계를 정의하는 가장 좋은 옵션입니다. 이 command의 중요성 때문에 design에서 사용하기 전에 도구 설명서를 참조하는 것이 좋습니다.
위의 예에서 command는 Vivado 에서 다음과 같이 사용될 수 있습니다(또는 다른 도구에서도 비슷하게):
set_clock_groups -asynchronous \ -group [list \ [get_clocks -of_objects [get_pins pll_i/clk_out1] ] \ [get_clocks -of_objects [get_pins pll_i/clk_out2] ] ] \ -group [get_clocks -of_objects [ get_pins pll_i/clk_in1] ]
get_clocks 및 get_pins 의 이러한 사용법은 이전에 설명되었습니다 . 각 get_clock command는 clk_wiz_1 의 관련 port 의 이름에 따라 clock object를 찾습니다( clk_wiz_1의 instantiation 의 이름은 pll_i임에 유의하세요). 예를 들어, 마지막 get_clock command는 @clk의 경우 clock object를 얻습니다.
이 예는 set_clock_groups가 clocks그룹을 정의하는 방법을 보여줍니다. 이 경우 한 그룹은 @pll_clk_6 와 @pll_clk_8로 구성되고 두 번째 그룹은 @clk 로만 구성됩니다. 이 constraint는 동일한 그룹에 속하는 모든 clocks가 related clocks임을 도구에 알려줍니다. 마찬가지로 두 개의 clocks가 서로 다른 그룹에 속해 있으면 도구는 unrelated clocks로 간주합니다.
즉, 도구는 path 의 양쪽에 있는 clocks가 동일한 그룹에 속하는 경우에만 path 에서 timing constraints를 적용합니다.
design의 timing constraints에는 여러 개의 set_clock_groups commands가 허용됩니다. 하지만 모든 clocks를 그룹으로 나누려면 하나의 set_clock_groups command를 사용하는 것이 가장 좋습니다. 이렇게 하면 모순을 피할 수 있고 혼란을 방지하는 데도 도움이 됩니다. 이 command 의 주요 장점은 clocks간의 관계에 대한 간결한 설명이라는 것입니다. 짧고 간결하며 수학적입니다. 바로 이런 방식이 우리가 원하는 방식입니다.
clocks objects는 이미 존재하기 때문에, create_clock commands대신에 set_clock_groups를 사용해야 합니다.
clocks간의 일관되지 않은 관계
design의 어떤 곳에서는 clocks가 related clocks 로, 다른 곳에서는 unrelated clocks 로 간주된다면 set_clock_groups를 사용할 수 없습니다.
예를 들어 @clk 및 @pll_clk_6은 위의 Verilog 코드에서 unrelated clocks 로 취급됩니다. 그러나 이론적으로는 related clocks로 취급하는 추가 logic이 있을 수 있습니다. 좋은 생각은 아니지만 이 추가 logic에 대해 @pll_clk_6 와 @clk 사이에 timing constraints를 적용할 수 있습니다.
이런 이유로 set_clock_groups를 사용할 수 없다면, 먼저 logic을 바꿔서 set_clock_groups를 사용할 수 있게 하고 싶지 않은지 자문해보세요. 이 command가 너무 좋기 때문만은 아닙니다. 어떤 clocks가 related clocks 인지 아닌지에 대한 간단한 규칙이 없으면 clock domain crossings로 실수하기 쉽습니다. 여전히 logic에서 이러한 변경을 원하지 않는 경우 해결 방법은 false paths를 정의하는 것입니다.
set_false_path command에 대한 간략한 소개
false paths를 선언하기 위한 두 가지 주요 commands가 있습니다. set_clock_groups 및 set_false_paths .
set_clock_groups command는 위에 소개되었습니다: 다른 그룹에 속하는 두 개의 clocks 사이의 모든 path는 false path로 간주됩니다. 하지만 set_clock_groups는 항상 false path로 선언되어야 하는 모든 paths 에 사용될 수 있는 것은 아닙니다. 어떤 경우에는 paths 의 선택이 clocks의 그룹을 정의하는 것보다 더 구체적이어야 합니다. set_false_path command는 paths의 특정 선택을 허용하여 이 문제를 해결합니다.
예를 들어, 위의 set_clock_groups command를 set_false_path command로 바꿔 봅시다. 수정해야 할 것은 @bar 에서 @baz_metaguard로의 path 뿐입니다. 다른 모든 paths 에 대한 timing 요구 사항은 그대로 올바르게 적용됩니다. 따라서 이것은 이 path에 대한 set_false_path command를 작성하는 한 가지 방법입니다. 하지만 이 예에서 배우지 마세요.
set_false_path -from [get_cells bar_reg__0] -to [get_cells baz_metaguard_reg]
이 command는 get_cells를 사용하여 path의 시작과 path의 끝을 선택합니다. 이를 위해서는 양쪽의 cell objects 이름을 알아야 합니다. 이 경우 "bar_reg__0"라는 이름이 있는데, 이는 이름에 의존하는 데 문제가 있음을 보여줍니다. 이 이름은 원래 "bar_reg"였어야 했지만 이미 설명했듯이 우연의 일치로 인해 "bar_reg__0"로 끝났습니다.
따라서 이 예는 set_false_path의 문제점 중 하나를 보여줍니다. design 에서 logic elements를 자세히 선택하려면 종종 object의 이름에 의존해야 합니다. 이 문제와 가능한 해결책 은 이전에 논의되었습니다 .
이 command는 단순화될 수 있습니다: @baz_metaguard는 metastability guard가 므로 paths 부터 이 register 까지 어디에서 왔는지는 중요하지 않습니다. 그렇다면 이 register에 대한 모든 paths를 무시하지 않는 이유는 무엇입니까?
set_false_path -to [get_cells baz_metaguard_reg]
이 command 의 효과는 정확히 같습니다.
set_clock_groups대신set_false_path
또 다른 가능성은 clocks에 따라 paths를 정의하는 것입니다. 사실, 위의 set_clock_groups command는 다음 constraints로 대체될 수 있습니다.
set_false_path -from [get_clocks -of_objects [get_pins pll_i/clk_out1]] \ -to [get_clocks -of_objects [ get_pins pll_i/clk_in1] ] set_false_path -from [get_clocks -of_objects [get_pins pll_i/clk_out2] ] \ -to [get_clocks -of_objects [ get_pins pll_i/clk_in1] ] set_false_path -from [get_clocks -of_objects [ get_pins pll_i/clk_in1] ] \ -to [get_clocks -of_objects [get_pins pll_i/clk_out1] ] set_false_path -from [get_clocks -of_objects [ get_pins pll_i/clk_in1] ] \ -to [get_clocks -of_objects [get_pins pll_i/clk_out2] ]
이것은 동일한 false paths를 만드는 길고 자세한 방법입니다. clocks를 그룹으로 나누는 대신, unrelated clocks한 쌍당 두 개의 set_false_path commands가 있습니다. 각 방향에 command가 하나씩 있습니다. constraints가 너무 많아서 실수를 하기 쉽다는 것은 매우 명백합니다. 그리고 이것은 clocks가 세 개 있는 간단한 예입니다.
그럼에도 불구하고 set_clock_groups대신 set_false_path를 이렇게 사용하는 경우가 많습니다. 누군가가 timing constraints를 어딘가에서 복사했기 때문일 가능성이 큽니다.
실수가 발생할 수 있는 방법의 예
가능한 실수의 간단한 예를 살펴보겠습니다. 위의 논의에서 false path로 선언해야 하는 path가 하나만 있음이 분명합니다. @bar 에서 @baz_metaguard로. 따라서 마지막 예의 네 개의 set_false_path commands 중에서 오직 이 하나만이 의미가 있습니다.
set_false_path -from [get_clocks -of_objects [get_pins pll_i/clk_out2] ] \ -to [get_clocks -of_objects [ get_pins pll_i/clk_in1] ]
나머지 세 개의 set_false_path commands는 paths를 하나도 커버하지 못합니다. 하지만 잠깐, constraint를 더욱 단순화하는 건 어떨까요? @clk 로 끝나는 모든 paths를 false paths로 하는 건 어떨까요? 이건 어떨까요?
set_false_path -to [get_clocks -of_objects [ get_pins pll_i/clk_in1] ]
실제로 "clk"를 정의하는 create_clock command가 set_false_path command바로 위에 있기 때문에 대신 다음과 같이 작성할 수 있습니다.
set_false_path -to [get_clocks clk]
이 constraint는 짧고 우아합니다. 불행히도 그것은 끔찍하게 잘못된 것입니다. 저는 @clk 로 끝나는 모든 paths가 false path여야 한다고 제안했습니다. 하지만 @baz_metaguard 에서 @baz까지의 path는 어떨까요? @clk 에서 @clk까지의 path 입니다. 이 path는 당연히 false path가 아니어야 합니다. 하지만 마지막 두 개의 set_false_path commands 에는 @clk로 끝나는 모든 paths가 포함되며, path가 @clk에서 시작하더라도 마찬가지입니다.
특히 false path 용 constraints가 수학적 사고 방식의 정확성 없이 작성된 경우 이런 종류의 실수를 하기 쉽습니다. paths가 false paths가 고 그렇지 않은 paths를 밝힐 수 있는 특별한 timing reports를 만드는 것이 도움이 될 수 있습니다.
이것으로 FPGA내부에 있는 paths 용 timing constraints 에 대한 실질적인 논의를 마칩니다. 다음 페이지에서는 이 주제에 속하는 multi-cycle paths에 대해 설명합니다. 그러나 multi-cycle path constraints는 일반적으로 권장되지 않습니다. 따라서 대신 I/O constraints소개로 건너뛰어도 됩니다.