Плис SoC Cyclone V, в QSys собрана HPS и несколько подключенных модулей, все на AvalonMM.
Проблем не было.
Но вот пробую добавить ещё один свой модуль, подключить надо к мосту FPGA-HPS теперь уже через AXI шину (надо тянуть AxCACHE и AxUSER линии).
Нужно всего-то записывать около сотни байтов в память HPS.
Написал простенький AXI мастер, подключил в QSys - всё нормально вроде бы, компилируется и синтезируется, но Квартус, собака, выкидывает после оптимизации почти весь код модуля!
Как я понял, шерстить он начинает внутренности сгенерированного QSys интерконнекта (судя по логам), а затем выбрасывает и мой модуль, так как считает, что данные отправить мне уже никуда не получится...
Если путём недолгих корректировок заменить AXI на Avalon - то всё остаётся на месте, ничего лишнего не "оптимизируется".
Что же за чертовщина получается?
Может, я что-то не то делаю, как правильно организовать обмен по AXI?
Вот кусок кода с записью одного слова, простая машина состояний адрес->данные->ответ:
Код
always_ff @(posedge clk or negedge reset_n)
begin
if (!reset_n)
begin
axi_state <= 0;
axm_awvalid <= 0;
axm_wvalid <= 0;
axm_bready <= 0;
axm_awaddr <= 0;
axm_wdata <= 0;
start <= 0;
end
else
begin
if (avs_write)
begin
if (!avs_address) axm_awaddr <= avs_writedata;
else
begin
axm_wdata <= avs_writedata;
start <= 1'b1;
end
end
case (axi_state)
2'd0:
begin
if (start)
begin
axm_awvalid <= 1'b1;
start <= 0;
axi_state <= 2'd1;
end
end
2'd1:
begin
if (axm_awready)
begin
axm_awvalid <= 0;
axm_wvalid <= 1'b1;
axi_state <= 2'd2;
end
end
2'd2:
begin
if (axm_wready)
begin
axm_wvalid <= 0;
axm_bready <= 1'b1;
axi_state <= 2'd3;
end
end
2'd3:
begin
if (axm_bvalid && axm_bid == axm_awid)
begin
axm_bready <= 0;
axi_state <= 0;
end
end
endcase
end
end
begin
if (!reset_n)
begin
axi_state <= 0;
axm_awvalid <= 0;
axm_wvalid <= 0;
axm_bready <= 0;
axm_awaddr <= 0;
axm_wdata <= 0;
start <= 0;
end
else
begin
if (avs_write)
begin
if (!avs_address) axm_awaddr <= avs_writedata;
else
begin
axm_wdata <= avs_writedata;
start <= 1'b1;
end
end
case (axi_state)
2'd0:
begin
if (start)
begin
axm_awvalid <= 1'b1;
start <= 0;
axi_state <= 2'd1;
end
end
2'd1:
begin
if (axm_awready)
begin
axm_awvalid <= 0;
axm_wvalid <= 1'b1;
axi_state <= 2'd2;
end
end
2'd2:
begin
if (axm_wready)
begin
axm_wvalid <= 0;
axm_bready <= 1'b1;
axi_state <= 2'd3;
end
end
2'd3:
begin
if (axm_bvalid && axm_bid == axm_awid)
begin
axm_bready <= 0;
axi_state <= 0;
end
end
endcase
end
end
Делал на основе этой диаграммы:
Нажмите для просмотра прикрепленного файла
Версия квартуса 16.0.1, попробую обновится на днях...