我正在尝试编写一些代码,这些代码只是向左或向右移动32位向量,其中5位输入将用于移位量(shamt
)。我遇到的问题是尝试将std_logic_vector
转换为integer
。我的代码是这样的:
library ieee;
use ieee.STD_LOGIC_1164.all;
use ieee.STD_LOGIC_ARITH.all;
entity shiftlogical is
port(x : in std_logic_vector(31 downto 0);
shamt : in std_logic_vector( 4 downto 0);
y : out std_logic_vector(31 downto 0));
end shiftlogical;
architecture beh of shiftlogical is
signal shift : integer;
signal temp : std_logic_vector(31 downto 0);
begin
shift <= conv_integer(unsigned(shamt));
temp <= x(shift downto 0);
y <= temp;
end beh;
我知道代码不完整,但为了测试一些想法,我试图将"00010"
(2)传递给shamt
,但转变为-2147483648。但我无法弄清楚为什么会这样做,我也无法在网上找到任何与我正在做的事情有所不同的资源。我非常感谢任何帮助。
答案 0 :(得分:4)
-2147483648(-2 ** 31)是整数的默认初始值,是其范围内最左侧,最负值。它表明尚未执行shift
的信号分配。最有可能的原因是它是一个连续的分配,并且shamt
上的事件还没有导致它更新。
std_logic_arith
不是IEEE标准库。您应该使用to_integer()
中的ieee.numeric_std
代替unsigned
。将数字端口保持为signed
或x
也是有益的,这样您的意图就可以清晰并最大限度地减少类型转换。此外,您无法直接将temp
的可变长度切片分配给resize()
,因为它们的长度不匹配。您应该使用{{1}}(来自numeric_std)将长度扩展回32位或重新考虑您的方法。
答案 1 :(得分:2)
我在实体名称中修复了明显的拼写错误,启动了模拟(ModelSim)并强制将信号shamt
强制为“00010”。然后在尝试运行1 ps之后,ModelSim抱怨:
致命:( vsim-3420)数组长度不匹配。左边是32(31下降0)。右为0(-2147483648 downto 0(空数组))。
时间:0 ps迭代次数:0进程:/ shiftlogical / line__16文件:shiftlogical.vhdl
在shiftlogical.vhdl第16行的架构中出现致命错误
这是因为所有并发语句都是并行执行的。新信号值被安排用于模拟中的下一个增量循环。因此,行
temp <= x(shift downto 0);
使用旧值shift
执行,这是该信号的初始值。凯文指出,整数的初始值是-2 ** 31。
当然你可以初始化信号shift
,但唯一不会导致错误的值将是31,因为在这个asignment中左边的信号和右边的表达式必须匹配数组( std_logic_vector
)尺寸。信号shamt
也必须强制为"11111"
,以便shift
保持31。
你无法轻易解决这个问题,因为对于左移,你必须在右边添加零(LSB),右移零或左边的标志(MSB)。
答案 2 :(得分:0)
@Martin Zabel我真正测试过的是看看shift是否会保持一个整数值,直到我试图将其传递给temp <= x(shift downto 0);
我意识到信号需要真正成为一个变量按预期工作,如下所示我的代码包括:
library ieee;
use ieee.STD_LOGIC_1164.all;
use ieee.STD_LOGIC_ARITH.all;
entity shiftlogical is
port(x: in std_logic_vector(31 downto 0);
shamt: in std_logic_vector(4 downto 0);
dir: in std_logic;
y: out std_logic_vector(31 downto 0));
end shiftlogical;
architecture beh of shiftlogical is
begin
process(dir)
variable shift : integer;
begin
shift := conv_integer(unsigned(shamt));
if(dir = '0') then --Left shift
y(31 downto shift) <= x(31-shift downto 0);
y(shift downto 0) <= (others => '0');
elsif(dir = '1') then --Right shift
y(31-shift downto 0) <= x(31 downto shift);
y(31 downto 31-shift) <= (others => '0');
else --Always left shift
y(31 downto shift) <= x(31-shift downto 0);
y(shift downto 0) <= (others => '0');
end if;
end process;
end beh;