1. 10진 카운터를 버튼을 눌러 증가시키고 Basys3의 LED와 FND를 통해 출력해보기
코드는 아래와 같다.
module btn_click_counter(
input button,
output [3:0] com_an,
output [6:0] seg_7,
output [3:0] led
);
wire [3:0] count_value;
assign led = count_value;
up_counter_sync_BCD ucounter( .clk(button), .reset_n(1),.count(count_value));
decoder_7_seg(.hex_value(count_value), .seg_7(seg_7), .com_an(com_an));
endmodule
코드는 매우 간단하다. 지난 시간에 만들었던 10진카운터를 가져와서 인스턴스 명을 붙여주고, 상위 모듈에서 선언했던 input과 output을 전달인자로 각각 지정해준다. 리셋 기능은 하지 않기에 1로 넣어준다. 그리고 버튼을 누르면 1씩 증가시켜야 하기에 input 변수로 button을 선언하여 up_counter_sync_BCD의 클럭에 넣어준다. 버튼을 누르게 되면, 클럭이 바뀌게 되고 그에 따라 1이 증가할 것이다. decoder_7_seg 모듈을 통해서 up_counter_sync_BCD로부터 받은 output값 count_value를 hex_value에 넣어 FND에 숫자로 보내줄 seg_7과 출력위치를 선택할 com_an을 받는다.
적절하게 xdc파일도 수정해준다.
Basys3로 결과를 확인해보자.
스위치 가운데 버튼을 누르면 1씩 증가하는 것을 볼 수 있다. 하지만 스위치를 누를 때 가끔 바운싱이 발생하기 때문에 2씩 증가하는 경우가 있다. 이를 해결해주어야 한다. AVR에서는 Delay를 주거나 Circular Queue를 이용하여 이를 해결하곤 했다. Basys3에서는 노이즈를 막기위해 다른 방법을 쓴다. 다음에서 알아보자.
2. 스위치를 누를 때 일어나는 바운싱 제거하기
위에서 일어나는 바운싱을 해결하기 위해서는 플립플롭을 써야한다. 딜레이를 1ms로 주도록 설정할 것이다. 왜냐하면 사람 손은 1ms보다 빠르지 않기에 D-플립플롭에 1ms의 클럭을 주어 딜레이를 시켜보자.
module btn_click_counter(
input clk, //시스템 클락
input button,
output [3:0] com_an,
output [6:0] seg_7,
output [3:0] led
);
wire [3:0] count_value;
wire debounced_button;
wire clk_usec, clk_msec;
//위처럼 reg에다가 0으로 초기화해도 된다. 하지만 wire에다가 0을 할 경우 접지가 되어버림.
assign led = count_value;
clock_usec UCLK (.clk(clk), .clk_usec(clk_usec));
clock_msec MCLK (.clk_usec(clk_usec), .clk_msec(clk_msec));
up_counter_sync_BCD ucounter( .clk(debounced_button), .reset_n(1),.count(count_value));
decoder_7_seg(.hex_value(count_value), .seg_7(seg_7), .com_an(com_an));
D_flip_flop_posedge dff1 (.D(button), .E(clk_msec), .Q(debounced_button));
endmodule
코드를 보자. 추가된 변수로는 input의 clk와 wire형의 clk_usec, clk_msec, debounce_button이 있다. clk은 xdc에 인위적으로 분주비를 설정하여 클락을 사용할 것이다. 클락을 사용해야 1ms동안 딜레이를 걸어줄 수 있기 때문이다. 다음은 wire형의 clk_usec, clk_msec인데, 다음 글에서 설명할 모듈 clock_usec와 clock_msec를 호출하였다. 자세한건 다음 글에서 알아보고, 간단하게 설명하자면, 지난 실습 때 카운터를 이용하여 시간을 계산하는 모듈이다. 클럭을 넣어주면 엣지에 따라 계속해서 값이 카운팅 될 것이고, output으로 ms와 us를 출력해준다. 이를 D플립플롭에게 입력 값으로 버튼 값과 clock_msec모듈로부터 받은 output clk_msec(1ms)를 클럭으로 넣어주면, 1ms동안 딜레이되어 바운싱을 제거시켜준다. 이를 이용하여 버튼이 누를 때, 정확하게 1씩 증가하도록 설정할 수 있다.
.
'FPGA' 카테고리의 다른 글
[FPGA] 12. 디지털 논리 회로 레지스터 (0) | 2023.05.02 |
---|---|
[FPGA] 11. 플립플롭과 카운터를 이용하여 Basys3 스톱워치 만들기 (0) | 2023.04.28 |
[FPGA] 9. 래치(Latch)와 플립플롭(Flip-Flop) (0) | 2023.04.28 |
[FPGA] 8. 2진수를 BCD코드로 변환 프로그램을 Basys3에서 구현하기 (0) | 2023.04.20 |
[FPGA] 7. 멀티플렉서와 디멀티플렉서 (0) | 2023.04.20 |