如何在 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