Сгенерируйте HDL-код для программируемого КИХ-фильтра

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

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

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

Предпосылки

У вас должна быть лицензия HDL Coder™, чтобы запустить этот пример.

Программируемый КИХ-фильтр модели

Введите следующие команды, чтобы открыть модель в качестве примера:

modelname = 'hdlcoder_dspprogfir';
open_system(modelname);

Рассмотрите два КИХ-фильтра, один с ответом lowpass и другим с highpass ответом. Коэффициенты могут быть заданы с Функцией обратного вызова Model Properties InitFcn.

Программируемый КИХ через блок Registers загружает коэффициенты lowpass от Поведенческой модели Хоста и обрабатывает входные выборки щебета сначала. Затем блок загружает highpass коэффициенты и обрабатывает те же выборки щебета снова.

Введите следующие команды, чтобы открыть Программируемого КИХ через блок Registers:

systemname = [modelname '/Programmable FIR via Registers'];
open_system(systemname);

Блок coeffs_registers загружает коэффициенты во внутренние регистры, когда сигнал 'write_enable' высок. Следующие теневые регистры обновляются от содействующих регистров, когда сигнал 'write_done' высок. Это включает одновременную загрузку и обработку данных сущностью фильтра. В этом примере мы применяем полностью параллельную реализацию архитектуры к блоку Discrete FIR Filter. Можно также выбрать последовательную архитектуру из меню HDL Block Properties.

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

Simulink® Simulation Results

Введите следующую команду, чтобы запустить модель в качестве примера:

sim(modelname);

Введите следующую команду, чтобы открыть осциллограф:

open_system([modelname '/Scope']);

Сравните DUT (Проект под Тестом) выход со ссылочным выходом.

Введите следующую команду, чтобы закрыть осциллограф:

close_system([modelname '/Scope']);

Используя Logic Analyzer

Можно также просмотреть сигналы в Logic Analyzer. Logic Analyzer позволяет вам просмотреть несколько сигналов в одном окне. Это также дает возможность определять переходы в сигналах.

% The signals of interest - input coefficient, write address, write enable,
% write done, filter in, filter out, reference out and error have been
% logged into a Dataset called hdlcoder_dspprogfir_logsout.

% The helper function hdlcoder_analyzeLogicFromSimulink creates a wave for every
% input provided in the Dataset. In order to make the default order of
% signals displayed more meaningful, we reorder the Dataset from Simulink
% to make the Coefficient signals appear first and the data signals next.
% The Error values are converted to logical values.
logsout_r = hdlcoder_dspprogfirReorderDataset(hdlcoder_dspprogfir_logsout);

% The Dataset can now be used to display data in the Logic Analyzer.
% We use the helper function hdlcoder_analyzeLogicFromSimulink, which
% creates a Logic Analyzer System object, adds in a wave for every input
% passed in, labels the wave based on the name of the logged signal and
% displays the data in the Dataset. The function returns a handle to
% the System object that can be used to modify the display.
H = hdlcoder_analyzeLogicFromSimulink(logsout_r);

Изменение отображения в Logic Analyzer

Системный объект Logic Analyzer имеет несколько свойств управлять его отображением. Можно изменить высоту всех каналов отображения, интервала между каналами отображения и отрезком времени отображения.

H.DisplayChannelSpacing = 8;
H.DisplayChannelHeight  = 24;
H.TimeSpan = 12;

Отображением Logic Analyzer можно также управлять на основе на делитель или на волну. Чтобы изменить отдельную волну или делитель, используйте тег, сопоставленный с ним. Можно получить тег, сопоставленный с волной или делителем как возвращаемое значение addWave и addDivider, или можно получить все теги для волн и делителей с помощью getDisplayChannelTags метода.

% Get all the tags for the displayed waves
HDisplayTags = H.getDisplayChannelTags;

% View the write address (second wave in the display) in Decimal mode
modifyDisplayChannel(H, 'DisplayChannelTag', HDisplayTags{2}, ...
    'Radix', 'Signed decimal');

Другой полезный режим визуализации в Logic Analyzer является Аналоговым форматом.

% View the Filter In, Filter Out and Ref Out signals in Analog format
modifyDisplayChannel(H, 'DisplayChannelTag', HDisplayTags{5}, ...
    'Format', 'Analog');
modifyDisplayChannel(H, 'DisplayChannelTag', HDisplayTags{6}, ...
    'Format', 'Analog');
modifyDisplayChannel(H, 'DisplayChannelTag', HDisplayTags{7}, ...
    'Format', 'Analog');
H.TimeSpan = 500;

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

% Add dividers for the coefficient and data signals. The divider for the
% coefficient signals is set to be shown in Display Channel 1. The divider
% for the data signals is added to the bottom of the display.
addDivider(H, 'DisplayChannel', 1, 'Name', 'Coeff');
divTagData = addDivider(H, 'Name', 'Data');

% Increase the size of the window so that all the waves and dividers are
% visible.
pos = H.Position;
H.Position = [pos(1) pos(2) pos(3) pos(4)+100];

Используя тег для данной волны или делителя, moveDisplayChannel метод может использоваться, чтобы переместить его в Канал Отображения по вашему выбору.

% Move the Data signal divider to Display Channel 6, right before the
% Filter In wave display
moveDisplayChannel(H, 'DisplayChannelTag', divTagData, 'DisplayChannel', 6);

Вышеупомянутые операции на отдельных каналах также доступны через графический интерфейс пользователя путем щелчка правой кнопкой по названию канала.

Для получения дополнительной информации о Системном объекте Logic Analyzer обратитесь к документации.

Сгенерируйте HDL-код и испытательный стенд

Получите уникальное временное имя каталога для сгенерированных файлов

workingdir = tempname;

Чтобы проверять, существуют ли какие-либо проблемы с моделью для генерации HDL-кода, не генерируя HDL-код, можно запустить следующую команду:

checkhdl(systemname,'TargetDirectory',workingdir);

Введите следующую команду, чтобы сгенерировать HDL-код:

makehdl(systemname,'TargetDirectory',workingdir);
### Generating HDL for 'hdlcoder_dspprogfir/Programmable FIR via Registers'.
### Using the config set for model <a href="matlab:configset.showParameterGroup('hdlcoder_dspprogfir', { 'HDL Code Generation' } )">hdlcoder_dspprogfir</a> for HDL code generation parameters.
### Starting HDL check.
### Begin VHDL Code Generation for 'hdlcoder_dspprogfir'.
### Working on hdlcoder_dspprogfir/Programmable FIR via Registers/coeffs_registers as /tmp/BR2019bd_1170825_64229/publish_examples0/tp9f60d38d_23ed_4570_81b5_b8a90903a27e/hdlcoder_dspprogfir/coeffs_registers.vhd.
### Working on hdlcoder_dspprogfir/Programmable FIR via Registers/Discrete FIR Filter as /tmp/BR2019bd_1170825_64229/publish_examples0/tp9f60d38d_23ed_4570_81b5_b8a90903a27e/hdlcoder_dspprogfir/Discrete_FIR_Filter.vhd.
### Working on hdlcoder_dspprogfir/Programmable FIR via Registers as /tmp/BR2019bd_1170825_64229/publish_examples0/tp9f60d38d_23ed_4570_81b5_b8a90903a27e/hdlcoder_dspprogfir/Programmable_FIR_via_Registers.vhd.
### Generating package file /tmp/BR2019bd_1170825_64229/publish_examples0/tp9f60d38d_23ed_4570_81b5_b8a90903a27e/hdlcoder_dspprogfir/Programmable_FIR_via_Registers_pkg.vhd.
### Creating HDL Code Generation Check Report file:///tmp/BR2019bd_1170825_64229/publish_examples0/tp9f60d38d_23ed_4570_81b5_b8a90903a27e/hdlcoder_dspprogfir/Programmable_FIR_via_Registers_report.html
### HDL check for 'hdlcoder_dspprogfir' complete with 0 errors, 0 warnings, and 0 messages.
### HDL code generation complete.

Введите следующую команду, чтобы сгенерировать испытательный стенд:

makehdltb(systemname,'TargetDirectory',workingdir);
### Begin TestBench generation.
### Generating HDL TestBench for 'hdlcoder_dspprogfir/Programmable FIR via Registers'.
### Begin simulation of the model 'gm_hdlcoder_dspprogfir'...

### Collecting data...
### Generating test bench data file: /tmp/BR2019bd_1170825_64229/publish_examples0/tp9f60d38d_23ed_4570_81b5_b8a90903a27e/hdlcoder_dspprogfir/coeffs_in.dat.
### Generating test bench data file: /tmp/BR2019bd_1170825_64229/publish_examples0/tp9f60d38d_23ed_4570_81b5_b8a90903a27e/hdlcoder_dspprogfir/write_address.dat.
### Generating test bench data file: /tmp/BR2019bd_1170825_64229/publish_examples0/tp9f60d38d_23ed_4570_81b5_b8a90903a27e/hdlcoder_dspprogfir/write_enable.dat.
### Generating test bench data file: /tmp/BR2019bd_1170825_64229/publish_examples0/tp9f60d38d_23ed_4570_81b5_b8a90903a27e/hdlcoder_dspprogfir/write_done.dat.
### Generating test bench data file: /tmp/BR2019bd_1170825_64229/publish_examples0/tp9f60d38d_23ed_4570_81b5_b8a90903a27e/hdlcoder_dspprogfir/filter_in.dat.
### Generating test bench data file: /tmp/BR2019bd_1170825_64229/publish_examples0/tp9f60d38d_23ed_4570_81b5_b8a90903a27e/hdlcoder_dspprogfir/filter_out_expected.dat.
### Working on Programmable_FIR_via_Registers_tb as /tmp/BR2019bd_1170825_64229/publish_examples0/tp9f60d38d_23ed_4570_81b5_b8a90903a27e/hdlcoder_dspprogfir/Programmable_FIR_via_Registers_tb.vhd.
### Generating package file /tmp/BR2019bd_1170825_64229/publish_examples0/tp9f60d38d_23ed_4570_81b5_b8a90903a27e/hdlcoder_dspprogfir/Programmable_FIR_via_Registers_tb_pkg.vhd.
### HDL TestBench generation complete.
 

Результаты симуляции ModelSim™

Следующий рисунок показывает симулятор HDL ModelSim после выполнения сгенерированных .do скриптов файла для испытательного стенда. Сравните результат ModelSim с результатом Simulink, как построено прежде.

Это заканчивает Сгенерировать HDL-код для Программируемого КИХ-примера Фильтра.