我正在尝试编写用于FPGA编程的verilog代码,我将在其中实现VGA应用程序。我使用Quartus II和Altera DE2。
目前,我的目标是在编译期间获得640x480 rgb图像(方法无关紧要,只要它有效且效率很高)。我想出的最佳解决方案是使用matlab将图片转换为rgb hex文件,并使用$ readmemh将它们放入寄存器中。
但正如这里所讨论的:verilog $readmemh takes too much time for 50x50 pixel rgb image
这需要花费太多时间,显然这种方法无法绕过它。如果它只是时间但是也有尺寸问题会很好,640x480几乎占用了大部分的免费空间。
我希望是一些系统函数或可变类型的verilog,它将以不同的方式获取和存储图片,以便大小不再是问题。我已经检查了verilog和quartus网页的解决方案,但我相信应该有更快的方法来完成这项一般任务,而不是从头开始写一些东西。
200x200 readmemh尝试的编译报告:
答案 0 :(得分:4)
根据您的编译报告,我建议您使用块ROM(或RAM)内存,而不是寄存器来存储图像。
此时您正在使用分布式RAM,即FPGA的每个小逻辑块内部可用的内存。这使得分布式RAM成为小型存储器的理想选择。但是当涉及大型存储器时,这可能会导致额外的布线延迟并增加合成时间(合成器需要连接所有这些块)。
另一方面,Block RAM是一个专用双端口存储器,包含几个千位(取决于您的设备和制造商)的RAM。这就是为什么你应该使用Block RAM来存储大容量存储器,而将FIFO用于FIFO或小型存储器。 Cyclone IV EP4CE115F29(DE2-115中提供)具有432个M9K存储器模块(3981312个存储器位)。
一个重要的事情是,READ操作对于分布式RAM是异步的(一旦给出地址就从内存中读取数据,不等待时钟边沿),但是对于Block RAM是同步的。
单端口ROM存储器的示例(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