简体   繁体   中英

How to get a rgb picture into FPGA most efficiently, using verilog

I am trying to write a verilog code for FPGA programming where I will implement a VGA application. I use Quartus II and Altera DE2.

At the moment, my aim is to get a 640x480 rgb image during compilation (method doesn't matter as long as it works and is efficient). The best solution I came up with is to convert the picture into rgb hex files using matlab and to use $readmemh to get them into a register.

But as discussed here: verilog $readmemh takes too much time for 50x50 pixel rgb image

it takes too much time and apparently there is no way around it with this method. It would be fine if it was only the time but there is also the size problem, 640x480 pretty much costs most of the free space.

What I am hoping is some system function or variable type of verilog that will take and store the picture in a different way so that size won't be a problem anymore. I have checked solutions for verilog and quartus webpage but I believe there should be a faster way to do this general task, rather than writing something from scratch.

compilation report for 200x200 readmemh attempt: 200x200编译报告

Based on your compilation report, I'd recommend you using a block ROM (or RAM) memory, instead of registers to store your image.

At this moment you're using distributed RAM, ie the memory that is available inside a each small logic blocks of FPGA. This makes distributed RAM, ideal for small sized memories. But when comes to large memories, this may cause an extra wiring delays and increase synthesis time (the synthesiser need to wire all of this blocks).

On the other hand, a block RAM is a dedicated two port memory containing several kilobits (depending on your device and manufacture) of RAM. That's why you should use block RAM for large sized memories, while distributed RAM for FIFO's or small sized memories. Cyclone IV EP4CE115F29 (available in DE2-115) has 432 M9K memory blocks (3981312 memory bits).

One important thing, the READ operation is asynchronous for distributed RAM (data is read from memory as soon as the address is given, doesn't wait for the clock edge), but synchronous for block RAM.

The example of single port ROM memory (Quartus II Verilog Template):

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM