我有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 <= x11 + 2*x21 + x31 - x13 - 2*x23 - x33;
您可能会注意到的问题是,从操作中获取的值超出了输出整数可能的值的范围 . 发生这种情况时,我的模拟会崩溃 . 我不知道我正在尝试做什么的正确的词,因此似乎无法弄清楚如何解决这个问题,它让我发疯 . 我基本上只想截断,或减小输出的大小,以确保它适合gradientInX输出端口 . 我尝试使用这样的进程块:
-- declared signals
signal gradientMem: integer;
--beginning of my architecture
begin
SobelOperator : process(gradientMem)
begin
gradientMem <= x11 + 2*x21 + x31 - x13 - 2*x23 - x33;
if (gradientMem > 255) then
gradientMem <= 255;
elsif (gradientMem < 0) then
gradientMem <= 0;
end if;
end process SobelOperator;
然后将gradientMem分配给gradientInX但由于某种原因它不起作用 . 真的很感激任何帮助 . 注意:我没有包含所有VHDL代码,因为我认为它会不必要地长 . 我得到的错误信息是来自操作的信号结果值超出范围(因为结果值为负且输出的范围仅为0到255) .
马修
3 回答
这是您应该使用变量而不是信号的少数几种情况之一 .
顺便说一句,此操作称为 clipping .
如果你想要 truncate ,那么这个过程应该写成:
正如@Paebbels在评论中建议的那样,很可能gradientMem的范围不足以处理操作的输出 .
需要注意的是:在整数运算中,中间范围(大部分)被认为是32b有符号,并且在赋值中检查范围 . 这为合成工具提供了很多推测,并且可以产生比最佳设计大得多的设计 .
为了克服这个问题,ieee.numeric_std.all用于未签名和签名的类型和操作 . 这给出了中间矢量长度的绝对控制 . 这也迫使您了解正在进行的加法,减法,乘法等操作,这通常有助于RTL设计 .
但是,需要注意的是,在矢量形式中,使用两者中最长的中间矢量长度成对地评估操作 .
例如:
得到:
使用括号解决了问题:
错误位于流程
SobelOperator : process(gradientMem)
的敏感度列表中 . 这里必须是影响结果信号的信号,换句话说,这是一个过程敏感的信号列表 . 所以应该有x11
,x21
,x31
,x13
,x23
和x33
,如SobelOperator : process(x11, x21, x31, x13, x23, x33)