Verilog를 이용하여 스톱워치를 만들었으나, 버튼이 제대로 동작하지 않는 문제가 있었다.
증상은 다음과 같다.
1. 버튼을 눌렀을때도 동작하지 않는다.
2. 버튼이 여러번 눌린 것처럼 동작후 바로 멈춘다.
버튼을 처리하는데 있어 무엇인가 문제가 있는 것 같다.
clock의 edge와 버튼의 입력이 겹칠때 발생하는 metastable 때문에 발생하는게 아닐까?
metastable을 해결하기 위해 synchronizer를 이용하여 해결해 보자.
비동기적인 입력이 들어올 경우, 무조건 synchronizer가 필요할 것 같다.
내가 사용해봤던 Atmega 128A의 GPIO에도 synchronizer가 시용된다.
구현할 것
1. Debounce 회로
-> 버튼은 평소 커페시터 처럼 전하를 충전하고있다가 눌렸을 경우, 전류가 순간적으로 흐르면서
스파크가 튀는 현상이 있다.
-> 스파크로 인한 Noise 발생
-> 이러한 Noise를 방지하기 위해 분주기를 이용하여 Noise를 무시할 수 있는 Delay를 주자
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의 동작에 따라 FSM을
훌륭한 글이네요. 감사합니다.