如何在 VHDL 中使用有符号和无符号
VHDL 中的有符号和无符号类型是位向量,就像 std_logic_vector 类型一样。不同之处在于,虽然 std_logic_vector 非常适合实现数据总线,但对于执行算术运算却毫无用处。
如果您尝试将任何数字添加到 std_logic_vector 类型,ModelSim 将产生编译错误:中缀运算符“+”没有可行条目。这是因为编译器不知道如何解释向量的这个比特集合。
这篇博文是基本 VHDL 教程系列的一部分。
我们必须将向量声明为有符号或无符号,以便编译器将其视为数字。
声明有符号和无符号信号的语法是:signal <name> : signed(<N-bits> downto 0) := <initial_value>;
signal <name> : unsigned(<N-bits> downto 0) := <initial_value>;
就像 std_logic_vector 一样,范围可以是 to
或 downto
任何范围。但是用 downto 0
以外的范围声明信号 如此罕见,以至于在这个主题上花费更多时间只会使我们感到困惑。初始值是可选的,默认是'U'
所有位。
我们已经在使用 integer
在之前的教程中输入算术运算。那么为什么我们需要有符号和无符号类型呢?对于大多数人来说,数字设计师喜欢更好地控制信号实际使用的位数。
此外,有符号和无符号值会环绕,而如果 integer
模拟器将抛出运行时错误 增加超出范围。最后,有符号和无符号可以有其他值,如 'U'
和 'X'
, 而整数只能有数字值。这些元值可以帮助我们发现设计中的错误。
运动
在本视频中,我们将了解有符号和无符号信号的行为方式有何相似之处,以及它们的行为方式有何不同:
我们在本教程中创建的最终代码:
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity T12_SignedUnsignedTb is end entity; architecture sim of T12_SignedUnsignedTb is signal UnsCnt : unsigned(7 downto 0) := (others => '0'); signal SigCnt : signed(7 downto 0) := (others => '0'); signal Uns4 : unsigned(3 downto 0) := "1000"; signal Sig4 : signed(3 downto 0) := "1000"; signal Uns8 : unsigned(7 downto 0) := (others => '0'); signal Sig8 : signed(7 downto 0) := (others => '0'); begin process is begin wait for 10 ns; -- Wrapping counter UnsCnt <= UnsCnt + 1; SigCnt <= SigCnt + 1; -- Adding signals Uns8 <= Uns8 + Uns4; Sig8 <= Sig8 + Sig4; end process; end architecture;
ModelSim 中的波形窗口,放大了有趣的部分:
分析
波形中所有信号的基数都设置为十六进制,以便我们可以平等比较。
在包装计数器示例中,我们看到有符号和无符号信号的行为方式完全相同。 UnsCnt
和 SigCnt
从 0 开始,逐一递增直到 FF。十六进制 FF(十进制 255)是我们的 8 位信号可以容纳的最大值。因此,下一个增量将它们都包装回 0。
我们创建了两个 4 位信号 Uns4
和 Sig4
,并给他们两个初始值“1000”。从波形中我们可以看出,它们都只是十六进制8(二进制1000)。
我们创建的最后两个 8 位信号是 Uns8
和 Sig8
.我们可以从波形中看出,它们的初始值为 0,正如人们所期望的那样。但是从那里开始,他们的行为就不同了!显然,有符号和无符号类型在添加两个不同长度的信号时会有所不同。
这是因为称为 符号扩展 .添加存储在等长向量中的正数或负数在数字逻辑中是相同的操作。这是因为二进制补码的工作原理。如果向量的长度不同,则必须延长最短的向量。
无符号 4 位二进制数“1000”是十进制 8,而有符号 4 位数字“1000”是十进制 -8。有符号数最左边的“1”表示这是一个负数。因此,编译器对这两个 4 位信号进行了不同的符号扩展。
这是符号扩展如何为 Uns8
创建不同值的可视化 和 Sig8
信号:
外卖
- 有符号和无符号类型的信号是可用于算术运算的向量
- 有符号和无符号类型的信号会静默溢出
- 符号扩展可能会为有符号和无符号类型创建不同的结果
转到下一个教程 »
VHDL