Проект

Общее

Профиль

Dac pcm5102

// BCK -> bclk              Bit Clock (Тактирование бит)
// OUT (или DIN) -> dout    Data In (Серийные данные)
// LRCK -> lrck             Word Select (Левый/Правый канал)
// SCK -> GND               (на плате модуля часто уже есть перемычка) или подать clk
// VCC -> 3.3V
// GND -> GND
/*
Перемычки для пайки:
H1L: FLT - Выбор фильтра: Нормальная задержка (Низкая) / Низкая задержка (Высокая)
H2L: DEMP - Управление де-эмфазисом для частоты дискретизации 44.1 кГц: Выкл (Низкая) / Вкл (Высокая)
H3L: XSMT - Управление мягким отключением звука: Мягкое отключение звука (Низкая) / Мягкое включение звука (Высокая)
H4L: FMT - Выбор аудиоформата: I2S (Низкая) / Left justified (Высокая)
Обычно работает без всякой пайки! Однако, если возникнут какие-либо проблемы, предлагаю попробовать с
FLT:Низкая, DEMP: Низкая, XSMT: Высокая, FMT: Низкая”

Эти платы приходят в приглушенном состоянии.
Чтобы включить звук, нужно подтянуть XSMT к высокому уровню.
Можно припаять перемычку 3 к H на задней стороне платы или соединить вывод "3" с A3V3 (тот, что между выводом 4 и G).
Состояние подтяжки FMT важно для чистого звука. Если подтянуть неправильно, звук может быть искажен.

Характеристики
Разрешение ЦАП	                    До 32 бит
Частота дискретизации (макс.)       384 кГц
Динамический диапазон               112 дБ
Отношение сигнал/шум                112 дБ
Выходное напряжение (RMS)           2.1 В
Интерфейс                           I2S
Напряжение питания                  От 2.7 до 3.6 В (для чипа); модули обычно используют 3.3 В или 5 В

Таблица настроек для популярных частот
Частота (Fs)    Нужный CLK (256 * Fs)	    Делитель (bclk_divider)			BCLK (Fs * 64)
44.1 кГц        11.2896 МГц                 2   (т.к. 11.28/2.82/2)         2.8224 МГц
48 кГц          12.288 МГц                  2                               3.072 МГц
48 кГц          24.576 МГц                  4                               3.072 МГц
96 кГц          24.576 МГц                  2                               6.144 МГц
192 кГц         49.152 МГц                  2                               12.288 МГц

I2S Format: 24-bit, 64 BCLKs per frame, MSB first, 1-bit delay after LRCK
*/
module dac_pcm5102 #(
    parameter RATIO = 4             // Делитель для BCLK (по умолчанию 4 для 48кГц при 24.576МГц)
)(
    input  wire         clk,        // Основной тактовый сигнал (н-р, 24.576 МГц)   SCK
    input  wire         rst_n,      // reset удерживается в низком состоянии во время перенастройки тактовых генераторов
    input  wire [23:0]  data_left,  // Входные данные левого канала
    input  wire [23:0]  data_right, // Входные данные правого канала
    input  wire         data_valid, // Импульс готовности новых данных

    output reg          bclk,       // Bit Clock на PCM5102                         BCK
    output reg          lrck,       // Left/Right Clock (WS)                        LRCK
    output reg          dout,       // Data Out                                     OUT (или DIN)
    output reg          data_req    // Запрос на новые данные (для AGC/Фильтров)
);

    // Параметры для частоты 48 кГц при clk 24.576 МГц:
    // BCLK = 48кГц * 64 = 3.072 МГц. Делитель = 24.576 / 3.072 / 2 = 4.
    reg [7:0] bclk_divider;
    reg [5:0] bit_cnt;      // Счетчик бит (0-63)
    reg [63:0] shift_reg;   // Сдвиговый регистр для двух каналов

    // Генерация BCLK (Bit Clock)
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            bclk_divider <= 0;
            bclk <= 0;
        end else begin
            if (bclk_divider == RATIO - 1) begin
                bclk_divider <= 0;
                bclk <= ~bclk;
            end else begin
                bclk_divider <= bclk_divider + 1'b1;
            end
        end
    end

    // Основная логика передачи (по спаду BCLK для стабильности на PCM5102)
    always @(negedge bclk or negedge rst_n) begin
        if (!rst_n) begin
            bit_cnt   <= 6'd63;
            lrck      <= 1'b1;
            dout      <= 0;
            shift_reg <= 0;
            data_req  <= 0;
        end else begin

            // Управление счетчиком и LRCK
            if (bit_cnt == 63) begin
                bit_cnt <= 0;
                lrck    <= 1'b0; // Начало левого канала
                data_req <= 1'b1;
            end else begin
                bit_cnt <= bit_cnt + 1'b1;
                data_req <= 0;

                if (bit_cnt == 31) begin
                    lrck <= 1'b1; // Начало правого канала
                end
            end

            // Логика загрузки и сдвига (одновременно)
            if (bit_cnt == 63) begin
                // Загружаем данные. Сразу ставим MSB левого канала в dout.
                // Формат: {MSB, остальные_биты...}
                // Для I2S MSB идет первым после паузы в 1 бит.
                // I2S формат: данные начинаются со 2-го такта BCLK (отступ 1 бит)
                // Формируем 64-битный фрейм: {L_data(24), 8'z, R_data(24), 8'z}
                // Если PCM5102 будет «хрипеть» или вы услышите щелчки, попробуйте изменить строку загрузки данных,
                // добавив один нулевой бит в начале, чтобы сдвинуть данные на 1 такт:
                // shift_reg <= {1'b0, data_left, 7'd0, data_right, 8'd0}; //(для классического I2S).
                // shift_reg <= {data_left, 8'd0, data_right, 8'd0};
                shift_reg <= {data_left, 8'd0, data_right, 8'd0};
                dout <= 1'b0; // 1 бит задержки перед данными по стандарту I2S
            end else begin
                dout <= shift_reg[63];
                shift_reg <= {shift_reg[62:0], 1'b0};
            end
        end
    end

endmodule