VHDL로 디지털 하드웨어를 기술하는 법

VHDL의 설계 단위, 타입 시스템, 모델링 방식과 합성 시 제약을 중심으로 디지털 하드웨어 설계 언어의 구조를 정리한다.

2026-08-14 · 최초 발행 2026-01-16

회로의 인터페이스와 구현을 나누는 언어

VHDL(VHSIC Hardware Description Language)은 디지털 회로와 시스템의 구조, 동작을 텍스트로 기술하는 하드웨어 기술 언어다. 미국 국방부의 VHSIC(Very High Speed Integrated Circuit) 프로젝트에서 복잡한 집적 회로를 문서화하고 시뮬레이션하기 위해 개발됐으며, 이후 IEEE 1076 표준으로 자리 잡았다.

Ada 기반 문법과 명시적 타입 선언은 대규모 디지털 시스템에서 설계 의도를 분명히 드러낸다. 신호와 변수의 타입을 분명하게 다루고, 하드웨어의 병렬 동작을 언어 구조로 표현하며, 시뮬레이션과 실제 하드웨어 합성을 함께 지원한다. 유럽, 항공우주, 군사 분야와 의료기기에서 널리 쓰이는 배경도 이런 엄격한 표현 방식에 있다.

VHDL은 계층을 가진 모듈 구조로 시스템을 나눌 수 있어, 큰 설계도 단위별로 관리할 수 있다.

표준 개정으로 확장된 VHDL

1981VHSIC 프로젝트 시작1983VHDL 개발 착수1987IEEE 1076 표준화1993VHDL-93 개정2002VHDL-20022008VHDL-20082019VHDL-2019

표준은 계속 개정됐다. VHDL-2008에는 고정 소수점 패키지, 향상된 제네릭, PSL(Property Specification Language) 통합이 포함됐고, VHDL-2019에서는 인터페이스와 API가 개선됐다.

설계를 이루는 단위와 경계

VHDL 설계는 다섯 가지 설계 단위(Design Unit)로 나뉜다.

설계 단위 역할 특징
Entity 모듈의 외부 인터페이스 정의 포트, 제네릭 선언
Architecture 모듈의 내부 구현 동작, 구조, 데이터플로우
Configuration 엔티티와 아키텍처 바인딩 다중 아키텍처 선택
Package 공유 타입, 상수, 함수 정의 라이브러리화 지원
Package Body 패키지에 선언된 함수 본문 구현 세부사항 캡슐화

이 가운데 Entity와 Architecture의 분리는 VHDL 설계의 중심 구조다. Entity가 블랙박스의 외부 인터페이스를 정의한다면, Architecture는 그 인터페이스 뒤의 동작을 구현한다.

Entity에는 포트와 제네릭을 선언한다.

entity counter is
    generic (
        WIDTH : integer := 8
    );
    port (
        clk     : in  std_logic;
        rst_n   : in  std_logic;
        enable  : in  std_logic;
        count   : out std_logic_vector(WIDTH-1 downto 0)
    );
end entity counter;

Architecture는 신호와 프로세스를 사용해 내부 동작을 적는다.

architecture rtl of counter is
    signal count_reg : unsigned(WIDTH-1 downto 0);
begin
    process(clk, rst_n)
    begin
        if rst_n = '0' then
            count_reg <= (others => '0');
        elsif rising_edge(clk) then
            if enable = '1' then
                count_reg <= count_reg + 1;
            end if;
        end if;
    end process;

    count <= std_logic_vector(count_reg);
end architecture rtl;

강타입 시스템이 표현하는 신호 상태

VHDL은 신호와 변수의 타입을 명시하는 강타입 언어다. 기본 스칼라 타입으로는 bit, boolean, integer, real, character, time이 있다. bit'0' 또는 '1'만 표현하며, booleanTRUE 또는 FALSE를 쓴다. integer의 범위는 -2^31 ~ 2^31-1이고, time은 시뮬레이션에 사용된다.

실제 하드웨어 신호 상태를 다루려면 IEEE 1164의 std_logicstd_logic_vector가 중요하다. 이들은 9-값 논리 시스템을 제공한다.

의미 합성 시 해석
'U' 초기화되지 않음 시뮬레이션용
'X' 강한 Unknown 충돌 상태
'0' 강한 0 논리 0
'1' 강한 1 논리 1
'Z' 고임피던스 트라이스테이트
'W' 약한 Unknown 시뮬레이션용
'L' 약한 0 풀다운
'H' 약한 1 풀업
'-' Don't Care 최적화 힌트

배열과 레코드는 데이터 구조를 회로 설계에 맞게 묶는 데 사용한다.

type byte_array is array (0 to 255) of std_logic_vector(7 downto 0);
type matrix is array (natural range <>, natural range <>) of integer;
type packet_t is record
    valid   : std_logic;
    addr    : std_logic_vector(31 downto 0);
    data    : std_logic_vector(63 downto 0);
    strobe  : std_logic_vector(7 downto 0);
end record;

회로를 서술하는 모델링 관점

구조적 모델링은 하위 컴포넌트를 인스턴스화하고 서로 연결하는 방식이다. 계층적 설계에 적합하다.

architecture structural of full_adder is
    component half_adder
        port (a, b : in std_logic; sum, carry : out std_logic);
    end component;
    signal s1, c1, c2 : std_logic;
begin
    HA1: half_adder port map (a => a, b => b, sum => s1, carry => c1);
    HA2: half_adder port map (a => s1, b => cin, sum => sum, carry => c2);
    cout <= c1 or c2;
end architecture;

데이터플로우 모델링은 신호 사이의 흐름을 동시 할당문으로 나타낸다. 조합 논리를 직접 표현할 때 쓴다.

architecture dataflow of full_adder is
begin
    sum  <= a xor b xor cin;
    cout <= (a and b) or (cin and (a xor b));
end architecture;

동작적 모델링은 process 문 안에 순차적 알고리즘으로 동작을 기술한다. 순차 논리와 FSM을 다룰 때 사용할 수 있다.

병렬 문장과 프로세스 내부 문장의 차이

Architecture 안의 동시문(Concurrent Statements)은 병렬로 실행되며, 하드웨어의 병렬 동작을 표현한다. 신호 할당문, when-else 조건 신호 할당, with-select 선택 신호 할당, 컴포넌트 인스턴스화, Generate 문, Process 문이 여기에 속한다.

반면 순차문(Sequential Statements)은 Process 안에서 위에서 아래로 실행된다. 변수 할당에는 :=를 사용하고, 신호 할당은 스케줄링을 의미하는 <=를 사용한다. if-then-else, case, forwhile 루프, wait도 프로세스 안에서 사용하는 순차문이다.

process(clk, rst_n)
begin
    if rst_n = '0' then
        state <= IDLE;
    elsif rising_edge(clk) then
        case state is
            when IDLE =>
                if start = '1' then
                    state <= RUNNING;
                end if;
            when RUNNING =>
                if done = '1' then
                    state <= COMPLETE;
                end if;
            when COMPLETE =>
                state <= IDLE;
            when others =>
                state <= IDLE;
        end case;
    end if;
end process;

Verilog와 다른 언어적 선택

항목 VHDL Verilog
기반 언어 Ada C
타입 시스템 강타입 약타입
대소문자 구분 구분 안함 구분함
배열 인덱싱 유연 (to, downto) 고정 [high:low]
문장 종료 세미콜론 세미콜론
코드 양 상대적으로 많음 간결함
학습 곡선 가파름 완만함

VHDL은 항공우주, 군사/방산, 유럽 반도체, 의료기기 분야에서 주요하게 사용된다. Verilog는 미국 반도체, 아시아 팹리스, 소비자 가전, 모바일 AP 분야에서 주요하게 사용된다.

합성 가능한 RTL을 작성할 때

VHDL 문법으로 작성한 모든 코드가 하드웨어로 합성되는 것은 아니다. 합성 도구가 인식하는 코딩 패턴을 지켜야 한다.

합성 가능한 구조에는 rising_edge(clk) 또는 falling_edge(clk) 기반 레지스터, 래치를 방지하는 완전한 if-else 또는 case 문, 조합 논리의 모든 입력을 포함한 민감도 리스트, 정의된 비트 폭의 신호 연산이 있다. 반대로 wait for 시간 지연, 파일 I/O, 동적 메모리 할당, 정적으로 펼칠 수 없는 일부 반복문은 합성할 수 없다.

동기 레지스터는 다음과 같이 기술할 수 있다.

process(clk, rst_n)
begin
    if rst_n = '0' then
        q <= '0';
    elsif rising_edge(clk) then
        q <= d;
    end if;
end process;

VHDL-2008 이후의 조합 논리에서는 process(all)을 사용할 수 있다.

process(all)  -- VHDL-2008 이후
begin
    case sel is
        when "00" => y <= a;
        when "01" => y <= b;
        when "10" => y <= c;
        when others => y <= d;
    end case;
end process;

제네릭과 Generate로 만드는 재사용 구조

제네릭은 재사용 가능한 모듈의 파라미터를 선언하는 수단이다.

entity fifo is
    generic (
        DATA_WIDTH : integer := 8;
        DEPTH      : integer := 16
    );
    port (
        clk     : in  std_logic;
        rst_n   : in  std_logic;
        wr_en   : in  std_logic;
        rd_en   : in  std_logic;
        din     : in  std_logic_vector(DATA_WIDTH-1 downto 0);
        dout    : out std_logic_vector(DATA_WIDTH-1 downto 0);
        full    : out std_logic;
        empty   : out std_logic
    );
end entity;

Generate 문은 조건부 또는 반복적인 하드웨어 구조를 생성할 때 사용한다.

gen_registers: for i in 0 to 7 generate
    reg_inst: entity work.reg8
        port map (
            clk => clk,
            d   => din((i+1)*8-1 downto i*8),
            q   => dout((i+1)*8-1 downto i*8)
        );
end generate;

VHDL-2008은 process all 키워드, 고정 소수점 패키지, 향상된 제네릭, 외부 이름, PSL 통합, 향상된 연산자를 제공한다. 향상된 제네릭은 타입과 서브프로그램 제네릭을 포함하며, process all은 민감도 리스트 작성을 자동화한다.

VHDL하드웨어 설계RTLIEEE 1076디지털 회로