我正在制作一个输入32位和7位控制输入的组件。这个组件的作用是它查看S的最后2位和
移位的数量/数量由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;
答案 0 :(得分:4)
首先,我建议您使用shift_left()
,shift_right()
,rotate_left()
和rotate_right()
功能。 VHDL&#39; 87和VHDL&#39;之间的移位运算符存在已知问题和可移植性问题(参见here)。
&#34; sra&#34;未在numeric_std
中为所有类型定义运算符。你必须做一些铸造才能得到你想要的东西。但最好使用shift_left
和shift_right
函数并明确。
另请注意,sra
的含义与srl
输入的unsigned
相同。为什么在这种情况下甚至定义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或案件。)
答案 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音符。