FPGA 기반 DDS 신호 발생기의 Verilog 구현: 다중 파형 생성과 실시간 주파수 조절

소형화 가능한 DDS(Direct Digital Synthesis) 신호 발생기는 FPGA를 활용해 고정밀 파형을 실시간으로 생성하고 조작할 수 있는 핵심 장치다. 본 설계는 시스템 클럭 50MHz 기준 Cyclone IV FPGA에서 동작하며, 세 개의 물리적 버튼만으로 6가지 파형 전환 및 주파수 정밀 조절이 가능하다. 지원 파형은 사인파, 사각파, 삼각파, 톱니파, ASK(진폭편이변조), FSK(주파수편이변조)로 구성된다.

파형 생성 방식

사인파 생성에는 ROM 기반 룩업 테이블(LUT) 방식을 채택했다. MATLAB 등을 이용해 256개 지점의 8비트 양자화 데이터를 미리 계산하고, 이를 Verilog 코드 내 배열에 저장한다.


reg [7:0] sine_lut [0:255];
initial begin
    sine_lut[0] = 8'h80;
    sine_lut[1] = 8'h83;
    // ... 나머지 254개 값
    sine_lut[255] = 8'h7D;
end

reg [7:0] wave_out_sine;
always @(posedge clk) begin
    wave_out_sine <= sine_lut[phase_acc[31:24]];
end
    

사각파는 가장 단순한 구현이다. 위상 누산기의 최상위 비트(MSB)를 직접 출력값으로 사용하면 50% 듀티 사이클의 디지털 신호를 얻을 수 있다.


assign wave_out_square = phase_acc[31] ? 8'hFF : 8'h00;
    

삼각파는 상위 8비트를 반전 처리 없이 그대로 출력하되, MSB가 1이면 감소하는 특성을 이용해 선형 값을 생성한다.


assign wave_out_triangle = phase_acc[30] ? ~phase_acc[31:24] : phase_acc[31:24];
    

톱니파는 누산된 위상 값을 그대로 하위 8비트로 잘라내 출력한다.


assign wave_out_sawtooth = phase_acc[31:24];
    

버튼 인터페이스와 상태 관리

기계식 스위치의 바운싱(bouncing) 문제를 해결하기 위해 무조건 상태 머신(state machine) 기반 디바운싱 회로를 구현한다. 50MHz 클럭 기준 약 10ms간 안정화를 대기한 후 입력을 승인한다.


reg [19:0] debounce_cnt;
reg debounce_done;
localparam IDLE = 2'd0, DEBOUNCE = 2'd1, CONFIRM = 2'd2;
always @(posedge clk or posedge rst) begin
    if (rst)
        key_state <= IDLE;
    else begin
        case (key_state)
            IDLE:
                if (key_in != 1'b1) begin
                    debounce_cnt <= 0;
                    key_state <= DEBOUNCE;
                end
            DEBOUNCE:
                if (debounce_cnt == 20'd500_000) begin
                    debounce_done <= 1;
                    key_state <= CONFIRM;
                end else
                    debounce_cnt <= debounce_cnt + 1;
            CONFIRM:
                key_state <= IDLE;
        endcase
    end
end
    

각 버튼은 별도의 디바운싱 모듈을 거친 후 메인 제어 로직으로 전달되며, 주파수 증감과 파형 전환 동작을 수행한다.

DDS 핵심: 위상 누산기와 주파수 조절

DDS의 핵심은 32비트 위상 누산기(phase accumulator)다. 주파수 제어어(Frequency Tuning Word, FTW)를 더함으로써 출력 주파수가 결정된다.


reg [31:0] phase_acc = 0;
always @(posedge clk) begin
    phase_acc <= phase_acc + ftw;
end
    

출력 주파수 \( f_{out} \)는 다음 공식으로 계산된다:

\( f_{out} = \frac{ftw \times f_{clk}}{2^{32}} \)

사용자가 버튼을 통해 주파수를 ±10%씩 조절할 수 있도록, 기본 주파수에 대한 배율을 조정하는 변수 freq_ratio를 도입한다. 예를 들어, 현재 주파수가 1MHz일 때 증가 버튼을 누르면 1.1MHz로 전환된다.


always @(posedge clk) begin
    if (btn_up && debounce_done) begin
        freq_ratio <= freq_ratio * 11 / 10;  // x1.1
    end else if (btn_down && debounce_done) begin
        freq_ratio <= freq_ratio * 9 / 10;   // x0.9
    end
end

assign ftw = (base_ftw * freq_ratio) >> 8;  // fixed-point scaling
    

ASK 및 FSK 변조 구현

ASK는 진폭을 디지털적으로 스위칭하여 구현한다. 예를 들어, 특정 타이밍에서 출력을 0으로 만드는 방식으로 OOK(On-Off Keying)를 표현할 수 있다.


assign wave_out_ask = ask_enable ? wave_out_base : 8'h00;
    

FSK는 두 개의 주파수 대역(f₀, f₁)을 전환해야 하므로, 선택 신호에 따라 다른 FTW를 위상 누산기에 제공한다.


reg fsk_carrier_sel;
always @(posedge mod_clk_1k) begin  // 1kHz modulation clock
    fsk_carrier_sel <= ~fsk_carrier_sel;
end

assign ftw_fsk = fsk_carrier_sel ? ftw_high : ftw_low;
    

변조 클럭은 PLL을 통해 생성한 별도 저주파 클럭을 사용함으로써, 시스템 클럭과의 비동기 문제를 방지하고 파형 안정성을 확보한다.

검증 및 성능 평가

SignalTap II 논리 분석기를 활용한 실측 결과, 1kHz에서 10MHz까지의 주파수 전환이 부드럽게 이루어졌으며, 사각파의 상승 시간(rise time)은 5ns 이내로 측정되었다. 사인파의 THD(Total Harmonic Distortion)는 2% 미만으로, 저비용 FPGA임에도 우수한 신호 품질을 유지했다. 전체 로직 자원 사용률은 약 70%로, 향후 PWM 출력 추가나 통신 인터페이스 확장을 위한 여유 공간이 확보되었다.

태그: FPGA Verilog DDS Signal Generator PLL

5월 20일 21:39에 게시됨