본문 바로가기

RTL Design/Verilog RTL 설계

Verilog RTL 설계(7월 17일 - 6, Advanced Clock Mode - 3)

1.  Chattering 문제 발생

 

 

1.1. 문제의 원인

  • button을 눌러 초나 분 값을 증가시키고자 하는데, Chattering으로 인해 한 번의 버튼 누름으로 값이 2 이상 씩 증가한다.
  • chattering 문제는 다양한 원인을 갖고 있지만, 대표적으로 버튼의 내부에 있는 스프링 노후화로 인한 발생, 저렴한 버튼으로 인한 문제 발생이 있다.

 

 

 

 

1.2. 문제 해결 방법 (소프트웨어적인 해결 방법 사용)

  • Chattering 문제를 해결하는 방법에는 소프트웨어적으로 해결하는 방법과 하드웨어적으로 해결하는 방법이 있다.

 

  ▶ 하드웨어적인 해결 방법

  • 하드웨어적으로 해결하는 방법에는 capacitor를 Switch와 병렬 연결시켜 Chattering 문제를 해결할 수 있다.
  • capacitor에 충전된 전하를 통해 Chattering으로 인한 Switch의 전압 레벨의 변화폭을 줄여줄 수 있다.
  • 작동 원리는 다음과 같은 과정을 통해 작동하게 된다.
    - Switch가 열려 있을 때에는 capacitor가 충전된다.
    - Switch를 누르면 capacitor에 저장되어 있었던 전하들이 천천히 방전된다.
    - chattering으로 인헤 Switch의 전압 레벨이 급격히 변화한다면 capacitor의 전하로 인해 Switch의 전압 레벨 변화 폭이 줄어들게 되어 전압 레벨이 급격하게 변하지 않는다.

 

 

  ▶ 소프트웨어적인 해결 방법

  • 하드웨어적으로 해결하는 방법에는 button의 입력값을 바로 받는 것이 아닌 일정한 delay를 갖고, button의 입력값을 받는 것이다.
  • Chattering으로 인해 굉장히 짧은 시간 동안 swtich의 전압 레벨이 급격하게 변화하기 때문에 일정한 delay 시간을 갖갖고, chattering 현상이 끝난 이후, 안정된 전압 레벨을 읽음으로서 chattering 문제를 해결할 수 있다.



  • 이번에는 Delay time을 갖기 위해 D Flip Flop을 사용할 것이며, D Flip Flop은 edge trigger에서 동작하며, 입력값을 그대로 출력값으로 내보내기 때문에 Delay time을 갖고, Button값을 읽어내기에 적합하다.
  • 다음과 회로도와 같이 D Flip-Flop을 구성하면 문제를 해결할 수 있다.

 

 

 

★★★★★★★★★★★★

  • Q) 어떻게 D Flip Flop을 통해 Chattering 현상을 해결 할 수 있는가?
  • A) 아래 Timing diagram와 함께 보면 이해하기 쉽다.

D Flip-Flop을 통해 Delay time을 갖고, Button의 입력값을 읽기

  • D Flip - Flop이 충분히 Chattering 현상이 발생하는 시간보다 길다면 첫 번째 Positive edge에서 Button의 입력값으로 어떤 값을 읽었던 간에 두 번째 Positive edge에서 Button 입력값으로 1을 읽기 때문에 Chattering 현상으로 인해 Button의 레벨 값이 여러번 변화하는 문제를 해결 할 수 있다.

 

 

  • D Flip Flop의 입력값인 Button의 One Cycle Pulse를 1ms 주기마다 읽기 위해 다음과 같이 설게할 것이다.
  • D Flip Flop의 Enable 단자에 주기가 1ms인 One Cycle Pulse 인가함으로서 1ms 주기 마다 button 값을 읽어서 debounced_btb 변수에 대입할 것이다.

 

 

 

 

 

 

1.3. 문제 해결

  • 17bit Counter를 통해 주기가 1ms이고, Duty Cycle이 50%인 Pulse Wave를 생성한 뒤, edge detector를 이용하여 One Cycle Pulse를 얻는다.
    - clk_1ms : 주기가 1ms이고, Duty Cycle이 50%인 Pulse Wave
    - clk_1ms_nedge : 주기가 1ms인 One Cycle Pulse
  • clk_1ms_nedge가 활성화 되었을 때마다 btn 값을 읽어서 출력값인 debounced_btn에 대입한다.
    - clk_1ms_nedge의 주기는 1ms이기 때문에 1ms마다 btn 값을 읽어서 출력으로 내보낸다.
    - 이는 1ms마다 동작하는 D Flip Flop 동작과 일치한다.
  • 이를 통해 1ms Delay time를 갖고, Button 값을 읽기 때문에 Chattering 현상을 해결할 수 있다.
// Control Button.
module button_cntr (
    input clk, reset_p,
    input btn,
    output btn_pedge, btn_nedge);
    
    // Get 1ms Pulse wave, One Cycle Pulse
    reg [16:0] counter;
    always @(posedge clk or posedge reset_p) begin
           if(reset_p) counter = 0 ;
           else begin
                if(counter >= 99999) counter = 0;
                else counter = counter + 1;
           end
    end
    
    wire clk_1ms, clk_1ms_nedge;
    assign clk_1ms = (counter < 50000)? 0 : 1;
    edge_detector_n edge_detector_0 (.clk(clk), .reset_p(reset_p), .cp(clk_1ms), .n_edge(clk_1ms_nedge));
    
    // Get positive edge of button, Negative edge of button.
    reg debounced_btn;
    always @(posedge clk or posedge reset_p) begin
        if(reset_p) debounced_btn = 0;
        else if(clk_1ms_nedge) debounced_btn = btn;
    end
    
    edge_detector_n edge_detector_1 (.clk(clk), .reset_p(reset_p), .cp(debounced_btn), .p_edge(btn_pedge), .n_edge(btn_nedge)); 
endmodule

 

 

 

  • Root of Module에서도 다음과 같이 수정할 필요가 있다.
  • 더이상 Edge Detector로 button 값을 읽지 않고, button_cntr 모듈을 통해 button 값을 읽는다.
  • button_cntr 모듈을 통해 1ms delay time을 갖고, button 값을 읽게 되며, 이를 통해 Chattering 문제를 소프트웨어적으로 해결할 수 있게 된다.
// Get One Cycle Pulse of button.
wire btn_set, btn_sec, btn_min;
button_cntr edge_btn_set (.clk(clk), .reset_p(reset_p), .btn(btn[0]), .btn_nedge(btn_set));
button_cntr edge_btn_sec (.clk(clk), .reset_p(reset_p), .btn(btn[1]), .btn_nedge(btn_sec));
button_cntr edge_btn_min (.clk(clk), .reset_p(reset_p), .btn(btn[2]), .btn_nedge(btn_min));

 

 

 

 

 

1.4. 구현 영상