Согласно нашему плану, начинаем адаптировать проект Amber для платы Марсоход2. Сейчас нам не нужно вдаваться в мелкие подробности, нужно просто попытаться формально скомпилировать проект по восможности с минимальными переделками.
1) Внимательно рассмотрим файловую структуру проекта Amber. Там есть три основных папки: doc, hw и fw. Видимо «hw» обозначает hardware, а «fw» – это firmware. Внутри папки hw создаем новую папку marsohod2 – там будет все относяшееся к нашему новому проекту для Altera Quartus II и платы Марсоход2.
2) Вообще топ модуль проекта Amber – это hw/vlog/system/system.v
Я решил не модифицировать его, ведь возможно изменений будет много. Поэтому я его просто копирую в свою папку под новым именем hw/marsohod2/msystem.v. Теперь мой топ модуль будет этот файл.
3) Создаю новый проект Altera Quartus II с именем mARM в этой папке hw/marsohod2. Подробно расписывать этот шаг не буду, надеюсь на нашем сайте https://marsohod.org можно отыскать эту информацию. Самое главное для проекта назначить:
- тип микросхемы FPGA нашей платы Marsohod2 - EP3C10E144C8;
- в настройках проекта Device and Pin Options желательно установить опцию Unused pins в состояние As Input tri-stated.
- нужно бы сделать назначения пинов согласно схеме платы. Но тут не все так просто, ведь мы еще не знаем толком какие входные и выходные сигналы у нас будут в проекте. Это нужно не забыть сделать позднее.
5) Из топ модуля msystem.v удаляю все относящееся к DDR. На нашей плате его все равно нет. Там где идет речь об Ethernet пока выключаю его – вдруг позже пригодится? Выключаю очень просто, пишу конструкцию Verilog для условной компиляции, как-то так:
`ifdef ETHERNET
eth_top u_eth_top (
.wb_clk_i ( sys_clk ),
.wb_rst_i
.....
`endif
При этом ETHERNET нигде не определено с помощью `define, значит участок кода будет исключен во время компиляции. Я надеюсь может когда-то мы его все же включим в будущем?
6) Создаю свой модуль генерации тактовой частоты hw/marsohod2/my_clocks_resets.v вместо оригинального hw/vlog/system/clocks_resets.v. Тут я так же применю условную компиляцию:
`ifdef MARSOHOD2
my_clocks_resets u_clk_r(
.i_brd_rst(brd_rst), //from board button
.i_brd_clk(brd_clk_p), //from board crystal
.o_sys_rst(sys_rst), //main project reset made out of board button reset
.o_sys_clk(sys_clk), //main system clock
.o_system_ready(system_rdy)
);
`else
clocks_resets u_clocks_resets (
.i_brd_rst ( brd_rst ),
.i_brd_clk_n ( brd_clk_n ),
.i_brd_clk_p ( brd_clk_p ),
.i_ddr_calib_done ( phy_init_done ),
.o_sys_rst ( sys_rst ),
.o_sys_clk ( sys_clk ),
.o_clk_200 ( clk_200 )
);
`endif
Только теперь я напротив, хочу определить макрос MARSOHOD2, если он будет определен, то выбирается мой участок исходного кода, если не определен, то оригинальный код. Определить макрос MARSOHOD2 можно в настройках проекта Altera Quartus II через меню Assignments => Settings и далее в диалоговом окне Analysis & Synthesis Settings / Verilog HDL Input.
Вообще модуль my_clocks_resets.v нужен, чтобы из одного входного сигнала тактовой частоты и одного сигнала сброса сделать все системные тактовые частоты и системный сброс. Теоретически в системе может быть несколько тактовых частот для разных нужд. У нас пока будет не так, но по крайней мере это нужно предусмотреть. Опять же я еще пока не могу сказать, на какой частоте сможет работать наш процессор. Нужна возможность как-то менять тактовую частоту системы.
Для этого я, с помощью меню Tools => MegaWizard Plug-in Manager создаю компонент PLL и вставляю его в мой модуль генерации тактовой частоты. Компонент PLL можно настраивать, задавать коэффициенты умножения и деления тактовой частоты. Про PLL можно еще почитать вот здесь.
Ну не знаю. Тактовый генератор на плате Марсоход2 имеет частоту 100Mhz. Можно пока просто поделить частоту на 2, пусть пока системная частота будет 50Mhz?
6) Начинаем компилировать проект с помощью Altera Quartus II. Когда компилятор говорит, что не хватает какого-то модуля, то ищем Verilog файл на диске в подпапках hw/vlog/ и добавляем найденный файл в наш проект. Таким образом в конце концов мы выясним, какие же на самом деле файлы нужны.
7) Вот еще проблема. В топ модуле обнаружился вот такой код:
`ifndef XILINX_FPGA
// ======================================
// Instantiate non-synthesizable main memory model
// ======================================
main_mem #(
.WB_DWIDTH ( WB_DWIDTH ),
.WB_SWIDTH ( WB_SWIDTH )
....
Мы ведь все, что связано с DDR удалили, макрос XILINX_FPGA не определили. Теперь Quartus пытается скомпилировать в проект модуль main_mem, который на самом деле является не синтизируемой моделью основной памяти системы на кристалле. Придется этот модуль так же выключить.
6) Постепенно добавляю новые файлы в проект. Странность – в файле a23_decode.v объявлен регистр с именем type – тип декодируемой инструкции процессора. Для альтеры это зарезервированное имя. Quartus II выдает ошибку в этом месте. Пришлось переименовывать type в itype по всему тексту.
7) При компиляции проекта Quartus II натурально виснет и теперь понял из-за чего. Как-то не может скомпилировать модуль generic_sram_line_en, это похоже модель статической памяти. Там в Verilog файле hw/vlog/amber23/a23_cache.v есть код:
generate
for ( i=0; i<WAYS;i=i+1 ) begin : rams
// Tag RAMs
`ifdef XILINX_SPARTAN6_FPGA
xs6_sram_256x21_line_en
`endif
`ifdef XILINX_VIRTEX6_FPGA
xv6_sram_256x21_line_en
`endif
`ifndef XILINX_FPGA
generic_sram_line_en
`endif
Видно проект мог использоваться с микросхемами Xilinx Spartan и Virtex. Если соответствующие макросы не определены, то в код включался generic_sram_line_en.
Вообще-то в FPGA есть встроенные блоки памяти. Для них есть специальные компоненты, у Альтеры это, например, altsyncram. На его основе, задавая его параметры можно делать модули разной разрядности и объема.
Тут пришлось повозиться.
Создаю основе altsyncram (с помощью Altera Quartus II MegaWizard Plug-in Manager) свои компоненты my_sram_256_21_line_en и my_sram_256_128_byte_en для модуля кэша a23_cache.v и и еще my_sram_2048_32_byte_en для boot_mem32.v – там приключилась такая-же история – не компилировался и Quartus зависал.
Вот после всех этих и других, более мелких изменений можно компилировать.
Случилось чудо – я смог формально откомпилировать проект!
Netlist Viewer показывает какие модули у нас существуют / остались в проекте (смотри выше иллюстрацию к статье):
- my_clocks_reset;
- timer_module;
- test_module;
- boot_mem32;
- interrupt_controller;
- a23_core;
- wishbone_arbiter;
- uart.
Конечно загружать проект в ПЛИС еще нельзя.
Во-первых, не назначено местоположение входных и выходных сигналов. Во-вторых, boot_mem32 не содержит собственно начальной программы, которая должна исполняться при включении процессора.
Эти вопросы придется решать.
Естественно, пока проект для загрузки выложить не могу, все равно его пороблвать нельзя. Зато можно посмотреть все изменения в нашем проекте System-on-Chip (SOC) в репозитории GITHUB: https://github.com/marsohod4you/Amber-Marsohod2
Следующее, что нужно сделать - написать и откомпилировать для ARM процессора какую-то программу и поместить ее код в BOOTROM нашей системы. Вот тогда будем ее пробовать.
Подробнее...