IMO 这需要属性:
procedure mul_fixed (
signal a : in unsigned_fixed;
signal b : in unsigned_fixed;
signal c : out unsigned_fixed
) is
constant a_temp : unsigned(a'length - 1 downto 0) := to_unsigned(a);
constant b_temp : unsigned(b'length - 1 downto 0) := to_unsigned(b);
variable result : unsigned(a'length + b'length - 1 downto 0);
-- notice this might be negative if a, b are (? downto +n), which is correct
constant num_fractional : integer := 0 - a'right - b'right;
-- c integral might be bigger than integral/fractional part, make sure we only access valid indices in result
constant result_left : integer := min(result'length - 1, num_fractional + c'left);
constant result_right : integer := max(0 , num_fractional + c'right);
begin
result := a_temp * b_temp;
c <= (others => '0'); -- make sure all bits are defined
c(result_left - num_fractional downto result_right - num_fractional) <= result(result_left downto result_right);
end procedure mul_fixed;
在哪里
type unsigned_fixed is array(range <>) of std_logic;
并且存在与无符号的转换函数。
所以你会
...
signal a : unsigned_fixed( 3 downto -10); -- 4Q10
signal b : unsigned_fixed(-1 downto -8); -- 0Q8
signal c : unsigned_fixed( 3 downto -10); -- 4Q10
mul_fixed(a, b, c);
我知道所有这些属性一开始看起来很可怕,但我经常发现自己编写了许多毫无意义的包,只是因为我有不同的数据类型:-/ IMO 应该花时间考虑一下,找出一个通用的解决方案并继续前进——那就是毕竟,VHDL 属性的用途是什么。
- 请注意,我在编写此代码时无法访问测试环境,因此在将结果分配给 c 时可能需要也可能不需要进行类型转换。
此外,如果可以的话,您可能至少应该看看定点库。或者使用带有定点包的 VHDL-2008。