大多数(如果不是全部)VHDL 教科书都会随意列出算术运算符,其中更随意地列出左移算术(SLA),即左移填充最右边的元素。虽然连wikipedia也不同意这个定义,但我从来没有见过有人对这个定义眨眼,它只是从表面上看,“是的,有道理”。
然而,在二进制算术中填充最右边的值显然完全没有用,这让我想知道 - 有人发现 SLA 在现实生活中真正有很好的用途吗?
(我并不反对SLA的存在,也不想从VHDL中根除它。这只是复活节假期的一点乐趣......)
这个网站提到:
VHDL 中曾经内置过实际的移位运算符。它们是:srl、sll、sra、sla。然而,这些轮班运算符从未正确工作并已从语言中删除。该网站详细介绍了这些 VHDL 移位运算符的历史,并讨论了为什么它们被 shift_right() 和 shift_left() 函数取代。
但是链接已损坏。
您链接的维基百科页面显示了一些非常重要的内容
VHDL 算术左移运算符 [sla] 很不寻常。它将原始 LSB 复制到新的 LSB 中,而不是用零填充结果的 LSB。虽然这是算术右移的精确镜像,但它不是运算符的传统定义,也不等于乘以 2 的幂。在 VHDL 2008 标准中,这种奇怪的行为保持不变(对于对于没有强制数字解释的参数类型(例如,BIT_VECTOR)但“SLA”对于无符号和有符号参数类型的行为符合预期 (即,最右边的位置用零填充)。 VHDL 的逻辑左移 (SLL) 函数确实实现了前面提到的“标准”算术移位。
即现在我们遇到了一个特殊的情况,即
sla
对于不同的数据类型表现不同。这对我来说听起来是一件非常愚蠢的事情。
但是,这是预期的......根据我的经验,IEEE 标准化委员会主要由很多年长的人组成,其中一些人在委员会成立时就在那里(<'87). The rest are representatives of companies, that also don't like change. If
sla
等将被删除,这意味着大量旧代码必须重写。
然后,经过几个月的讨论,他们决定通过保留旧数据类型的旧行为并更改新数据类型的行为来让老人高兴......
编辑
为了让它更尴尬,似乎
sla
没有为 std_logic_vector
和 unsigned
类型等定义......但它又为 ufixed
类型等定义。所以我设法编写了一些(vhdl-2008)代码来演示行为的差异:
entity test_e is
end entity;
library ieee;
architecture test_a of test_e is
constant value1 : bit_vector(3 downto 0) := "0001";
constant value2 : bit_vector(3 downto 0) := value1 sla 2;
use ieee.fixed_pkg.all;
constant value3 : ufixed(3 downto 0) := to_ufixed(1,3,0);
constant value4 : ufixed(3 downto 0) := value3 sla 2;
begin
end architecture;
模拟时,value2 将保持“0111”,value4 将保持“0100”。
当然,当需要倍增到2^n时,只需SLA到n位即可。
我在当前项目中使用它,为了减少FPGA的使用资源,在除法之前我使用SRA,结果我得到的数字比原来要小,使用除法然后使用SRL得到正确的值比例。
看起来像,
C=A/B
,减少了C*N=(A/N)/B
。
您在 C 中遇到一些错误,但减少了使用的资源。