Verilog_RTL 설계/Basys_3

[Basys_3] Implementation of a 7-Segment Counter Circuit with Debouncing and Edge Detection

juniha 2025. 7. 7. 20:35

목적 

  • 비동기 리셋, 버튼 디바운싱, 에지 검출, 카운터, 7세그먼트 디코더를 조합하여 FPGA에서 정확한 사용자 입력 기반의 디지털 카운터 시스템을 구현

 

사용 코드 _ top_module

module counter_top(
    input clk,               // 시스템 클럭
    input reset_p,           // 비동기 리셋 입력 (양의 엣지에서 작동)
    input btn,               // 버튼 입력 (사용자가 누름)
    output [7:0] seg_7,      // 7세그먼트 LED 출력 (a~g + dp)
    output [3:0] com         // FND의 자릿수 선택 (common)
);
    
    reg [3:0] count;         // 현재 카운트 값 (0~15, 4비트)
    wire btn_nedge;          // 버튼 하강 에지 검출 신호

    // 버튼 하강 에지를 감지하는 서브모듈 (디바운싱 포함)
    botton_cntr btn0(
        .clk(clk), 
        .reset_p(reset_p), 
        .btn(btn), 
        .btn_nedge(btn_nedge)
    );
        
    // 버튼이 눌려졌을 때(count 증가), 또는 리셋일 때 동작
    always @(posedge clk, posedge reset_p) begin
        if (reset_p)
            count = 0;               // 리셋 시 카운터 초기화
        else if (btn_nedge)
            count = count + 1;       // 버튼 하강 에지 시 카운트 증가
    end
    
    // 현재 count 값을 7세그먼트에 표시
    fnd_4digit_cntr fnd(
        .value(count), 
        .seg_7(seg_7), 
        .com(com)
    );
   
endmodule

 

 

 

사용 코드_2 _하위 모듈

module botton_cntr(
    input clk,               // 시스템 클럭 입력
    input reset_p,           // 비동기 리셋 (양의 엣지에서 동작)
    input btn,               // 버튼 입력
    output btn_pedge,        // 버튼 상승 에지 감지 출력
    output btn_nedge         // 버튼 하강 에지 감지 출력
);

    // 17비트 클럭 분주기: 버튼 디바운싱을 위한 느린 클럭 생성
    reg [16:0] clk_div;
    always @(posedge clk)
        clk_div = clk_div + 1;   // 클럭 상승엣지마다 증가 (자동 순환)

    // 분주된 클럭의 상승 에지를 검출하기 위한 와이어
    wire clk_div_16_pedge;
    edge_detector_p edp(              // 클럭 분주기의 bit[16]에서 에지 검출
        .clk(clk), 
        .reset_p(reset_p), 
        .cp(clk_div[16]), 
        .p_edge(clk_div_16_pedge)
    );

    // 디바운싱된 버튼 값을 저장하는 레지스터
    reg debounced_btn;
    always @(posedge clk, posedge reset_p) begin
        if (reset_p)
            debounced_btn = 0;       // 리셋 시 버튼 값 초기화
        else if (clk_div_16_pedge)
            debounced_btn = btn;     // 분주된 클럭에서 버튼 값 샘플링
    end

    // 디바운싱된 버튼 값의 상승/하강 에지 검출기
    edge_detector_p ed(
        .clk(clk), 
        .reset_p(reset_p), 
        .cp(debounced_btn), 
        .p_edge(btn_pedge),    // 버튼 상승 에지 출력
        .n_edge(btn_nedge)     // 버튼 하강 에지 출력
    );

endmodule

사용 코드_2 하위 모듈 _edge_detector

  • 입력 신호(cp)의 상승 엣지 또는 하강 에지를 검출하는 엣지 검출기(edge detector)
module edge_detector_p(
    input clk,             // 클럭 입력
    input reset_p,         // 비동기 리셋 입력 (posedge 기준)
    input cp,              // 엣지를 감지할 입력 신호
    output p_edge,         // 양의 엣지(상승 에지) 검출 출력
    output n_edge          // 음의 엣지(하강 에지) 검출 출력
);
    
    reg ff_cur, ff_old;    // 현재 값과 이전 값을 저장할 플립플롭

    // 클럭 상승 또는 리셋 상승 시 동작
    always @(posedge clk, posedge reset_p) begin
        if (reset_p) begin
            ff_cur = 0;     // 리셋 시 플립플롭 초기화
            ff_old = 0;
        end
        else begin
            ff_old <= ff_cur;  // 이전 상태 저장
            ff_cur <= cp;      // 현재 입력 cp 저장
        end
    end   
    
    // 양의 에지 검출: 이전 값 0 → 현재 값 1
    assign p_edge = {ff_cur, ff_old} == 2'b10 ? 1 : 0;

    // 음의 에지 검출: 이전 값 1 → 현재 값 0
    assign n_edge = {ff_cur, ff_old} == 2'b01 ? 1 : 0;
                
endmodule

 

Schematic_top_module

결과 동작

결론

1) 버튼 처리: botton_cntr

  • 버튼은 노이즈(글리치)가 발생하므로, 디바운싱엣지 검출이 필요합니다.
  • botton_cntr 모듈은 내부적으로 다음을 포함합니다:
    • 클럭 분주기 (clk_div)를 통해 느린 주기로 샘플링
    • 디바운싱 처리: 지정된 주기마다 버튼 상태를 읽음
    • edge_detector_p 모듈을 사용해 버튼의 상승/하강 에지를 검출

 2) 카운터 회로: counter_top

  • counter_top은 최상위 모듈로, 다음과 같은 역할을 수행합니다:
    • botton_cntr의 출력으로부터 버튼 하강 에지 감지
    • 버튼이 눌릴 때마다 4비트 레지스터 count 값을 +1
    • 리셋 시 count는 0으로 초기화

 3) 7세그먼트 디코딩: fnd_4digit_cntr + decoder_7seg

  • fnd_4digit_cntr는 decoder_7seg 모듈을 통해 count 값을 **7세그먼트용 8비트 신호(seg_7)**로 변환
  • com 신호는 어떤 자릿수에 출력할지를 선택 (4'b0011으로 고정, 1자리 출력)

 동작에 대한 결론

 

  • 전원이 인가되고 reset_p가 HIGH로 입력되면 카운터는 0부터 시작
  • 사용자가 버튼을 누를 때마다:
    1. 버튼 신호가 디바운싱 처리됨
    2. 하강 에지가 감지됨
    3. 카운터가 1 증가
    4. 새로운 숫자가 7세그먼트에 표시됨

 

 

'Verilog_RTL 설계 > Basys_3' 카테고리의 다른 글

[Baysys_3] Stop_Watch  (2) 2025.07.09
[Basys_3]_Alarm / Timer  (0) 2025.07.09
[Sequential Circuit] Ring_Counter  (0) 2025.07.07
[Sequential Circuit] Down_Counter  (0) 2025.07.07
[Sequential Circuit] Up_Counter  (1) 2025.07.07