Необходимо создать систему обработки видеоизображений с применением софт-процессора NIOS II. Задача такая: записать изображение с CMOS-камеры в оперативную память и произвести над ним некоторую обработку при помощи процессора.
Аппаратное обеспечение: стенд DE2-115 (Cyclone 4), плата с камерой TRDB-D5M.
Нашел пример от альтеры DE2_115_CAMERA, в котором реализовано на верилоге примерно следующая система:
захват изображения->декодер->контроллер SDRAM->ТВ-деодекодер
Подумал, что всего-то делов - подключить к этой системе NIOS и забрать данные из SDRAM. Не тут-то было

Мои варианты решения задачи:
1. Решил отказаться от идеи расшаривания SDRAM. Решил писать картинку в SRAM, и расшарить её. От SDRAM отказался по следующим соображениям: не понимаю, может ли быть в одной системе два контроллера памяти - один у HDL, другой - у NIOS. Если такое возможно, то как будет происходить разделение шины между ними, и самое главное - какой из контроллеров будет заниматься регенерацией памяти. SRAM подключил через Avalon MM Tristate Bridge ( по инструкции http://naliwator.narod.ru/les/les_nios_sram_00.html). В Top-level дизайн проекта DE2_115_CAMERA добавил соответсвенно свою систему из сопц-билдера. Софт-процессор с памятью SRAM заработал. Когда я попытался подключить шину моста SRAM к декодеру изображения - ничего не получилось. От ошибки разделения пинов
Цитата
Error: The pin "SRAM_ADDR[1]" has multiple drivers due to the non-tri-state driver "nios:u9|bridge_2_sram_avalon_slave_arbitrator:the_bridge_2_sram_avalon_slav
e|bridge_2_sram_address[1]"
не смог избавиться. Точнее для шины данных ошибку смог побороть, а для шины адреса - нет(?). Пришёл к выводу, что таким образом Расшарить SRAM у меня не получится. Подключение HDL-дизайна к выводам FPGA (assign SRAM_ADDR[19:0] = rSRAM_ADDR[19:0]e|bridge_2_sram_address[1]"

2. Создание в SOPC-Builder компонента на основе HDL описания всей камеры целиком. То есть создать такой компонент в который запихать всё - и блок захвата, и блоки обработки и контроллер SDRAM. Как управлять этим монстром - не понятно. Не ясно что делать с разнородными интерфейсами модуля - там и Conduit и Memory Mapped. Предлагаемый подход я нашёл в реализации "Nios II CRC Acceleration Example Design v2.2.0"(http://www.altera.com/support/examples/nios2/exm-crc-acceleration.html). Но там компонент попроще - всего лишь генератор CRC.
3. Создание в SOPC-Builder компонента на основе HDL модуля контроллера SDRAM. Придётся перенести SDRAM-контроллер с HDL в процессор. Возможно самый правильный подход. Пока не рассматривал.
В итоге вопрос, как же обмениваться данными между HDL и NIOS так и повис в воздухе. Видел советы по использованию в подобных ситуациях SGDMA, DMA... Но мне не дает покоя мысль, что всё должно быть гораздо проще. Какой путь более правильный и менее трудозатратный в моем случае? Подскажите пожалуйста.
top-level по первому варианту решения - в приложении. Ниже приведен отрывок топ-левела, где к выводам NIOS подключен HDL код инициализации SRAM памяти.
...
nios u9(
.clk_0 (CLOCK_50),
.reset_n (reset_n),
.bridge_2_sram_address (SRAM_ADDR),
.bridge_2_sram_byteenablen ({SRAM_UB_N, SRAM_LB_N}),
.bridge_2_sram_data (SRAM_DQ),
.bridge_2_sram_writen (SRAM_WE_N),
.in_port_to_the_sw (in_port_to_the_sw),
.out_port_from_the_led (out_port_from_the_led),
.rxd_to_the_uart (rxd_to_the_uart),
.txd_from_the_uart (txd_from_the_uart)
);
...
always@(posedge CLOCK_50 or negedge iRST)
begin
if(!iRST)
begin
writen_pixel <= 0;
nDW <= 1'b1;
end
else
begin
if (writen_pixel < 400*300)
begin
nDW <= 1'b1;
writen_pixel <= writen_pixel + 1;
rSRAM_ADDR[19:0] <= writen_pixel;
rSRAM_CE_N <= 1'b0;
rSRAM_DQ[15:0] <= 16'h5555;
rSRAM_LB_N <= 1'b0;
rSRAM_OE_N <= 1'b0;
rSRAM_UB_N <= 1'b1;//сташий байт не используется
rSRAM_WE_N <= 1'b0;
end
else
begin
rSRAM_ADDR[19:0] <= 20'hZZZZZ;
rSRAM_CE_N <= 1'bz;
rSRAM_DQ[15:0] <= 16'hZZZZ;
rSRAM_LB_N <= 1'bZ;
rSRAM_OE_N <= 1'bZ;
rSRAM_UB_N <= 1'bZ;//сташий байт не используется
rSRAM_WE_N <= 1'bZ;
nDW <= 1'b0;
end
end //else (nRST==1)
end
assign SRAM_DQ = rSRAM_DQ;
assign SRAM_ADDR[19:0] = rSRAM_ADDR[19:0];
assign SRAM_CE_N = rSRAM_CE_N;
assign SRAM_LB_N = rSRAM_LB_N;
assign SRAM_OE_N = rSRAM_OE_N;
assign SRAM_UB_N = rSRAM_UB_N;
assign SRAM_WE_N = rSRAM_WE_N;
...