如何在vhdl中将大整数转换为小整数?
我有VHDL代码,我试图乘以像素值。我拥有以下实体:如何在vhdl中将大整数转换为小整数?,vhdl,Vhdl,我有VHDL代码,我试图乘以像素值。我拥有以下实体: entity xGradient is port( clk : in std_logic; x11, x12, x13, x21, x22, x23, x31, x32, x33 : in integer range 0 to 255; gradientInX : out integer range 0 to 255 ); end xGradient; 我对这些执行以下操作: gradientInX <=
entity xGradient is
port(
clk : in std_logic;
x11, x12, x13, x21, x22, x23, x31, x32, x33 : in integer range 0 to 255;
gradientInX : out integer range 0 to 255
);
end xGradient;
我对这些执行以下操作:
gradientInX <= x11 + 2*x21 + x31 - x13 - 2*x23 - x33;
gradientInX流程的灵敏度列表中有一个错误SobeOperator:process(gradientMem)
。这里必须有影响结果信号的信号,换句话说,这是一个进程敏感的信号列表。因此应该有x11
,x21
,x31
,x13
,x23
和x33
像SobeOperator:process(x11,x21,x31,x13,x23,x33)
正如@Paebbels在评论中所建议的那样,gradientMem的范围很可能不足以处理操作的输出
需要注意的是:在整数运算中,中间范围(大部分)被认为是32b有符号的,并且在赋值中检查该范围。这为合成工具提供了大量的推测,并且可以产生比最优设计大得多的设计
为了克服这个问题,ieee.numeric_std.all用于无符号和有符号的类型和操作。这就为中间向量长度提供了绝对控制。这也迫使您了解加法、减法、乘法等,这通常有助于RTL设计
然而,需要注意的是,在向量形式中,运算是成对计算的,使用两个运算中最长的一个作为中间向量长度
例如:
process
variable i1 : integer range 0 to 15 := 15;
variable i2 : integer range 0 to 15 := 9;
variable i3 : integer range 0 to 15 := 11;
variable i4 : integer range 0 to 31 := 2;
variable iSum : integer range 0 to 63;
variable u1 : unsigned(3 downto 0) := to_unsigned(15,4);
variable u2 : unsigned(3 downto 0) := to_unsigned(9,4);
variable u3 : unsigned(3 downto 0) := to_unsigned(11,4);
variable u4 : unsigned(5 downto 0) := to_unsigned(2,6);
variable uSum : unsigned(5 downto 0);
begin
iSum := i1 + i2 + i3 + i4;
uSum := u1 + u2 + u3 + u4;
write(output, "int: " & to_string(iSum) & lf &
"us : " & to_string(to_integer(uSum)) & lf);
wait;
end process;
给出:
#国际:37
#美国:5
使用括号可以解决以下问题:
uSum := (u1 + (u2 + (u3 + u4)));
这是少数几个应该使用变量而不是信号的情况之一
SobelOperator : process(x11, x21, x31, x13, x23, x33)
variable gradientMem : integer;
begin
gradientMem := x11 + 2*x21 + x31 - x13 - 2*x23 - x33;
if (gradientMem > 255) then
gradientMem := 255;
elsif (gradientMem < 0) then
gradientMem := 0;
end if;
gradientInX <= gradientMem;
end process SobelOperator;
SobeOperator:进程(x11、x21、x31、x13、x23、x33)
变量gradientMem:整数;
开始
梯度记忆:=x11+2*x21+x31-x13-2*x23-x33;
如果(gradientMem>255),则
梯度Mem:=255;
elsif(gradientMem<0)则
梯度膜:=0;
如果结束;
Gradentinix嘿,谢谢你的回应!是的,我在写问题的时候注意到了。我会设法解决这个问题,看看会发生什么。我仍然想知道,例如,数字库中是否有一个函数可以将整数信号从一个范围截断为一个较小的范围。对于输出的截断,您可以使用std\u logic\u vector
类型,并从总线中获取所需的位,然后将其转换为整数,如果您需要输出为integer
typeYes,敏感度列表是错误的,但这不是他射程问题的原因…@Paebles我无法添加评论,因为我没有足够的声誉,所以我将其作为答案发布。或者我应该怎么做?写一个答案是可以的,但是仅仅改变敏感度列表是不够的。它不能解决越界错误。您的问题遗漏了两个基本部分:1)梯度的声明和2)错误消息。VHDL检查赋值的范围界限。您想创建一个饱和度算法。所以用更大的范围来定义gradientMem
。我只是编辑它来包含这些。我想我的主要问题是敏感度列表不正确。我还想知道VHDL是否有特定于整数的操作,这些操作会强制结果进入某个范围,但我猜不存在这样的函数或操作,所以我只能自己实现它。不管怎样,我的问题似乎已经解决了。谢谢你的回复,请随意添加其他内容。我知道你刚才回答了这个问题,但这是最有帮助的。谢谢
SobelOperator : process(x11, x21, x31, x13, x23, x33)
variable gradientMem : integer;
begin
gradientMem := x11 + 2*x21 + x31 - x13 - 2*x23 - x33;
if (gradientMem > 255) then
gradientMem := 255;
elsif (gradientMem < 0) then
gradientMem := 0;
end if;
gradientInX <= gradientMem;
end process SobelOperator;
SobelOperator : process(x11, x21, x31, x13, x23, x33)
variable gradientMem : integer;
begin
gradientMem := x11 + 2*x21 + x31 - x13 - 2*x23 - x33;
gradientInX <= gradientMem mod 256;
end process SobelOperator;