' SRA'不在VHDL工作

时间:2016-03-15 20:10:42

标签: vhdl alu

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

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

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

  

发现' 0' operator" sra"的定义无法确定" 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;

2 个答案:

答案 0 :(得分:4)

首先,我建议您使用shift_left()shift_right()rotate_left()rotate_right()功能。 VHDL&#39; 87和VHDL&#39;之间的移位运算符存在已知问题和可移植性问题(参见here)。

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

另请注意,sra的含义与srl输入的unsigned相同。为什么在这种情况下甚至定义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或案件。)

答案 1 :(得分:4)

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

在-2008之前的IEEE包numeric_std中未定义

sra 。您的代码将使用符合-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语句是互斥的,所以可以用if语句替换内部if语句或用elsif替换条件替换单个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;

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

一般情况下,您应该使用shift_right,shift_left,向右旋转并将包numeric_std中定义的左侧函数旋转为PlayDough音符。