Как получить RGB-изображение в FPGA наиболее эффективно, используя Verilog

Я пытаюсь написать Verilog-код для программирования на ПЛИС, где я буду реализовывать приложение VGA. Я использую Quartus II и Altera DE2.

На данный момент моя цель - получить изображение 640x480 rgb во время компиляции (метод не имеет значения, пока он работает и эффективен). Лучшее решение, которое я придумал, - преобразовать картинку в шестнадцатеричные файлы rgb с помощью matlab и использовать $readmemh, чтобы получить их в регистр.

Но, как обсуждалось здесь: verilog $readmemh занимает слишком много времени для изображения RGB размером 50x50 пикселей.

это занимает слишком много времени и, видимо, с этим методом не обойтись. Было бы хорошо, если бы это было только время, но есть и проблема размера, 640x480 в значительной степени стоит большую часть свободного пространства.

Я надеюсь, что это какая-то системная функция или переменный тип verilog, который будет принимать и сохранять изображение другим способом, так что размер больше не будет проблемой. Я проверил решения для веб-страниц Verilog и Quartus, но я считаю, что должен быть более быстрый способ выполнить эту общую задачу, а не писать что-то с нуля.

отчет компиляции для попытки readmemh 200x200:Отчет о компиляции 200x200

1 ответ

Решение

На основании вашего отчета о компиляции я бы порекомендовал вам использовать блочную ПЗУ (или ОЗУ) вместо регистров для хранения вашего изображения.

В данный момент вы используете распределенную оперативную память, то есть память, доступную внутри каждого небольшого логического блока ПЛИС. Это делает распределенное ОЗУ идеальным для памяти небольшого размера. Но когда дело доходит до больших объемов памяти, это может привести к дополнительным задержкам проводки и увеличению времени синтеза (синтезатору необходимо соединить все эти блоки).

С другой стороны, блочная оперативная память - это выделенная двухпортовая память, содержащая несколько килобит (в зависимости от вашего устройства и производителя) оперативной памяти. Вот почему вы должны использовать блочную оперативную память для памяти большого размера, а распределенную оперативную память для памяти FIFO или памяти небольшого размера. Cyclone IV EP4CE115F29 (доступный в DE2-115) имеет 432 блока памяти M9K (3981312 битов памяти).

Одна важная вещь: операция READ является асинхронной для распределенной оперативной памяти (данные считываются из памяти, как только адрес задан, не ожидает окончания тактового сигнала), но синхронна для блочной оперативной памяти.

Пример однопортовой ПЗУ (шаблон Quartus II Verilog):

module single_port_rom
#(parameter DATA_WIDTH=8, parameter ADDR_WIDTH=8)
(
    input [(ADDR_WIDTH-1):0] addr,
    input clk, 
    output reg [(DATA_WIDTH-1):0] q
);

    // Declare the ROM variable
    reg [DATA_WIDTH-1:0] rom[2**ADDR_WIDTH-1:0];

    initial
    begin
        $readmemh("single_port_rom_init.txt", rom);
    end

    always @ (posedge clk)
    begin
        q <= rom[addr];
    end

endmodule
Другие вопросы по тегам