§ Описание

Этот модуль сделан специально для платы Марсоход2, а точнее говоря, для его шилда коннектов. Конечно, его можно адаптировать для каких угодно проектов, просто там создана особая схема, которую, если переделывать, надо тоже учитывать.
Схема этого шилда я прикрепил в этом PDF.

Модуль генерирует некоторый уровень напряжения на выходе, основываясь на скорости обновления 0 или 1 на входе. То есть уровень напряжения напрямую зависит от скважности 0 и 1 на входе, то есть, другими словами, двоичный сигнал на 1 проводе преобразуется в аналоговый.

§ Верхний уровень

PWM-модуль для преобразования числа 0..255 в PWM для канала аудио на шилде Марсоход2
audio_pwm AUDIO_PWM(

    .clk  (clk),                  // 100 MHz
    .vol  (...),                  // громкость 0..255 [0..1]
    .pwm  (sound_left)            // sound_left или sound_right, либо другой wire
);

§ Код

PWM-модуль для преобразования числа 0..255 в PWM для канала аудио на шилде Марсоход2
module audio_pwm(

    input  wire       clk,    // 100 mhz
    input  wire [7:0] vol,    // 0..255
    output reg        pwm     // 0/1

);

    reg [9:0] DeltaAdder; // Output of Delta adder
    reg [9:0] SigmaAdder; // Output of Sigma adder
    reg [9:0] SigmaLatch; // Latches output of Sigma adder
    reg [9:0] DeltaB;     // B input of Delta adder

    always @(SigmaLatch)
        DeltaB = {SigmaLatch[9], SigmaLatch[9]} << (8);

    always @(vol or DeltaB)
        DeltaAdder = vol + DeltaB;

    always @(DeltaAdder or SigmaLatch)
        SigmaAdder = DeltaAdder + SigmaLatch;

    always @(posedge clk)
    begin
        SigmaLatch <= SigmaAdder;
        pwm <=  SigmaLatch[9];
    end

endmodule

§ Бинауральные биения

Простой пример, который выдает нечто похожее на бинауральные ритмы
audio_pwm AudioLf(

    .clk  (clk),
    .vol  (vol_lf),
    .pwm  (sound_left)
);

audio_pwm AudioRt(

    .clk  (clk),
    .vol  (vol_rt),
    .pwm  (sound_right)
);

// --------------------------------------------------------------------------
integer lcnt;
integer rcnt;
integer ncnt;

parameter vol = 1;

// 1HZ = (25.000.000/2)
// Nhz = (25.000.000/2)/N
integer llen = 50000; // 250 hz
integer rlen = 48076; // 260 hz

always @(posedge clock_25) begin

	lcnt <= lcnt + 1;
	rcnt <= rcnt + 1;

	if (lcnt > llen) begin lcnt <= 0; vol_lf <= vol_lf == 128-vol ? 128+vol : 128-vol; end
	if (rcnt > rlen) begin rcnt <= 0; vol_rt <= vol_rt == 128-vol ? 128+vol : 128-vol; end

end