在 VHDL、Verilog、sim 行为中写入 RAM 的无效地址



让我们在Verilog或VHDL下有一个BRAM或任何其他内存。 例如:

module raminfr (clk, we, a, di, do);   
input clk;   
input we;   
input  [4:0] a;   
input  [3:0] di;   
output [3:0] do;   
reg    [3:0] ram [31:0]; 
always @(posedge clk) begin   
if (we)   
ram[a] <= di;   
end   
assign do = ram[a];   
endmodule

现在让我们假设我们已经将有效数据写入 "ram"。

如果地址"a"具有无效值(4'bxxxx(("we"=1,clk 将具有posedge(,模拟器是否会入侵"ram"中的所有项目? 或者它让 ram 中的值保持原样?

对于 Verilog

IEEE Std 1800-2009 SystemVerilog 标准包含 IEEE Std1364-2005 Verilog 标准和 IEEE Std 1800-2005 SystemVerilog 标准。IEEE Std 1800-2012 SystemVerilog 标准取代了 -2009 版本。

请参阅 IEEE Std 1800-2012 7.4.6 数组的索引和切片:

如果索引表达式

越界,或者索引表达式中的任何位是xz,则该索引应无效。从具有无效索引的任何类型的解压缩数组中读取应返回表 7-1 中指定的值。写入具有无效索引的数组不应执行任何操作,但写入队列的元素 [$+1] (在 7.10.1 中描述(和创建关联数组的新元素(在 7.8.6 中描述(除外。如果数组上的读取或写入操作出现无效索引,则实现可能会发出警告。

对于 VHDL

等效的 VHDL 设计描述可能是:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity raminfr is
port (
clk:  in  std_logic;
we:   in  std_logic;
a:    in  std_logic_vector(4 downto 0);
di:   in  std_logic_vector(3 downto 0);
do:   out std_logic_vector(3 downto 0)
);
end entity;
architecture behave of raminfr is
type ram_type is array (0 to 15) of std_logic_vector (3 downto 0);
signal ram:  ram_type;
begin
process (clk)
begin
if rising_edge(clk) then
if we = '1' then
ram(to_integer(unsigned(a))) <= di;
end if;
end if;
end process;
do <= ram(to_integer(unsigned(a)));
end architecture;

其中,numeric_stdto_integer函数用于将a的数组值转换为整数索引。(VHDL 在这里更灵活一些,数组索引可以是整数类型或枚举类型,统称为离散类型(。

读取源代码to_integer我们看到它将包含"X"的输入无符号数组值转换为所有"X",并且作为"X"的"LEFT 值"将返回自然整数子类型值 0,并选择性地报告:

if (XARG(XARG'left) = 'X') then
assert NO_WARNING
report "NUMERIC_STD.TO_INTEGER: metavalue detected, returning 0"
severity warning;
return 0;
end if;

可以通过更改本地静态的NO_WARNING的值在实现范围内禁用这些警告。使用 to_integer(或与 Synopsys 软件包std_logic_arith和函数conv_integer一起使用(,索引将为 0。

此外,VHDL 实现能够停止对严重性警告报告的模拟。

虽然您可以以不同的方式处理分配结果,其中索引作为数组值提供(例如在 2、4、8、16 或 32 个无效内存位置中,具体取决于此处a的"X"元素值的数量(,但您已经损害了设计模型状态的完整性,在依靠 SystemVerilog 或 VHDL 设计模型的仿真结果之前,应采取一些纠正措施。

一般来说,复杂摆弄的开销似乎不值得。这些警告属于一类警告,应在合成之前进行检查。

当数组值的默认初始值为元值时,这些警告可能会在重置数组值之前发生。在大多数 FPGA 设计中,您可以通过初始化a和任何前置产品来防止这种情况a这样它包含一个表示值的二进制文件,或者只是在重置生效之前忽略时间 0 的报告。

您还可以通过将we和任何前置任务初始化为"0"来防止写入地址 0。

模拟器不会使任何东西失效。相反,写入将被忽略。

对于在这种情况下的读取,它将返回"x"。

最新更新