'sra' 无法在 VHDL 中工作
'sra' not working in VHDL
我正在制作一个接受 32 位输入和 7 位控制输入的组件。这个组件所做的是它查看 S 的最后 2 位和 for
- S = 00,它在 inp
上进行逻辑左移
- S = 01,它在 inp
上进行逻辑右移
- S = 10,它在 inp
上做算术右移
- S = 11,它确实在 inp
上向右旋转
移位的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_left
和 shift_right
函数并明确说明。
另请注意,对于 unsigned
输入,sra
的含义与 srl
相同。为什么在这种情况下还要定义一个 sra
操作?也许您想要签名的输入?
如果您的输入是 signed
,可以通过以下操作在 srl
和 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 或一个案例。)
您的代码可以在 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 注释。
我正在制作一个接受 32 位输入和 7 位控制输入的组件。这个组件所做的是它查看 S 的最后 2 位和 for
- S = 00,它在 inp 上进行逻辑左移
- S = 01,它在 inp 上进行逻辑右移
- S = 10,它在 inp 上做算术右移
- S = 11,它确实在 inp 上向右旋转
移位的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_left
和 shift_right
函数并明确说明。
另请注意,对于 unsigned
输入,sra
的含义与 srl
相同。为什么在这种情况下还要定义一个 sra
操作?也许您想要签名的输入?
如果您的输入是 signed
,可以通过以下操作在 srl
和 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 或一个案例。)
您的代码可以在 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 注释。