代码之家  ›  专栏  ›  技术社区  ›  Ankit Shubham

“sra”在VHDL中不工作

  •  2
  • Ankit Shubham  · 技术社区  · 8 年前

    我正在制作一个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;
    
    2 回复  |  直到 8 年前
        1
  •  4
  •   user1155120 user1155120    8 年前

    您的代码可以在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 可以用case语句替换内部if语句,或者用elsif替换条件替换单个if语句。这将允许在第一个匹配值 手写笔 .

    看起来是这样的:

    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、rotate right和rotate left函数。

        2
  •  4
  •   PlayDough    8 年前

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

    未为中的所有类型定义“sra”运算符 numeric_std 。你必须做一些选角才能得到你想要的。但最好使用 shift_left shift_right 功能和明确。

    还要注意 sra 与相同 srl 对于 unsigned 输入为什么还要定义 sra公司 这种情况下的操作?也许你想要签名输入?

    如果您的输入是 signed ,可以选择 固体火箭发动机 sra公司 通过执行以下操作:

    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。)