본문 바로가기

RTL Design/Verilog RTL 설계

Verilog RTL 설계(7월 18일 - 4, Stop Watch - 3)

1. Clear 기능 추가하기

  • 이번 게시글은 지난 게시글에 이어 Clear 기능을 추가하도록 하겠다.
  • 이전 게시글에 대해서 궁금하다면 아래 링크를 통해 이전 게시글을 참조 하길 바란다.
    https://jbhdeve.tistory.com/271
 

Verilog RTL 설계(7월 18일 - 3, Stop Watch - 2)

1. Lap 기능 추가하기이전 게시글에서 구현한 기본적인 Stop Watch에 이어 랩 기능을 추가하도록 하겠다.https://jbhdeve.tistory.com/270 Verilog RTL 설계(7월 18일 - 2, Stop Watch - 1)1. Stop Watch 이전 게시글에서

jbhdeve.tistory.com

  • Clear 버튼을 누르면 랩 모드에 저장된 시간과 Stop Watch 모드에서 이때까지 재었던 시간을 0분 0초로 초기화 할 뿐만 아니라 모드와 관련된 start_stop 변수, lap 변수 값들도 0으로 초기화 된다.
  • 따라서 Clear 버튼을 누르면 Start / Stop 모드에서 Stop 모드로 설정된 상태에서 0분 0초로 돌아가게 된다.\
  • 이번에는 크게 두 단계로 나누어 구현하고자 한다.
    - Clear 버튼을 추가한 뒤, BCD 60진 카운터를 초기화하는 하는 과정
    - Clear 버튼을 누르면 시간은 0분 0초로 초기화 되지만, Stop Watch가 자동적으로 실행되는 문제점을 해결하는 과정

 

 

 

 

2. Clear 버튼을 추가하고, BCD 60진 카운터를 초기화하여 0분 0초로 초기화하는 과정

 

2.1. 구현하기 전 대략적으로 생각해 보았을 때, 어떻게 구현해야 할까?

  • Clear 버튼을 추가한 뒤, 이를 button_cntr 모듈을 통해 Clear 버튼을 눌렸는지 여부를 확인할 수 있는 One Cycle Pulse를 얻을 필요가 있다.
  • BCD 60진 카운터에서 clear enable 변수가 들어왔을 때, 이 전까지 카운터 했던 값들인 bcd1, bcd10을 초기화시켜줄 필요가 있기 때문에 BCD 60진 카운터에 대해서 새롭게 설계할 필요가 있다.
  • BCD 60진 카운터의 초기화는 Stop Watch 모드의 시간 값을 초기화해주는 것이고, Lap 모드에서 기록된 시간을 초기화 시켜줄 필요가 있다.

 

 

2.2. 구체적인 구현

  • 구체적인 구현에 대해서는 소스 코드와 함께 설명하도록 하겠다.

< Source , Add button for clear >

// Control Stop Watch
wire btn_start, btn_lap, btn_clear;
button_cntr control_btn_set (.clk(clk), .reset_p(reset_p), .btn(btn[0]), .btn_nedge(btn_start));
button_cntr control_btn_lap (.clk(clk), .reset_p(reset_p), .btn(btn[1]), .btn_nedge(btn_lap));
button_cntr control_btn_clear (.clk(clk), .reset_p(reset_p), .btn(btn[2]), .btn_nedge(btn_clear));
  • Clear 기능을 수행하기 위해서 btn[2] 을 추가하였다.
  • btn[2] 값을 button_cntr 모듈의 argument 값으로 전달시켜 btn[2]가 눌렀음을 확인할 수 있는 One Cycle Pulse를 얻게 되며, 이를 btn_clear 변수에 넣어 저장한다.

 

 

< Source, BCD 60 Counter for clear function >

// BCD 60 Counter (add claer function)
wire [3:0] min10, min1, sec10, sec1;
counter_bcd_60_clear counter_sec(.clk(clk), .reset_p(reset_p), .clk_time(clk_sec), .clear(btn_clear), .bcd1(sec1), .bcd10(sec10));
counter_bcd_60_clear counter_min(.clk(clk), .reset_p(reset_p), .clk_time(clk_min), .clear(btn_clear), .bcd1(min1), .bcd10(min10));
module counter_bcd_60_clear (
    input clk, reset_p,
    input clk_time, 
    input clear,
    output reg [3:0] bcd1, bcd10 );
    
    wire clk_time_nedge;
    edge_detector_n edge_dector_0 (.clk(clk), .reset_p(reset_p), .cp(clk_time), .n_edge(clk_time_nedge));
    
    always @(posedge clk or posedge reset_p) begin
        if(reset_p | clear) begin
            bcd1 = 0;
            bcd10 = 0;
        end
        else if(clk_time_nedge) begin
            if(bcd1 >= 9) begin
                bcd1 = 0;
                if(bcd10 >= 5) bcd10 = 0;
                else bcd10 = bcd10 + 1;
            end else bcd1 = bcd1 + 1;
        end
    end
    
endmodule
  • 새롭게 정의된 clear 기능을 포함한 BCD 60진 카운터이다.
  • clear enable 입력값을 들어오고, clear 변수 값이 true라면 현재까지 Counting하였던 값, bcd1, bcd10에 대해서 0으로 초기화시켜준다.
  • 나머지 기능들은 일반적인 BCD 60진 카운터와 동일하다.

 

 

 

< Source, Clear lap time >

always @(posedge clk or posedge reset_p) begin
    if(reset_p | btn_clear) lap_time = 0;
    else if(btn_lap) lap_time = cur_time;
end
  • clear 버튼의 One Cycle Pulse인 btn_clear가 활성화되면 lap_time을 0으로 초기화 한다. 

 

 

 

 

3. 구현 영상 (리셋 기능 추가)

  • clear 버튼을 누르면 lap time, stop watch time은 0으로 초기화되지만, 자동으로 다시 stop watch가 시작한다.
  • 이부분에 대해서 다음에 수정해보고, 이번 구현에서는 0으로 초기화 되는지만 확인하자.

 

 

 

 

 

 

4. 리셋 버튼을 누를 경우, lap_time과 cur_time은 0분 0초로 초기화 되지만, stop watch가 자동으로 시작한다.

  • 리셋 버튼을 누를 경우, 랩 모드에서 기록한 시간과 스톱워치 모드에서의 시간이 0분 0초로 초기화 되는 것을 관찰했다.
  • 그러나, 0분 0초로 초기화된 뒤, Stop Watch가 자동적으로 실행하는 문제를 확인할 수 있었다.
  • 이를 위해 다음과 같이 코드를 수정하였다.

 // Control Start / Stop mode.
wire reset_start = reset_p | btn_clear;
wire start_stop;
t_flip_flop t_flip_flop_0 (.clk(clk), .reset_p(reset_start), .t(btn_start), .q(start_stop));
    
// Control Lap mode
wire lap;
t_flip_flop t_flip_flop1 (.clk(clk), .reset_p(reset_start), .t(btn_lap), .q(lap));
  • clear 버튼의 One Cycle Pulse와 시스템 리셋 변수인 reset_p를 OR 게이트의 입력으로 넣은 뒤, OR 게이트의 출력 값으로 reset_start 값을 얻을 수 있다.
  • reset_start 변수 값을 stop watch와 lap의 T Flip Flop의 reset_p의  argument 값으로 전달하면 프로그램 시작시, 시행되는 reset_p 뿐만아니라 clear 버튼을 눌렀을 때에도 모드 변수인 start_stop, lap 변수를 0으로 초기화 시켜준다.
  • 이를 통해 reset 버튼을 눌렀음에도 자동적으로 stop watch가 실행되는 문제점을 해결 할 수 있다.

 

 

 

 

5. 구현 영상 (Reset 버튼을 눌렀을 때, Stop Watch가 자동적으로 실행하는 문제점 해결)