以verilog

时间:2017-11-16 22:38:41

标签: audio verilog

所以我试图通过音频控制器产生声音,通过创建各种频率的方波,具体取决于哪个开关在FPGA上翻转。我正在使用一个芯片时钟为48kHz的音频控制器,所以我正在使用一个时钟分频器(每个音符一个,现在没有必要,但如果你想知道为什么我这样做会更晚)计算每个音符的占空比,每半个占空比在+幅度和幅度之间翻转。由于某种原因,我能够输出音频,但音符的音调并不代表我给它们的频率(音调看起来是随机的,并且音调比它们应该高得多)。我已经在网上搜索干了,无法想出解决方案,为什么会这样...任何帮助都非常感谢!

以下是我的代码片段:

// Positive and negative amplitude parameters for square wave
parameter pos_amp = 32'h7FFFFFFF;
parameter neg_amp = 32'h80000000;

// Determines channel_audio_out via dac_out
wire signed [32:1] channel_audio_out = dac_out ? pos_amp : neg_amp;

// Seperate 8-bit counter for each note
reg [7:0] ac_counter_C4;
reg [7:0] ac_counter_D4;
reg [7:0] ac_counter_E4;
reg [7:0] ac_counter_F4;
reg [7:0] ac_counter_G4;
reg [7:0] ac_counter_A4;
reg [7:0] ac_counter_B4;

reg clear_audio_out_memory;             // To clear audio_out buffer when no SW is flipped
reg write_audio_out;                            // To signal when to write to audio_out buffer
reg dac_out;                                    // Determines pos_amp or neg_amp for channel_audio_out

// Determines dac_out via ac_counter's (AUD_XCK dividers)
always@(posedge AUD_XCK) // 48kHz
begin
    clear_audio_out_memory <= 1'b0;
        if (SW[0] == 1'b1) // C4 --- f = 261.626 Hz --- Duty Cycle = 184
            begin
                ac_counter_C4 <= ac_counter_C4 + 1'b1;
                if (ac_counter_C4 >= 8'd183)
                    ac_counter_C4 <= 8'd0;
                write_audio_out <= 1'b1;
                dac_out = (ac_counter_C4 < 8'd92) ? 1'b1 : 1'b0;
            end
        else if (SW[1] == 1'b1) // D4 --- f = 293.665 Hz --- Duty Cycle = 164
            begin
                ac_counter_D4 <= ac_counter_D4 + 1'b1;
                if (ac_counter_D4 >= 8'd163)
                    ac_counter_D4 <= 8'd0;
                write_audio_out <= 1'b1;
                dac_out = (ac_counter_D4 < 8'd82) ? 1'b1 : 1'b0;
            end
        else if (SW[2] == 1'b1) // E4 --- f = 329.628 Hz --- Duty Cycle = 146
            begin
                ac_counter_E4 <= ac_counter_E4 + 1'b1;
                if (ac_counter_E4 >= 8'd145)
                    ac_counter_E4 <= 8'd0;
                write_audio_out <= 1'b1;
                dac_out = (ac_counter_E4 < 8'd73) ? 1'b1 : 1'b0;
            end
        else if (SW[3] == 1'b1) // F4 --- f = 349.228 Hz --- Duty Cycle = 138 // Wrong note completely
            begin
                ac_counter_F4 <= ac_counter_F4 + 1'b1;
                if (ac_counter_F4 >= 8'd137)
                    ac_counter_F4 <= 8'd0;
                write_audio_out <= 1'b1;
                dac_out = (ac_counter_F4 < 8'd69) ? 1'b1 : 1'b0;
            end
        else if (SW[4] == 1'b1) // G4 --- f = 391.995 Hz --- Duty Cycle = 122
            begin
                ac_counter_G4 <= ac_counter_G4 + 1'b1;
                if (ac_counter_G4 >= 8'd121)
                    ac_counter_G4 <= 8'd0;
                write_audio_out <= 1'b1;
                dac_out = (ac_counter_G4 < 8'd61) ? 1'b1 : 1'b0;
            end
        else if (SW[5] == 1'b1) // A4 --- f = 440 Hz --- Duty Cycle = 110
            begin
                ac_counter_A4 <= ac_counter_A4 + 1'b1;
                if (ac_counter_A4 >= 8'd109)
                    ac_counter_A4 <= 8'd0;
                write_audio_out <= 1'b1;
                dac_out = (ac_counter_A4 < 8'd55) ? 1'b1 : 1'b0;
            end
        else if (SW[6] == 1'b1) // B4 --- f = 493.883 Hz --- Duty Cycle = 98
            begin
                ac_counter_B4 <= ac_counter_B4 + 1'b1;
                if (ac_counter_B4 >= 8'd97)
                    ac_counter_B4 <= 8'd0;
                write_audio_out <= 1'b1;
                dac_out = (ac_counter_B4 < 8'd44) ? 1'b1 : 1'b0;
            end
        else // NO SWITCH ON --- DEFAULT STATE
            begin

                ac_counter_C4 <= 1'd0;
                ac_counter_D4 <= 1'd0;
                ac_counter_E4 <= 1'd0;
                ac_counter_F4 <= 1'd0;
                ac_counter_G4 <= 1'd0;
                ac_counter_A4 <= 1'd0;
                ac_counter_B4 <= 1'd0;

                write_audio_out <= 1'b0;
                clear_audio_out_memory <= 1'b1;
                dac_out <= 1'b0;
            end
end

谢谢!

1 个答案:

答案 0 :(得分:0)

如果我正确理解您的系统,您是否应该生成指定频率的正弦波幅度值作为DAC的输入? 。如果你向DAC输入2幅度信号,我假设模拟输出也是一个方波,它基本上是你所需的基频和更高次谐波的组合(这些可能会导致明显更高的音调)。 / p>