Перенос проекта Amber в среду Altera Quartus II для платы Марсоход2

soc Amber в плате Марсоход2

Согласно нашему плану, начинаем адаптировать проект 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
  • нужно бы сделать назначения пинов согласно схеме платы. Но тут не все так просто, ведь мы еще не знаем толком какие входные и выходные сигналы у нас будут в проекте. Это нужно не забыть сделать позднее.
4) Добавляю в проект пока единственный файл msystem.v и делаю его модулем Top Level через меню Project => Set As-Top Level Entity.

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 нашей системы. Вот тогда будем ее пробовать.

 


Добавить комментарий