VHDL 레코드로 깔끔하고 재사용 가능한 FIFO 인터페이스 만들기
VHDL에서 레코드(record)는 C의 구조체(struct)처럼 설계를 간소화하는 강력한 방법입니다. 관련 신호들을 단일 타입으로 그룹화하면 코드 중복을 크게 줄이고 가독성을 높이며 여러 엔티티 간 포트 맵을 단순화할 수 있습니다.
레코드는 오프칩 메모리나 FIFO 연결 같이 크고 반복되는 인터페이스에서 빛을 발합니다. 같은 제어·데이터 신호 세트가 반복 등장할 때 레코드를 패키지에 한 번 정의하고 어디서나 재사용하면 엔티티 인터페이스가 깔끔해지고 향후 수정이 쉬워집니다.
다음 예제는 전용 패키지(example_record_pkg.vhd)에 두 레코드 타입을 만들고 FIFO 입·출력 신호를 모델링하는 방법을 보여줍니다. 단일 레코드 신호가 FIFO로부터의 모든 입력을, 다른 하나가 FIFO로의 모든 출력을 나타냅니다.
핵심 포인트:
- 레코드는 VHDL 엔티티 선언과 포트 맵을 단순화함.
std_logic, integer, std_logic_vector 등 다양한 타입 요소 보유 가능.
- C 구조체와 유사해 많은 엔지니어에게 친숙한 패러다임 제공.
- 공유 레코드 타입은 단일 패키지에 두어 일관성 유지.
- 레코드 신호는 상수로 초기화해 예측 가능한 시작 값 보장.
- 레코드 배열로 구조화된 데이터 처리 가능(예: FIFO 설정 테이블).
아래는 패키지 정의와 레코드 타입을 사용해 FIFO 읽기/쓰기 로직을 관리하는 예제 엔티티입니다. 코드는 IEEE 1076-2008 표준을 완벽 준수합니다.
library ieee; use ieee.std_logic_1164.all; package example_record_pkg is -- FIFO로부터의 출력. type t_FROM_FIFO is record wr_full : std_logic; -- FIFO Full Flag rd_empty : std_logic; -- FIFO Empty Flag rd_dv : std_logic; rd_data : std_logic_vector(7 downto 0); end record t_FROM_FIFO; -- FIFO로의 입력. type t_TO_FIFO is record wr_en : std_logic; wr_data : std_logic_vector(7 downto 0); rd_en : std_logic; end record t_TO_FIFO; constant c_FROM_FIFO_INIT : t_FROM_FIFO := (wr_full => '0', rd_empty => '1', rd_dv => '0', rd_data => (others => '0')); constant c_TO_FIFO_INIT : t_TO_FIFO := (wr_en => '0', wr_data => (others => '0'), rd_en => '0'); end package example_record_pkg;
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.example_record_pkg.all; -- 패키지 사용! entity example_record is port ( i_clk : in std_logic; i_fifo : in t_FROM_FIFO; o_fifo : out t_TO_FIFO := c_TO_FIFO_INIT -- 출력 레코드 초기화 ); end example_record; architecture behave of example_record is signal r_WR_DATA : unsigned(7 downto 0) := (others => '0'); begin -- FIFO 쓰기 처리 p_FIFO_WR : process (i_clk) is begin if rising_edge(i_clk) then if i_fifo.wr_full = '0' then o_fifo.wr_en <= '1'; o_fifo.wr_data <= std_logic_vector(r_WR_DATA + 1); end if; end if; end process p_FIFO_WR; -- FIFO 읽기 처리 p_FIFO_RD : process (i_clk) is begin if rising_edge(i_clk) then if i_fifo.rd_empty = '0' then o_fifo.rd_en <= '1'; end if; end if; end process p_FIFO_RD; end behave;