为什么 VHDL 左移器不起作用?
Why won't VHDL left shifter work?
我是 VHDL 的新手,我正在尝试编写一个接受 32 位值和 5 位值的左移器。然后,左移器尝试通过向左移出由 5 位数指定的位数并在右边带来那么多的零来执行 32 位值的逻辑左移。我不明白为什么数组符号不起作用。 1 << 1 的结果产生 20000000 而不是 00000002。有人可以解释我哪里出错了吗?这是代码:
SIGNAL lshiftOutput : STD_LOGIC_VECTOR( 31 downto 0 );
COMPONENT Lshift32
Port( a : in STD_LOGIC_VECTOR( 31 downto 0 );
b : in STD_LOGIC_VECTOR( 4 downto 0 );
lshiftOutput : out STD_LOGIC_VECTOR( 31 downto 0 ) );
END COMPONENT;
PROCESS( a, b, opcode, adderOutput, subtractOutput, xorOutput, lshiftOutput, rshiftOutput )
BEGIN
IF opcode = "0000" THEN
result <= x"00000000";
ELSIF opcode = "0001" THEN
result <= adderOutput;
ELSIF opcode = "0010" THEN
result <= subtractOutput;
ELSIF opcode = "0011" THEN
result <= NOT a;
ELSIF opcode = "0100" THEN
result <= a AND b;
ELSIF opcode = "0101" THEN
result <= a OR b;
ELSIF opcode = "0110" THEN
result <= xorOutput;
ELSIF opcode = "0111" THEN
result <= lshiftOutput;
ELSIF opcode = "1000" THEN
result <= rshiftOutput;
END IF;
END PROCESS;
LIBRARY ieee;
USE ieee.std_logic_unsigned.ALL;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY Lshift32 IS
Port( a : in STD_LOGIC_VECTOR ( 31 downto 0 );
b : in STD_LOGIC_VECTOR ( 4 downto 0 );
lshiftOutput : out STD_LOGIC_VECTOR ( 31 downto 0 ) );
END Lshift32;
ARCHITECTURE Lshift32Architecture of Lshift32 IS
BEGIN
PROCESS( a, b )
VARIABLE shiftAmount : INTEGER := 0;
BEGIN
shiftAmount := to_integer( b(4 downto 0) );
-- Shift left
lshiftOutput <= a( 31-shiftAmount downto 0 ) & ( shiftAmount-1 downto 0 => '0' );
END PROCESS;
END Lshift32Architecture;
这个测试台是:
-- Shift Left -------------------------------------------------------
WAIT FOR 9 ns;
op <= "0111";
-- 1 << 1
input_a <= x"00000001";
input_b <= x"00000001";
WAIT FOR 1 ns;
IF (output /= x"00000002") THEN
ASSERT false REPORT "1 << 1 has incorrect result" severity error;
END IF;
Brian 要求您提供 Minimal, Complete, and Verifiable example,您编辑的代码没有这样做。询问的原因是可以围绕您最初提供的代码部分创建一个 mcve,它确实给出了正确的答案:
library ieee; -- added
use ieee.std_logic_1164.all; -- added
use ieee.numeric_std_unsigned.all; -- added
entity lshift32 is
port( a : in std_logic_vector ( 31 downto 0 );
b : in std_logic_vector ( 4 downto 0 );
lshiftoutput : out std_logic_vector ( 31 downto 0 ) );
end entity lshift32;
architecture lshift32architecture of lshift32 is
begin
process( a, b )
variable shiftamount : integer := 0;
begin
shiftamount := to_integer( b(4 downto 0) );
-- shift left
lshiftoutput <= a( 31-shiftamount downto 0 ) & ( shiftamount-1 downto 0 => '0' );
end process;
end architecture lshift32architecture;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std_unsigned.all;
entity lshift32_tb is
end entity;
architecture foo of lshift32_tb is
signal a: std_logic_vector (31 downto 0) := (others => '0');
signal b: std_logic_vector (4 downto 0) := (others => '0');
signal lshiftoutput: std_logic_vector (31 downto 0);
begin
DUT:
entity work.lshift32
port map (
a => a,
b => b,
lshiftoutput => lshiftoutput
);
SIMULIS:
process
begin
wait for 10 ns;
a(0) <= '1'; -- 1
b(0) <= '1'; -- 1
wait for 10 ns;
wait;
end process;
ANALYSIS:
process (lshiftoutput)
variable shiftamount: integer;
begin
if now > 0 ns then
shiftamount := to_integer(b);
report "ShiftAmount = " & integer'image(shiftamount);
report "lshiftOutput = " & to_string(lshiftoutput);
end if;
end process;
end architecture;
和 运行 上面的测试平台给出:
ghdl -a --std=08 lshift.vhdl
ghdl -e --std=08 lshift32_tb
ghdl -r lshift32_tb
lshift.vhdl:60:13:@10ns:(report note): ShiftAmount = 1
lshift.vhdl:61:13:@10ns:(report note): lshiftOutput = 00000000000000000000000000000010
你的执行失败说明你的上下文子句(use 子句)有问题或者你的测试平台有问题。
请注意,您同时使用了 none 标准包 std_logic_unsigned 和 IEEE 标准包 numeric_std。你真的不应该混搭,否则会产生意想不到的后果。
包 numeric_std_unsigned 可用于符合 IEEE Std 1076-2008 标准的 VHDL 实现。如果使用以前版本的 VHDL 标准,您可以使用 package numeric_std 并键入 convert b
to unsigned 作为传递给 to_integer
.
的表达式
对于随此答案提供的测试台,您还会发现未提供 to_string
for std_logic_vector。没有看到你的整个测试平台,它很可能是功能性的。
如果您想证明所提供的答案在非 -2008 修订版环境中有效:
function to_string (inp: std_logic_vector) return string is
variable image_str: string (1 to inp'length);
alias input_str: std_logic_vector (1 to inp'length) is inp;
begin
for i in input_str'range loop
image_str(i) := character'VALUE(std_ulogic'IMAGE(input_str(i)));
end loop;
return image_str;
end function;
该函数可以作为体系结构声明项提供。
我是 VHDL 的新手,我正在尝试编写一个接受 32 位值和 5 位值的左移器。然后,左移器尝试通过向左移出由 5 位数指定的位数并在右边带来那么多的零来执行 32 位值的逻辑左移。我不明白为什么数组符号不起作用。 1 << 1 的结果产生 20000000 而不是 00000002。有人可以解释我哪里出错了吗?这是代码:
SIGNAL lshiftOutput : STD_LOGIC_VECTOR( 31 downto 0 );
COMPONENT Lshift32
Port( a : in STD_LOGIC_VECTOR( 31 downto 0 );
b : in STD_LOGIC_VECTOR( 4 downto 0 );
lshiftOutput : out STD_LOGIC_VECTOR( 31 downto 0 ) );
END COMPONENT;
PROCESS( a, b, opcode, adderOutput, subtractOutput, xorOutput, lshiftOutput, rshiftOutput )
BEGIN
IF opcode = "0000" THEN
result <= x"00000000";
ELSIF opcode = "0001" THEN
result <= adderOutput;
ELSIF opcode = "0010" THEN
result <= subtractOutput;
ELSIF opcode = "0011" THEN
result <= NOT a;
ELSIF opcode = "0100" THEN
result <= a AND b;
ELSIF opcode = "0101" THEN
result <= a OR b;
ELSIF opcode = "0110" THEN
result <= xorOutput;
ELSIF opcode = "0111" THEN
result <= lshiftOutput;
ELSIF opcode = "1000" THEN
result <= rshiftOutput;
END IF;
END PROCESS;
LIBRARY ieee;
USE ieee.std_logic_unsigned.ALL;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY Lshift32 IS
Port( a : in STD_LOGIC_VECTOR ( 31 downto 0 );
b : in STD_LOGIC_VECTOR ( 4 downto 0 );
lshiftOutput : out STD_LOGIC_VECTOR ( 31 downto 0 ) );
END Lshift32;
ARCHITECTURE Lshift32Architecture of Lshift32 IS
BEGIN
PROCESS( a, b )
VARIABLE shiftAmount : INTEGER := 0;
BEGIN
shiftAmount := to_integer( b(4 downto 0) );
-- Shift left
lshiftOutput <= a( 31-shiftAmount downto 0 ) & ( shiftAmount-1 downto 0 => '0' );
END PROCESS;
END Lshift32Architecture;
这个测试台是:
-- Shift Left -------------------------------------------------------
WAIT FOR 9 ns;
op <= "0111";
-- 1 << 1
input_a <= x"00000001";
input_b <= x"00000001";
WAIT FOR 1 ns;
IF (output /= x"00000002") THEN
ASSERT false REPORT "1 << 1 has incorrect result" severity error;
END IF;
Brian 要求您提供 Minimal, Complete, and Verifiable example,您编辑的代码没有这样做。询问的原因是可以围绕您最初提供的代码部分创建一个 mcve,它确实给出了正确的答案:
library ieee; -- added
use ieee.std_logic_1164.all; -- added
use ieee.numeric_std_unsigned.all; -- added
entity lshift32 is
port( a : in std_logic_vector ( 31 downto 0 );
b : in std_logic_vector ( 4 downto 0 );
lshiftoutput : out std_logic_vector ( 31 downto 0 ) );
end entity lshift32;
architecture lshift32architecture of lshift32 is
begin
process( a, b )
variable shiftamount : integer := 0;
begin
shiftamount := to_integer( b(4 downto 0) );
-- shift left
lshiftoutput <= a( 31-shiftamount downto 0 ) & ( shiftamount-1 downto 0 => '0' );
end process;
end architecture lshift32architecture;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std_unsigned.all;
entity lshift32_tb is
end entity;
architecture foo of lshift32_tb is
signal a: std_logic_vector (31 downto 0) := (others => '0');
signal b: std_logic_vector (4 downto 0) := (others => '0');
signal lshiftoutput: std_logic_vector (31 downto 0);
begin
DUT:
entity work.lshift32
port map (
a => a,
b => b,
lshiftoutput => lshiftoutput
);
SIMULIS:
process
begin
wait for 10 ns;
a(0) <= '1'; -- 1
b(0) <= '1'; -- 1
wait for 10 ns;
wait;
end process;
ANALYSIS:
process (lshiftoutput)
variable shiftamount: integer;
begin
if now > 0 ns then
shiftamount := to_integer(b);
report "ShiftAmount = " & integer'image(shiftamount);
report "lshiftOutput = " & to_string(lshiftoutput);
end if;
end process;
end architecture;
和 运行 上面的测试平台给出:
ghdl -a --std=08 lshift.vhdl
ghdl -e --std=08 lshift32_tb
ghdl -r lshift32_tb
lshift.vhdl:60:13:@10ns:(report note): ShiftAmount = 1
lshift.vhdl:61:13:@10ns:(report note): lshiftOutput = 00000000000000000000000000000010
你的执行失败说明你的上下文子句(use 子句)有问题或者你的测试平台有问题。
请注意,您同时使用了 none 标准包 std_logic_unsigned 和 IEEE 标准包 numeric_std。你真的不应该混搭,否则会产生意想不到的后果。
包 numeric_std_unsigned 可用于符合 IEEE Std 1076-2008 标准的 VHDL 实现。如果使用以前版本的 VHDL 标准,您可以使用 package numeric_std 并键入 convert b
to unsigned 作为传递给 to_integer
.
对于随此答案提供的测试台,您还会发现未提供 to_string
for std_logic_vector。没有看到你的整个测试平台,它很可能是功能性的。
如果您想证明所提供的答案在非 -2008 修订版环境中有效:
function to_string (inp: std_logic_vector) return string is
variable image_str: string (1 to inp'length);
alias input_str: std_logic_vector (1 to inp'length) is inp;
begin
for i in input_str'range loop
image_str(i) := character'VALUE(std_ulogic'IMAGE(input_str(i)));
end loop;
return image_str;
end function;
该函数可以作为体系结构声明项提供。