Симуляция проекта Amber с Icarus Verilog.

После первой неудачной попытки запустить проект Amber в плате Марсоход2 нужно подумать, что же делать дальше. Есть несколько вариантов:
Пункт первый – использование SignalTap, позволит «вживую» увидеть некоторые сигналы внутри процессора Amber, но проблема в том, что я точно не знаю куда смотреть, на какие сигналы обращать внимание. Все сразу посмотреть конечно нельзя, выбор сигналов для исследования требует последующей перекомпиляции, которая занимает время (примерно 12 минут на моем ноутбуке). Значит придется потратить довольно много времени на итерации исследуя одну или другую группу сигналов.

Пункт второй наверное самый правильный, поскольку позволит просимулировать все, включая такие родные компоненты Альтеры, как PLL или блоки памяти ALTSYNCRAM.
Честно говоря,  ModelSim мне не нравится – и главное причин в общем никаких нет – вполне нормальный инструмент. Наверное я его просто не до конца освоил.

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

Итак, я определяю переменную ICARUS для условной компиляции. Теперь в файле hw/marsohod2/my_clocks_reset.v там где инсталируется экземпляр PLL будет условная компиляция:

`ifdef ICARUS
  assign pll_clk = i_brd_clk;
  assign pll_locked  = 1'b1;
`else
  //insert altera's PLL
  my_pll my_pll_inst (
   .inclk0(i_brd_clk),
   .areset(1'b0 /*i_brd_rst*/ ),
   .c0(pll_clk),
   .locked(pll_locked)
  );
`endif

В отличие от проекта для Quartus II для симуляции с Icarus Verilog я не буду определять переменную условной компиляции MARSOHOD2. Тогда, например, в файле hw/vlog/system/boot_mem32.v для памяти программы будет использован компонент generic_sram_byte_en вместо my_sram_2048_32_byte_en (который я создавал с помощью Altera Quartus II визарда)

`ifndef XILINX_FPGA
 `ifdef MARSOHOD2
    my_sram_2048_32_byte_en
  `else
    generic_sram_byte_en
  `endif
#(
.DATA_WIDTH     ( WB_DWIDTH             ),
.ADDRESS_WIDTH  ( MADDR_WIDTH           )
)
`endif
u_mem (
  .i_clk          ( i_wb_clk             ),
  .i_write_enable ( start_write          ),
  .i_byte_enable  ( byte_enable          ),
  .i_address      ( address              ),  // 2048 words, 32 bits
  .o_read_data    ( read_data            ),
  .i_write_data   ( write_data           )
);

Еще одна тонкость – похоже Icarus Verilog не поддерживает  log2(..), так что пришлось исправить hw/vlog/amber23/a23_cache.v вот так:

`ifdef ICARUS
 parameter CACHE_ADDR_WIDTH  = 8,                // = 8
 parameter WORD_SEL_WIDTH    = 2,                // = 2
`else
 parameter CACHE_ADDR_WIDTH  = log2 ( CACHE_LINES ),           // = 8
 parameter WORD_SEL_WIDTH    = log2 ( CACHE_WORDS_PER_LINE ),  // = 2
`endif


В проект я добавил свою папку hw/marsohod2/my_tb и там теперь несколько новых файлов:
  • hello-world.mem – текстовый файл, описывающий содержимое bootrom. Создается при компиляции программы hello-world.c компилятором Sourcery CodeBench
  • srclist – список всех Verilog файлов в проекте
  • c.bat – командный файл запускающий компиляцию проекта с помощью Icarus Verilog. По сути дела там всего одна длинная команда: iverilog -o qqq -g2005 -DICARUS=1 -DAMBER_A23_CORE=1 -DNOMEMORY=1 -csrclist -I../../vlog/system/ -I../../vlog/amber23/ -I../../vlog/tb/
  • tb.v – мой тестбенч. Создан на основе оригинального тестбенча из проекта Amber, который лежит в папке hw/vlog/tb

Весь проект лежит на GitHub https://github.com/marsohod4you/Amber-Marsohod2

Сам тестбенч вы можете посмотреть прямо сейчас вот здесь.

В тестбенче есть экземпляр модуля msystem и экземпляр модуля tb_uart – он будет иммитировать программу терминала, работающую на компьютере – принимать и печатать символы. Тестбенч считывает файл hello-world.mem и инициализирует bootrom перед началом запуска системы.

Собственно лог симуляции в консоли cmd выглядит вот так:


 

c:\Altera\Amber-Marsohod2\hw\marsohod2\my_tb>c.bat

c:\Altera\Amber-Marsohod2\hw\marsohod2\my_tb>iverilog -o qqq -g2005 -DICARUS=1 -
-I../../vlog/system/ -I../../vlog/amber23/ -I../../vlog/tb/

c:\Altera\Amber-Marsohod2\hw\marsohod2\my_tb>vvp qqq
VCD info: dumpfile out.vcd opened for output.
reseting..
Load boot memory from hello-world.mem
Read in 951 lines
log file tests.log, timeout 0, test name my ARM simulation
go..

Marsohod2: Hello, World!
* 0 *
* 1 *
* 2 *
* 3 *
* 4 *
** VVP Stop(0) **
** Flushing output streams.
** Current simulation time is 960856250 ticks.
> finish
** Continue **

c:\Altera\Amber-Marsohod2\hw\marsohod2\my_tb>


 

Как видите - процессор-то работает! В консоли симулятора появилась надпись "Marsohod2: Hello, World!" - это то сообщение, которое мы выводим функцией printf в нашей программе на C.

Кстати, в результате симуляции мы получили файл out.vcd и его можно открыть с помощью программы GtkWave и поисследовать сигналы в процессоре:

сигналы процессора Amber в gtkwave

По крайней мере, теперь мы можем заглянуть внутрь и увидеть, как должно быть, что бы работало. Теперь можно, например запускать SignalTap и сравнивать реальные сигналы в ПЛИС с теми, что должны быть, какими их видно в симуляторе.

Да, пока остается неясным, почему не работает проект в плате Марсоход2, но я уверен, что с этим разберемся.

 

 

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