До сих пор мы рассматривали тему, как повысить производительность системы с помощью некоторых интенсивных методов.
Но на самом деле существуют обширные методы.
В данный момент мы работаем на тактовой частоте 50 МГц, что связано с использованием компонента из комплекта для университетской программы (а без него невозможно тактировать SDRAM, что требует, чтобы тактовые импульсы, идущие на чип, были сдвинуты относительно основных).
Когда я вводил этот компонент в игру, я предупредил, что это решение временное.
Тогда я вывалил на читателя столько новой информации, что любое ненужное занудство могло привести к восклицанию: «Ох уж эти ПЛИС, здесь все так сложно!» Теперь мы можем легко и непринужденно проектировать процессорные системы, все страшное позади.
Пришло время разобраться, как можно сделать свой компонент, позволяющий увеличить тактовую частоту как процессора, так и подключенной к нему периферии.
Предыдущие статьи серии:
- Разработка простейшей «прошивки» для ПЛИС, установленной в Redd, и отладка на примере теста памяти.
- Разработка простейшей «прошивки» для ПЛИС, установленной в Redd. Часть 2. Программный код.
- Разработка собственного ядра для интеграции в процессорную систему на базе FPGA.
- Разработка программ для центрального процессора Redd на примере доступа FPGA.
- Первые эксперименты по использованию потокового протокола на примере связи ЦП и процессора в ПЛИС комплекса Redd.
- Весёлый Квартусель, или как процессор дошёл до такой жизни.
- Методы оптимизации кода для Redd. Часть 1. Влияние на кэш.
- Методы оптимизации кода для Redd. Часть 2: некэшируемая память и параллелизм шин.
Немного теоретических рассуждений
Давайте выясним, какую частоту мы можем безопасно установить для тактирования всего нашего оборудования.Используемый в комплексе чип SDRAM допускает максимальную частоту 133 МГц.
О максимальных тактовых частотах ядра процессора можно узнать из документа Тесты производительности Nios II .
Там для нашей ПЛИС Cyclone IV E частота ядра Nios II/f гарантированно составляет 160 МГц.
Я не сторонник выжимать из системы все соки, поэтому речь пойдет о работе на частоте 100 МГц.
Честно говоря, я до сих пор не освоился с методом расчета сдвига тактовой частоты, приведенным в разделе 32.7. Часы, ФАПЧ и вопросы синхронизации документ Руководство пользователя встроенной периферии IP , но похоже я не один такой.
По крайней мере, долгий поиск в Интернете не привел меня к статьям, которые содержали бы какие-либо результаты, рассчитанные аналогичным образом, но не для частоты, приведенной в основном документе (те же 50 МГц).
Есть интересная статья, на которую дам прямую ссылку.
www.emb4fun.de/fpga/nutos1/index.html .
Можно было бы просто сослаться на него и сказать «Давайте сделаем как автор», если бы не одно «но»: автор этой статьи использует блок PLL (по-русски — PLL, а на бытовом уровне — преобразователь частоты), вставив его в свой собственный код VHDL. Я, как уже отмечал в статья о забавном Квартуселе , я придерживаюсь идеологии, что наша процессорная система должна находиться на верхнем уровне иерархии проекта.
Никакие вставки не нужны ни для одного языка, будь то VHDL или Verilog. Недавно этот мой подход получил еще одно подтверждение: у нас появился новый сотрудник, студент, который еще не владеет языком Verilog, но отлично справляется с написанием кода для комплекса Redd, поскольку выбранный подход позволяет это сделать.
Получается, что мы просто возьмем за основу то, что у автора все работает при сдвиге в минус 54 градуса (какие градусы описаны в статье, ссылку на которую я дал абзацем выше).
Далее давайте посмотрим еще одну интересную статью.
asral.unimap.edu.my/wp-content/uploads/2019/07/2019_IJEECS_Chan_Implementation-Camera-System.pdf .
Там, по мнению авторов, все работает при сдвиге в минус 65 градусов.
Попробуем создать собственную систему, используя значение из этого диапазона.
Если при ежедневном тесте оперативной памяти не будет сбоев, то оставим это значение как боевое.
Имеем право, поскольку разрабатываемая для Redd «прошивка» не пойдет Заказчикам, а будет использоваться для внутренних нужд, причем в отдельных количествах.
В случае чего всегда можно будет все исправить без лишних сложностей (сложности возникают, когда необходимо обновить «прошивку» на тысячах проданных устройств, да еще и просто у удаленного Заказчика).
Новая часть аппаратной конфигурации
Мне почему-то кажется, что проще сделать процессорную систему для этой статьи с нуля, чем переделывать ее из старой.Просто вместо того, чтобы демонстрировать процесс «выкручивания, выкручивания, запутывания», постоянно ссылаясь на прошлые статьи, я лучше покажу все заново с самого начала.
При этом мы закрепим материал.
Итак, давайте начнем.
В самом начале нам показывают совершенно пустую систему, содержащую только тактовый генератор и источник сигнала сброса.
Обычно я там ничего не меняю, но сегодня сделаю исключение.
Не хочу отвлекаться на схему сброса, так как работать мы все равно будем из-под отладчика.
Поэтому я переключу условие сброса с уровня на отрицательный дифференциал, а затем обнулю саму ногу.
Но здесь тактовый сигнал имеет частоту 50 МГц (эта частота задается характеристиками генератора, припаянного к плате).
В первой статье, о которой я упоминал выше, использовался блок PLL, добавленный в основной проект. Где мы его здесь возьмем? И вот он!
Это тот же блок, но здесь нам не нужно вставлять код Verilog или VHDL. У нас уже все вставлено! Правда, настройки у разных типов ПЛИС различаются чуть более чем полностью.
Точнее, настраиваемые параметры более-менее одинаковы, но расположены в принципиально разных местах диалогов настроек.
Поскольку в комплексе Redd используется ПЛИС Cyclone IV E, мы рассмотрим возможность установки данного варианта.
На первой вкладке изменяем входную частоту на 50 МГц (по умолчанию было 100) и переходим на следующую вкладку (нажимаем Далее, для Cyclone IV E нам придется проделать это много раз).
Снимите флажки с дополнительных входов и выходов.
Они нам не нужны:
Мы пропускаем следующие несколько вкладок, пока не доберемся до настройки выхода C0. Там переключаем переключатель для установки частоты и вводим значение 100 МГц:
С выходом С1 все немного сложнее.
Сначала мы устанавливаем флажок, в котором говорится, что это также следует использовать.
Во-вторых, аналогично выставляем частоту 100 МГц.
Ну и в-третьих, выставляем сдвиг частоты.
Какой из них мне следует спросить? Минус 58 или минус 65? Конечно, я попробовал оба варианта.
Оба работали на меня.
Но рассуждение на тему минус 58 выглядит несколько менее убедительно, поэтому здесь я порекомендую ввести значение минус 65 градусов (в этом случае автоматика подскажет мне, что реально достигнутое значение будет минус 63 градуса).
Вот и все.
Теперь можно ходить с кнопкой Следующий до конца или просто нажмите Заканчивать .
Подключение входов inclk_interface И inclk_interface_reset .
Выход с0 Мы будем использовать его как часы для всей системы.
Выход с1 экспорт для тактовой частоты чипа сдрам .
В дальнейшем нужно будет не забыть подключить шину данных ко входу pll_slave .
Для Cyclone V в этом не было бы необходимости.
Другие детали оборудования, предназначенные исключительно для фиксации материала.
Добавьте ядро процессора.
Сегодня нам предстоит протестировать SDRAM. Это означает, что код не должен находиться в нем.
А это, в свою очередь, означает, что весь код будет находиться во внутренней оперативной памяти ПЛИС.
То есть нам не нужен кэш инструкций.
Выключаем его, экономя память ПЛИС.
Также подключаем одну сильно связанную шину инструкций и данных.
Больше никаких интересных настроек ядра процессора пока не требуется.
Обычным движением руки добавляем два блока внутренней оперативной памяти ПЛИС.
Один двухпортовый, емкостью 16 килобайт, и один однопортовый, емкостью 4 килобайта.
Надеюсь, все помнят, как их называть и как их подключить.
В прошлый раз мне нравилось выделять покрышки цветами, возможно, для удобства чтения, в этой статье я сделаю то же самое.
Не забудем присвоить этим блокам памяти в личном диапазоне специальные адреса и заблокировать их.
Пусть память КодПамять будет присвоено 0x20000000, и Память данных - до 0x20004000. Что ж, добавим блок в систему SDRAM настроив его, а также блоки JTAG-UART для вывода сообщений и однобитовых GPIO , при котором мы измерим фактическую частоту, чтобы убедиться, что она увеличилась.
Для справки, вот некоторые неочевидные настройки:
Итого получаем следующую систему (я выделил шину данных, так как она распространяется на все внешние устройства):
Мы назначаем процессору векторы, автоматически назначаем адреса, автоматически назначаем номера прерываний и генерируем систему.
Подключаем систему к проекту, делаем черновую сборку, присваиваем номера ногам и на этот раз делаем не только виртуальные СКЕ , но и сброс_n (Я рассказал вам, как это делается в одна из предыдущих статей , там ищите слова Virtual Pin).
Делаем финальную сборку, заливаем оборудование в ПЛИС.
Все.
Теперь, когда мы закончили с аппаратной частью, перейдем к программной части.
Настройка BSP для нашей среды
Создадим проект на основе шаблона для разнообразия Привет, маленький мир , А Тест памяти малый :Когда он будет создан, перейдите в редактор BSP. Как обычно, первым делом отключаем проверку SysID и разрешаем использование C++ (правда, в этот раз тип файла менять не буду, но у меня это уже вошло в привычку):
Но самое главное, что нам предстоит исправить, находится на вкладке Скрипт компоновщика .
Автоматика распознала, что наша шина инструкций идет только в память.
КодПамять , поэтому я опубликовал фрагмент кода (он называется .
текст ) в уме КодПамять .
Но она, заботясь о нас, поместила всё остальное в самую большую область данных, которая находится в SDRAM .
Откуда она могла знать, что мы безжалостно сотрем эту память?
Придется вручную, построчно заменять регион на Память данных (там появятся списки выбора, в них следует переставить выбор).
У нас должна получиться вот такая картинка:
Ээксперименты с программой
Выходим из редактора, генерируем BSP и пытаемся запустить программу для отладки.
Получаем следующий текст:
Если я нажал Enter, у меня ничего не получилось.
Я бы напечатал что-нибудь (даже пробел) и затем нажал Enter. Потом меня спросили:
С каждым часом легче не становится.
И какой адрес вводить? Вы можете открыть конструктор платформ и посмотреть там значение.
Но я обычно смотрю в универсальном справочнике — файле system.h (полный путь моего проекта — C:\Work\CachePlay5\software\MemoryTest_bsp\system.h).
Там нас интересуют две строки:
То же самое в тексте
где десятичное 33554432 равно шестнадцатеричному 0x2000000. Итак, мои ответы и вывод должны выглядеть так:#define ALT_MODULE_CLASS_new_sdram_controller_0 altera_avalon_new_sdram_controller #define NEW_SDRAM_CONTROLLER_0_BASE 0x0 #define NEW_SDRAM_CONTROLLER_0_CAS_LATENCY 3 #define NEW_SDRAM_CONTROLLER_0_CONTENTS_INFO #define NEW_SDRAM_CONTROLLER_0_INIT_NOP_DELAY 0.0 #define NEW_SDRAM_CONTROLLER_0_INIT_REFRESH_COMMANDS 2 #define NEW_SDRAM_CONTROLLER_0_IRQ -1 #define NEW_SDRAM_CONTROLLER_0_IRQ_INTERRUPT_CONTROLLER_ID -1 #define NEW_SDRAM_CONTROLLER_0_IS_INITIALIZED 1 #define NEW_SDRAM_CONTROLLER_0_NAME "/dev/new_sdram_controller_0" #define NEW_SDRAM_CONTROLLER_0_POWERUP_DELAY 100.0 #define NEW_SDRAM_CONTROLLER_0_REFRESH_PERIOD 15.625 #define NEW_SDRAM_CONTROLLER_0_REGISTER_DATA_IN 1 #define NEW_SDRAM_CONTROLLER_0_SDRAM_ADDR_WIDTH 0x18 #define NEW_SDRAM_CONTROLLER_0_SDRAM_BANK_WIDTH 2 #define NEW_SDRAM_CONTROLLER_0_SDRAM_COL_WIDTH 9 #define NEW_SDRAM_CONTROLLER_0_SDRAM_DATA_WIDTH 16 #define NEW_SDRAM_CONTROLLER_0_SDRAM_NUM_BANKS 4 #define NEW_SDRAM_CONTROLLER_0_SDRAM_NUM_CHIPSELECTS 1 #define NEW_SDRAM_CONTROLLER_0_SDRAM_ROW_WIDTH 13 #define NEW_SDRAM_CONTROLLER_0_SHARED_DATA 0 #define NEW_SDRAM_CONTROLLER_0_SIM_MODEL_BASE 0 #define NEW_SDRAM_CONTROLLER_0_SPAN 33554432 #define NEW_SDRAM_CONTROLLER_0_STARVATION_INDICATOR 0
Отлично, но для ежедневного теста не подходит. Я переписал функцию основной Так:
int main(void)
{
int step = 0;
while (1)
{
if (step++0 == 0)
{
alt_printf (".
");
}
if (MemTestDevice(NEW_SDRAM_CONTROLLER_0_BASE, NEW_SDRAM_CONTROLLER_0_SPAN)!=0)
{
printf ("*");
}
}
return (0);
}
Точки означают, что программа не зависла.
Если есть ошибка, будет отображаться звездочка.
Для надежности на его выходе можно поставить брейкпоинт, тогда мы его точно не проспим.
Правда, откуда-то появились «левые» точки.
Оказалось, что они печатаются внутри функции МемТестУстройство() .
Там я стер их заключение.
Тест прошел успешно.
Полученная система может быть использована, как минимум, для внутренних нужд (в частности, такие разработки ведутся для комплекса «Редд»).
Проверка конечной производительности системы
Но я уже привык, что при работе с техникой доверять нельзя ничему.Все следует тщательно проверить.
Давайте позаботимся о том, чтобы мы работали вдвое чаще, чем в предыдущих статьях.
Добавляем известную функцию MagicFunction1().
Напомню, как она выглядит. void MagicFunction1()
{
Теги: #Программирование микроконтроллеров #Компьютерное оборудование #микроконтроллеры #Системное программирование #оптимизация кода #FPGA #FPGA #FPGA #FPGA #Redd #Nios II #увеличение тактовой частоты
-
Кофеин
19 Oct, 24 -
Много Менеджеров
19 Oct, 24 -
Обои В Тему
19 Oct, 24