01signal.com

FPGA의Asynchronous resets : 많은 사람들이 믿는 것처럼 쉽지 않다

이 페이지는 FPGAs의 resets에 대한 시리즈 세 개 중 첫 번째 페이지입니다. 많은 사람들이 예상대로 작동하지 않는다는 사실을 모른 채 asynchronous resets를 사용하기 때문에 이 첫 페이지에서 전체 주제가 생각만큼 쉽지 않은 이유를 설명합니다.

reset이 정말 작동합니까?

잘못된 state machine재설정에 대한 다음 예를 고려하십시오.

always @(posedge clk or negedge resetn)
     if (!resetn)
       state <= ST_START;
     else
       case (state)
	 ST_START:
	   begin
	      state <= ST_NEXT;
	      [  ... do some stuff maybe? ... ]
	   end

	 ST_NEXT:
	   begin
	      [ ... do something ... ]
	   end
       endcase

여기서 reset 의 문제점은 무엇입니까? 교과서에 나오는 그대로입니다! @state를 구현하는 register를 초기 상태로 만드는 active low asynchronous reset. 무엇이 잘못될 수 있습니까?

논의를 위해 @resetn 신호 자체는 OK라고 가정합시다. 즉, pushbutton 등에 직접 연결되어 있지 않습니다. reset 신호를 생성하도록 설계된 chip이 사용되었거나 reset이 FPGA에 의해 내부적으로 생성되었을 수 있습니다. 이런 식으로 또는 다른 방법으로 reset이 안정적인 방식으로 활성화되고 충분히 오랫동안 활성 상태를 유지한 다음 비활성화된다고 가정합니다. 여전히 잘못되었습니다.

그리고 내가 틀렸다고 말하는 것은 FPGA가 명백한 이유 없이 때때로 이상하게 동작하게 만드는 종류의 잘못된 것을 의미합니다.

그래서 문제가 무엇입니까? 글쎄요, reset은 충분히 오랫동안 활성화되어 있기 때문에 @state를 초기 상태로 되돌릴 것입니다. 그러나 비활성화되면(즉, 위의 예에서 다시 '1' 로 변경) 어떻게 됩니까? 그 때 관련 flip-flops가 @clk의 rising edges 에 응답하기 시작해야 합니다.

그러나 flip-flop이 reset 신호에서 복구하고 rising clock edges에서 data input 샘플링을 시작하는 데 약간의 시간이 걸립니다. 그리고 reset은 정의상 비동기식이므로 @clk와 관련하여 언제든지 비활성화될 수 있습니다.

@clk 의 첫 번째 rising edge가 reset의 비활성화 후 너무 빨리 도착하면 flip-flop은 이 rising edge를 무시합니다. @clk 에 연결된 모든 flip-flops가 그렇게 하면 완벽합니다. 그러나 모든 flip-flops가 정확히 같은 것은 아니며 일부는 다른 것보다 조금 더 일찍 clock edge를 얻고 일부는 다른 것보다 늦게 reset을 비활성화합니다.

사실, 이 설명은 다소 단순합니다. 문제에 대한 보다 정확한 견해는 timing의 기본 사항을 설명하는 페이지 에서 Recovery 및 Removal 에 대한 부분을 참조하십시오.

따라서 다음과 같이 요약됩니다. 운이 좋지 않으면 reset이 clock의 rising edge에 충분히 가깝게 비활성화되어 일부 flip-flops가 첫 번째 rising edge에 응답하고 다른 일부는 무시할 수 있습니다. 실제로 일부 flip-flops는 수행할 작업을 결정하는 데 시간이 더 걸릴 수 있습니다. 동일한 chip 에서 flip-flops 의 차이점을 탓하거나 clock skew 와 reset skew를 탓하십시오. 결론은 일부 flip-flops가 다른 clock cycle 보다 앞서 있다는 것입니다.

이것이 얼마나 나쁜지 이해하려면 위의 예를 고려하십시오. synthesizer가 이것이 state machine임을 인식한다면 one-hot encoding와 함께 state variable을 구현할 가능성이 높습니다. 즉, 각 state에 대해 single-bit register를 할당합니다. 이러한 registers 각각은 state machine이 관련 state에 있을 때 활성화됩니다. synthesizer가 ST_START라는 이름의 state 에 대해 hot_state_0 라는 register를 할당하고 ST_NEXT에 hot_state_1을 할당했다고 가정해 보겠습니다. 분명히 reset은 hot_state_0을 활성화하고 hot_state_1을 비활성화합니다.

이제 state machine은 ST_START 에서 ST_NEXT로 무조건 이동합니다. 따라서 reset이 출시된 후 첫 번째 clock 에서 hot_state_0이 비활성화되고 hot_state_1이 활성화됩니다.

그러나 reset이 불운한 타이밍으로 비활성화되어 일부 flip-flops가 첫 번째 clock edge를 놓치고 다른 clock edge는 놓치면 어떻게 될까요? 한 가지 가능성은 hot_state_0이 첫 번째 clock을 놓치고 hot_state_1이 이에 응답한다는 것입니다. 결과적으로 둘 다 활성 상태가 되며 이는 one-hot encoding에서 잘못된 조건입니다. 반대의 경우 두 registers가 모두 비활성화되므로 실제로 state machine 의 모든 one-hot registers가 비활성화됩니다. 어느 쪽이든 state machine은 합법적인 상태로 절대 복구할 수 없습니다.

이것은 실제로 어떻게 보일 것입니까? 물론 응용 프로그램에 따라 다르지만 reset이 FPGA 에 다시 적용될 때까지 무언가가 올바르게 작동하지 않을 가능성이 있습니다. 이 문제는 무작위로 나타나며 반드시 자주 나타나는 것은 아니기 때문에 이 동작의 원인을 찾는 것이 매우 어려울 수 있습니다. 또한 한 FPGA design 의 compilation 에서 다른 compilation 와 다르게 동작할 수 있으며 전자 보드마다 다를 수 있습니다. 요컨대, 그것은 당신을 미치게 할 수 있는 일종의 버그입니다. 문제의 원인이 이 토론의 주제이기 때문에 이 토론에서 그다지 나쁘게 들리지 않을 수도 있습니다. 그러나 실생활에서 그러한 불안정이 발생하면 그것은 무엇이든 될 수 있으며 종종 FPGA가 귀신 들린 것처럼 느낍니다 .

하지만 나는 항상 이것을 하고 있고 그것은 효과가 있다!

물론. 대부분의 경우 일부 flip-flops가 reset이후 첫 번째 clock을 놓치더라도 그다지 중요하지 않습니다.

위의 state machine 예제가 실패할 수 있는 주된 이유는 첫 번째 clock cycle에서 초기 상태를 유지하기 때문입니다. 실제 designs 의 대부분의 state machines 에는 초기 상태에서 벗어나는 규칙이 있으므로 처음 몇 개의 clock cycles동안 항상 이 상태를 유지합니다. 그래서 사람은 이 실수를 잊게 됩니다.

그러나 여기에 또 다른 예가 있습니다. 간단한 counter:

reg [15:0] counter;

   always @(posedge clk or negedge resetn)
     if (!resetn)
       counter <= 0;
     else
       counter <= counter + 1;

이 경우 @counter는 16개의 flip-flops로 구성됩니다. 이러한 flip-flops 각각은 data input에서 다음 clock cycle 에 대한 카운터 값을 수신하고 asynchronous reset input에서 @resetn을 수신합니다.

@resetn이 활성화되면 @counter는 값 0을 얻고 다음 clock cycle 에 대한 카운터 값은 1입니다. 따라서 counter[0]을 제외한 모든 flip-flops는 첫 번째 clock edge를 놓쳤는지 여부에 관계없이 0으로 유지됩니다. 따라서 어느 쪽이든 올바르게 계산하기 시작합니다. 이와 같은 코드가 작성되는 대부분의 경우 카운터가 첫 번째 clock cycle을 놓쳤는지 여부는 중요하지 않습니다.

그러나 이것은 다른 이야기입니다.

reg [15:0] counter;

   always @(posedge clk or negedge resetn)
     if (!resetn)
       counter <= 0;
     else
       counter <= counter - 1;

작은 차이지만 중요한 것: 카운터가 0에서 시작하여 카운트 다운 되면 다음 clock cycle 의 카운터 값은 0xffff입니다. 즉, 모든 flip-flops는 reset이후 첫 번째 clock 에서 값을 변경해야 합니다. 따라서 일부는 reset이후의 첫 번째 clock edge 에 응답하고 나머지는 응답하지 않는 경우 카운터는 거의 모든 임의 값에서 시작할 수 있습니다.

그러나 값이 0인 카운터를 재설정한 다음 카운트다운하는 사람은 누구입니까?

다음은 보다 현실적인 예입니다. logic이 clock의 주파수가 절반으로 줄어든 것처럼 동작하도록 하는 clock enable 신호(필요한 경우 multi-cycle path 허용):

reg en;

   always @(posedge clk or negedge resetn)
     if (!resetn)
       en <= 0;
     else
       en <= !en;

   always @(posedge clk)
     if (en)
       [ ... do something ... ]

여기에서는 아무 것도 잘못될 수 없다고 생각할 수 있습니다. clock enable, @en은 단일 register가 므로 토글을 시작할 때 실제로 중요하지 않은가요, 아니면...? 문제는 clock enable 신호가 높은 fan-out를 갖는 경향이 있으므로 synthesizer가 fan-out의 한계를 초과하지 않도록 이를 복제할 수 있다는 것입니다.

Vivado synthesizer 에 대한 나의 일화적인 실험은 @en을 구현한 복제된 registers 각각이 자체 output signal에 의존한다는 것을 보여주었습니다. 다시 말해, 모든 flip-flops가 다음 output이 무엇인지 결정하는 데 사용한 단일 신호가 없었습니다. 오히려 clock의 rising edge 에서 항상 값을 변경하는 독립적인 flip-flops가 많이 있었습니다. 따라서 이러한 flip-flops가 동일한 clock cycle에서 토글을 시작하지 않으면 outputs가 무기한 다르게 유지됩니다.

이러한 사고가 발생하면 logic이 완전히 오작동할 수 있습니다. 따라서 asynchronous reset을 고집한다면 최소한 모든 clock enables가 다음과 같이 단일 소스에 의존하는지 확인하십시오.

reg pre_en; // Apply some don't-touch synthesis directive on this
   reg en;

   always @(posedge clk or negedge resetn)
     if (!resetn)
       pre_en <= 0;
     else
       pre_en <= !pre_en;

   always @(posedge clk or negedge resetn)
     if (!resetn)
       en <= 0;
     else
       en <= pre_en;

   always @(posedge clk)
     if (en)
       [ ... do something ... ]

트릭은 @pre_en이 다음 값을 결정하는 register 라는 것입니다. flip-flop은 fan-out가 낮고 synthesizer가 이를 조작하지 않도록 지시하는 속성이 있을 수 있습니다. 이런 식으로, 그것은 확실히 단일 register입니다. @en을 구현하는 모든 flip-flops는 @pre_en에 의존하므로 모두 다음 clock에서 @en 의 가치에 동의합니다. reset이후 첫 번째 clock 의 경우 첫 번째 clock cycle 의 @en 값이 어쨌든 0이기 때문에 flip-flops중 일부가 놓치더라도 문제가 되지 않습니다.

따라서 결론은 logic이 일반적으로 reset이 clock에 대해 비활성화될 때의 불확실성에 대해 일반적으로 관대하기 때문에 asynchronous reset을 잘못 사용하는 것이 일반적 으로 괜찮을 것이라는 것입니다. 그럼에도 불구하고 asynchronous resets를 부주의하게 적용하면 해결하기가 매우 어려울 수 있는 가끔 오작동이 발생할 수 있습니다.

reset 와 clock사이에서 timing constraint 사용

reset의 비활성화와 clock의 rising edge 사이의 불확실한 타이밍 관계를 피하는 명백한 방법은 reset 신호에서 timing constraint를 사용하는 것입니다. 그러나 이렇게 하면 reset 신호가 동기화됩니다.

그러나 어떤 clock와 동기식입니까? 전체 logic design에 대해 하나의 글로벌 asynchronous reset을 사용하는 것이 편리한 경우가 많습니다. 이 reset은 하나의 특정 clock와 동기화되는 logic 로 생성됩니다. 이 reset이 다른 clock와 동기화된 logic 와 함께 사용된다면 clock domain crossing이 됩니다. 이것은 그 자체로 주제 이지만 가장 중요한 점은 도구가 관련 paths에서 timing을 무시할 가능성이 있다는 것입니다.

따라서 asynchronous resets 에서 timing constraints를 사용하기 위한 출발점은 각 clock에 대해 별도의 asynchronous reset이 있어야 한다는 것입니다. 또는 related clocks의 각 그룹에 대해 별도의 asynchronous reset을 주장하는 경우. 그렇지 않으면 timing constraint에 의미가 없습니다. 이상하게 들린다면 asynchronous reset이 더 이상 비동기식이 아니기 때문입니다.

Verilog 코드가 asynchronous reset 에 대한 패턴을 사용한다는 사실은 차이가 없습니다. flip-flop의 asynchronous reset input이 사용되거나 flip-flop이 reset input을 비동기식으로 간주하도록 구성된 경우에도 중요하지 않습니다. reset이 clock와 동기식이고 timing constraint가 사용되는 경우 reset은 실질적으로 동기식입니다. 이 경우 Verilog 패턴을 직접 사용하는 것을 고려할 수 있습니다.

always @(posedge clk)
     if (!resetn)
       state <= ST_START;
[ ... ]

즉, timing closure에 대한Intel의 Youtube 비디오는 clock 와 동기화되는 asynchronous resets를 사용하여 홍보하며 timing constraints 도 사용해야 합니다. asynchronous reset 의 선택은 FPGA에서 global routing 전용 리소스를 활용하기 위한 것입니다. global routing 조차도 특히 큰 FPGAs에서 상당한 delay을 가질 수 있기 때문에 이것이 매우 이상하다는 것을 알았습니다. 그러나 이것이 의미가 있는 몇 가지 시나리오가 분명히 있습니다.

사실, asynchronous reset이 효과적인 동기일 때에도 asynchronous reset을 계속 사용하는 또 다른 이유가 있습니다. 이에 대해서는 다음 페이지 에서 설명합니다. reset 신호의 활성화를 비동기적으로 전파할 수 있으므로 시뮬레이션 및 ASICs테스트에 유용합니다.

동기화된 asynchronous reset 와 함께 이 방법을 사용하는 경우 timing constraint가 flip-flops의 asynchronous reset inputs로 이동하는 모든 signal paths 에 적용되는지 확인하는 것이 중요합니다. reset이 대상의 flip-flop와 동일한 clock 와 동기화된 flip-flop 에 의해 생성된다는 사실 자체만으로는 그들 사이의 path가 시간이 정해진다는 것을 보장하지 않습니다. 기본적으로 일부 timing 도구는 asynchronous inputs로 끝나는 모든 path를 무시하므로 이 적용을 명시적으로 활성화해야 할 수 있습니다. 이러한 paths가 실제로 timing constraints에 포함되는지 timing reports 에서 확인하십시오. 이것에 빠지기 쉽습니다.

이것으로 resets에 대한 이 시리즈 의 첫 페이지를 마칩니다. 다음 페이지 에서는 resets 에 대한 다양한 옵션과FPGA 초기화에 대해 설명합니다 .

이 페이지는 영어에서 자동으로 번역됩니다. 불분명한 사항이 있으면 원본 페이지를 참조하십시오.
Copyright © 2021-2024. All rights reserved. (6f913017)