0

我正在尝试使用下面的代码在 ModelSim 中使用 Verilog 中的数组声明一个 1MB 内存模型。我还需要在地址空间中有地址 0x80020000。

parameter MEM_START = 32'h7FFA_0000;
parameter MEM_END = 32'h800A_0000;
reg [7:0] MEMORY [MEM_START:MEM_END];

上面的代码编译得很好,但是当我尝试模拟它时它给出了以下错误:

# Loading project.memoryModule
# ** Fatal: (vsim-3419) Array with element size 2 and index range 2147090432 downto -2146828288 is too large.
#    Time: 0 ns  Iteration: 0  Instance: Project/memoryModule.v
# FATAL ERROR while loading design
# Error loading design

但是,如果我将内存索引从 7FEF_FFFF 初始化为 7FFF_FFFF,这也应该是 1 MB,一切都很好,我可以在模拟中看到分配的内存。如果我将范围从 7FEF_FFFF 修改为 8000_0000,我现在在编译期间会出现内部数据大小溢出。为什么内存的结束范围在错误(2的补码)中显示为-2146828288(FFFF FFFF 800A 0000)?

我在网上看到的所有示例都显示较小的记忆,即 256 个单词,所以 reg [7:0] MEMORY [0:255]) 所以我不确定我的逻辑是否有问题,或者问题是否与我机器上的硬件。我正在使用 32 位版本的 Modelsim 并且有 4 GB 的 RAM。

4

2 回答 2

3

该数组中的每个条目将是两个字节,因为每个位可以是01或。该数组是条目,即十进制的 2147614720 个条目。ZX0x80020000

2 * 2147614720 是 4295229440在一个阵列上是 4 + 1 GB 。

相信我,你不想这样做。即使只是将单个值写入所有这些位置也需要大量的模拟时间。

如果您在 SystemVerilog 中,则使用以地址作为索引的关联数组。这只会将内存用于存储有内容的位置。否则,我建议您将内存包装在将较小的数组移动到地址空间的正确部分的东西中。

于 2012-05-16T12:06:32.693 回答
1

起初这看起来像一个错误,但也许不是。数组索引被视为常量整数表达式。

指定数组索引的表达式应为常量整数表达式。常量表达式的值可以是正整数、负整数或零。

该规范对常量整数也非常清楚,并且它们与变量整数不同。

没有大小和基本格式的简单十进制数应视为有符号整数,而如果包含 s 指示符,则使用基本格式指定的数字应视为有符号整数,如果仅使用基本格式,则应视为无符号整数。

但是,该参数被强制为整数类型(即使它是常量),它始终是有符号的。这是规范中隐含的。

在应用任何值覆盖后,没有类型或范围规范的参数声明应默认为分配给参数的最终值的类型和范围。

如果您运行 sim 并使用 MEM_END 打印出一些算术结果,它可能会充当 32 位有符号值。您看到的消息肯定与正在签名的 MEM_END 一致。就个人而言,我永远不会以这种方式使用偏移数组索引。


要解决此问题,您可以尝试以下几种方法:

  • 使用无符号函数:

    reg [7:0] MEMORY [$unsigned(MEM_START):$unsigned(MEM_END)];

  • 如果你需要一个 1MB 的范围,你可以使用 0x8000_0000..0x8010_0000 然后忽略索引中的 MSB。

  • 如果您需要测试地址的 MSB,您可以在内存模型中应用偏移量。

  • 使用 64 位版本的 Modelsim。

  • 用于`define避免参数,尽管并不理想,因为定义是全局的并且参数是作用域的。

    `define MEM_START 32'h7FFA_0000;
    `define MEM_END   32'h800A_0000; 
    reg [7:0] MEMORY [`MEM_START:`MEM_END];

如果不确切知道您要做什么,就很难回答这个问题。

于 2012-05-16T20:56:04.143 回答