2

我正在制作一个接收 32 位输入和 7 位控制输入的组件。这个组件的作用是查看 S 的最后 2 位和

  • S = 00,它在 inp 上进行逻辑左移
  • S = 01,它在 inp 上进行逻辑右移
  • S = 10,它在 inp 上进行算术右移
  • S = 11,它确实在 inp 上向右旋转

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

找到运算符“sra”的“0”定义,无法确定“sra”的确切重载匹配定义我的代码是:

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;
4

2 回答 2

4

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

“sra”运算符并未针对numeric_std. 你必须做一些铸造才能得到你想要的。但最好使用shift_leftandshift_right函数并明确。

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

如果您的输入是,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 或 case。)

于 2016-03-15T21:14:26.523 回答
4

您的代码可以在 VHDL 中“按原样”使用。

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;

因为条件依赖的 if 语句stype是互斥的,所以您可以将内部 if 语句替换为 case 语句,或者将单个 if 语句替换为 elsif 替代条件。这将允许在 的第一个匹配值之后出现条件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 注释。

于 2016-03-15T23:23:37.840 回答