在VHDL

时间:2016-02-16 19:46:01

标签: vhdl

我正在尝试编写一些代码,这些代码只是向左或向右移动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。但我无法弄清楚为什么会这样做,我也无法在网上找到任何与我正在做的事情有所不同的资源。我非常感谢任何帮助。

3 个答案:

答案 0 :(得分:4)

-2147483648(-2 ** 31)是整数的默认初始值,是其范围内最左侧,最负值。它表明尚未执行shift的信号分配。最有可能的原因是它是一个连续的分配,并且shamt上的事件还没有导致它更新。

std_logic_arith不是IEEE标准库。您应该使用to_integer()中的ieee.numeric_std代替unsigned。将数字端口保持为signedx也是有益的,这样您的意图就可以清晰并最大限度地减少类型转换。此外,您无法直接将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;