Verilog 복습 3일차

JS·2023년 7월 20일
0

Button Debounce

Verilog를 이용하여 스톱워치를 만들었으나, 버튼이 제대로 동작하지 않는 문제가 있었다.
증상은 다음과 같다.
1. 버튼을 눌렀을때도 동작하지 않는다.
2. 버튼이 여러번 눌린 것처럼 동작후 바로 멈춘다.

버튼을 처리하는데 있어 무엇인가 문제가 있는 것 같다.
clock의 edge와 버튼의 입력이 겹칠때 발생하는 metastable 때문에 발생하는게 아닐까?
metastable을 해결하기 위해 synchronizer를 이용하여 해결해 보자.

비동기적인 입력이 들어올 경우, 무조건 synchronizer가 필요할 것 같다.

내가 사용해봤던 Atmega 128A의 GPIO에도 synchronizer가 시용된다.

구현할 것
1. Debounce 회로
-> 버튼은 평소 커페시터 처럼 전하를 충전하고있다가 눌렸을 경우, 전류가 순간적으로 흐르면서
스파크가 튀는 현상이 있다.
-> 스파크로 인한 Noise 발생
-> 이러한 Noise를 방지하기 위해 분주기를 이용하여 Noise를 무시할 수 있는 Delay를 주자

  1. Oneshot 회로
    -> 1 클럭만 동작하도록 하기 위한 회로
    -> 버튼 신호가 1 clock 이상으로 클 경우, 여러번 눌리는 현상이 발생할 수 있다.
module debounce(
    input clk,
    input reset,
    input i_btn,
    output o_btn 
    );

    reg d1_ff, d2_ff, d3_ff;
    reg r_clk = 0;//100MHz
    reg [31:0] counter =0;

always@(posedge clk, posedge reset) begin
    if(reset) begin 
        counter <= 0;
        r_clk  <= 0 ;
    end 
    
    else begin
        if(counter == (500_000 -1)) begin 
        //if(counter == (5 -1)) begin // for testbench 
           counter <= 0;
           r_clk <= ~r_clk;
        end     
    
        else begin
            counter <= counter +1;
        end 
    end
  end 

always@(posedge r_clk, posedge reset)begin //debounce
    if (reset) begin
        d1_ff <= 0;
        d2_ff <=0;
    end 

    else begin  
        d1_ff <= i_btn;
        d2_ff <= d1_ff;
    end
end 


always @ (posedge clk, posedge reset) begin // oneshot
    if (reset) begin
        d3_ff <= 0;
    end

    else begin
        d3_ff <= d2_ff;
    end 
end

assign o_btn = d2_ff & ~d3_ff;

endmodule

시뮬레이션은 정상적을 동작하였다.

하지만 보드에 업로드할 경우, 동작하지 않았다.


Schematic을 확인해 봤다.
겉보기에는 큰 이상이 없어보인다.

Debounce 모듈에 clk이 물려있지 않음을 볼 수 있었다.


상위 모듈에서 받은 clk가 들어가야하는데 엉뚱한 wire clk100Hz가 들어가 있으니... 작동이 안될 수 밖에 없다.


코드를 수정하였다.


clk가 잘 물려있음을 볼 수 있다.

RunStop이 잘동작됨을 볼 수 있다.
그러나 Clear는 여전히 먹통이다...

CPU


CPU설계를 다시 복습하였다.
CPU의 동작에 따라 FSM을

1개의 댓글

comment-user-thumbnail
2023년 7월 20일

훌륭한 글이네요. 감사합니다.

답글 달기

관련 채용 정보