'sra' 无法在 VHDL 中工作

'sra' not working in VHDL

我正在制作一个接受 32 位输入和 7 位控制输入的组件。这个组件所做的是它查看 S 的最后 2 位和 for

移位的amount/number由S的前5位决定。例如如果S=0001001,则输入必须逻辑右移2位。下面是我的代码。问题出现在 'sra' 中,出现以下错误:

found '0' definitions of operator "sra", cannot determine exact overloaded matching definition for "sra" My code is:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity barrelshifter is
port(
clk : in std_logic;
    inp : in unsigned (31 downto 0):= (others => '0'); 
    s : in unsigned (6 downto 0);
    outp : out unsigned (31 downto 0)
    );
end barrelshifter;

architecture Behavioral of barrelshifter is
  signal samt : unsigned (4 downto 0);
  signal stype : unsigned (1 downto 0);
  signal inp1 : unsigned (31 downto 0);
begin
  samt <= s(6 downto 2);
  stype <= s(1 downto 0);
  inp1 <= inp;

  process(clk)
  begin 
    if  stype = "00"  then 
      outp <= inp sll to_integer(samt);  
    end if;   
    if  stype = "01"  then
      outp <= inp srl to_integer(samt);
    end if; 
    if  stype = "10"  then
      outp <= inp sra to_integer(samt);
    end if; 
    if  stype = "11"  then
      outp <= inp ror to_integer(samt);
    end if; 
  end process;
end Behavioral;

首先,我建议您改用 shift_left()shift_right()rotate_left()rotate_right() 函数。 VHDL '87 和 VHDL '08 之间的移位运算符存在已知问题和可移植性问题(参见 here)。

"sra" 运算符并未为 numeric_std 中的所有类型定义。你必须做一些铸造才能得到你想要的。但最好使用 shift_leftshift_right 函数并明确说明。

另请注意,对于 unsigned 输入,sra 的含义与 srl 相同。为什么在这种情况下还要定义一个 sra 操作?也许您想要签名的输入?

如果您的输入是 signed,可以通过以下操作在 srlsra 之间进行选择:

outp <= signed(shift_right(unsigned(inp), to_integer(samt))); -- srl
outp <= shift_right(inp, to_integer(samt)); --sra

(编辑:您还缺少 rising_edge() 进行轮班的流程检查。)

(编辑 2:您最好使用 case 语句来选择移位操作。您拥有的 if 链虽然互斥,但不是典型的编码风格。要么使用 if/elsif/else 或一个案例。)

您的代码可以在 VHDL 中使用 'as is'。

sra 未在 -2008 之前的 IEEE 包 numeric_std 中定义。您的代码将使用符合 -2008 的 VHDL 实现进行分析而不会出错

否则对于先前版本兼容的实现:

outp <= unsigned (to_stdlogicvector(to_bitvector(std_logic_vector(inp)) sra to_integer(samt)));

因为 sra 是为 bit_vector 类型预定义的,而 samt 是无符号类型(具有具有自然范围的等效二进制值)。

您还缺少符合条件的时序逻辑综合 RTL 描述 - 未标记的过程在其敏感列表中有 clk

更改它并在符合 -2008 之前的 VHDL 实现中显示上述修复:

library ieee;
use ieee.std_logic_1164.all;

use ieee.numeric_std.all;

entity barrelshifter is
    port (
        clk:  in  std_logic;
        inp:  in  unsigned (31 downto 0):= (others => '0'); 
        s:    in  unsigned (6 downto 0);
        outp: out unsigned (31 downto 0)
    );
end entity barrelshifter;

architecture behavioral of barrelshifter is
    signal samt:   unsigned (4 downto 0);
    signal stype:  unsigned (1 downto 0);
    signal inp1:   unsigned (31 downto 0);
begin
    samt <= s(6 downto 2);
    stype <= s(1 downto 0);
    inp1 <= inp; 

UNLABELLED:    
    process(clk)
    begin 
        if rising_edge(clk) then
            if stype = "00" then 
                outp <= inp sll to_integer(samt);  
            end if;   
            if stype = "01" then
                outp <= inp srl to_integer(samt);
            end if; 
            if stype = "10" then
                outp <= unsigned (to_stdlogicvector(to_bitvector(std_logic_vector(inp)) sra to_integer(samt)));
            end if; 
            if stype = "11" then
                outp <= inp ror to_integer(samt);
            end if;
        end if; 
    end process;
end architecture behavioral;

因为条件取决于 stype 的 if 语句是互斥的,您可以用 case 语句或带有 elsif 替代条件的单个 if 语句替换内部 if 语句。这将允许在 stype.

的第一个匹配值之后的条件

看起来像这样:

architecture with_elsif of barrelshifter is
    signal samt:   unsigned (4 downto 0);
    signal stype:  unsigned (1 downto 0);
    signal inp1:   unsigned (31 downto 0);
begin
    samt <= s(6 downto 2);
    stype <= s(1 downto 0);
    inp1 <= inp; 

UNLABELLED:    
    process(clk)
    begin 
        if rising_edge(clk) then
            if stype = "00" then 
                outp <= inp sll to_integer(samt);  
            -- end if;
            elsif stype = "01" then
                outp <= inp srl to_integer(samt);
            -- end if;
            elsif stype = "10" then
                outp <= unsigned (to_stdlogicvector(to_bitvector(std_logic_vector(inp)) sra to_integer(samt)));
                -- end if; 
            elsif stype = "11" then
                outp <= inp ror to_integer(samt);
            end if;
        end if; 
    end process;
end architecture with_elsif;

或者这个:

architecture with_case of barrelshifter is
    signal samt:   unsigned (4 downto 0);
    signal stype:  unsigned (1 downto 0);
    signal inp1:   unsigned (31 downto 0);
begin
    samt <= s(6 downto 2);
    stype <= s(1 downto 0);
    inp1 <= inp; 

UNLABELLED:    
    process(clk)
    begin 
        if rising_edge(clk) then
            case stype is
                when "00" => 
                    outp <= inp sll to_integer(samt);  
                when "01" =>
                    outp <= inp srl to_integer(samt);
                when "10" => 
                    outp <= unsigned (to_stdlogicvector(to_bitvector(std_logic_vector(inp)) sra to_integer(samt)));
                when "11" =>
                    outp <= inp ror to_integer(samt);
                when others =>
            end case;
        end if; 
    end process;
end architecture with_case;

所有这些代码示例分析。这三种架构尚未被模拟,我们鼓励您这样做以确保操作员按照您的期望进行操作。

一般来说,您应该使用包 numeric_std 中定义的 shift_right、shift_left、向右旋转和向左旋转功能,如 PlayDough 注释。