我想知道VHDL中是否定义了整数溢出.我无法在2002规范中找到任何内容.
作为一个例子(注意,这可能无法编译,它只是一个通用的例子......):
entity foo is port (
clk : std_logic
);
end entity;
architecture rtl of foo is
signal x : integer range 0 to 2 := 0;
begin
process (clk)
begin
if rising_edge(clk) then
x <= x + 1;
end if;
end process;
end architecture;
Run Code Online (Sandbox Code Playgroud)
很明显,x它将从0变为1,然后变为2.是否定义了下一个增量会发生什么?是不确定的行为?
对于ghdl中frt的rtl测试平台:
ghdl -r foo_tb --wave = foo_tb.ghw
./foo_tb:error:foo_tb.vhdl中的绑定检查失败:15
./foo_tb:error:模拟失败
我在Bill的foo实体和架构中添加了一个context子句:
library ieee;
use ieee.std_logic_1164.all;
entity foo is port (
Run Code Online (Sandbox Code Playgroud)
第15行是x的信号分配:
x <= x + 1;
Run Code Online (Sandbox Code Playgroud)
这是模拟错误(在运行时发生).
来自IEEE 1076-1993:
7.2.4添加运营商
添加运算符+和 - 是为任何数字类型预定义的,并具有其传统的数学含义.
这意味着"+"运算符的结果可以在x的子类型约束之外.请注意,声明为"+"提供重载的函数不允许指定结果子类型.(返回的值可以是使用子类型指示声明的对象,可以定义值范围或数组长度).
和12.6.2信号值的传播
为了在给定的模拟周期期间更新信号,内核过程首先确定该信号的驱动和有效值.然后,内核进程使用新确定的有效值更新包含信号当前值的变量,如下所示:
a)如果S是某种不是数组类型的信号,则S的有效值用于更新S的当前值.检查S的有效值是否属于S的子类型.如果此子类型检查失败,则会发生错误.最后,S的有效值被分配给表示信号当前值的变量.
如果加法的结果与目标x的子类型约束不匹配,则会生成错误.该子类型约束由对象x声明提供,该声明提供整数(范围)的子类型指示.
运行时错误导致模拟终止以符合LRM的实现.
如果没有标准化的错误报告格式,ghdl不会提供当前的模拟时间.可以通过检查产生的波形来找到:
20 ns后波形正在更新.下一个预定活动:
library ieee;
use ieee.std_logic_1164.all;
entity foo_tb is
end entity;
architecture foo of foo_tb is
signal clk: std_logic := '0';
begin
DUT:
entity work.foo
port map (
clk => clk
);
CLOCK:
process
begin
wait for 5 ns;
clk <= not clk;
if now > 30 ns then
wait;
end if;
end process;
end architecture;
Run Code Online (Sandbox Code Playgroud)
clns的上升沿可能是25 ns.
所以这告诉我们受约束的整数如何产生溢出错误.
没有子类型约束的整数怎么样:
architecture fum of foo is
signal x : integer := INTEGER'HIGH - 2;
begin
process (clk)
begin
if rising_edge(clk) then
x <= x + 1;
end if;
end process;
end architecture;
Run Code Online (Sandbox Code Playgroud)
我们将x定义为无约束整数设置它的默认值,我们期望x溢出.
包标准明确声明INTEGER"+":
-- function "+" (anonymous, anonymous: INTEGER) return INTEGER;
Run Code Online (Sandbox Code Playgroud)
如果我们看到"+"具有普通的数学意义,则预期结果超出INTEGER的范围.
但是,从包标准中的实现依赖声明:
type integer is range -2147483648 to 2147483647;
Run Code Online (Sandbox Code Playgroud)
和模拟:
我们看到x环绕的价值.
"+"运算符结果的赋值没有违反任何约束:
3种类型:
给定类型的对象的可能值的集合可以经受被称为约束的条件(也包括不施加约束的约束的情况); 如果满足相应条件,则称该值满足约束.子类型是与约束一起的类型.如果一个值属于该类型并满足约束,则该值属于给定类型的子类型; 给定的类型称为子类型的基本类型.类型是其自身的子类型; 据说这种子类型不受约束(它对应于不施加限制的条件).类型的基类型是类型本身.
在我们的第二个体系结构中,没有约束,但类型为INTEGER的声明范围之外没有可能的值.该值反而翻转.
已经构造了VHDL的语义以在此不需要检测,这与表示二进制位(硬件)的元素的单维数组上的数学运算相匹配.