Verilog/Systemverilog:将一个未包装阵列的切片传递给模块

发布于 2025-01-24 09:44:42 字数 766 浏览 0 评论 0原文

我正在使用具有Quartus Prime的De10-Nano来尝试实现以下内容。

我有两个模块:module1module2module1声明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),
);

这有效,即,显示器正确显示了所有白色像素。

如果我尝试使用模拟器,则两个解决方案都可以。

我想念什么?为什么我不能将未包装阵列的切片传递给子模块?我还尝试使用中间电线,但它仍然不起作用。我想念什么吗?

谢谢,

I am using a DE10-Nano with Quartus Prime to try to implement the following.

I have two modules: Module1 and Module2. Module1 declares a RAM like this:

reg [15:0] RAM[0:24576];
// init RAM 0:8191 with all 1

And then passes a subset of the RAM to Module2:

Module2 Module2 (
  // input
  .screen_mem(RAM[0:8191]),
);

Module2 shows screen_mem on a monitor to be displayed. Unfortunately above solution does not work, i.e., display goes all black.

But if I try:

reg [15:0] screen_mem[0:8191];
// init screen_mem with all 1
Module2 Module2 (
  // input
  .screen_mem(screen_mem),
);

This works, i.e., the display properly shows all the white pixels.

If I try to use a simulator, both solutions work.

What am I missing? Why I can't pass a slice of an unpacked array to a submodule? I also tried to use an intermediate wire, but it still doesn't work. Am I missing something?

Thanks,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

红玫瑰 2025-01-31 09:44:42

您的第一个实现可能会导致推断的RAM,这是从硬件角度来看正确的。

但是,您正在尝试将其直接索引到其中,就好像它是综合工具不知道该怎么做的一系列寄存器一样。本质上,您需要将RAM作为一个推断的RAM块完全封装,并用Write Enable,写入索引,读取启用和读取索引,然后将其与您的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

IT最终将综合与这样的东西:

可以理解的是,模拟器可以正常工作,因为它可以将RAM数组用作RAM和寄存器数组……它只是将其视为SIM中的一个内存位置。但是,硬件需要将其映射到FPGA中的真实对象,这就是为什么模拟不匹配的原因。

It is likely that your first implementation is resulting in an inferred ram, which is correct from a hardware-perspective.

However then you are trying to index directly into it as if it is an array of registers which the synthesis tool doesn't know how to do. Essentially you need to fully encapsulate your RAM as an inferred RAM block with write enables, write indexes, read enables, and read indexes, then combine that with your example of the screen_mem (which I assume is used like an array or registers):

// 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

It will end up synthesizing to something like this:
crappy drawing

It is understandable that the simulator works correctly because it can use the RAM array as both a RAM and as an array of registers...it just sees it as an array of memory locations in the sim. Hardware, however, needs to map this to real objects in the FPGA which is why you have a simulation mismatch.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文