[英]Verilog/SystemVerilog: passing a slice of an unpacked array to a module
我正在使用 DE10-Nano 和 Quartus Prime 来尝试实现以下功能。
我有两个模块: Module1
和Module2
。 Module1
像这样声明一个RAM
:
reg [15:0] RAM[0:24576];
// init RAM 0:8191 with all 1
然后将 RAM 的一个子集传递给Module2
:
Module2 Module2 (
// input
.screen_mem(RAM[0:8191]),
);
Module2
在要显示的监视器上显示screen_mem
。 不幸的是,上述解决方案不起作用,即显示全黑。
但如果我尝试:
reg [15:0] screen_mem[0:8191];
// init screen_mem with all 1
Module2 Module2 (
// input
.screen_mem(screen_mem),
);
这有效,即显示器正确显示所有白色像素。
如果我尝试使用模拟器,两种解决方案都有效。
我错过了什么? 为什么我不能将解压缩数组的一部分传递给子模块? 我也试过用中间wire
,但还是不行。 我错过了什么吗?
谢谢,
您的第一个实现很可能会产生一个推断的 ram,从硬件的角度来看这是正确的。
然而,您正试图直接索引到它,就好像它是一个综合工具不知道如何做的寄存器数组。 本质上,您需要将 RAM 完全封装为具有写入启用、写入索引、读取启用和读取索引的推断 RAM 块,然后将其与您的 screen_mem 示例(我假设它像数组或寄存器一样使用)结合起来:
// Read side of RAM
always@(posedge clk) begin
if(ram_read_en == 1'b1) begin
// This makes the RAM act like a true RAM
ram_read_data <= RAM[ram_read_addr];
end else begin
// Default here depends on your synthesizer....may not need it...
end
end
// Screen Mem Updater Handshaking
always@(posedge clk) begin
if(rst_n == 1'b0) begin
ram_read_addr <= '0;
ram_read_en <= '0;
end else begin
// "Map" address from RAM to screen_mem at same location
if(ram_read_addr == 'd8191) begin
ram_read_addr <= '0;
end else begin
ram_read_addr <= ram_read_addr + 1;
end
// Always reading to update screen_mem
ram_read_en <= '1;
end
end
// Screen Mem Updater
always@(posedge clk) begin
// Map RAM to screen_mem based on the same address above
// Probably have to play with pipelining of the ram_read_addr as
// the RAM takes time to readout...
screen_mem[ram_read_addr] <= ram_read_data;
end
模拟器可以正常工作是可以理解的,因为它可以将 RAM 阵列用作 RAM 和寄存器阵列……它只是将其视为 sim 中的 memory 个位置的阵列。 然而,硬件需要 map 将其转换为 FPGA 中的真实对象,这就是模拟不匹配的原因。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.