preview
intro
해당 글에서는 Segment에 대해 간단히 알아보고
FPGA 보드에서 Segment를 제어하는 방법에 대해 공유하고자 합니다.
-
💻 about Code
Verilog, XDC 코드는 제 Github 페이지에서 확인할 수 있습니다.해당 코드는 Nexys A7-T100 보드에 맞게 작성되었으며
보드에 따라 코드의 수정이 필요할 수 있습니다.
Segment
7-digit segment는 7개의 막대와 하나의 점으로 구성된 디스플레이 입니다.
각 막대는 A~G로 표기되며 점은 dp라고 불립니다. (그림참고)
각 부분을
조합해서 숫자나 알파벳 등을 표시할 수 있습니다.
Common Anode & Common Cathode

- Common Anode : 모든 세그먼트의 양극(애노드)이 공통으로 연결되어 있으며,
세그먼트를 켜기 위해서는 해당 세그먼트의 음극(캐소드)에 LOW 신호를 인가합니다. - Common Cathode : 모든 세그먼트의 음극(캐소드)이 공통으로 연결되어 있으며,
세그먼트를 켜기 위해서는 해당 세그먼트의 양극(애노드)에 HIGH 신호를 인가합니다.
Multiplexing

여러 개의 7세그먼트 디스플레이를 제어하려면 각각의 디스플레이마다 별도의 핀이 필요하고, 이에 따라 전력 소모도 증가합니다. 하지만 이러한 방식은 비효율적입니다.
이를
해결하기 위해, 8개의 제어 핀을 모든 세그먼트에 공유하여 연결하고, 매우 빠른 속도로 각 디스플레이를 순차적으로 켜고 끄는 멀티플렉싱 방식을 사용합니다. 이 방식은 눈에
보이지 않을 만큼 빠른 전환 속도 덕분에, 마치 여러 디스플레이가 동시에 숫자를 표시하고 있는 것처럼 보이게 해줍니다.
Implement
Hardware
Nexys
A7 레퍼런스를 확인해 보면 Nexys A7-T100 보드에 포함된 세그먼트는 common anode 방식임을 알 수 있습니다. 따라서 세그먼트 제어를 위해
다음과 같은 핀을 사용합니다.
- AN[7:0]: 8개의 디지트(자릿수) 선택 핀
- CA, CB, CC, CD, CE, CF, CG: 각 세그먼트(A-G)
제어 핀
- DP: 소수점 제어 핀
Verilog coding
세그먼트 제어를 위한 Verilog 모듈의 기본 구조는 다음과 같습니다:
module seven_segment_controller (
input wire clk,
input wire [4:0] buttons,
output reg [7:0] segment_display,
output reg [7:0] digit_enable
);
// 구현 코드
endmodule
주요 기능 구현
- 디지트 값 저장: 8개의 디지트에 대한 값을 저장할 레지스터 배열을 선언합니다.
- 버튼 입력 처리: 버튼 입력을 감지하고 디바운싱 처리를 합니다. 버튼에 따라 디지트 선택, 값 변경, 편집 모드 전환 등의 기능을 구현합니다.
- 멀티플렉싱 로직: 고속으로 디지트를 전환하여 모든 디지트가 동시에 켜진 것처럼 보이게 합니다.
- 7-세그먼트 변환: 숫자를 7-세그먼트 패턴으로 변환하는 함수를 구현합니다.
reg [3:0] digit_value [7:0];
always @(posedge clk) begin
if (counter[15:0] == 16'hFFFF) begin
display_digit <= display_digit + 1;
digit_enable <= ~(1 << display_digit);
// 세그먼트 값 설정 로직
end
end
function [7:0] digit_to_7segment;
input [3:0] digit;
case (digit)
4'd0: digit_to_7segment = 8'b11000000; // 0
4'd1: digit_to_7segment = 8'b11111001; // 1
// ... 다른 숫자들 ...
default: digit_to_7segment = 8'b11111111; // blank
endcase
endfunction
XDC 파일 설정
보드의 핀 매핑을 위해 XDC를 작성해 줍니다.
래퍼런스 메뉴얼 9 Basic I/O항목을 보면 세그먼트는 3.3V로 동작하고 각각의 핀의 번호가 명시되어 있으니
참고하면 되겠습니다.
Code
main.v
main.xdc
Buttons (BTNL, BTNR, BTNU, BTND, BTNC)
set_property PACKAGE_PIN P17 [get_ports {buttons[0]}]
set_property IOSTANDARD LVCMOS33
[get_ports {buttons[0]}]
set_property PACKAGE_PIN M17 [get_ports {buttons[1]}]
set_property IOSTANDARD LVCMOS33
[get_ports {buttons[1]}]
set_property PACKAGE_PIN M18 [get_ports {buttons[2]}]
set_property IOSTANDARD LVCMOS33
[get_ports {buttons[2]}]
set_property PACKAGE_PIN P18 [get_ports {buttons[3]}]
set_property IOSTANDARD LVCMOS33
[get_ports {buttons[3]}]
set_property PACKAGE_PIN N17 [get_ports {buttons[4]}]
set_property IOSTANDARD LVCMOS33
[get_ports {buttons[4]}]
Seven Segment Display (segment_display[0] ~ segment_display[7])
set_property PACKAGE_PIN T10 [get_ports {segment_display[0]}]
set_property IOSTANDARD
LVCMOS33 [get_ports {segment_display[0]}]
set_property PACKAGE_PIN R10 [get_ports {segment_display[1]}]
set_property IOSTANDARD
LVCMOS33 [get_ports {segment_display[1]}]
set_property PACKAGE_PIN K16 [get_ports {segment_display[2]}]
set_property IOSTANDARD
LVCMOS33 [get_ports {segment_display[2]}]
set_property PACKAGE_PIN K13 [get_ports {segment_display[3]}]
set_property IOSTANDARD
LVCMOS33 [get_ports {segment_display[3]}]
set_property PACKAGE_PIN P15 [get_ports {segment_display[4]}]
set_property IOSTANDARD
LVCMOS33 [get_ports {segment_display[4]}]
set_property PACKAGE_PIN T11 [get_ports {segment_display[5]}]
set_property IOSTANDARD
LVCMOS33 [get_ports {segment_display[5]}]
set_property PACKAGE_PIN L18 [get_ports {segment_display[6]}]
set_property IOSTANDARD
LVCMOS33 [get_ports {segment_display[6]}]
set_property PACKAGE_PIN H15 [get_ports {segment_display[7]}]
set_property IOSTANDARD
LVCMOS33 [get_ports {segment_display[7]}]
Digit Enable (digit_enable[0] ~ digit_enable[7])
set_property PACKAGE_PIN U13 [get_ports {digit_enable[0]}]
set_property IOSTANDARD
LVCMOS33 [get_ports {digit_enable[0]}]
set_property PACKAGE_PIN K2 [get_ports {digit_enable[1]}]
set_property IOSTANDARD
LVCMOS33 [get_ports {digit_enable[1]}]
set_property PACKAGE_PIN T14 [get_ports {digit_enable[2]}]
set_property IOSTANDARD
LVCMOS33 [get_ports {digit_enable[2]}]
set_property PACKAGE_PIN P14 [get_ports {digit_enable[3]}]
set_property IOSTANDARD
LVCMOS33 [get_ports {digit_enable[3]}]
set_property PACKAGE_PIN J14 [get_ports {digit_enable[4]}]
set_property IOSTANDARD
LVCMOS33 [get_ports {digit_enable[4]}]
set_property PACKAGE_PIN T9 [get_ports {digit_enable[5]}]
set_property IOSTANDARD
LVCMOS33 [get_ports {digit_enable[5]}]
set_property PACKAGE_PIN J18 [get_ports {digit_enable[6]}]
set_property IOSTANDARD
LVCMOS33 [get_ports {digit_enable[6]}]
set_property PACKAGE_PIN J17 [get_ports {digit_enable[7]}]
set_property IOSTANDARD
LVCMOS33 [get_ports {digit_enable[7]}]
Code Review
- 주요 특징과 기능
- 8자리 7-세그먼트 디스플레이 제어
- 5개의 버튼 입력을 사용하여 디스플레이를 조작
- 편집 모드와 일반 모드 지원
- 디스플레이 멀티플렉싱 구현하여 8자리를 동시에 제어
- Code structure
- 모듈 정의
입력: 클럭, 5개 버튼
출력: 7-세그먼트 디스플레이 출력, 자릿수 활성화 신호 - 레지스터 정의
각 자릿수의 값, 현재 선택된 자릿수, 카운터, 이전 버튼 상태 등 - 버튼 로직
디바운싱을 위한 카운터 사용
좌/우 버튼으로 자릿수 선택
중앙 버튼으로 편집 모드 전환
위/아래 버튼으로 선택된 자릿수 값 변경 - 블링킹 로직
약 0.5초 간격으로 선택된 자릿수 깜빡임 - 디스플레이 멀티플렉싱
고속으로 각 자릿수를 순환하며 표시
현재 활성화된 자릿수만 켜짐 - 7-세그먼트 변환 함수
0-9 숫자를 7-세그먼트 패턴으로 변환
- 모듈 정의