ЛР4 > Реализация КИХ-фильтра для обработки аудиосигнала с помощью процессорного ядра Nios II

Тема: Настройка КИХ-фильтра для обработки аудио-сигналов процессорным ядром Nios II

Теоретические сведения

 Скачать Материалы к лабораторной работе №4.

В данной работе необходимо реализовать фильтр с конечной импульсной характеристикой (КИХ-фильтр), на процессорном ядре NiosII, для обработки аудиосигнала. Для
обработки аудиосигналов на стенде DE2 имеется аудиокодек WM8731, который преобразовывает входной аналоговый сигнал в цифровую форму. Затем, полученный цифровой сигнал поступает на обработку в процессор. Блок-схема такого устройства представлена на рисунке 1.

Рисунок 1. Блок-схема устройства для обработки аудиосигнала.

 Входной аудиосигнал оцифровывается аудиокодеком WM8731 и передается процессору NiosII (Digital Data Input). В процессоре программно реализован КИХ-фильтр, который по каждому нарастающему фронту сигнала Strobe принимает и обрабатывает очередную порцию аудиоданных. Выходные обработанные аудиоданные (Digital Data Output) по каждому нарастающему фронту сигнала Strobe возвращаются аудиокодеку, который конвертирует их в аналоговую форму. Тип КИХ-фильтра задается с помощью нажатий соответствующих кнопок (KEY0 – KEY3). При этом, в программу реализации фильтра загружаются различные наборы коэффициентов, изменяющие тип фильтра (ФНЧ, ФВЧ или полосовой). Номер, соответствующий текущему типу фильтра, отображается на семисегментных индикаторах. Блок Initial configuration logic необходим для начальной конфигурации аудиокодека.

Задание 1

1. Создайте новый проект в Вашей рабочей директории. Укажите название проекта nios2_de2.

2. Для реализации всех необходимых функций с помощью утилиты SOPC Builder создайте процессорное ядро следующей конфигурации

Рисунок 2. Конфигурация процессорного ядра Nios II.

3. Настройки процессорного ядра (cpu_0), контроллера внешней памяти (sdram_0), блока PLL (clocks), встроенных таймеров (hi_res_timer и sys_timer), порта ввода/вывода (S7SEG) должны быть такими же, как и для лабораторной работы № 2.

4. Укажите адрес контроллера внешней памяти, равный 0x00800000 зафиксируйте его.

5. Блоки sysid и jtag_uart подключите с настройками по умолчанию.

6. Блок buttons – входной 4-разрядный параллельный порт.

7. Блок AUD_STROBE – входной 1-разрядный параллельный порт. Используется для синхронизации процессорного ядра со входным аудиопотоком от аудиокодека.

8. Блок AUD_DIN – входной 32-разрядный параллельный порт. Передает аудиопоток от аудиокодека в процессор.

9. Блок AUD_DOUT – выходной 32-разрядный параллельный порт. Передает обработанный аудиопоток от процессора в аудиокодек.

10. Блок AUD_RESET – выходной 1-разрядный параллельный порт. Используется для начального сброса аудиокодека.

11. С помощью команды System -> Auto-assign IRQs выполните автоматическое распределение векторов прерывания в системе.

12. С помощью команды System -> Auto-assign Base Addresses выполните автоматическое распределение базовых адресов устройств в системе. Обратите внимание на подключение сигналов тактовой частоты!

13. Сохраните конфигурацию процессорного ядра.
Выполните команду Generate.

Задание 2

1. После успешного создания процессорного ядра необходимо создать файл верхнего уровня иерархии проекта.

2. Откройте файл nios2_de2.bdf (в папке с исходными данными). Подключите процессорное ядро. Окончательная схема должна выглядеть так же, как показано на рисунке 3. Задайте назначения контактов ввода/вывода (используя файл DE2_pin_assignments.csv).

Рисунок 3. Схема процессорного устройства (файл верхнего уровня иерархии).

3. Кроме процессорного ядра файл проекта содержит следующие модули:

  • Reset_Delayблок начального сброса процессора перед его инициализацией;
  • SEG7_LUT_4блок дешифратора для четырех используемых семисегментных индикаторов;
  • I2C контроллер шины I2S для конфигурирования аудиокодека WM8731;
  • CLOCK_500 – делитель частоты и загрузчик начальных конфигурационных параметров для аудиокодека WM8731;

    Блок I2C совместно с CLOCK_500 выполняют загрузку начальной конфигурации аудиокодека. Они настраивают его для работы в режиме мастер (в этом режиме аудиокодек генерирует строб AUD_STROBE для фиксации аудиоданных в порт AUDIO_IN процессора). Разрядность цифровых аудиоданных – 16 бит для каждого канала (левый и правый).

    • de2_audio_if – контроллер обмена информацией с аудиокодеком WM8731.

 Описание интерфейса модуля de2_audio_if

Рисунок 4. Интерфейс модуля
de2_audio_if

Сигналы iBCLK, iLRCK, iDIN, oDOUT представляют собой стандартный последовательный канал передачи и приема аудиопотока (индекс перед названием сигнала обозначает его направление: i – вход, o – выход). Модуль поддерживает 2 стандартных протокола обмена: I2S и DSP/PCM Mode A (более подробная информация представлена в технической документации на аудиокодек). Режим работы выбирается установкой высокого или низкого уровня на управляющем входе iAUDMODE. Высокий уровень на этом входе соответсвует режиму I2S, низкий-DSP/PCM Mode A.

iCLK, iRSTn– управляющие входы модуля (причем активный уровень сигнала iRSTn – низкий).

На выходе oStrobe генерируются стробирующие импульсы, сигнализирующие о готовности принятых данных на выходах oDataLeft и oDataRight. Эти же импульсы тактируют передачу данных с параллельных входов модуля в аудиокодек. Поэтому, данные на входах iDataLeft и iDataRight должны быть установлены до момента появления стробирующего импульса.

Более подробно ознакомиться с режимами и принципом работы аудиокодека WM8731 можно по технической документации на него.

Все необходимые файлы с описанием этих устройств находятся в папке с исходными данными.

4. Выполните компиляцию проекта. После успешной компиляции загрузите проект в ПЛИС.

Задание 3

1. Для разработки программного обеспечения для процессорного ядра создайте новый проект в среде Nios II IDE.

2. В настройках системной библиотеке проекта укажите параметры, как и в лабораторной работе № 2.

3. Добавьте в проект исходные файлы, которые размещаются в папке software с исходными данными к лабораторной работе. Скомпилируйте проект.

4. Перед запуском программы, к стенду необходимо подключить дополнительные аудиоустройства, как показано на рисунке 5.

Рисунок 5. Подключение аудиоустройств к стенду DE2.

Внимание! Переключатель SW0 на стенде осуществляет аппаратный сброс процессора. Перед запуском убедитесь, что переключатель SW0 на стенде установлен в верхнее положение.

5. Запустите выполнение программы на стенде с помощью команды Run As -> Nios II Hardware.

В начальном состоянии фильтрация отключена, и весь аудиопоток со входа передается прямо на выход. Выбор типа КИХ-фильтра осуществляется с помощью кнопок KEY0-KEY3 на стенде. В таблице представлены варианты его конфигурации:

Кнопка

Номер

Описание фильтра

KEY0

0

Фильтрация отключена. Весь аудиопоток со входа дублируется на выход

KEY1

1

Фильтр верхних частот (ФВЧ)

KEY2

2

Фильтр нижних частот (ФНЧ)

KEY3

3

Полосовой фильтр

Номер текущего типа фильтра отображается на семисегментном индикаторе.

Дополнительная информация

Программная реализация КИХ-фильтра на языке C

Стандартные КИХ-фильтры реализуются с помощью трех основных элементов: умножителя, сумматора и блока задержки. Структура реализованного в данной работе КИХ-фильтра показана на рисунке 6.


Рисунок 6. Структура реализованного КИХ-фильтра.

Отсчеты входного аудиосигнала  хранятся в рабочем сдвиговом массиве. Длина массива, необходимая для обработки одного входного осчета равна N ( N – число коэффициентов фильтра). Размер массива для обработки М отсчетов будет равен N – 1 + M. Основные этапы обработки сигнала программой КИХ-фильтра  следующие:

  • Добавление новых отсчетов по старшим адресам массива:

    // put the new samples at the high end of the buffer


    memcpy( &insamp[filterLength – 1], input,

    length * sizeof(alt_16) );

  • Внешний цикл, в котором вычисляются выходные значения фильтра для всего массива отсчетов;
  • Внутренний цикл, в котором вычисляется значение фильтра для одного отсчета (умножение на коэффициенты фильтра и добавление к накапливаемой сумме);
  • Если полученное выходное значение фильтра слишком велико либо слишком мало – оно обрезается;

    // apply the filter to each input sample


    for ( n = 0; n < length; n++ ) {

    // calculate output n

    coeffp = coeffs;

    inputp = &insamp[filterLength – 1 + n];

    // load rounding constant

    acc = 1 << 14;

    // perform the multiply-accumulate


    for ( k = 0; k < filterLength; k++ ) {

    acc += (alt_32)(*coeffp++) * (alt_32)(*inputp–);

    }

    // saturate the result


    if ( acc > 0x3fffffff ) {

    acc = 0x3fffffff;

    } else
    if ( acc < -0x40000000 ) {

    acc = -0x40000000;

    }

    // convert from Q30 to Q15

    output[n] = (alt_16)(acc >> 16);

    }

  • сдвиг предыдущих входных отсчетов  назад на величину, равную количеству  новых обработанных отсчетов.

// shift input samples back in time for next time


memmove( &insamp[0], &insamp[length],

(filterLength – 1) * sizeof(alt_16) );

Более подробно изучить принцип работы фильтра можно просмотрев исходный код, прилагаемый к проекту.

Задание для самостоятельной работы

1. Разработайте и реализуйте заграждающий фильтр (фильтр-пробку). Порядок фильтра и полосу частот выберите самостоятельно. Проверьте работоспособность фильтра на стенде.