Amber ARM впервые работает на плате Марсоход2!

Вывод в консоль последовательного порта сообщения Hello, World!

Теперь уже работает – после нескольких исправлений в коде проекта Amber. Сейчас программа hello-world, написаннная на языке C и откомпилированная для ARM запускается в плате Марсоход2. Программа печатает сообщение функцией printf(..), которая отсылает его нам через последовательный порт на скорости 921600 бит/сек. А дело было так.

После симуляции проекта в Icarus Verilog я убедился, что сам проект Amber рабочий (вообще было бы странно, если бы он был нерабочим). Но проблема оставалась – в моем проекте Quartus II для ПЛИС Altera что-то видимо было сделано не верно.

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

Мой проект сделан таким образом, что вход с кнопочки (той, что ближе к разъему USB) платы Марсоход2 является сигналом сброса brd_n_rst  для проекта. Правда у самого процессора Amber сброса нет, но зато есть сигнал i_system_rdy, который я и связал со сбросом. Таким образом, процессор должен стартовать после того, как сигнал сброса будет снят. Это дает возможности для использования логического анализатора на самом старте процессора.

В SignalTap я задаю исследуемые сигналы, например внешние сигналы процессора к шине Wishbone bus. Я хочу посмотреть как процессор читает код программы из bootrom. Начальный момент захвата для логического анализатора (trigger) – это сигнал процесора i_system_rdy. Анализ внутренних сигналов в момент старта процессора производится следующим образом:

  • компилирую проект с включенным логическим анализатором и выбранными сигналами для анализа.
  • запускаю SignalTap.
  • на плате нажимаю кнопочку сброса для проекта Amber.
  • из SignalTap загружаю проект в ПЛИС – при этом проект не стартует, так как я держу кнопку сброса.
  • в SignalTap запускаю логический анализатор, который «подвисает» ожидая сигнала триггера на процессоре i_system_rdy.
  • отпускаю кнопочку сброса на плате – SignalTap тут же выдает мне картинку, как выглядят мои сигналы внутри ПЛИС Cyclone III.

Использование SignalTap для исследования внутренних сигналов процессора Amber

Используя этот метод я смог убедиться, что процессор на старте скорее мертв, чем жив. На шине Wishbone bus не происходит ничего, хотя адрес на bootrom выдается правильный – это ноль и с bootrom поступает первая команда процессора ARM 0xE3A00000 (это mov r0, #0x00000000). Другие сигналы шины o_wb_cyc, o_wb_stb, i_wb_ack не шевелятся.

Пришлось довольно долго повозиться рассматривая откуда эти сигналы берутся и от чего зависят. Каждая итерация занимает довольно много времени, поскольку, если я меняю список исследуемых сигналов в SignalTap мне требуется перекомпилировать проект.

В конце концов я добрался до одной очень странной странности – в модуле hw/vlog/amber23/a23_cache.v есть так называемая «машина состояний» (StateMachine) и похоже, что ее состояние при старте системы изначально не верное.

Использование SignalTap для исследования внутренних сигналов процессора Amber

Видите, что начальное состояние машины состояний в кэш контроллере c_state.CS_INIT = 1, но ведь должно быть не так! В коде Verilog a23_cache.v написано ведь совсем другое:

reg  [3:0] c_state = CS_IDLE;

Более того, если зайти в Quartus II в меню Tools => Netlist Viewers => State Machine Viewer то можно видеть, что компилятор Quartus II действительно неправильно определил поведение описанной на языке Verilog машины состояний.

Машина состояний кэш контроллера в проекте Amber

Quartus II считает, что у этой машины начальное состояние это CS_INIT, а должно быть CS_IDLE.

На самом деле мне трудно утверждать, что это именно баг компилятора Quartus II, возможно есть какие-то тонкости или неопределенности в стандарте языка Verilog. Я не являюсь досконольным знатоком спецификации Verilog. Все, что я утверждаю – написанное не соответствует скомпилированному и синтезированному в ПЛИС.

Очень странно, что даже явное указание начального значения для регистра c_state не меняет ситуацию, я написал вот так:

reg  [3:0] c_state = CS_IDLE;
initial
  c_state = CS_IDLE;


Но и это не помогло. Все из-за того, что, видимо, регистр c_state интерпретируется компилятором Quartus II каким-то особым образом из-за того, что описывает машину состояний. Очень странный баг (или фича?) в Quartus II.

В принципе в Quartus II есть множество настроек связанных с особенностями компиляции. Посмотреть их можно через меню Assignments => Settings и далее в диалоговом окне настройки Analysis & Synthesis Settings и далее кнопка More Settings.

Настройки компилятора Altera Quartus II

Здесь в списке есть Ignore Verilog initial constructs и у меня, как положенно, стоит здесь Off. Тоесть я хочу, чтобы initial constructs работали, чтобы в проекте при старте в регистрах были заданные в проекте значения.

В общем, помучавшись немного, я обнаружил здесь же в настройках другую полезную опцию – Extract Verilog State Machines – здесь стояло On. Это как раз та опция, которая заставляла компилятор Quartus интерпретировать регистр c_state не как обычный регистр, а как специфический регистр машины состояний. Как написано в подсказке Quartus эта опция позволяет:

Allows the Compiler to extract state machines from Verilog Design Files. The Compiler optimizes state machines using special techniques to reduce area and/or improve performance. If set to Off, the Compiler extracts and optimizes state machines in Verilog Design Files as regular logic.

Ага, как-же, дооптимизировали area и performance, что проект не правильно работает. В общем, выключил я эту опцию в настройках. Теперь Extract Verilog State Machines => Off.

Вы знаете, стало лучше, но не намного. Сигналы на Wishbone bus стали хоть как-то меняться, но все равно процессор не работает:

Использование SignalTap для исследования внутренних сигналов процессора Amber

После этого, я нашел еще одно место в проекте Amber неправильно интерпретируемое компилятором Quartus II – это в файле a23_decode.v

В этом файле выходные сигналы модуля объявляются и одновременно задается их начальное значение, вот так:


module a23_decode
(
input                       i_clk,
input       [31:0]          i_read_data,
...................
output reg  [31:0]          o_read_data = 1'd0,
output reg  [4:0]           o_read_data_alignment = 1'd0,  // 2 LSBs of read address used for calculating shift in LDRB ops

output reg  [31:0]          o_imm32 = 'd0,
output reg  [4:0]           o_imm_shift_amount = 'd0,
output reg                  o_shift_imm_zero = 'd0,
output reg  [3:0]           o_condition = 4'he,             // 4'he = al
output reg                  o_exclusive_exec = 'd0,         // exclusive access request ( swap instruction )
output reg                  o_data_access_exec = 'd0,       // high means the memory access is a read
// read or write, low for instruction
output reg  [1:0]           o_status_bits_mode = 2'b11,     // SVC
output reg                  o_status_bits_irq_mask = 1'd1,
output reg                  o_status_bits_firq_mask = 1'd1,
.................



Так вот получается, что все эти начальные значения для output reg проигнорированны компилятором. Я не смог найти опцию в настройках Quartus II, которая бы заставила использовать эти назначенные значения.

Пришлось ниже в тексте модуля задавать их явно с помощью конструкции initial.

 

Вот только после всех этих манипуляций с настройками проекта и изменений в коде a23_decode.v проект заработал и в консоли последовательного порта я увидел заветную фразу “Marsohod2: Hello, World!

Теперь и в SignalTap я вижу активный процесс чтения кода процессором из bootrom:

Использование SignalTap для исследования внутренних сигналов процессора Amber

Да и сообщение в консоли последовательного порта - это явное доказательство работоспособности проекта.

Вот теперь его можно и дальше развивать.

В общем, оказалось, что проект Amber использует какие-то конструкции языка Verilog, которые интерпретируются компилятором Quartus II несколько специфическим образом. Тем не менее, мы смогли это обойти исправив настройки проекта Altera Quartus II и несколько модифицировав исходный текст процессора Amber.

Все последние изменения в проекте есть на GitHub в нашем разделе https://github.com/marsohod4you/Amber-Marsohod2.

 

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