적절한 주파수 선택은 대상 디바이스 의존. LED는 가시적 깜빡임 방지 위해 수백 헤르츠면 충분. 브러시리스 DC 모터는 보통 수십 킬로헤르츠 범위 동작; 주파수 너무 낮으면 기계적 진동, 너무 높으면 전력 낭비.
MOSFET 스위치가 FPGA 로직보다 느리므로 PWM을 너무 빠르게 동작시키면 트랜지스터가 부분 도통 상태에서 시간 보내 추가 열 발생.
PWM 생성기 모듈
아래는 어떤 카운터 폭과 클럭 분주 인자로도 인스턴스화 가능한 제네릭 VHDL PWM 컨트롤러 구현.
엔티티 선언
entity pwm is generic ( pwm_bits : integer; clk_cnt_len : positive := 1 ); port ( clk : in std_logic; rst : in std_logic; duty_cycle : in unsigned(pwm_bits - 1 downto 0); pwm_out : out std_logic ); end pwm;
clk와 rst 포트가 동기 제어 제공. duty_cycle 입력 폭은 pwm_bits로 정의되어 카운터 해상도 직접 구성 가능. pwm_out 신호는 MOSFET 게이트 구동하는 FPGA 핀으로 라우팅.
내부 신호
signal pwm_cnt : unsigned(pwm_bits - 1 downto 0); signal clk_cnt : integer range 0 to clk_cnt_len - 1;
pwm_cnt 카운터가 듀티 사이클 폭 미러링. clk_cnt 카운터가 선택적 클럭 분주 구현; clk_cnt_len을 1로 설정하면 분주 비활성화 및 관련 로직 제거.
클럭 분주 프로세스
CLK_CNT_PROC : process(clk) begin if rising_edge(clk) then if rst = '1' then clk_cnt <= 0; else if clk_cnt < clk_cnt_len - 1 then clk_cnt <= clk_cnt + 1; else clk_cnt <= 0; end if; end if; end if; end process;
기본 clk_cnt_len = 1이면 합성 도구가 이 프로세스 자동 제거.
PWM 출력 프로세스
PWM_PROC : process(clk) begin if rising_edge(clk) then if rst = '1' then pwm_cnt <= (others => '0'); pwm_out <= '0'; else if clk_cnt_len = 1 or clk_cnt = 0 then pwm_cnt <= pwm_cnt + 1; pwm_out <= '0'; if pwm_cnt = unsigned(to_signed(-2, pwm_cnt'length)) then pwm_cnt <= (others => '0'); end if; if pwm_cnt < duty_cycle then pwm_out <= '1'; end if; end if; end if; end if; end process;
카운터는 clk_cnt가 0일 때만 증가하여 PWM 주파수 효과적으로 스로틀링. pwm_cnt를 두 번째로 높은 값에서 리셋하는 조건문이 100% 듀티 사이클 달성 보장.