Материал: ВКР_Соболев

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

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

2.1.3 Условия тестирования модулей первичной обработки

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

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

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

2.2 Описание программы

Далее приведены описания программ ARM-части и FPGA-части, а также описание их соединения друг с другом.

2.2.1 Соединение fpga- и arm-частей между собой и блоками памяти

Для соединения компонентов модуля сопряжения между собой используется средство Platform Designer программы Quartus Prime Lite. В нем же объявляются блоки памяти на чипе.

Размерности блоков памяти на чипе следующие:

- блок служебной информации: 5 однобайтных слов.

- блоки входных данных: по 256 двухбайтных слов в каждом.

- блок выходных данных: 512 четырехбайтных слов.

Увеличение разрядности выходных данных в 2 раза обусловлено допустимостью операции умножения на выходах некоторых модулей цепочки.

Доступ ARM-компонента и FPGA-компонента к одним и тем же блокам памяти достигается путем объявления двухпортовой памяти, тактируемой одним тактовым сигналом, и выделения ARM- и FPGA-компонентам отдельных портов. Соединение компонентов показано на рисунке 2.2.

Рисунок 2.2 – Соединение компонентов в Platform Designer

Здесь hps_0 – ARM-компонент, ocm_service, ocm_data_input_re, ocm_data_input_im, ocm_data_output_re – блоки памяти. Один порт блоков памяти соединяется с hps_0, другой экспортируется для использования в FPGA. Блокам памяти назначаются базовые адреса, впоследствии используемые в ARM-сервере.

Полная схема соединения компонентов в Platform Designer приведена в приложении A.

2.2.2 Программа сервера на hps

Сервер написан с помощью языка C с использованием Linux-библиотеки socket, а также с использованием API для HPS компании Altera.

Форматы датаграмм, принимаемых от клиенты, представлены на рисунках 2.3 (служебная датаграмма) и 2.4 (датаграмма данных).

Рисунок 2.3 – Формат служебной датаграммы

Здесь number_of_channels – количество каналов радара, first_block_id – номер первого блока цепочки, last_block_id – номер последнего блока цепочки, data_length_h – старший байт количества данных, data_length_l – младший байт количества данных. Необходимость хранить количество данных в двух байтах обусловлена размерностью входных данных – максимум 512 отсчетов на канал, число 512 в один байт не умещается.

Рисунок 2.4 – Формат датаграммы данных

Здесь data_re – данные для первого блока памяти, data_im – данные для второго блока памяти. Всего датаграмма содержит до 256 четырехбайтных слов, каждое из которых затем делится на два двухбайтных слова и записывается в соответствующий блок памяти.

Также сервер формирует и отправляет датаграмму выходных данных, которая содержит до 512 четырехбайтных слов.

Код программы сервера приведен в приложении Б.

2.2.3 Модули на fpga

Для взаимодействия с памятью на чипе со стороны FPGA в соответствии со структурным подходом к проектированию разработаны три отдельных подмодуля: подмодуль для выгрузки служебной информации (eth_service), подмодуль для выгрузки и передачи входных данных в модули цепочки первичной обработки (eth_read), подмодуль для загрузки выходных данных цепочки первичной обработки в память на чипе (eth_write). Разработка модулей велась с помощью ЯПА Verilog. Выбор именно этого языка для описания модулей обусловлен прошлым знакомством с ним в рамках учебного плана, а также более простым, чем у альтернатив, написанием testbench. Оформление производилось в соответствии с правилами документации проектов для ПЛИС [20] и требованиями по единой системе программной документации. [21, 22]

Схематические обозначения подмодулей представлены на рисунке 2.5.

Рисунок 2.5 – Подмодули взаимодействия с памятью на чипе

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

2.2.3.1 Подмодуль чтения служебной информации

Листинг 2.1 содержит заголовок модуля eth_service.

Листинг 2.1 – Объявление и порты подмодуля eth_service

Данный подмодуль производит выгрузку служебной информации из служебного блока памяти на чипе и запись ее в регистры в FPGA-части для дальнейшего использования, до начала работы устанавливает выходной сигнал finished, начинает работу по нижнему уровню входного сигнала reset, в конце работы сбрасывает сигнал finished. Взаимодействие с блоком памяти на чипе производится через двунаправленные порты service_address (шина адреса блока памяти), service_readdata (шина считывания данных с блока памяти), service_write (флаг записи данных в блок памяти, требует отдельного выставления после каждой смены адреса). Подмодуль тактируется входным сигналом clock и имеет выходами считанные значения служебных признаков (number_of_channels, first_block_id, last_block_id, data_length).

2.2.3.2 Подмодуль чтения из входного блока памяти

Заголовок модуля eth_read представлен в листинге 2.2.

Листинг 2.2 – Объявление и порты подмодуля eth_read

Данный подмодуль производит выгрузку данных из одного из блоков входных данных. Как и подмодуль eth_service, eth_read имеет три двунаправленных порта для взаимодействия с блоком памяти – input_address(шина адреса), input_readdata(шина считывания данных), input_write(флаг записи данных). Подмодуль начинает работу по нижнему уровню входного сигнала reset и до начала работы устанавливает выходные сигналы input_finished и done. Первый сигнал модуль сбрасывает по окончании считывания блока данных, начальный адрес begin_addr и размер addr_span которого задаются соответствующими входами, второй сигнал модуль импульсно сбрасывает после каждого считанного значения, считываемое значение подается на выходную шину read_data_output, ширина которой задается параметром read_data_output_length. Подмодуль тактируется сигналом clock.

2.2.3.3 Подмодуль записи полученных значений в блок выходных данных

В листинге 2.3 представлен заголовок модуля eth_write.

Листинг 2.3 – Объявление и порты модуля eth_write

Данный подмодуль производит загрузку значений на выходе тестируемого модуля (тестируемой цепочки?) в блок памяти на чипе для выходных данных. Как и предыдущие два подмодуля, eth_write взаимодействует с блоком памяти на чипе через три двунаправленных порта: шину адреса output_address, шину записи данных в блок output_writedata и флаг записи данных output_write, который выставляется для определенного адреса после произведенной операции записи. Область записи данных в блок памяти задается входами begin_addr(начальный адрес) и addr_span(количество данных для записи). Подмодуль до начала работы выставляет выходной сигнал done, начинает работу по нижнему уровню сигнала reset, по окончании работы сбрасывает сигнал done. Данные для записи в память подаются на шину write_data_input, ширина которой определяется параметром write_data_input_length. Подмодуль тактируется сигналом clock.

2.3 Моделирование fpga-подмодулей

Для проверки правильности работы аппаратурных модулей была проведена симуляция в среде ModelSim. В качестве блоков памяти выступают пары вида «адрес - массив регистров», где адрес выступает индексом массива. Рассмотрим два примера, которые были описаны выше:

1. Комбинационный элемент, в данном случае возьмем 8-разрядный инвертор. Это простой пример, на котором можно промоделировать базовую функциональность и в дальнейшем экспериментально проверить связь между внешним устройством и отладочной платой.

2. Модуль, имеющий внутреннюю память, в данном случае – пороговое устройство. Этот пример уже имеет непосредственное отношение к проекту радара и позволит промоделировать и проверить модуль в реальных условиях.

2.3.1 Пример 1 – 8-разрядный инвертор

Схематическое изображение соединения инвертора и подмодулей модуля сопряжение представлено на рисунке 2.6.

Рисунок 2.6 – Схема соединения модуля сопряжения и инвертора

В качестве данных для проверки была взята последовательность из 10 8-разрядных шестнадцатеричных чисел:

[0xFE, 0x54, 0x12, 0x32, 0x8A, 0xBA, 0x8C, 0xDE, 0x92, 0x11];

На выходе модуля eth_write в итоге ожидается последовательность:

[0x01, 0xAB, 0xED, 0xCD, 0x75, 0x45, 0x73, 0x21, 0x6D, 0xEE]

Результат моделирования представлен на рисунке 2.7.

Рисунок 2.7 – Результат моделирования для примера 1

Продолжение рисунка 2.7

Сигнал output_enable подается на вход reset модуля eth_write и формируется с появлением первых данных на входе инвертора (шина input_data), выход инвертора – шина output_data. Шина input_data является выходом read_data_output модуля eth_read, а шина output_data – входом write_data_input модуля eth_write. В результате моделирования видно, что данные проходят через модули верно, на выходе output_writedata формируются верные значения.

2.3.2 Пример 2 – Пороговое устройство

Схематическое изображение порогового устройства представлено на рисунке 2.8.

Рисунок 2.8 – Пороговое устройство

На вход порогового устройства подается массив N-разрядных данных (шина input_data), постоянный коэффициент из ПЗУ (ROM_coefficient), а также данные для сравнения (input_to_compare). Один из параметров модуля, rank, является рангом для выбора значения из input_data. Остальные параметры модуля для данной задачи рассматривать излишне.

Схематическое изображение соединения модуля порогового устройства и подмодулей модуля сопряжения представлено на рисунке 2.9.

Рисунок 2.9 – Схема взаимного соединения модулей

Пороговое устройство тактируется сигналом rtc_divided_clock с частотой, равной половине главной частоты CLOCK_50.

Источник: https://studfile.net/preview/16673049/